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 build 和 docker 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 中完成,无需本地手动构建。

浙公网安备 33010602011771号