云原生基础:容器、Kubernetes核心概念与CI/CD的关联

在深入Tekton与Argo CD之前,我们必须先建立对云原生基石的清晰认知。CI/CD流水线并非运行在真空中,它需要一套稳定、可扩展、可移植的基础设施来承载构建、测试和部署任务。容器与Kubernetes(K8s)正是这套基础设施的核心。本章将系统梳理容器技术原理、Kubernetes的核心对象(Pod、Service、Deployment、Namespace),并明确它们与CI/CD流水线之间的具体映射关系,为后续使用Tekton定义流水线任务、使用Argo CD进行应用同步打下坚实的知识基础。

云原生基础设施与CI/CD流水线映射关系 容器 (Container) 镜像打包应用+依赖 隔离进程/文件系统 CI构建产物 Kubernetes 核心对象 Pod 最小调度单元 Service 稳定访问入口 Deployment 声明式滚动更新 Namespace 资源隔离 CI/CD 流水线 (Tekton + Argo CD) Tekton: 构建/测试/推送镜像 Argo CD: 同步/部署/回滚 关键映射关系: 1. Tekton Task 运行在 Pod 中 → 需要容器镜像与资源配额 2. Argo CD 管理 Deployment 清单 → 通过 Service 暴露应用 → 受 Namespace 隔离约束

上图展示了本章的核心逻辑:容器作为CI/CD流水线的最小执行单元,Kubernetes提供编排能力,而Tekton与Argo CD分别负责流水线执行与应用部署。理解这些基础组件的职责边界与交互方式,是后续配置流水线、排查故障的前提。

容器技术:CI/CD的原子载体

核心原理:镜像与容器的分层关系

容器本质上是操作系统级虚拟化,它利用Linux内核的命名空间(Namespace)和控制组(Cgroups)实现进程隔离与资源限制。在CI/CD语境下,我们更关注容器镜像(Image)与容器实例(Container)的关系。镜像是只读的模板,由多层文件系统叠加而成;容器则是镜像的运行实例,在镜像层之上增加可写层。这种分层设计使得镜像可以复用、缓存和快速分发。

在流水线中,每个构建步骤(如编译、测试、打包)都可以封装为一个独立的容器镜像。例如,Node.js构建任务使用node:20-alpine镜像,而Docker镜像构建任务则使用docker:24镜像。这种原子化设计带来三个关键优势:环境一致性(开发、测试、生产使用相同镜像)、资源隔离(每个任务独立运行,互不干扰)、弹性伸缩(按需创建和销毁容器)。

CI/CD视角:Tekton的每个Step都对应一个容器。当流水线执行时,Kubernetes会为每个Step创建独立的Pod,Pod内的容器共享网络和存储卷。这意味着,如果Step A需要访问Step B生成的文件,必须通过共享卷(Volume)来实现,而不是依赖容器内的本地文件系统。

判断方法:如何选择基础镜像

选择基础镜像是流水线性能与安全的关键决策。以下是判断标准:

  • 体积优先:优先选择Alpine、Slim等精简版本,减少拉取时间。例如node:20-alpine比node:20小约50%。
  • 安全合规:检查镜像的CVE漏洞报告,避免使用包含已知高危漏洞的镜像。
  • 构建工具链完整性:对于需要编译的步骤,确保镜像包含完整的工具链(如gcc、make),而不是仅包含运行时。
  • 缓存友好性:将依赖安装层与源码复制层分离,利用Docker层缓存加速重复构建。

案例拆解:多阶段构建优化流水线

假设我们有一个Java Spring Boot项目,传统构建方式需要Maven和JDK,但运行环境只需要JRE。通过多阶段构建,我们可以将构建与运行环境分离:

# 阶段1:编译
FROM maven:3.9-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# 阶段2:运行
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

这个案例中,最终镜像仅包含JRE和JAR包,体积从800MB降至180MB。在Tekton流水线中,我们可以将这个Dockerfile作为构建步骤的输入,通过kaniko或buildah工具在容器内构建镜像,而无需Docker守护进程。

常见误区:不要在流水线中使用docker build命令,除非你明确知道如何配置Docker-in-Docker(DinD)或使用特权模式。在Kubernetes环境中,推荐使用Kaniko或Buildah等无守护进程的构建工具,它们更安全且不需要特权容器。

Kubernetes核心对象:从Pod到Deployment

核心原理:Pod是最小调度单元

Pod是Kubernetes中最小的部署和调度单元,它封装了一个或多个容器、存储资源、网络IP以及容器运行方式。Pod的设计哲学是:紧密耦合的容器共享同一个网络命名空间和存储卷。例如,一个Web应用容器与一个日志采集Sidecar容器可以放在同一个Pod中,它们通过localhost通信,共享日志文件。

在CI/CD场景中,Pod的临时性尤为重要。Tekton的TaskRun会创建Pod来执行任务,任务完成后Pod即被销毁。这种设计保证了流水线的隔离性和可重复性,但也意味着任务之间不能通过Pod IP直接通信,必须使用共享存储或外部服务。

Service:稳定的访问入口

Service为Pod提供稳定的网络访问入口。由于Pod的IP是动态分配的,Service通过标签选择器(Label Selector)关联一组Pod,并提供一个虚拟IP(ClusterIP)和DNS名称。Service还支持负载均衡,将请求分发到后端的多个Pod实例。

在Argo CD的部署流程中,Service是暴露应用的标准方式。例如,一个微服务应用部署后,通过Service将内部端口映射为集群内可访问的地址。对于外部访问,可以进一步使用NodePort或Ingress。

Deployment:声明式应用管理

Deployment是Kubernetes中最常用的工作负载控制器,它负责管理无状态应用的部署、更新和回滚。Deployment的核心特性包括:

  • 期望状态:声明副本数(Replicas),控制器确保实际运行数量与期望一致。
  • 滚动更新:支持零停机更新,通过maxSurge和maxUnavailable控制更新节奏。
  • 回滚机制:保留历史版本,可一键回滚到任意之前的版本。

在GitOps实践中,Deployment的YAML清单是Argo CD管理的核心对象。当应用代码更新后,CI流水线构建新镜像并推送至镜像仓库,然后更新Git仓库中的Deployment镜像标签。Argo CD检测到Git仓库变化后,自动将新配置同步到集群。

Namespace:多环境隔离

Namespace用于在同一个Kubernetes集群中划分多个虚拟集群。它提供资源配额(ResourceQuota)、网络策略(NetworkPolicy)和权限控制(RBAC)的隔离边界。在CI/CD中,Namespace通常用于区分开发、测试、生产环境:

环境 Namespace 资源限制 CI/CD策略
开发 dev CPU 2核/内存4GB 每次代码提交触发自动部署
测试 test CPU 4核/内存8GB 合并请求通过后部署
生产 prod CPU 16核/内存32GB 手动审批后通过Argo CD同步

这种隔离方式使得不同环境的配置、权限和资源互不干扰,同时降低了硬件成本(共享同一集群)。

CI/CD视角下的Kubernetes实践

操作流程:从代码提交到应用部署

理解Kubernetes对象后,我们来看一个完整的CI/CD流程如何与这些对象交互:

  1. 代码提交:开发者推送代码到Git仓库,触发Tekton的PipelineRun。
  2. 流水线执行:Tekton创建Pod运行构建任务,生成容器镜像并推送至镜像仓库(如Harbor或Docker Hub)。
  3. 配置更新:流水线更新Git仓库中的Deployment YAML文件,将镜像标签从v1.0.0改为v1.0.1。
  4. Argo CD同步:Argo CD检测到Git仓库变化,将新配置同步到目标Namespace。
  5. 滚动更新:Deployment控制器执行滚动更新,逐步替换旧Pod,确保服务不中断。
  6. 健康检查:Kubernetes通过ReadinessProbe检查新Pod是否就绪,就绪后才将流量切换过去。

案例拆解:微服务应用的完整部署

假设我们有一个电商应用,包含前端(React)、后端(Spring Boot)和数据库(PostgreSQL)。在Kubernetes中,我们为每个组件创建独立的Deployment和Service:

# backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: prod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: registry.example.com/backend:v1.0.1
        ports:
        - containerPort: 8080
        env:
        - name: DB_HOST
          value: postgres-service
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10

在这个案例中,Argo CD管理整个prod命名空间下的所有资源。当后端镜像更新时,Argo CD自动同步Deployment,触发滚动更新。如果新版本存在健康问题,ReadinessProbe会阻止流量切换,Argo CD可以自动回滚到上一个健康版本。

经验总结:在配置Kubernetes资源时,始终为Deployment设置资源请求(requests)和限制(limits)。这不仅能防止资源争抢,还能让集群调度器更合理地分配Pod。对于CI/CD流水线任务,建议在Tekton的Task中设置较小的资源请求(如CPU 100m),以便快速调度。

常见误区与复盘

在云原生CI/CD实践中,以下误区需要特别注意:

  • 误区一:将Pod视为持久化资源。Pod是临时性的,任何需要持久化的数据都应存储在PersistentVolume或外部存储中。
  • 误区二:在流水线中直接修改集群状态。正确的做法是修改Git仓库中的配置,让Argo CD自动同步,保持Git作为单一事实来源。
  • 误区三:忽略Namespace的资源配额。如果Namespace设置了ResourceQuota,而Deployment的请求超出配额,Pod将无法创建,导致部署失败。
  • 误区四:使用latest镜像标签。这会导致无法追踪具体版本,且Argo CD无法准确判断配置漂移。应始终使用不可变的版本标签(如Git SHA或语义化版本)。

通过本章的学习,我们建立了容器与Kubernetes核心对象的完整认知框架。这些基础概念将直接应用于后续的Tekton流水线定义和Argo CD部署策略中。理解Pod的临时性、Service的稳定性、Deployment的声明式管理以及Namespace的隔离性,是构建可靠、可扩展的云原生CI/CD体系的前提。