部署云原生KubernetesSkill deploying-cloud-k8s

本技能专注于使用CI/CD流水线将应用程序高效、可靠地部署到云Kubernetes平台(如AKS, GKE, DOKS)。核心内容包括区分构建时与运行时环境变量、确保容器镜像架构与集群节点匹配、配置GitHub Actions实现选择性构建与自动化部署、使用Helm进行应用管理,并提供一套完整的故障排除指南和部署前检查清单。适用于DevOps工程师、SRE和云原生开发者,旨在解决生产环境部署中的常见问题,提升部署成功率和系统稳定性。关键词:Kubernetes部署,CI/CD流水线,云原生,Helm,GitHub Actions,故障排除,生产环境,架构匹配,环境变量。

Docker/K8s 0 次安装 0 次浏览 更新于 3/2/2026

name: 部署云原生Kubernetes description: | 使用CI/CD流水线将应用程序部署到云Kubernetes(AKS/GKE/DOKS)。 适用于生产环境部署、设置GitHub Actions、故障排除部署问题。 涵盖构建时与运行时变量、架构匹配以及经过实战检验的调试方法。

部署云原生Kubernetes

快速开始

  1. 检查集群架构:kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.architecture}'
  2. 将构建平台与集群匹配(arm64 vs amd64)
  3. 使用路径过滤器设置GitHub Actions
  4. 使用Helm部署,通过--set传递密钥

关键点:构建时与运行时变量

问题

Next.js的NEXT_PUBLIC_*变量在构建时嵌入,而非运行时:

# 错误:运行时ENV对NEXT_PUBLIC_*无效
ENV NEXT_PUBLIC_API_URL=https://api.example.com

# 正确:必须是构建ARG
ARG NEXT_PUBLIC_API_URL=https://api.example.com
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL

构建时变量(Next.js)

变量 用途
NEXT_PUBLIC_SSO_URL 浏览器OAuth的SSO端点
NEXT_PUBLIC_API_URL 浏览器fetch的API端点
NEXT_PUBLIC_APP_URL 重定向的应用URL

运行时变量(ConfigMaps/Secrets)

变量 来源
DATABASE_URL 密钥(Neon/托管数据库)
SSO_URL ConfigMap(内部K8s:http://sso:3001
BETTER_AUTH_SECRET 密钥

架构匹配

在任何部署之前,检查架构:

kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.architecture}'
# 输出:arm64 arm64  或  amd64 amd64

Docker构建

- uses: docker/build-push-action@v5
  with:
    platforms: linux/arm64      # 匹配你的集群!
    provenance: false           # 避免清单问题
    no-cache: true              # 调试时使用

为什么设置provenance: false Buildx认证会创建复杂的清单列表,导致“no match for platform”错误。

GitHub Actions CI/CD

使用路径过滤器进行选择性构建

jobs:
  changes:
    runs-on: ubuntu-latest
    outputs:
      api: ${{ steps.filter.outputs.api }}
      web: ${{ steps.filter.outputs.web }}
    steps:
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            api:
              - 'apps/api/**'
            web:
              - 'apps/web/**'

  build-api:
    needs: changes
    if: needs.changes.outputs.api == 'true'

Next.js构建参数

- name: 构建并推送(web)
  uses: docker/build-push-action@v5
  with:
    build-args: |
      NEXT_PUBLIC_SSO_URL=https://sso.${{ vars.DOMAIN }}
      NEXT_PUBLIC_API_URL=https://api.${{ vars.DOMAIN }}

Helm部署

- name: 部署
  run: |
    helm upgrade --install myapp ./helm/myapp \
      --set global.imageTag=${{ github.sha }} \
      --set "secrets.databaseUrl=${{ secrets.DATABASE_URL }}" \
      --set "secrets.authSecret=${{ secrets.BETTER_AUTH_SECRET }}"

故障排除指南

快速诊断流程

Pod未运行?
    │
    ├─► ImagePullBackOff
    │       ├─► "not found" ──► 标签错误或注册表错误
    │       ├─► "unauthorized" ──► 认证/imagePullSecrets问题
    │       └─► "no match for platform" ──► 架构不匹配
    │
    ├─► CrashLoopBackOff
    │       ├─► "exec format error" ──► CPU架构错误
    │       ├─► 退出代码1 ──► 应用启动失败
    │       └─► OOMKilled ──► 内存限制过低
    │
    └─► Pending
            ├─► 资源不足 ──► 扩展集群
            └─► 无匹配节点 ──► 检查nodeSelector

诊断命令

kubectl get pods -n <命名空间>
kubectl describe pod <pod名称> -n <命名空间> | grep -E "(Image:|Failed|Error)"
kubectl get events -n <命名空间> --sort-by='.lastTimestamp' | tail -20
kubectl logs <pod名称> -n <命名空间> --tail=50

错误:ImagePullBackOff “not found”

原因:

  • 标签不存在(短SHA vs 完整SHA)
  • 注册表路径错误
  • 路径过滤器跳过了构建

修复: 验证部署时使用的确切标签是否已推送镜像

错误:“no match for platform in manifest”

原因: 镜像为错误架构构建 或 buildx认证问题

修复:

platforms: linux/arm64  # 匹配集群!
provenance: false       # 简单清单
no-cache: true          # 强制重建

错误:“exec format error”

原因: 二进制架构与节点不匹配

修复: 使用正确平台重建,使用no-cache: true

错误:Helm逗号解析

failed parsing --set data: key "com" has no value

原因: Helm将逗号解释为数组分隔符

修复: 使用heredoc值文件:

- name: 部署
  run: |
    cat > /tmp/overrides.yaml << EOF
    sso:
      env:
        ALLOWED_ORIGINS: "https://a.com,https://b.com"
    EOF
    helm upgrade --install app ./chart --values /tmp/overrides.yaml

错误:密码认证失败

原因: 密码包含特殊字符(base64 +/=

修复: 使用十六进制密码:

# 错误
openssl rand -base64 16  # 可能包含+/=

# 正确
openssl rand -hex 16     # 仅字母数字

错误:注销重定向到0.0.0.0

原因: request.url返回容器绑定地址

修复:

const APP_URL = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
const response = NextResponse.redirect(new URL("/", APP_URL));

部署前检查清单

架构

  • [ ] 检查集群节点架构
  • [ ] 构建平台与集群匹配

Docker构建

  • [ ] 设置provenance: false
  • [ ] platforms: linux/<架构>匹配集群
  • [ ] 构建和部署之间的镜像标签一致

CI/CD

  • [ ] 所有NEXT_PUBLIC_*作为构建参数
  • [ ] 密钥通过--set传递(不在values.yaml中)
  • [ ] 配置路径过滤器

Helm

  • [ ] --set值中没有逗号
  • [ ] 内部K8s服务名称用于服务间通信
  • [ ] 密码在values.yaml中单一来源

生产环境调试

追踪请求路径

# 1. 前端日志
kubectl logs deploy/web -n myapp --tail=50

# 2. API日志
kubectl logs deploy/api -n myapp --tail=100 | grep -i error

# 3. 边车日志(Dapr等)
kubectl logs deploy/api -n myapp -c daprd --tail=50

常见错误模式

错误 可能原因
AttributeError: no attribute 'X' 模型/模式不匹配
内部调用404 Not Found 端点URL错误
时间偏差数小时 时区处理错误
greenlet_spawn not called 异步SQLAlchemy模式

使用ArgoCD的GitOps

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/org/repo.git
    path: k8s/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: myapp
  syncPolicy:
    automated:
      prune: true      # 删除Git中不存在的资源
      selfHeal: true   # 自动修复漂移

可观测性

# Prometheus的ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  endpoints:
    - port: metrics
      interval: 30s

安全性

# Pod安全上下文
securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop: ["ALL"]

弹性

# HPA + PDB
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: policy/v1
kind: PodDisruptionBudget
spec:
  minAvailable: 1

完整GitOps、可观测性、安全性和弹性模式,请参阅references/production-patterns.md

验证

运行:python scripts/verify.py

相关技能

  • containerizing-applications - Docker和Helm图表
  • operating-k8s-local - 使用Minikube的本地Kubernetes
  • building-nextjs-apps - Next.js模式

参考资料