K8s 学习:常用命令 100 条(三)- CI/CD 集成实战
系列文章: K8s 命令实战指南
适用人群: DevOps 工程师、开发人员、运维工程师
阅读时间: 15 分钟
前言
将 Kubernetes 集成到 CI/CD 流水线中,可以实现自动化部署、滚动更新和快速回滚。本文介绍如何在常见的 CI/CD 工具中使用 kubectl 命令。
一、CI/CD 基础配置
1.1 配置 kubeconfig
# 方式1:使用 Service Account(推荐)
kubectl create serviceaccount gitlab-deployer -n default
kubectl create clusterrolebinding gitlab-deployer-binding --clusterrole=cluster-admin --serviceaccount=default:gitlab-deployer
# 获取 Service Account Token
kubectl get secret $(kubectl get serviceaccount gitlab-deployer -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode
# 获取 CA 证书
kubectl get secret $(kubectl get serviceaccount gitlab-deployer -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.ca\.crt}'
# 方式2:使用 kubeconfig 文件
cat ~/.kube/config
# 方式3:在 CI/CD 中设置环境变量
export KUBECONFIG=/path/to/kubeconfig
使用场景:
- GitLab CI 连接集群
- Jenkins 连接集群
- GitHub Actions 连接集群
- 自动化脚本认证
1.2 验证连接
# 在 CI/CD 中测试连接
kubectl cluster-info
# 验证权限
kubectl auth can-i create deployments
kubectl auth can-i delete pods
# 查看当前上下文
kubectl config current-context
# 查看可用命名空间
kubectl get namespaces
使用场景:
- CI/CD 配置验证
- 权限检查
- 环境确认
二、GitLab CI 集成
2.1 基础配置
# .gitlab-ci.yml
stages:
- build
- deploy
variables:
IMAGE_NAME: registry.example.com/myapp
IMAGE_TAG: $CI_COMMIT_SHA
build:
stage: build
script:
- docker build -t $IMAGE_NAME:$IMAGE_TAG .
- docker push $IMAGE_NAME:$IMAGE_TAG
deploy:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$IMAGE_NAME:$IMAGE_TAG
- kubectl rollout status deployment/myapp --timeout=300s
only:
- master
使用场景:
- 代码提交自动构建
- 自动更新镜像版本
- 滚动更新应用
- 生产环境部署
2.2 高级配置
# .gitlab-ci.yml(高级)
stages:
- test
- build
- deploy-staging
- deploy-production
variables:
IMAGE_NAME: registry.example.com/myapp
STAGING_NAMESPACE: staging
PRODUCTION_NAMESPACE: production
test:
stage: test
script:
- npm test
- npm run lint
build:
stage: build
script:
- docker build -t $IMAGE_NAME:$CI_COMMIT_SHA .
- docker tag $IMAGE_NAME:$CI_COMMIT_SHA $IMAGE_NAME:latest
- docker push $IMAGE_NAME:$CI_COMMIT_SHA
- docker push $IMAGE_NAME:latest
deploy-staging:
stage: deploy-staging
script:
- kubectl config set-context --current --namespace=$STAGING_NAMESPACE
- kubectl apply -f k8s/staging/
- kubectl set image deployment/myapp myapp=$IMAGE_NAME:$CI_COMMIT_SHA
- kubectl rollout status deployment/myapp --timeout=300s
environment:
name: staging
url: https://staging.example.com
only:
- develop
deploy-production:
stage: deploy-production
script:
- kubectl config set-context --current --namespace=$PRODUCTION_NAMESPACE
- kubectl apply -f k8s/production/
- kubectl set image deployment/myapp myapp=$IMAGE_NAME:$CI_COMMIT_SHA
- kubectl rollout status deployment/myapp --timeout=300s
environment:
name: production
url: https://www.example.com
when: manual
only:
- master
使用场景:
- 多环境部署(staging/production)
- 手动审批部署
- 自动化测试
- 环境隔离
2.3 回滚配置
# .gitlab-ci.yml(回滚)
rollback:
stage: rollback
script:
- kubectl rollout undo deployment/myapp
- kubectl rollout status deployment/myapp --timeout=300s
when: manual
only:
- master
rollback-to-revision:
stage: rollback
script:
- kubectl rollout history deployment/myapp
- kubectl rollout undo deployment/myapp --to-revision=$REVISION
when: manual
only:
- master
使用场景:
- 快速回滚到上一个版本
- 回滚到指定版本
- 手动触发回滚
- 紧急修复
三、Jenkins 集成
3.1 声明式 Pipeline
// Jenkinsfile
pipeline {
agent any
environment {
IMAGE_NAME = 'registry.example.com/myapp'
IMAGE_TAG = "${env.BUILD_NUMBER}"
KUBECONFIG = credentials('kubeconfig')
}
stages {
stage('Build') {
steps {
sh 'docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .'
sh 'docker push ${IMAGE_NAME}:${IMAGE_TAG}'
}
}
stage('Deploy to Staging') {
steps {
sh 'kubectl config set-context --current --namespace=staging'
sh 'kubectl set image deployment/myapp myapp=${IMAGE_NAME}:${IMAGE_TAG}'
sh 'kubectl rollout status deployment/myapp --timeout=300s'
}
}
stage('Deploy to Production') {
steps {
input 'Deploy to Production?'
sh 'kubectl config set-context --current --namespace=production'
sh 'kubectl set image deployment/myapp myapp=${IMAGE_NAME}:${IMAGE_TAG}'
sh 'kubectl rollout status deployment/myapp --timeout=300s'
}
}
}
post {
failure {
sh 'kubectl rollout undo deployment/myapp'
}
}
}
使用场景:
- Jenkins 流水线集成
- 自动化构建和部署
- 失败自动回滚
- 手动审批部署
3.2 脚本式 Pipeline
// Jenkinsfile(脚本式)
node {
def imageName = 'registry.example.com/myapp'
def imageTag = env.BUILD_NUMBER
try {
stage('Build') {
sh "docker build -t ${imageName}:${imageTag} ."
sh "docker push ${imageName}:${imageTag}"
}
stage('Deploy') {
sh "kubectl set image deployment/myapp myapp=${imageName}:${imageTag}"
sh "kubectl rollout status deployment/myapp --timeout=300s"
}
} catch (Exception e) {
// 失败时回滚
sh 'kubectl rollout undo deployment/myapp'
throw e
}
}
使用场景:
- 复杂流水线逻辑
- 条件判断
- 异常处理
- 自定义流程
四、GitHub Actions 集成
4.1 基础配置
# .github/workflows/deploy.yml
name: Deploy to Kubernetes
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up kubectl
uses: azure/setup-kubectl@v3
- name: Configure kubectl
run: |
mkdir -p ~/.kube
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > ~/.kube/config
- name: Build and push Docker image
run: |
docker build -t registry.example.com/myapp:${{ github.sha }} .
docker push registry.example.com/myapp:${{ github.sha }}
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/myapp myapp=registry.example.com/myapp:${{ github.sha }}
kubectl rollout status deployment/myapp --timeout=300s
使用场景:
- GitHub 仓库自动化部署
- 代码推送触发部署
- 自动更新镜像版本
- 滚动更新应用
4.2 多环境部署
# .github/workflows/deploy.yml(多环境)
name: Deploy to Kubernetes
on:
push:
branches: [ main, develop ]
jobs:
deploy-staging:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
steps:
- uses: actions/checkout@v3
- name: Deploy to Staging
run: |
kubectl config set-context --current --namespace=staging
kubectl apply -f k8s/staging/
kubectl set image deployment/myapp myapp=registry.example.com/myapp:${{ github.sha }}
kubectl rollout status deployment/myapp --timeout=300s
deploy-production:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Deploy to Production
run: |
kubectl config set-context --current --namespace=production
kubectl apply -f k8s/production/
kubectl set image deployment/myapp myapp=registry.example.com/myapp:${{ github.sha }}
kubectl rollout status deployment/myapp --timeout=300s
使用场景:
- 分支对应环境
- 自动化多环境部署
- 环境隔离
- 条件触发
五、蓝绿部署
5.1 蓝绿部署流程
# 1. 部署绿色版本
kubectl apply -f deployment-green.yaml
# 2. 等待绿色版本就绪
kubectl rollout status deployment/myapp-green --timeout=300s
# 3. 切换流量到绿色版本
kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'
# 4. 验证绿色版本
curl http://myapp-service/
# 5. 如果有问题,回滚到蓝色版本
kubectl patch service myapp -p '{"spec":{"selector":{"version":"blue"}}}'
# 6. 确认无误后,删除蓝色版本
kubectl delete deployment myapp-blue
使用场景:
- 零停机部署
- 快速回滚
- 生产环境验证
- 版本切换
5.2 自动化蓝绿部署脚本
#!/bin/bash
# blue-green-deploy.sh
IMAGE_TAG=$1
NAMESPACE=${2:-default}
echo "开始蓝绿部署..."
# 获取当前活跃版本
CURRENT_VERSION=$(kubectl get service myapp -n $NAMESPACE -o jsonpath='{.spec.selector.version}')
if [ "$CURRENT_VERSION" == "blue" ]; then
NEW_VERSION="green"
else
NEW_VERSION="blue"
fi
echo "当前版本: $CURRENT_VERSION"
echo "新版本: $NEW_VERSION"
# 部署新版本
cat deployment-template.yaml | \
sed "s/{{VERSION}}/$NEW_VERSION/g" | \
sed "s/{{IMAGE_TAG}}/$IMAGE_TAG/g" | \
kubectl apply -n $NAMESPACE -f -
# 等待新版本就绪
kubectl rollout status deployment/myapp-$NEW_VERSION -n $NAMESPACE --timeout=300s
# 切换流量
kubectl patch service myapp -n $NAMESPACE -p "{\"spec\":{\"selector\":{\"version\":\"$NEW_VERSION\"}}}"
echo "蓝绿部署完成!当前版本: $NEW_VERSION"
使用场景:
- 自动化蓝绿部署
- 版本切换
- 零停机更新
- 生产环境验证
六、金丝雀发布
6.1 金丝雀发布流程
# 1. 部署金丝雀版本(10% 流量)
kubectl apply -f deployment-canary.yaml
# 2. 配置 Service 流量分割
kubectl apply -f service-canary.yaml
# 3. 监控金丝雀版本
kubectl logs -l version=canary -f
# 4. 逐步增加流量(20% -> 50% -> 100%)
kubectl patch service myapp -p '{"spec":{"selector":{"version":"canary"}}}'
# 5. 如果正常,完全切换到新版本
kubectl scale deployment myapp-stable --replicas=0
kubectl scale deployment myapp-canary --replicas=3
# 6. 如果有问题,回滚
kubectl scale deployment myapp-canary --replicas=0
kubectl scale deployment myapp-stable --replicas=3
使用场景:
- 渐进式发布
- 风险控制
- 小流量验证
- 灰度发布
6.2 自动化金丝雀发布脚本
#!/bin/bash
# canary-deploy.sh
IMAGE_TAG=$1
NAMESPACE=${2:-default}
CANARY_REPLICAS=${3:-1}
STABLE_REPLICAS=${4:-9}
echo "开始金丝雀发布..."
# 部署金丝雀版本
cat deployment-canary.yaml | \
sed "s/{{IMAGE_TAG}}/$IMAGE_TAG/g" | \
sed "s/{{REPLICAS}}/$CANARY_REPLICAS/g" | \
kubectl apply -n $NAMESPACE -f -
# 等待金丝雀版本就绪
kubectl rollout status deployment/myapp-canary -n $NAMESPACE --timeout=300s
echo "金丝雀版本已部署($CANARY_REPLICAS 个副本)"
echo "监控命令: kubectl logs -l version=canary -n $NAMESPACE -f"
# 监控 5 分钟
echo "监控 5 分钟..."
sleep 300
# 检查错误率
ERROR_RATE=$(kubectl logs -l version=canary -n $NAMESPACE | grep -c "ERROR")
if [ $ERROR_RATE -gt 10 ]; then
echo "错误率过高,回滚金丝雀版本..."
kubectl scale deployment myapp-canary -n $NAMESPACE --replicas=0
exit 1
fi
# 逐步增加金丝雀副本
echo "增加金丝雀副本到 $((CANARY_REPLICAS * 2))..."
kubectl scale deployment myapp-canary -n $NAMESPACE --replicas=$((CANARY_REPLICAS * 2))
kubectl scale deployment myapp-stable -n $NAMESPACE --replicas=$((STABLE_REPLICAS - CANARY_REPLICAS))
echo "金丝雀发布完成!"
使用场景:
- 自动化金丝雀发布
- 错误率监控
- 渐进式流量切换
- 自动回滚
七、配置管理
7.1 ConfigMap 更新
# 更新 ConfigMap(不重启 Pod)
kubectl create configmap app-config --from-file=config.yaml --dry-run=client -o yaml | kubectl apply -f -
# 触发 Pod 滚动更新(让 Pod 重新加载配置)
kubectl rollout restart deployment/myapp
# 查看 ConfigMap 变更历史
kubectl describe configmap app-config
# 比较 ConfigMap 差异
kubectl get configmap app-config -o yaml > current-config.yaml
diff config.yaml current-config.yaml
使用场景:
- 应用配置更新
- 配置热更新
- 配置版本控制
- 配置回滚
7.2 Secret 更新
# 更新 Secret(不重启 Pod)
kubectl create secret generic app-secret --from-literal=password=newpass --dry-run=client -o yaml | kubectl apply -f -
# 触发 Pod 滚动更新
kubectl rollout restart deployment/myapp
# 查看 Secret 变更历史
kubectl describe secret app-secret
# 解码 Secret 内容
kubectl get secret app-secret -o jsonpath='{.data.password}' | base64 --decode
使用场景:
- 密码更新
- 密钥轮换
- 证书更新
- 安全配置
八、监控与告警
8.1 部署状态监控
# 监控部署状态
kubectl rollout status deployment/myapp --timeout=300s
# 查看部署历史
kubectl rollout history deployment/myapp
# 查看 Pod 状态
kubectl get pods -l app=myapp -w
# 查看事件
kubectl get events --field-selector involvedObject.name=myapp
# 监控资源使用
kubectl top pod -l app=myapp
使用场景:
- 部署进度监控
- 异常检测
- 性能监控
- 事件追踪
8.2 自动化健康检查
#!/bin/bash
# health-check.sh
DEPLOYMENT_NAME=$1
NAMESPACE=${2:-default}
echo "开始健康检查..."
# 等待部署完成
kubectl rollout status deployment/$DEPLOYMENT_NAME -n $NAMESPACE --timeout=300s
# 检查 Pod 状态
READY_PODS=$(kubectl get deployment $DEPLOYMENT_NAME -n $NAMESPACE -o jsonpath='{.status.readyReplicas}')
DESIRED_PODS=$(kubectl get deployment $DEPLOYMENT_NAME -n $NAMESPACE -o jsonpath='{.status.replicas}')
if [ "$READY_PODS" != "$DESIRED_PODS" ]; then
echo "健康检查失败:就绪副本数不匹配"
exit 1
fi
# 检查容器重启次数
RESTART_COUNT=$(kubectl get pods -l app=$DEPLOYMENT_NAME -n $NAMESPACE -o jsonpath='{.items[0].status.containerStatuses[0].restartCount}')
if [ "$RESTART_COUNT" -gt 3 ]; then
echo "健康检查失败:容器重启次数过多"
exit 1
fi
# 测试服务连通性
SERVICE_IP=$(kubectl get service $DEPLOYMENT_NAME -n $NAMESPACE -o jsonpath='{.spec.clusterIP}')
if ! kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- wget -qO- http://$SERVICE_IP:80 > /dev/null 2>&1; then
echo "健康检查失败:服务不可访问"
exit 1
fi
echo "健康检查通过!"
使用场景:
- 部署后自动验证
- 服务可用性检查
- 自动化测试
- CI/CD 集成
九、总结
9.1 CI/CD 集成最佳实践
-
安全性
- 使用 Service Account 认证
- 限制权限范围
- 保护敏感信息
-
可靠性
- 滚动更新策略
- 健康检查
- 自动回滚
-
可追溯性
- 版本标签
- 部署历史
- 审计日志
-
效率
- 并行构建
- 缓存优化
- 增量部署
9.2 常用命令速查
| 场景 | 命令 |
|---|---|
| 更新镜像 | kubectl set image deployment/<name> <container>=<image> |
| 查看部署状态 | kubectl rollout status deployment/<name> |
| 查看历史 | kubectl rollout history deployment/<name> |
| 回滚 | kubectl rollout undo deployment/<name> |
| 重启 | kubectl rollout restart deployment/<name> |
| 应用配置 | kubectl apply -f <yaml-file> |
参考资料
作者: PaPaBot
发布时间: 2026-03-07
标签: #Kubernetes #K8s #DevOps #CI/CD #自动化部署
本文属于《K8s 命令实战指南》系列文章第三篇
Views: 0
