5.1 容器化与 K8s 集成


5.1 容器化与 K8s 集成

本节摘要:Docker 将应用与依赖打包为不可变镜像;Kubernetes 编排容器部署、扩缩与滚动更新。本节给出安全 Dockerfile、CI 中 build-push-deploy 完整流程,以及 Deployment/Service/Ingress 最小 manifest。

核心问题

阅读完本节,你应当能够:

  1. 编写多阶段、非 root 的 Dockerfile
  2. 在 GitHub Actions 中 build 并 push 到 Registry
  3. 编写 K8s Deployment 与 Service manifest
  4. 解释容器化如何支撑「构建一次,随处部署」

一、安全 Dockerfile

FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . FROM python:3.11-slim RUN useradd -m appuser WORKDIR /app COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY --from=builder /app /app USER appuser EXPOSE 8080 CMD ["gunicorn", "-b", "0.0.0.0:8080", "app:application"]

要点:多阶段减体积;非 root 防容器逃逸;slim 基础镜像减 CVE 面。

容器在 CI/CD 中的位置

容器在 CI/CD 中的位置

二、CI build-push-deploy

jobs: docker: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/login-action@v3 with: registry: registry.corp.com username: ${{ secrets.REG_USER }} password: ${{ secrets.REG_PASS }} - uses: docker/build-push-action@v5 with: push: true tags: registry.corp.com/myapp:${{ github.sha }} deploy: needs: docker runs-on: ubuntu-latest steps: - run: | kubectl set image deployment/myapp \ app=registry.corp.com/myapp:${{ github.sha }} \ -n production - run: kubectl rollout status deployment/myapp -n production

同一 SHA tag 从 CI 到 prod——容器化天然支持原则5。

三、K8s 最小 manifest

apiVersion: apps/v1 kind: Deployment metadata: { name: myapp, namespace: production } spec: replicas: 3 selector: { matchLabels: { app: myapp } } template: metadata: { labels: { app: myapp } } spec: containers: - name: app image: registry.corp.com/myapp:abc123 ports: [{ containerPort: 8080 }] resources: requests: { cpu: 100m, memory: 128Mi } limits: { cpu: 500m, memory: 512Mi } livenessProbe: httpGet: { path: /health, port: 8080 } initialDelaySeconds: 10 --- apiVersion: v1 kind: Service metadata: { name: myapp } spec: selector: { app: myapp } ports: [{ port: 80, targetPort: 8080 }]

livenessProbe 让 K8s 自动重启 unhealthy pod——与第4章 rollback 互补。

Docker vs VM 部署

维度 VM + Ansible Docker + K8s
启动 分钟
密度
回滚 rollout undo
环境一致 需配置管理 镜像即环境

⚠️ 常见坑:latest tag——K8s 默认 imagePullPolicy: IfNotPresent,节点缓存旧 latest,「部署了但没更新」。

💡 关键直觉:SOURCE 强调 Docker 是通用构建产物——Java JAR、Node dist 都可封进同一交付单元。

.dockerignore 加速构建

.git node_modules __pycache__ *.md tests/

减少 build context 体积——CI 中 COPY 更快,缓存层更稳。

Helm 封装(简要)

helm create myapp helm upgrade --install myapp ./myapp -f values-prod.yaml

manifest 模板化后,CD 管道只需 helm upgrade --set image.tag=$SHA

四、K8s 集成与镜像安全(SOURCE 5.1 扩展)

资源配额与 LimitRange

resources: requests: { cpu: 100m, memory: 128Mi } limits: { cpu: 500m, memory: 512Mi }

无 limits 的 pod 可能 OOM 拖垮节点——CI 生成的 manifest 模板应强制 limits。ResourceQuota 限制 namespace 总 CPU/memory。

镜像扫描与准入

Kyverno/OPA Gatekeeper 拒绝 Critical CVE 镜像 deploy:

validate: message: "Critical CVE found" pattern: spec: containers: - name: "*" image: "!*:latest"

与 Trivy CI 扫描双保险——坏镜像进不了 cluster。

Sidecar 与 service mesh

Istio sidecar 注入后,金丝雀 traffic split 在 mesh 层——app 无感知。代价:每 pod 多一个 envoy 容器,内存 +128Mi 量级。

Docker BuildKit 缓存

- uses: docker/build-push-action@v5 with: cache-from: type=registry,ref=registry/app:buildcache cache-to: type=registry,ref=registry/app:buildcache,mode=max

跨 CI job 复用 layer——Java Maven dependency layer 尤其受益。

要点速记

  • 多阶段 + 非 root Dockerfile 安全基线
  • build-push-action CI 标准流程
  • kubectl set image + rollout status 部署验证
  • livenessProbe 运行时健康
  • SHA tag 禁止 latest
  • .dockerignore 加速 CI build
  • Helm 多环境 manifest 管理

下一节 5.2 Terraform 与 IaC 如何 provisioning 环境。

容器化的工程最佳实践

容器化 CI/CD 的核心收益是「交付单元统一」:无论 Java、Node 还是 Python,都以镜像为交付单元,构建、扫描、部署、回滚的操作全部统一。落地时先从 Dockerfile 开始:多阶段构建分离构建环境与运行环境,非 root 用户降低逃逸风险,基础镜像固定 tag 而非 latest。镜像 tag 一律用 commit SHA 或含版本号的不变标识,禁止 latest——latest 在 K8s 下会因 IfNotPresent 导致「部署了但没更新」。

镜像安全要在 CI 阶段扫描:Trivy/Grype 扫 CVE,Cosign 签名保证供应链完整,Kyverno 准入控制拒绝 Critical 镜像进集群。K8s 侧配置 resources 与探针(liveness/readiness)是上线的基本要求,配合 HPA 实现弹性。对团队规模较小的项目,先从单个 Deployment+Service 开始,逐步引入 Helm 与 GitOps,避免一开始就背上 Argo CD 的复杂度。

容器化的渐进路线

对没有容器基础的团队,建议按四步渐进:第一步把服务打包进镜像并在本地验证;第二步将镜像推送到私有仓库并在 CI 中构建;第三步部署到 K8s 并配置探针与资源限制;第四步加入镜像扫描与签名。每一步都先解决「跑得起来」,再谈优化与安全。容器化不是终点,而是为后续 IaC、GitOps 与弹性伸缩打基础的统一交付形态。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U