返回文章列表

Kubernetes 微服務佈署自動化與 Jenkins 整合

本文介紹如何利用 Jenkins 實作 Docker 微服務在 Kubernetes 上的自動化佈署,涵蓋 Kubernetes Secret 管理、Jenkins Pipeline 設定、服務建立、HTTPS 設定、儀錶板佈署、Kompose 與 Helm 使用等關鍵步驟,並提供詳細的 YAML

Web 開發 DevOps

Kubernetes 已成為微服務佈署的首選平台。本文將探討如何結合 Jenkins 與 Kubernetes,開發自動化的 CI/CD 流程,並有效管理佈署的微服務應用。首先,我們會利用 Kubernetes 的 Secret 機制保護敏感資訊,例如資料函式庫密碼。接著,透過設定 Jenkins Pipeline,自動執行建置、測試和佈署流程。此外,我們也會探討如何建立 Kubernetes 服務,讓微服務應用對外提供服務,並設定 HTTPS 確保安全性。最後,我們將介紹如何使用 Kompose 和 Helm 簡化 Kubernetes 組態檔的管理,提升佈署效率。

在 Kubernetes 上佈署 Docker 微服務

在佈署定義中最有趣的部分是環境變數的處理。我們並未直接寫入 MongoDB 的憑證,而是使用了 Kubernetes 的 Secrets 來儲存驗證憑證,以確保只有 Kubernetes 可以存取這些敏感資訊。

建立 Kubernetes Secret

在建立 Kubernetes Secret 之前,我們需要在 Kubernetes 叢集中建立一個獨立的名稱空間(Namespace),以便於管理和檢視與應用程式相關的 Pods、Services 和 Deployments。執行以下命令來建立名稱空間:

kubectl create namespace watchlist

接著,在本地機器上執行以下命令來建立 MongoDB 的 Secret:

kubectl create secret generic mongodb-access \
  --from-literal=database='watchlist' \
  --from-literal=username='root' \
  --from-literal=password='PASSWORD' \
  -n watchlist

內容解密:

  • kubectl create namespace watchlist:建立一個名為 watchlist 的名稱空間。
  • kubectl create secret generic mongodb-access:建立一個名為 mongodb-access 的 Secret,用於儲存 MongoDB 的連線資訊。
  • --from-literal:直接在命令列中指定要儲存的鍵值對。
  • -n watchlist:指定 Secret 所在的名稱空間為 watchlist

建立佈署檔案

為其餘的服務(movies-store、movies-parser 和 movies-marketplace)建立佈署檔案。佈署資料夾的結構應如下所示:

deployments/
  mongodb-deploy.yaml
  movies-store-deploy.yaml
  movies-loader-deploy.yaml
  movies-parser-deploy.yaml
  movies-marketplace-deploy.yaml

所有原始碼都可以從 GitHub 儲存函式庫中的 chapter11/deployment/kubectl/deployments 資料夾下載。

使用 Jenkins 佈署應用程式

要在 Jenkins 中佈署應用程式,請在 watchlist-deployment 專案的頂層目錄中建立一個名為 Jenkinsfile.eks 的檔案,如下所示。該 Jenkinsfile 將使用 aws eks update-kubeconfig 命令組態 kubectl,然後使用 kubectl apply 命令佈署資源。

def region = 'AWS_REGION'
def accounts = [master:'production', preprod:'staging', develop:'sandbox']

node('master'){
  stage('Checkout'){
    checkout scm
  }
  stage('Authentication'){
    sh "aws eks update-kubeconfig --name ${accounts[env.BRANCH_NAME]} --region ${region}"
  }
  stage('Deploy'){
    sh 'kubectl apply -f deployments/'
  }
}

內容解密:

  • def region = 'AWS_REGION':定義 AWS 區域變數。
  • def accounts = [...]:定義不同分支對應的環境名稱。
  • node('master'):指定在 master 節點上執行。
  • stage('Checkout'):簽出程式碼階段。
  • stage('Authentication'):使用 AWS CLI 更新 kubeconfig,以便能夠連線到 EKS 叢集。
  • stage('Deploy'):使用 kubectl apply 命令佈署應用程式。

設定 Jenkins 與 EKS 的整合

在推播 Jenkinsfile 和佈署檔案到 Git 遠端儲存函式庫之前,需要在 Jenkins 主節點上安裝 kubectl 命令列工具,並提供對 EKS 的 IAM 角色存取許可權。編輯 Kubernetes 中的 aws-auth ConfigMap,將 Jenkins 例項的 IAM 角色新增到 mapRoles 部分。

圖表翻譯:

此圖示展示了 Jenkins 與 EKS 的整合流程,包括更新 kubeconfig 和佈署應用程式的步驟。

推播變更到 Git 儲存函式庫

準備就緒後,將 Jenkinsfile 和 Kubernetes 佈署檔案推播到 Git 儲存函式庫的 develop 分支:

git add .
git commit -m "k8s deployment files"
git push origin develop

推播後,GitHub 儲存函式庫的內容應該與圖 11.4 類別似。

自動觸發 Jenkins 建置

一旦變更被提交,之前在第 7.6 節建立的 GitHub webhook 將會觸發 watchlist-deployment 多分支作業中 develop 分支的建置,如圖 11.5 所示。

驗證佈署結果

在 Deploy 階段,kubectl apply 命令將被執行以佈署應用程式的佈署資源。在本地機器上執行以下命令,以列出在 sandbox K8s 叢集中執行的佈署:

kubectl get deployments --namespace=watchlist

這將顯示應用程式的四個元件(loader、parser、store 和 marketplace)以及 MongoDB 伺服器已經被佈署。

建立 Kubernetes Service

為了存取已佈署的應用程式,需要為 marketplace 和 store 建立 Kubernetes Service。建立一個名為 services 的目錄,並在其中建立一個名為 movies-store.svc.yaml 的檔案,如下所示:

apiVersion: v1
kind: Service
metadata:
  name: movies-store
spec:
  selector:
    app: movies-store
  ports:
  - name: http
    port: 80
    targetPort: 8080
  type: LoadBalancer

圖表翻譯:

此圖示展示了 Kubernetes Service 的設定,包括選擇器、連線埠和服務型別等。

建立 Service 之後的下一步:

建立 Service 之後,可以使用 LoadBalancer 的外部 IP 地址存取 Movies Store API。具體操作步驟如下:

  1. 使用 kubectl get svc -n watchlist 命令取得 Service 的外部 IP 地址。
  2. 使用取得到的 IP 地址存取 Movies Store API。

藉由上述步驟,我們成功地在 Kubernetes 上佈署了 Docker 微服務,並透過 Jenkins 自動化了佈署流程。

在 Kubernetes 上佈署 Docker 微服務的持續整合與佈署流程自動化

在現代化的軟體開發流程中,持續整合(CI)與持續佈署(CD)是確保軟體品質和快速交付的關鍵環節。本文將探討如何利用 Jenkins 自動化 Docker 微服務在 Kubernetes(K8s)上的佈署流程。

建立 Kubernetes 服務

為了使微服務能夠相互通訊並對外提供服務,需要建立 Kubernetes 服務。以下是建立服務的 YAML 組態檔案範例:

apiVersion: v1
kind: Service
metadata:
  name: movies-store
  namespace: watchlist
spec:
  ports:
  - port: 80
    targetPort: 3000
  selector:
    app: movies-store
  type: LoadBalancer

內容解密:

  • apiVersionkind 定義了 Kubernetes 資源的版本和型別。
  • metadata 包含了服務的名稱和名稱空間。
  • spec 定義了服務的規格,包括埠、選擇器和服務型別。
  • ports 部分定義了服務的埠和目標埠,將外部請求轉發到 Pod 的指定埠。
  • selector 部分根據標籤選擇對應的 Pod。
  • typeLoadBalancer 表示該服務將透過雲端服務提供商的負載平衡器對外暴露。

更新 Jenkinsfile 以佈署 Kubernetes 服務

為了自動化佈署流程,需要更新 Jenkinsfile 以包含佈署 Kubernetes 服務的步驟:

stage('Deploy'){
  sh 'kubectl apply -f deployments/'
  sh 'kubectl apply -f services/'
}

內容解密:

  • stage('Deploy') 定義了一個名為 Deploy 的階段。
  • sh 'kubectl apply -f deployments/' 使用 kubectl apply 命令佈署 deployments 目錄下的資源組態檔案。
  • sh 'kubectl apply -f services/' 使用 kubectl apply 命令佈署 services 目錄下的資源組態檔案。

組態 HTTPS 監聽器

為了確保 Store API 的安全性,可以在負載平衡器上啟用 HTTPS 監聽器。更新 movies-store 服務的 YAML 組態檔案如下:

apiVersion: v1
kind: Service
metadata:
  name: movies-store
  namespace: watchlist
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:{region}:{user id}:certificate/{id}
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
spec:
  ports:
  - name: http
    port: 80
    targetPort: 3000
  - name: https
    port: 443
    targetPort: 3000
  selector:
    app: movies-store
  type: LoadBalancer

內容解密:

  • annotations 部分包含了 AWS 負載平衡器的組態,包括後端協定、SSL 證書 ARN 和 SSL 埠。
  • spec.ports 部分定義了 HTTP 和 HTTPS 埠,將外部請求轉發到 Pod 的指定埠。

佈署 Kubernetes 控制台

為了更好地管理和監控 Kubernetes 叢集,可以佈署 Kubernetes 控制台:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.5/aio/deploy/recommended.yaml

內容解密:

  • 第一個命令佈署了 metrics-server,用於收集叢集資源指標。
  • 第二個命令佈署了 Kubernetes 控制台 v2.0.5。

建立 eks-admin 服務帳戶

為了存取 Kubernetes 控制台,需要建立一個具有管理員許可權的服務帳戶:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: eks-admin
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: eks-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: eks-admin
  namespace: kube-system

內容解密:

  • 建立了一個名為 eks-admin 的服務帳戶和叢集角色繫結,賦予其管理員許可權。

透過上述步驟,可以實作 Docker 微服務在 Kubernetes 上的自動化佈署和持續整合,確保軟體開發流程的高效性和可靠性。

自動化持續佈署流程於 Jenkins 的應用

登入 Kubernetes 儀錶板

首先,您需要取得 Kubernetes 儀錶板的 token。執行以下命令以取得 token:

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk '{print $1}')

複製產生的 token,並在登入畫面中貼上至「Enter Token」欄位。點選「Sign In」按鈕後,您將以管理員身份登入。

Kubernetes 儀錶板的功能

Kubernetes 儀錶板提供使用者友好的功能,以便管理和排查已佈署的應用程式。成功建立雲原生應用的 CI/CD 流程後,您可以利用該儀錶板進行進一步的操作。

使用 Kompose 將 Docker Compose 轉換為 K8s 組態檔

Kompose 是一個開源工具,可以將 docker-compose.yml 檔案轉換為 Kubernetes 組態檔。首先,請參考 Kompose 的官方 GitHub 儲存函式庫(https://github.com/kubernetes/kompose)以取得安裝。

安裝 Kompose 後,執行以下命令以轉換 docker-compose.yml 檔案:

kompose convert -f docker-compose.yml

此命令將根據 docker-compose.yml 中的設定和網路拓撲結構產生 Kubernetes 的佈署和服務組態檔。

使用 Helm 簡化 Kubernetes 組態檔的管理

Helm 是 Kubernetes 的套件管理器,可以簡化組態檔的管理。Helm 包含客戶端(CLI)和伺服器(Tiller,在 Helm 3 中已被移除)兩部分。客戶端安裝在本地機器上,而伺服器則執行在 Kubernetes 叢集中。

要使用 Helm,您需要了解以下三個概念:

  • Chart:一組預先組態的 Kubernetes 資源套件。
  • Release:使用 Helm 佈署到叢集中的特定 Chart 例項。
  • Repository:一組已發布的 Chart,可以透過遠端登入檔提供給其他人使用。

建立 Helm Chart

執行以下命令以建立一個名為 watchlist 的新 Chart:

helm create watchlist

此命令將建立一個名為 watchlist 的目錄,其中包含以下檔案和資料夾:

  • Values.yaml:定義要注入 Kubernetes 範本的所有值。
  • Chart.yaml:描述正在封裝的 Chart 版本。
  • .helmignore:類別似於 .gitignore.dockerignore,包含在封裝 Helm Chart 時要排除的檔案和資料夾列表。
  • templates/:包含實際的組態檔,例如 Deployments、Services、ConfigMaps 和 Secrets。

定義範本檔案

templates 資料夾中,為每個微服務定義範本檔案。例如,movies-loader 範本資料夾使用與清單 11.4 中定義的相同佈署檔案,但參照了 values.yaml 中定義的變數。

movies-loader Deployment 組態檔
apiVersion: apps/v1
kind: Deployment
metadata:
  name: movies-loader
  namespace: {{ .Values.namespace }}
  labels:
    app: movies-loader
    tier: backend
spec:
  selector:
    matchLabels:
      app: movies-loader
  template:
    metadata:
      name: movies-loader
      labels:
        app: movies-loader
        tier: backend
      annotations:
        jenkins/build: {{ .Values.metadata.jenkins.buildTag | quote }}
        git/commitId: {{ .Values.metadata.git.commitId | quote }}
    spec:
      containers:
      - name: movies-loader
        image: "{{ .Values.services.registry.uri }}/mlabouardy/movies-loader:{{ .Values.deployment.tag }}"
        imagePullPolicy: Always

ConfigMap 和 Secret 組態檔

ConfigMap 和 Secret 組態檔用於定義環境變數和敏感資訊。例如,movies-loader 的 ConfigMap 組態檔如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.namespace }}-movies-loader
  namespace: {{ .Values.namespace }}
  labels:
    app: {{ .Values.namespace }}-movies-loader
data:
  AWS_REGION: {{ .Values.services.aws.region }}
  SQS_URL: https://sqs.{{ .Values.services.aws.region }}.amazonaws.com/{{ .Values.services.aws.account }}/movies_to_parse_{{ .Values.environment }}

Secret 組態檔用於儲存敏感資訊,例如 MongoDB 的憑證:

apiVersion: v1
kind: Secret
metadata:
  name: {{ .Values.namespace }}-secrets
  namespace: {{ .Values.namespace }}
data:
  MONGO_URI: {{ .Values.services.mongodb.uri | b64enc }}
  MONGO_DATABASE : {{ .Values.mongodb.mongodbDatabase | b64enc }}
  MONGODB_USERNAME : {{ .Values.mongodb.mongodbUsername | b64enc }}
  MONGODB_PASSWORD : {{ .Values.mongodb.mongodbPassword | b64enc }}

使用 Helm Charts 的優點

Helm Charts 使我們能夠在 values.yaml 檔案中定義可覆寫的預設值,從而簡化了組態檔的管理。我們可以將盡可能多的變數移出範本檔案,並在 values.yaml 中定義它們。