KubeSphere学习笔记:从 Gitee 拉取代码到部署到 K8s

任务: 从 Gitee 仓库拉取 FastAPI 项目代码,构建 Docker 镜像,部署到 KubeSphere 管理的 Kubernetes 集群,最终通过浏览器访问应用。

环境:

  • 操作系统:Windows 11
  • Docker Desktop(内置 Kubernetes 集群)
  • KubeSphere v4.2.0(容器管理平台)
  • 代码语言:Python FastAPI
  • 容器镜像:fastapi-demo:latest

1. 创建凭证

KubeSphere 里配置 Gitee 的登录凭据,选择用户名和密码类型。

注意:GitRepository CRD 只支持 basic-auth 凭据,不支持 SSH 私钥。

2. 创建 DevOps 项目

在 KubeSphere 控制台进入目标企业空间 → DevOps 项目 → 创建 DevOps 项目。DevOps 项目用于管理流水线及其运行记录,与普通项目(管理应用负载)是分开的。

3. 创建流水线

在 DevOps 项目下选择创建流水线多分支流水线 → 关联 Gitee 仓库和凭据 → 创建。

4. 踩坑:Docker 构建和部署

正常情况下的流程

一般来说,流水线的过程是:

KubeSphere 创建 Agent 容器(builder-base 镜像)
    → Agent 里有 docker CLI
    → 通过 docker.sock 调用宿主机上的 Docker Daemon
    → 实现 docker build、docker run

Docker Desktop 的架构缺陷

Docker Desktop on Windows 的 Kubernetes 运行在 Linux VM 中,使用 containerd 作为容器运行时,没有运行 Docker Daemon。因此 Agent 容器里的 docker.sock 无法连接任何 Daemon,docker builddocker run 无法执行。

# 验证容器运行时
kubectl get nodes -o wide
# → CONTAINER-RUNTIME: containerd://2.2.0

尝试过的方案均未成功:

方案 结果
改用 podman ❌ Agent 里同样找不到
curl 下载静态 docker 二进制 ✅ CLI 能运行,但连不上 dockerd
容器以 root 运行 ✅ 能访问 socket,但 VM 里没有 dockerd
Docker-in-Docker 侧边容器 ❌ 需特权模式,端口映射到容器内部无法访问

最终解决方案

换了一种思路:不在 Pipeline 中构建镜像,改为本地手动构建,Pipeline 只做部署。

本机:docker build -t fastapi-demo:latest .    ← 本机 dockerd 正常构建
      git push                                 ← 触发 Pipeline

Pipeline Agent:kubectl apply -f deploy.yaml   ← 直接用现有镜像部署
                kubectl rollout status ...      ← 等待 Pod 就绪

Docker Desktop 的 K8s 集群共享本机的镜像存储,所以本机构建的镜像 K8s 可以直接拉取,无需推送仓库。

需要额外配置的权限

默认的 Agent(ServiceAccount: kubesphere-devops-worker:default)没有权限在其他命名空间部署资源,需要授权:

# 创建角色(Role):允许在 fastapi 命名空间里操作 deployments、services、pods
kubectl create role deployer -n fastapi \
  --verb=* \
  --resource=deployments,services,pods

# 绑定角色(RoleBinding):把 deployer 角色绑定到 Pipeline Agent 的 ServiceAccount
# 这样 Agent Pod 就有权限在 fastapi 命名空间里执行 kubectl apply 了
kubectl create rolebinding deployer-binding -n fastapi \
  --role=deployer \
  --serviceaccount=kubesphere-devops-worker:default

4. 最终部署效果

FastAPI 应用部署在 KubeSphere 的 fastapi 项目下(对应 K8s 命名空间),可以在控制台可视化查看工作负载和服务:

  • Deployment:fastapi(1 Pod)
  • Service:fastapi(LoadBalancer,端口 8000)
  • 访问地址:http://localhost:8000

工作负载

服务

最终 deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi                        # Deployment 名称
  namespace: fastapi                   # 部署到 fastapi 命名空间(对应 KubeSphere 项目)
spec:
  replicas: 1                          # 运行 1 个 Pod 副本
  selector:
    matchLabels:
      app: fastapi
  template:
    metadata:
      labels:
        app: fastapi
    spec:
      containers:
        - name: fastapi
          image: fastapi-demo:latest   # 使用本机构建的镜像
          imagePullPolicy: IfNotPresent # 本地有就直接用,不远程拉取
          ports:
            - containerPort: 8000      # 容器内 FastAPI 监听端口
          livenessProbe:               # 存活检查:/health 挂了就重启 Pod
            httpGet:
              path: /health
              port: 8000
          readinessProbe:              # 就绪检查:/health 通了才接收流量
            httpGet:
              path: /health
              port: 8000
---
apiVersion: v1
kind: Service
metadata:
  name: fastapi                        # Service 名称
  namespace: fastapi
spec:
  type: LoadBalancer                   # LoadBalancer 类型,Docker Desktop 会映射到 localhost
  ports:
    - port: 8000                       # 外部访问端口
      targetPort: 8000                 # 转发到容器的 8000 端口
  selector:
    app: fastapi                       # 关联到上面 Deployment 的 Pod

最终 Jenkinsfile

pipeline {
    // Agent 配置:在 K8s 上创建临时 Pod 来跑流水线
    agent {
        kubernetes {
            inheritFrom 'base'                                             // 继承 KubeSphere 的 base Agent 模板(含 docker.sock 挂载等)
            containerTemplate {
                name 'base'                                                // 容器名称
                image 'swr.cn-north-9.myhuaweicloud.com/ks/kubesphere/builder-base:v4.2.0'   // Agent 镜像(含 git、kubectl)
                ttyEnabled true
                command 'cat'                                              // 保持容器运行,等待 Jenkins 下发指令
                runAsUser '0'                                              // 以 root 运行(kubectl 需要读写 kubeconfig)
            }
        }
    }

    stages {
        // 第 1 步:从 Gitee 拉取代码
        stage('拉取代码') {
            steps { checkout scm }                                         // scm 自动关联流水线配置的 Gitee 仓库
        }

        // 第 2 步:部署到 Kubernetes
        stage('部署到 Kubernetes') {
            steps {
                script {
                    // 使用 deploy.yaml 创建/更新 Deployment 和 Service
                    sh "kubectl apply -f deploy.yaml"
                    // 等待 Pod 就绪,最多等 60 秒
                    sh "kubectl rollout status deployment -l app -n fastapi --timeout=60s"
                }
            }
        }
    }

    post {
        success { echo "✅ 部署成功!" }
        failure { echo "❌ 部署失败" }
    }
}

总结

问题 错误信息 根因 方案
Docker 构建 docker: not found / Cannot connect Docker Desktop K8s VM 无 Docker Daemon 本机构建 + kubectl 部署
K8s 部署 deployments is forbidden Agent SA 无权限 创建 Role + RoleBinding

结论: Docker Desktop 的架构限制(VM 隔离导致 docker.sock 不通)导致 Pipeline 无法直接构建部署。在真正的 Linux 服务器上部署 K8s 时,Docker 构建这一步可以直接在 Pipeline 中完成,无需本地手动构建。

posted @ 2026-08-06 15:22  PC2005-cloud  阅读(13)  评论(0)    收藏  举报