開始吧
為了讓 Web 應用程式在所有機器上可用,我們必須將其容器化,而容器化這個詞比 docker 更好。
我創建了一個 Dockerfile 來運行該應用程序,但我使用了多階段格式
原因很簡單,如果我在單一階段中創建圖像,它將消耗更多的機器空間,而透過使用多階段構建,我們可以透過分離構建和運行時環境來優化圖像的最終大小,並減少攻擊我們影像的表面以獲得更好的安全性
具體方法如下
# Start with a base image FROM golang:1.22 as base WORKDIR /app COPY go.mod ./ RUN go mod download COPY . . RUN go build -o main . ####################################################### # Reduce the image size using multi-stage builds # We will use a distroless image to run the application FROM gcr.io/distroless/base # Copy the binary from the previous stage COPY --from=base /app/main . # Copy the static files from the previous stage COPY --from=base /app/static ./static # Expose the port on which the application will run EXPOSE 8080 # Command to run the application CMD ["./main"]
現在我們有了 dockerfile,讓我們建置它並將其部署到 dockerhub
docker build -t pankaj892/webapp:v1 .
我們嘗試檢查應用程式是否在本機上按預期運行
docker run -p 8080:8080 pankaj892-webapp:v1
讓我們將其推送到 dockerhub
docker Push pankaj892/webapp:v1 .
您可以使用 mininkube/kind 在本地建立集群,也可以使用雲端上的任何一種託管解決方案。我將使用 AWS 的 Elastic Kubernetes Service(EKS)。
您可以使用控制台或命令列在 EKS 中啟動叢集。我將使用命令列
eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code>
這將只選擇具有 2 個 vCPU 和 4GB 記憶體的節點組的機器類型
我們可以一一部署所有資源,但隨著規模的擴大,管理它們會很困難,這就是 Helm 的用武之地,它充當包管理器,使用圖表來管理我們的所有資源
建立舵圖
# Start with a base image FROM golang:1.22 as base WORKDIR /app COPY go.mod ./ RUN go mod download COPY . . RUN go build -o main . ####################################################### # Reduce the image size using multi-stage builds # We will use a distroless image to run the application FROM gcr.io/distroless/base # Copy the binary from the previous stage COPY --from=base /app/main . # Copy the static files from the previous stage COPY --from=base /app/static ./static # Expose the port on which the application will run EXPOSE 8080 # Command to run the application CMD ["./main"]
Helm 將建立供我們使用的文件,但我們的專案不需要其中的大部分文件。
建立以下檔案並加入helm目錄
部署
eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code>
服務
helm create web-app
入口
# This is a sample deployment manifest file for a simple web application. apiVersion: apps/v1 kind: Deployment metadata: name: web-app labels: app: web-app spec: replicas: 1 selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: containers: - name: web-app image: {{ .Values.image.repository }}:{{ .Values.image.tag }} ports: - containerPort: 8080
將值檔更新為此
# Service for the application apiVersion: v1 kind: Service metadata: name: web-app labels: app: web-app spec: ports: - port: 80 targetPort: 8080 protocol: TCP selector: app: web-app type: ClusterIP
Helm 部分現已完成,讓我們繼續部署我們的 CI
Github Actions 允許我們根據倉庫中的一些事件(如推、拉)自動建立應用程式。
讓我們建立管道檔案
工作流程檔案儲存在(.github/workflows/cicd.yml)
# Ingress resource for the application apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-app annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx rules: - host: web-app.local http: paths: - path: / pathType: Prefix backend: service: name: web-app port: number: 80
這個工作流程檔案首先從 dockerfile 建置我們的映像,然後將其推送到 dockerhub,然後在 helm 的 Charts.yaml 檔案中更新映像的標籤。
我們將使用 argocd 作為我們的 Cd 管道,因為 argocd 將能夠從我們的 git 儲存庫中獲取更改並在應用程式中更新它們。
讓我們在叢集上安裝 argocd
kubectl 建立命名空間 argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
要存取 argocd 伺服器,我們需要將服務變更為負載平衡器類型
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
對於 Windows,這將是
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
如果它不起作用,只需通過 kubectl 編輯服務並將類型更改為 LoadBalancer 它應該可以工作
現在取得服務的IP
kubectl get svc argocd-server -n argocd
我們取得了 IP,但需要密碼才能登入 argocd
kubectl 取得秘密 argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --解碼
此指令將取得密碼並解碼密碼,因為密碼以 Base64 格式編碼
登入後點擊「新專案」>;新增您的專案名稱>新增儲存庫,以便 argocd 可以同步儲存庫 argocd 將自動尋找值檔案並在按一下提交後選擇該檔案
我們建立了管道,但我們如何存取我們的應用程序,您不能每次都從 EKS 中輸入叢集 URL 來存取它,我們需要為此使用入口
我正在使用來自 AWS 的 Nginx Ingress,以便我可以存取該應用程式
在我們的叢集上部署入口
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/aws/deploy.yaml
現在 Ingress 已部署,我們需要將來自 EKS 的叢集 IP 新增至本機主機檔案(對於 Linux,其為 /etc/hosts),對於 Windows,它位於 C:WindowsSystem32etchosts
# Start with a base image FROM golang:1.22 as base WORKDIR /app COPY go.mod ./ RUN go mod download COPY . . RUN go build -o main . ####################################################### # Reduce the image size using multi-stage builds # We will use a distroless image to run the application FROM gcr.io/distroless/base # Copy the binary from the previous stage COPY --from=base /app/main . # Copy the static files from the previous stage COPY --from=base /app/static ./static # Expose the port on which the application will run EXPOSE 8080 # Command to run the application CMD ["./main"]
現在我們可以在 web-app.local 上存取我們的應用程式
我們已經完成了所有步驟,讓我們測試我們的應用程式
如您所見,頂部的 url 是我們在主機檔案中定義的
我們已經運行了應用程序,讓我們添加一些內容並提交到我們的存儲庫,以便 argocd 可以獲取該更改並部署到應用程序
我對我的儲存庫進行了更改,這應該會觸發管道
管道已啟動,完成後讓我們看看 argocd 是否接受該更改
是的,我們看到應用程式發生了變化,argocd 確實拾取了更改並將我們的應用程式與最新更改同步
如果你做到了這一步那麼恭喜! ! !
這個專案對我來說是一次很棒的學習經歷,從在 AWS 上部署 Kubernetes 到建立管道和部署以及對其進行故障排除。這個專案幫助我為 Go 應用程式創建了一個端到端的 DevOps 管道,並且它可以根據需求進行擴展。我計劃進行更多探索,例如使用 terraform 或 cloudformation 堆疊部署 eks clutser 並進行更多改進。
如果遇到困難,可以參考這個倉庫
請在評論中告訴我您建立此管道的體驗如何。
以上是使用 Gitops 和 Kubernetes 在 Golang Web 應用程式上進行 DevOps 管道的詳細內容。更多資訊請關注PHP中文網其他相關文章!