Docker & Kubernetes 完全指南 第10篇:Helm 和 CI/CD 流水线
Docker & Kubernetes Complete Guide Part 10: Helm and CI/CD Pipeline
前言:高效的 Kubernetes 应用程序部署
到目前为止,我们已经学习了 Kubernetes 的各种资源和配置方法。但在实际生产环境中,需要管理数十甚至数百个 YAML 文件,并且需要为不同环境应用不同的配置。为了解决这种复杂性,Helm 包管理器应运而生。
此外,在现代软件开发中,自动化从代码变更到生产部署的整个过程的 CI/CD 流水线 是必不可少的。本篇将详细介绍 Helm 的使用方法和基于 GitOps 的 CI/CD 流水线构建方法。
1. 什么是 Helm?
1.1 Helm 概述
Helm 是 Kubernetes 的包管理器。就像 Linux 的 apt、yum 或 macOS 的 Homebrew 一样,Helm 可以轻松地安装、升级和管理 Kubernetes 应用程序。
Helm 的核心概念:
- Chart:定义 Kubernetes 应用程序的文件集合
- Release:安装在集群中的 Chart 实例
- Repository:存储和共享 Chart 的仓库
- Values:用于自定义 Chart 默认设置的值
1.2 为什么使用 Helm
| 问题 | Helm 的解决方案 |
|---|---|
| 管理大量 YAML 文件 | 打包为单个 Chart |
| 环境间配置差异 | 使用 values.yaml 覆盖 |
| 部署历史管理 | 发布版本管理和回滚 |
| 复杂的依赖关系 | Chart 依赖管理 |
| 缺乏可重用性 | 模板和可共享的 Chart |
2. Helm 安装和基本用法
2.1 Helm 安装
# macOS
brew install helm
# Linux(脚本)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Windows (Chocolatey)
choco install kubernetes-helm
# 验证安装
helm version
2.2 Repository 管理
# 添加官方 Helm Chart 仓库
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
# 查看仓库列表
helm repo list
# 更新仓库
helm repo update
# 搜索 Chart
helm search repo nginx
helm search repo mysql
# 从 Hub 搜索
helm search hub prometheus
2.3 基本命令
# 安装 Chart
helm install my-release bitnami/nginx
# 安装到特定命名空间
helm install my-release bitnami/nginx -n my-namespace --create-namespace
# 使用 values 文件安装
helm install my-release bitnami/nginx -f custom-values.yaml
# 在命令行指定值
helm install my-release bitnami/nginx --set replicaCount=3
# 查看发布列表
helm list
helm list -A # 所有命名空间
# 查看发布状态
helm status my-release
# 升级发布
helm upgrade my-release bitnami/nginx --set replicaCount=5
# 回滚发布
helm rollback my-release 1 # 回滚到修订版 1
# 查看发布历史
helm history my-release
# 删除发布
helm uninstall my-release
3. 理解 Chart 结构
3.1 Chart 目录结构
my-chart/
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认配置值
├── charts/ # 依赖 Chart
├── templates/ # Kubernetes 清单模板
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ ├── secret.yaml
│ ├── _helpers.tpl # 模板辅助函数
│ ├── NOTES.txt # 安装后输出的消息
│ └── tests/ # 测试文件
│ └── test-connection.yaml
├── .helmignore # 打包时排除的文件
└── README.md # 文档
3.2 Chart.yaml
# Chart.yaml
apiVersion: v2
name: my-app
description: A Helm chart for my application
type: application
version: 1.0.0 # Chart 版本
appVersion: "2.0.0" # 应用程序版本
# 依赖定义
dependencies:
- name: mysql
version: "9.x.x"
repository: https://charts.bitnami.com/bitnami
condition: mysql.enabled
- name: redis
version: "17.x.x"
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
# 关键词和元数据
keywords:
- web
- application
home: https://example.com
sources:
- https://github.com/example/my-app
maintainers:
- name: DevOps Team
email: devops@example.com
3.3 values.yaml
# values.yaml
# 默认配置值定义
# 应用程序设置
replicaCount: 2
image:
repository: myregistry/my-app
tag: "latest"
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
# 服务设置
service:
type: ClusterIP
port: 80
targetPort: 8080
# Ingress 设置
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: myapp-tls
hosts:
- myapp.example.com
# 资源限制
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
# 自动扩缩
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# 环境变量
env:
- name: APP_ENV
value: production
- name: LOG_LEVEL
value: info
# 依赖启用
mysql:
enabled: true
auth:
database: myapp
username: appuser
redis:
enabled: false
3.4 模板编写
templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-app.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-app.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
{{- if .Values.env }}
env:
{{- toYaml .Values.env | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
templates/_helpers.tpl
{{/*
生成应用程序名称
*/}}
{{- define "my-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
生成完整名称(包含发布名称)
*/}}
{{- define "my-app.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
通用标签
*/}}
{{- define "my-app.labels" -}}
helm.sh/chart: {{ include "my-app.chart" . }}
{{ include "my-app.selectorLabels" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
选择器标签
*/}}
{{- define "my-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "my-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Chart 名称和版本
*/}}
{{- define "my-app.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
4. values.yaml 自定义
4.1 环境特定的 values 文件
# 环境特定的 values 文件结构
values/
├── values.yaml # 默认值
├── values-dev.yaml # 开发环境
├── values-staging.yaml # 预发布环境
└── values-prod.yaml # 生产环境
values-prod.yaml
# values-prod.yaml - 生产环境设置
replicaCount: 5
image:
tag: "1.2.3" # 固定特定版本
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 20
targetCPUUtilizationPercentage: 70
ingress:
hosts:
- host: api.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: api-prod-tls
hosts:
- api.example.com
env:
- name: APP_ENV
value: production
- name: LOG_LEVEL
value: warn
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-credentials
key: host
# 组合多个 values 文件
helm install my-app ./my-chart \
-f values.yaml \
-f values-prod.yaml \
--set image.tag=1.2.4
4.2 模板渲染验证
# 查看渲染后的模板(不实际部署)
helm template my-release ./my-chart -f values-prod.yaml
# 仅查看特定模板
helm template my-release ./my-chart -s templates/deployment.yaml
# 调试模式
helm install my-release ./my-chart --dry-run --debug
5. 实用 Helm Charts
5.1 Prometheus 栈安装
# 添加 prometheus-community 仓库
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# 安装 kube-prometheus-stack(Prometheus + Grafana + AlertManager)
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.adminPassword=admin123
自定义 values 文件
# prometheus-values.yaml
prometheus:
prometheusSpec:
retention: 15d
resources:
requests:
memory: 2Gi
cpu: 500m
limits:
memory: 4Gi
cpu: 1000m
storageSpec:
volumeClaimTemplate:
spec:
storageClassName: standard
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
grafana:
adminPassword: "secure-password"
persistence:
enabled: true
size: 10Gi
ingress:
enabled: true
hosts:
- grafana.example.com
tls:
- secretName: grafana-tls
hosts:
- grafana.example.com
alertmanager:
alertmanagerSpec:
storage:
volumeClaimTemplate:
spec:
storageClassName: standard
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
5.2 Grafana 单独安装
# 添加 Grafana 仓库
helm repo add grafana https://grafana.github.io/helm-charts
# 安装 Grafana
helm install grafana grafana/grafana \
--namespace monitoring \
--set persistence.enabled=true \
--set adminPassword='admin123'
5.3 其他实用 Charts
# Nginx Ingress Controller
helm install nginx-ingress ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace
# cert-manager(TLS 证书自动化)
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--set installCRDs=true
# Redis
helm install redis bitnami/redis \
--set auth.password=mypassword
# PostgreSQL
helm install postgresql bitnami/postgresql \
--set auth.postgresPassword=mypassword
# Elasticsearch
helm install elasticsearch elastic/elasticsearch \
--set replicas=3
6. CI/CD 概念回顾
6.1 什么是 CI/CD?
- CI(持续集成):频繁集成代码变更,执行自动化构建和测试
- CD(持续交付):始终保持可部署到生产环境的状态
- CD(持续部署):所有变更自动部署到生产环境
6.2 传统 CI/CD vs GitOps
| 特性 | 传统 CI/CD | GitOps |
|---|---|---|
| 部署触发 | CI 流水线 push | Pull Git 变更 |
| 真相源 | CI 服务器状态 | Git 仓库 |
| 回滚 | 需要重新部署 | Git revert |
| 审计追踪 | CI 日志 | Git 历史 |
| 安全性 | CI 需要集群访问权限 | 仅在集群内部运行 |
7. GitOps 介绍
7.1 GitOps 原则
- 声明式配置:以声明式方式定义所有基础设施和应用程序状态
- 版本控制:使用 Git 作为唯一真相源
- 自动同步:批准的变更自动应用到集群
- 持续调和:持续检测并修复实际状态与期望状态之间的差异
7.2 ArgoCD
ArgoCD 是使用最广泛的 GitOps 工具。
# 安装 ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 安装 ArgoCD CLI(macOS)
brew install argocd
# 查看初始 admin 密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# 端口转发访问
kubectl port-forward svc/argocd-server -n argocd 8080:443
ArgoCD Application 定义
# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/my-app-config.git
targetRevision: main
path: kubernetes/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # 自动清理已删除的资源
selfHeal: true # 自动恢复手动更改
syncOptions:
- CreateNamespace=true
7.3 Flux CD
# 安装 Flux CLI
curl -s https://fluxcd.io/install.sh | sudo bash
# Flux 引导(使用 GitHub)
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=./clusters/production \
--personal
Flux GitRepository 和 Kustomization
# flux-source.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app
namespace: flux-system
spec:
interval: 1m
url: https://github.com/myorg/my-app-config
ref:
branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
namespace: flux-system
spec:
interval: 10m
targetNamespace: production
sourceRef:
kind: GitRepository
name: my-app
path: ./kubernetes/overlays/production
prune: true
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: my-app
namespace: production
8. 使用 GitHub Actions 自动化 K8s 部署
8.1 GitHub Actions 工作流基本结构
# .github/workflows/ci-cd.yaml
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# 1. 测试和构建
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Run linting
run: npm run lint
# 2. Docker 镜像构建和推送
build:
needs: test
runs-on: ubuntu-latest
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix=
type=ref,event=branch
type=semver,pattern={{version}}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# 3. Kubernetes 部署
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment: production
steps:
- uses: actions/checkout@v4
- name: Set up kubectl
uses: azure/setup-kubectl@v3
with:
version: 'latest'
- name: Configure kubeconfig
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBECONFIG }}" | base64 -d > $HOME/.kube/config
chmod 600 $HOME/.kube/config
- name: Set up Helm
uses: azure/setup-helm@v3
with:
version: 'latest'
- name: Deploy with Helm
run: |
helm upgrade --install my-app ./charts/my-app \
--namespace production \
--create-namespace \
--set image.tag=${{ github.sha }} \
--set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \
--wait \
--timeout 5m
- name: Verify deployment
run: |
kubectl rollout status deployment/my-app -n production
kubectl get pods -n production -l app.kubernetes.io/name=my-app
8.2 GitOps 方式的 GitHub Actions
# .github/workflows/gitops-ci.yaml
name: GitOps CI Pipeline
on:
push:
branches: [main]
paths:
- 'src/**'
- 'Dockerfile'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
CONFIG_REPO: myorg/k8s-config
jobs:
build-and-update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# GitOps: 更新配置仓库
- name: Checkout config repo
uses: actions/checkout@v4
with:
repository: ${{ env.CONFIG_REPO }}
token: ${{ secrets.CONFIG_REPO_TOKEN }}
path: config-repo
- name: Update image tag
run: |
cd config-repo
# 使用 kustomize 时
cd kubernetes/overlays/production
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
- name: Commit and push
run: |
cd config-repo
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add .
git commit -m "Update image to ${{ github.sha }}"
git push
9. 实战流水线构建示例
9.1 完整项目结构
my-project/
├── .github/
│ └── workflows/
│ ├── ci.yaml # CI 流水线
│ ├── cd-staging.yaml # 预发布部署
│ └── cd-production.yaml # 生产部署
├── src/ # 应用程序源代码
├── tests/ # 测试代码
├── charts/
│ └── my-app/ # Helm Chart
│ ├── Chart.yaml
│ ├── values.yaml
│ ├── values-staging.yaml
│ ├── values-production.yaml
│ └── templates/
├── Dockerfile
└── package.json
9.2 完整的 CI/CD 流水线
.github/workflows/ci.yaml
name: Continuous Integration
on:
pull_request:
branches: [main, develop]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm test
env:
DATABASE_URL: postgres://postgres:test@localhost:5432/testdb
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: .
push: false
tags: test-image:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
.github/workflows/cd-staging.yaml
name: Deploy to Staging
on:
push:
branches: [develop]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
deploy:
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:staging
- name: Configure kubectl
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.STAGING_KUBECONFIG }}" | base64 -d > $HOME/.kube/config
- name: Deploy to Staging
run: |
helm upgrade --install my-app-staging ./charts/my-app \
--namespace staging \
--create-namespace \
-f ./charts/my-app/values-staging.yaml \
--set image.tag=${{ github.sha }} \
--wait
- name: Run smoke tests
run: |
STAGING_URL=$(kubectl get ingress my-app-staging -n staging -o jsonpath='{.spec.rules[0].host}')
curl -f https://$STAGING_URL/health || exit 1
- name: Notify Slack
if: always()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
fields: repo,message,commit,author
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
.github/workflows/cd-production.yaml
name: Deploy to Production
on:
release:
types: [published]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract version
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Configure kubectl
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.PRODUCTION_KUBECONFIG }}" | base64 -d > $HOME/.kube/config
- name: Deploy to Production
run: |
helm upgrade --install my-app ./charts/my-app \
--namespace production \
--create-namespace \
-f ./charts/my-app/values-production.yaml \
--set image.tag=${{ steps.version.outputs.VERSION }} \
--wait \
--timeout 10m
- name: Verify deployment
run: |
kubectl rollout status deployment/my-app -n production
kubectl get pods -n production
- name: Run integration tests
run: |
PROD_URL=$(kubectl get ingress my-app -n production -o jsonpath='{.spec.rules[0].host}')
npm run test:integration -- --url=https://$PROD_URL
- name: Create deployment record
run: |
echo "Deployed version ${{ steps.version.outputs.VERSION }} at $(date)" >> DEPLOYMENTS.md
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add DEPLOYMENTS.md
git commit -m "Record deployment ${{ steps.version.outputs.VERSION }}" || true
git push || true
10. 结论与系列总结
本篇我们了解了简化 Kubernetes 应用程序部署的 Helm 和自动化 CI/CD 流水线:
- Helm:作为 Kubernetes 包管理器,简化复杂应用程序的部署
- Chart 结构:利用模板、values、辅助函数创建可重用的包
- GitOps:以 Git 为真相源的现代部署方式
- ArgoCD/Flux:代表性的 GitOps 工具
- GitHub Actions:构建完整的 CI/CD 流水线
Docker & Kubernetes 完全指南系列总结
在这10篇系列中,我们涵盖了 Docker 和 Kubernetes 的核心概念和实战应用:
- 第1篇:Docker 基础和容器概念
- 第2篇:Docker 镜像和 Dockerfile
- 第3篇:使用 Docker Compose 管理多容器
- 第4篇:Kubernetes 基础和架构
- 第5篇:Pod、Deployment、Service
- 第6篇:Volume 和持久化
- 第7篇:资源管理和扩缩
- 第8篇:网络和 Service Mesh
- 第9篇:ConfigMap、Secret、Ingress
- 第10篇:Helm 和 CI/CD 流水线
希望通过本系列,您已经掌握了从容器技术基础到生产级 Kubernetes 运维的全面知识。容器和编排技术在不断发展,请通过官方文档和社区持续关注最新动态。
实践和经验是最好的老师。请将所学知识直接应用到您的项目中!