創作 container image 的藝術
我們正處於軟體產品開發不斷發展的時代,因此對高效、一致和可擴展的部署方法的需求變得更加迫切。
該領域最重要的進步之一是容器的使用。容器徹底改變了我們建置、打包和部署應用程式的方式,提供了傳統方法通常缺乏的靈活性和可靠性。
它是 DevOps 流程自動化 (CI/CD) 中的關鍵自動化支柱之一,有助於發布已開發的凍結程式碼。它確保程式碼打包到容器鏡像後不會發生任何變更。
在本部落格中,我們將探討容器的概念,深入研究應用程式打包的傳統方法,並重點介紹建立容器映像的最佳實踐。此外,我們將提供使用容器打包 React 和基於 Java 的應用程式的範例。
容器是輕量級、可移植的軟體單元,它將應用程式及其依賴項打包在一起,確保它在不同的運算環境中一致運作。與虛擬機器不同,容器共享主機系統的內核,這使得它們在資源使用方面更加有效率。容器可以在任何支援容器執行時的系統上執行,這使其成為現代雲端原生應用程式開發和部署的理想選擇。
在容器出現之前,應用程式通常使用傳統方法打包和部署。這通常涉及建立將應用程式二進位與必要的庫和設定檔捆綁在一起的安裝包。然後將這些軟體包安裝到執行應用程式的目標系統上。雖然這種方法多年來一直有效,但它有一些固有的限制。
環境不一致:傳統的打包方法常常會導致開發、測試和生產環境之間的不一致。這可能會導致應用程式根據其執行位置的不同而表現出不同的行為。開發人員有可能會覆蓋即將部署在發布環境中的最終包,從而導致產品或功能發布的延遲。
依賴關係衝突:管理依賴關係是一項重大挑戰。不同的應用程式可能需要同一庫的不同版本,從而導致衝突和“依賴地獄”。
資源開銷:傳統方法通常需要為每個應用程式提供單獨的作業系統實例,導致資源消耗高且效率低。
複雜部署:部署過程往往複雜且容易出錯,需要人工幹預和詳細配置。
容器解決了傳統應用程式打包方法的許多缺點:
一致性:透過將應用程式及其相依性打包在一起,容器可以確保應用程式以相同的方式執行,無論其部署在何處。
隔離:容器提供進程和檔案系統隔離,降低依賴衝突的風險並增強安全性。
效率:容器共享主機系統的核心和資源,使其比虛擬機器更有效率。這允許更高的密度和更好的資源利用率。
簡化部署:可使用 Kubernetes 等容器編排平台輕鬆部署、擴充和管理容器。這簡化了部署過程並降低了錯誤風險。
建立高效且安全的容器映像對於充分利用容器化的優勢至關重要。以下是一些需要遵循的最佳實踐:
使用最小基礎鏡像:從最小基礎鏡像開始,例如alpine
或distroless
,以減少整體鏡像大小。
多階段建置:使用多階段建置將建置環境與執行時間環境分開。這有助於透過排除不必要的建置工具和相依性來保持最終映像的輕量級。
刪除不必要的檔案:在映像建置過程中清理臨時檔案、快取和其他不必要的檔案。
定期更新:定期更新基礎映像和相依性以包含最新的安全性修補程式和更新。
安全掃描:在部署映像之前,使用 Trivy 或 Clair 等工具掃描映像是否有已知漏洞。
最小權限:確保應用程式以最小的權限執行,以減少潛在的攻擊面。
限制暴露的連接埠:僅暴露應用程式執行所需的連接埠。避免暴露不必要的連接埠以減少攻擊面。
使用非標準連接埠:如果可能,使用非標準連接埠使攻擊者更難找到和利用開放服務。
使用非 root 使用者:在容器內以非 root 使用者身分執行應用程式,以最大程度地減少潛在安全漏洞的影響。
環境變數:避免對影像中的敏感資訊進行硬編碼。使用環境變數在執行時傳遞敏感資料。
網路策略:實施網路策略來控制容器之間的流量,並增強容器化環境內的安全性。
讓我們來看看使用 Docker 打包 React 應用程式和基於 Java 的應用程式的範例。
在建立和推送映像之前,您需要在電腦上安裝 Docker。您可以在此處按照適用於您的作業系統的官方 Docker 安裝指南進行操作。
讓我們考慮一個基於 React 的 Web 應用程式。這是容器建立 Dockerfile 的樣子,
這是一個多階段 Dockerfile。我們有兩個階段,第 2 階段依賴第 1 階段的建置。
必須將 Dockerfile 新增到專案主路徑中。
# Stage 1: Build the React app
FROM node:14-alpine as build
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY . ./
RUN npm run build
# Stage 2: Serve the React app using Nginx
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
建立 Docker 檔案後,我們可以執行以下命令在使用者工作站中建立映像。
docker build -t my-react-app .
docker run -d -p 80:80 my-react-app
讓我們考慮另一個應用程式,它是一個基於 Java 的 Web 應用程式。這是容器建立 Dockerfile 的樣子,
這也是一個多階段的 Dockerfile。我們有兩個階段,第 1 階段建構程式碼,第 2 階段依賴第 1 階段建置。
必須將 Dockerfile 新增到專案主路徑中。
# Stage 1: Build the Java app
FROM maven:3.8.1-jdk-11 as build
WORKDIR /app
COPY pom.xml ./
COPY src ./src
RUN mvn clean package -DskipTests
# Stage 2: Run the Java app
FROM openjdk:11-jre-slim
COPY --from=build /app/target/my-java-app.jar /app/my-java-app.jar
EXPOSE 8080
CMD ["java", "-jar", "/app/my-java-app.jar"]
建立 Docker 檔案後,我們可以執行以下命令在使用者工作站中建立映像。
docker build -t my-java-app .
docker run -d -p 8080:8080 my-java-app
一旦容器映像在本機建置和測試,您通常需要將它們推送到容器註冊表以儲存並部署到其他環境。以下是如何將映像推送到不同的註冊表。
建立 Docker Hub 帳戶:如果您還沒有帳戶,請前往Docker Hub並建立帳戶。
登入 Docker Hub :
docker login
系統將提示您輸入 Docker Hub 使用者名稱和密碼。
docker tag my-image:latest your-dockerhub-username/my-image:latest
docker push your-dockerhub-username/my-image:latest
gcloud auth login
gcloud auth configure-docker
docker tag my-image:latest gcr.io/your-project-id/my-image:latest
docker push gcr.io/your-project-id/my-image:latest
aws ecr create-repository --repository-name my-repo
aws ecr get-login-password --region your-region | docker login --username AWS --password-stdin your-account-id.dkr.ecr.your-region.amazonaws.com
docker tag my-image:latest your-account-id.dkr.ecr.your-region.amazonaws.com/my-repo:latest
docker push your-account-id.dkr.ecr.your-region.amazonaws.com/my-repo:latest
az acr create --resource-group myResourceGroup --name myACR --sku Basic
az acr login --name myACR
docker tag my-image:latest myACR.azurecr.io/my-repo:latest
docker push myACR.azurecr.io/my-repo:latest
所需的註冊平台並根據需要建立儲存庫。
登入註冊表:使用 CLI 命令透過註冊表對您的 Docker 用戶端進行身份驗證。
標記您的映像:正確標記您的 Docker 映像以符合登錄機碼的命名約定。
推送映像:使用docker push
指令將映像上傳到註冊表。
容器改變了我們打包和部署應用程式的方式,與傳統方法相比具有顯著的優勢。透過遵循容器鏡像建立的最佳實踐,我們可以建立高效、安全、可靠的容器化應用程式。無論您使用的是 React 等現代 JavaScript 框架還是更傳統的 Java 應用程式,容器化都可以簡化您的開發和部署流程,確保跨不同環境的一致性和可擴展性。立即開始利用容器將您的應用程式開發提升到一個新的水平。
探索 Kubernetes 等容器編排平台。
將持續整合和持續部署 (CI/CD) 管道與容器化整合。
了解用於在容器化環境中管理微服務的服務網格技術。
透過採用這些技術和實踐,您可以進一步提高應用程式的效率和可擴展性。
原文出處:https://dev.to/aws-builders/the-art-of-creating-container-images-and-best-practices-3p9d