AWS企業實名帳號 基於 Kubernetes 的雲原生 CI/CD 流水線設計

亞馬遜雲AWS / 2026-10-21 17:01:16

# 基於 Kubernetes 的雲原生 CI/CD 流水線設計

在搜尋「基於 Kubernetes 的雲原生 CI/CD 流水線設計」時,多數使用者並不是想看概念介紹,而是希望解決這幾類實際問題:

1. **如何在 Kubernetes 內搭建可運行的 CI/CD 流水線**。
2. **如何把 Git 倉庫、鏡像倉庫、Kubernetes 部署流程串起來**。
3. **如何處理權限、密鑰、網路連通、安全組、Ingress、Registry 憑證等細節**。
4. **如何避免部署失敗、Pod 啟動異常、鏡像拉取失敗、滾動更新卡住等常見故障**。

本文不做泛泛而談,直接從實際部署角度出發,給出一套適合中小型團隊快速落地的 Kubernetes 原生 CI/CD 設計方案,重點覆蓋:叢集準備、流水線元件選型、資源建立、配置實踐、部署策略與故障排查。

---

## 一、適用場景與設計目標

這套方案適合以下場景:

- 已有 Kubernetes 叢集,準備部署應用自動化交付流程。
- 程式碼託管在 GitLab、GitHub、Gitea 等平台。
- 鏡像需要推送到私有 Registry 或雲端鏡像倉庫。
- 應用部署到 Kubernetes Namespace,要求支援滾動更新與快速回滾。
- 希望把建置、測試、發佈、部署統一到容器化流程中。

設計目標如下:

- **流水線全部容器化運行**,避免依賴傳統固定 Jenkins 節點。
- **建置與部署解耦**,可分環境發佈。
- **權限最小化**,CI 任務只擁有必要的 Kubernetes 操作權限。
- **支援故障回滾與可觀測性**。
- **方便擴容與維護**。

---

## 二、整體架構設計

一個可實施的雲原生 CI/CD 架構通常包含以下模組:

1. **Git 程式碼倉庫**:保存應用程式碼與 Kubernetes YAML/Helm Chart。
2. **CI 工具**:Jenkins、GitLab CI、Tekton、Argo Workflows 均可。若強調 Kubernetes 原生,建議優先考慮 **Tekton + Argo CD** 或 **GitLab Runner on Kubernetes**。
3. **鏡像建置工具**:Docker、Kaniko、BuildKit。若在 Kubernetes 內構建鏡像,建議使用 **Kaniko**,避免 Docker in Docker。
4. **鏡像倉庫**:Harbor、GitLab Registry、雲廠商容器鏡像服務。
5. **CD 工具**:kubectl、Helm、Argo CD。
6. **Kubernetes 叢集**:應用實際運行環境。
7. **Ingress / Service**:對外暴露服務。
8. **Secret 管理**:保存 Registry、Git Token、KubeConfig、資料庫密鑰。

推薦的流程如下:

```text
開發者提交程式碼
↓
Webhook 觸發 CI
↓
單元測試 / 編譯 / 打包
↓
Kaniko 構建鏡像並推送 Registry
↓
更新部署檔案(Helm values 或 Kubernetes manifests)
↓
CD 工具部署到 Kubernetes
↓
健康檢查 / 滾動更新 / 驗證
↓
失敗則回滾
```

---

## 三、Kubernetes 叢集準備

在設計流水線前,先確認叢集具備以下基礎條件。

### 1. 建立專用 Namespace

建議至少拆分三類 Namespace:

- `cicd`:部署 Runner、Tekton、Argo CD 等流水線工具。
- `dev`:開發環境應用。
- `prod`:正式環境應用。

命令如下:

```bash
kubectl create namespace cicd
kubectl create namespace dev
kubectl create namespace prod
```

### 2. 配置節點資源

流水線建置任務很吃 CPU、記憶體與磁碟 I/O。若叢集節點太小,常見問題有:

- Pod Pending
- 建置過程被 OOMKilled
- 鏡像構建超時
- 節點磁碟空間不足

建議初始規格:

- CI 節點池:2 vCPU / 4GB 以上起步
- 構建任務較多時:4 vCPU / 8GB 以上
- 節點系統碟:至少 100GB
- 若大量構建鏡像,建議掛載獨立資料盤

### 3. 網路與安全組檢查

若 Kubernetes 部署在雲伺服器上,需要確認:

- 控制節點與工作節點之間內網可通。
- 叢集節點能訪問 Git 倉庫。
- 叢集節點能訪問鏡像倉庫。
- 若使用 NodePort / Ingress,對應端口已在安全組開放。

常見需要開放的端口:

- 22:SSH 管理
- 80 / 443:Web / Ingress
- 30000-32767:NodePort 範圍(如使用 NodePort)
- 6443:Kubernetes API Server(僅管理端需要)

若是雲主機環境,還需同步檢查:

- 雲控制台安全組
- 作業系統防火牆(firewalld / iptables / ufw)
- Kubernetes NetworkPolicy

---

## 四、CI/CD 工具選型建議

### 方案一:GitLab CI + Kubernetes Runner

適合已有 GitLab 的團隊。

優點:

- 倉庫與流水線整合簡單
- `.gitlab-ci.yml` 易於管理
- Runner 可直接運行在 Kubernetes

適合需求:

- 快速上線
- 不想引入太多額外元件

### 方案二:Tekton + Argo CD

更偏 Kubernetes 原生。

分工如下:

- **Tekton**:負責 CI 任務,如拉程式碼、測試、建鏡像
- **Argo CD**:負責 CD,同步 Git 中的部署配置到 Kubernetes

適合需求:

- 追求 GitOps
- 多環境部署
- 希望將交付流程完全放在 Kubernetes 生態內

### 方案三:Jenkins Agent on Kubernetes

適合已有 Jenkins 維運經驗的團隊,但不建議新團隊從零開始重度依賴傳統 Jenkins Master 模式。

如果題目是「基於 Kubernetes 的雲原生 CI/CD 流水線設計」,更建議採用:

**Tekton + Kaniko + Harbor + Argo CD**。

以下內容以這套組合為主進行配置實踐。

---

AWS企業實名帳號 ## 五、流水線核心資源設計

### 1. ServiceAccount 與 RBAC

CI/CD 任務需要有部署權限,但不應直接使用 cluster-admin。

先建立 ServiceAccount:

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: cicd-deployer
namespace: cicd
```

建立 Role,限制只可操作指定 Namespace 內常見工作負載:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: deployer-role
rules:
- apiGroups: ["", "apps", "extensions"]
resources: ["pods", "services", "configmaps", "secrets", "deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
```

RoleBinding:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployer-binding
namespace: dev
subjects:
- kind: ServiceAccount
name: cicd-deployer
namespace: cicd
roleRef:
kind: Role
name: deployer-role
apiGroup: rbac.authorization.k8s.io
```

常見錯誤:

- `forbidden: User system:serviceaccount... cannot create deployments`
- 原因通常是 Namespace 不一致,或 RoleBinding 綁定錯誤。

排查命令:

```bash
kubectl auth can-i create deployment -n dev --as=system:serviceaccount:cicd:cicd-deployer
```

### 2. Registry 憑證

若要從私有鏡像倉庫拉取鏡像,需要配置 `imagePullSecret`。

建立 Secret:

```bash
kubectl create secret docker-registry regcred \
--docker-server=harbor.example.com \
--docker-username=admin \
--docker-password='YourPassword' \
[email protected] \
-n dev
```

Deployment 中引用:

```yaml
spec:
template:
spec:
imagePullSecrets:
- name: regcred
```

常見錯誤:

- `ImagePullBackOff`
- `ErrImagePull`
- `unauthorized: authentication required`

排查方向:

1. Secret 所在 Namespace 是否正確。
2. Harbor / Registry 地址是否包含正確域名與端口。
3. 憑證是否過期。
4. 節點是否可解析 Registry 域名。

---

## 六、使用 Kaniko 在 Kubernetes 內構建鏡像

在 Kubernetes 內建置鏡像,建議優先使用 Kaniko。

### 1. 建立 Docker 認證 Secret

Kaniko 推送鏡像時需要讀取 `/kaniko/.docker/config.json`。

```bash
kubectl create secret generic kaniko-secret \
--from-file=.dockerconfigjson=/root/.docker/config.json \
--type=kubernetes.io/dockerconfigjson \
-n cicd
```

### 2. Kaniko Task 示例

若使用 Tekton,可定義一個構建 Task:

```yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: kaniko-build
namespace: cicd
spec:
params:
- name: IMAGE
type: string
- name: CONTEXT
type: string
default: .
workspaces:
- name: source
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:latest
workingDir: $(workspaces.source.path)
args:
- --dockerfile=Dockerfile
- --context=$(params.CONTEXT)
- --destination=$(params.IMAGE)
volumeMounts:
- name: docker-config
mountPath: /kaniko/.docker/
volumes:
- name: docker-config
secret:
secretName: kaniko-secret
```

### 3. 常見構建失敗排查

#### 問題一:推送鏡像時認證失敗

現象:

```text
error checking push permissions
```

處理方式:

- 確認 Secret 掛載路徑為 `/kaniko/.docker/`
- 確認 `config.json` 格式正確
- 確認鏡像地址完整,如:

```text
harbor.example.com/project/app:commit-sha
```

#### 問題二:Context 路徑錯誤

現象:

```text
error resolving dockerfile path
```

處理方式:

- 檢查 Tekton workspace 是否已掛載程式碼
- 確認 Dockerfile 位於工作目錄
- 使用 `ls -lah` 增加除錯步驟

#### 問題三:建置過程 OOM

處理方式:

給 Task 設定資源限制:

```yaml
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2"
```

---

## 七、部署流程設計:kubectl 還是 Helm

### 1. 小型專案可直接用 kubectl apply

如果應用配置簡單,可以把 YAML 放在 Git 倉庫中,由流水線直接執行:

```bash
kubectl apply -f k8s/deployment.yaml -n dev
kubectl apply -f k8s/service.yaml -n dev
```

適合:

- 單服務
- 配置變動少
- 環境不多

### 2. 多環境建議使用 Helm

AWS企業實名帳號 當你有 dev / test / prod 多套環境時,建議用 Helm 管理參數差異。

常見目錄:

```text
chart/
Chart.yaml
values.yaml
values-dev.yaml
values-prod.yaml
templates/
```

部署命令:

```bash
helm upgrade --install myapp ./chart -n dev -f ./chart/values-dev.yaml
```

正式環境:

AWS企業實名帳號 ```bash
helm upgrade --install myapp ./chart -n prod -f ./chart/values-prod.yaml
```

常見踩坑:

AWS企業實名帳號 - values 中 image.tag 未更新,導致部署後仍拉舊版本
- readinessProbe 配置過嚴,滾動更新卡住
- 資源 requests 太低,導致實際壓力上來後 Pod 不穩定

---

## 八、推薦的 Kubernetes 部署 YAML 設計

以下是一個適合納入 CI/CD 的 Deployment 配置示例:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: dev
spec:
replicas: 2
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
imagePullSecrets:
- name: regcred
containers:
- name: myapp
image: harbor.example.com/project/myapp:latest
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "1"
memory: "1Gi"
```

這裡幾個關鍵點:

- `revisionHistoryLimit`:保留歷史版本,方便回滾。
- `maxUnavailable: 0`:更新時不減少可用實例。
- `readinessProbe`:避免 Pod 尚未就緒就接流量。
- `resources`:避免節點被建置或應用擠爆。

---

## 九、CD 落地方式:Argo CD 配置實踐

AWS企業實名帳號 如果要讓部署更加標準化,建議導入 Argo CD。

### 1. 安裝 Argo CD

```bash
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```

### 2. 暴露 Web 介面

測試環境可用 port-forward:

```bash
kubectl port-forward svc/argocd-server -n argocd 8080:443
```

若正式使用,建議配置 Ingress 並綁定 HTTPS。

### 3. 建立 Application

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-dev
namespace: argocd
spec:
project: default
source:
repoURL: 'https://git.example.com/devops/myapp-deploy.git'
targetRevision: main
path: chart
helm:
valueFiles:
- values-dev.yaml
destination:
server: 'https://kubernetes.default.svc'
namespace: dev
syncPolicy:
automated:
prune: true
selfHeal: true
```

AWS企業實名帳號 這種模式下,CI 只需要做兩件事:

1. 建置並推送鏡像
2. 更新 Git 中的 Helm values image tag

剩下的同步工作交給 Argo CD。

這是比較穩定的拆分方式,能降低「CI 腳本直接操作線上叢集」的風險。

---

## 十、流水線完整設計示例

以下是一套簡化的實施流程。

AWS企業實名帳號 ### 階段 1:提交程式碼

開發者將程式碼 push 到 Git 分支。

### 階段 2:CI 觸發

Webhook 觸發 Tekton Pipeline 或 GitLab CI。

### 階段 3:執行建置

步驟包括:

- 拉取原始碼
- 執行單元測試
- 產出編譯結果
- Kaniko 構建鏡像
- 推送鏡像到 Harbor

### 階段 4:更新部署版本

CI 腳本修改:

- `values-dev.yaml` 中的 image tag
- 或 Kubernetes manifest 中的 image 標籤

然後提交回部署倉庫。

### 階段 5:CD 同步到叢集

Argo CD 發現 Git 變更,自動同步到 `dev` Namespace。

### 階段 6:驗證與回滾

驗證內容包括:

- Pod 是否 Running
- readinessProbe 是否通過
- Service 是否正常轉發
- Ingress 是否可訪問
- 應用日誌是否有異常

若異常,可回滾:

```bash
kubectl rollout undo deployment/myapp -n dev
```

若使用 Helm:

```bash
helm history myapp -n dev
helm rollback myapp 1 -n dev
```

---

## 十一、關鍵配置:網路、Ingress、私網與公網

在 Kubernetes CI/CD 流程裡,部署成功不代表業務可用。很多問題出在網路層。

### 1. Service 配置檢查

```yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: dev
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: ClusterIP
```

排查方法:

```bash
kubectl get svc -n dev
kubectl get endpoints -n dev
```

若 Endpoints 為空,通常是:

- Service selector 與 Pod label 不匹配
- Pod 尚未 Ready

### 2. Ingress 配置

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
namespace: dev
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
```

常見問題:

- DNS 未解析到 Ingress 公網 IP
- 安全組未開放 80/443
- NGINX Ingress Controller 未安裝
- 後端 Service 端口配置錯誤

### 3. 私網拉取依賴失敗

若建置階段需要拉 Maven、npm、pip 依賴,但叢集在私網內,可能遇到:

- 無法連外
- DNS 解析失敗
- NAT 未配置

處理方式:

- 為工作節點配置 NAT Gateway 或公網出口
- 使用企業內部制品倉庫
- 配置正確的 DNS 轉發

---

## 十二、常見故障排查清單

這部分是實際操作中最常遇到的。

### 1. Runner / Pipeline Pod 一直 Pending

排查:

```bash
kubectl describe pod -n cicd
```

AWS企業實名帳號 常見原因:

- 節點資源不足
- PVC 無法綁定
- 節點 taint 未容忍
- namespace ResourceQuota 限制

### 2. 鏡像推送成功,但部署後拉取失敗

原因通常是:

- CI 使用的 Registry 憑證與運行環境的 `imagePullSecret` 不同
- dev Namespace 沒有對應 secret
- 鏡像 tag 寫錯

### 3. Deployment 更新卡住

排查:

```bash
kubectl rollout status deployment/myapp -n dev
kubectl describe deployment myapp -n dev
kubectl get pod -n dev
```

常見原因:

- readinessProbe 失敗
- 新鏡像啟動報錯
- 端口監聽不正確
- ConfigMap / Secret 缺失

### 4. Pod 啟動後反覆重啟

排查:

AWS企業實名帳號 ```bash
kubectl logs -n dev --previous
```

檢查:

- 環境變數是否缺失
- 資料庫連接是否正常
- Redis 地址是否可達
- 啟動命令是否正確
- JVM / Node.js 記憶體配置是否超過 limits

### 5. Argo CD 顯示 OutOfSync

常見原因:

- 手工修改了叢集資源
- Helm 模板渲染結果與線上資源不同
- 自動注入欄位造成 diff

處理方式:

- 儘量避免手工改線上資源
- 把所有配置變更回收到 Git
- 針對必要欄位設定 ignoreDifferences

---

AWS企業實名帳號 ## 十三、性能與穩定性優化建議

### 1. 建置節點與業務節點分離

給 CI 任務單獨節點池,避免大量建置影響線上服務。

可以使用:

- nodeSelector
- taints / tolerations
- affinity

### 2. 使用快取提升構建速度

常見快取包括:

AWS企業實名帳號 - Maven `.m2`
- npm cache
- pip cache
- Kaniko layer cache

如果快取做得好,構建速度能明顯縮短。

### 3. 使用版本化鏡像標籤

不要只用 `latest`,建議使用:

- Git Commit SHA
- 分支名 + Commit SHA
- 發版號

AWS企業實名帳號 例如:

```text
myapp:main-a81c9d2
myapp:v1.2.3
```

這對回滾、追蹤與審計都很重要。

### 4. 加入部署前檢查

在正式部署前,可先執行:

- YAML 語法校驗
- Helm template 渲染
- Kubernetes schema 驗證
- 單元測試 / 整合測試

AWS企業實名帳號 例如:

```bash
helm template myapp ./chart -f values-prod.yaml
kubectl apply --dry-run=client -f deployment.yaml
```

### 5. 配置資源請求與 HPA

AWS企業實名帳號 若應用流量有波動,應考慮設定 HPA,但前提是 requests 要合理,否則自動擴縮容判斷不準。

---

## 十四、資料庫與外部服務在流水線中的注意事項

雖然本文重點是 Kubernetes CI/CD,但很多部署失敗其實與資料庫連線有關。

實踐建議:

AWS企業實名帳號 - 把資料庫連接字串放到 Secret,不要寫死在映像中。
- 發佈前先測試應用到 MySQL / Redis 的連通性。
- 若資料庫位於雲資料庫產品中,需確認白名單或安全組允許 Kubernetes 節點所在網段訪問。
- 若是私網資料庫,確認 Kubernetes 節點與資料庫在同一 VPC 或已建立對等連線。

排查 MySQL 連線失敗:

```bash
kubectl exec -it -n dev -- sh
nc -zv mysql.example.internal 3306
```

排查 Redis:

```bash
nc -zv redis.example.internal 6379
```

常見問題:

- 目標地址填錯
- 安全組未放行
- DNS 解析不到內網域名
- Kubernetes Pod 所在網段未加入資料庫白名單

---

## 十五、建議的目錄結構

為了讓 CI/CD 更易維護,建議把代碼倉庫結構整理清楚:

AWS企業實名帳號 ```text
project/
├── src/
├── Dockerfile
├── .gitlab-ci.yml 或 tekton/
├── k8s/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ingress.yaml
└── chart/
├── Chart.yaml
├── values.yaml
├── values-dev.yaml
└── templates/
```

如果採用 GitOps,建議把「應用程式碼倉庫」與「部署配置倉庫」分開,避免部署權限過度集中。

---

## 十六、落地建議:從最小可用方案開始

如果你的團隊剛開始做 Kubernetes CI/CD,不建議一開始就把所有功能堆滿。更穩妥的做法是分三步:

### 第一階段

- Git 倉庫 + GitLab CI / Tekton
- Kaniko 構建鏡像
- kubectl apply 到 dev 環境

### 第二階段

- 引入 Helm 管理多環境
- 加入 imagePullSecret、RBAC、健康檢查
- 實作滾動更新與回滾

### 第三階段

- 導入 Argo CD
- 實施 GitOps
- 加入審批流程、灰度發佈、通知告警

這樣的實施順序能減少一次性改造風險,也更符合實際工程推進方式。

---

## 十七、總結

基於 Kubernetes 的雲原生 CI/CD 流水線設計,真正的難點不在「工具安裝」,而在以下幾個細節是否處理到位:

- 叢集資源是否足夠支撐構建任務
- Registry 憑證與拉取權限是否正確
- CI 的 Kubernetes 權限是否最小且可用
- 部署 YAML / Helm Chart 是否適合滾動更新
- Ingress、Service、DNS、安全組是否打通
- 發佈失敗後是否能快速定位與回滾

如果你要一套更穩定的方案,推薦採用:

**Tekton 負責建置,Kaniko 負責鏡像生成,Harbor 保存鏡像,Argo CD 負責部署同步。**

這種拆分方式更適合 Kubernetes 環境下的長期維護,也便於後續擴展多環境、多叢集與更細緻的發佈策略。

實作時請優先關注:**權限、網路、鏡像、探針、回滾** 這五個部分。多數部署事故,基本都能在這幾個點找到原因。

Telegram售前客服
客服ID
@cloudcup
联系
Telegram售后客服
客服ID
@yanhuacloud
联系