Tekton不能用本地docker build + kubectl apply,因其Task运行在无Docker daemon的Pod中,dind方案存在安全、缓存和资源问题;应改用ko/kaniko等无守护进程工具实现集群内构建、推送与部署。

Tekton 能直接驱动 Go 应用的 Kubernetes 部署,但必须绕过“本地构建 → 手动推镜像 → kubectl apply”这种反模式;核心是让 Tekton 在集群内完成构建、镜像推送、资源配置生成与部署全流程。
为什么不能用本地 docker build + kubectl apply 做 CI/CD
这种做法在 Tekton 环境下会失败或不可靠,因为 Tekton Task 运行在 Pod 中,默认没有 Docker daemon,docker build 会报 Cannot connect to the Docker daemon;即使启用 docker-in-docker(dind),也会带来安全风险、镜像层缓存失效和资源开销问题。
正确路径是:用 ko 或 buildah / kaniko 这类无守护进程构建工具,在 Tekton Task 中完成镜像构建并推送到仓库。
-
ko最适合 Go 应用:自动识别main包、静态编译、默认使用 distroless 基础镜像、无需写 Dockerfile - 若需自定义构建逻辑(如多阶段、非标准依赖),用
kaniko+ 多阶段Dockerfile,配合gcr.io/kaniko-project/executor镜像 - 所有镜像推送地址必须可写(如
registry.example.com/myapp),且 Tekton PipelineRun 的 ServiceAccount 需绑定含imagePullSecrets的 Secret
如何用 ko 实现零配置 Go 构建与部署
ko 是专为 Go 和 Kubernetes 设计的构建工具,它把 Go 二进制直接打包成 OCI 镜像,并自动生成 Deployment YAML。Tekton 中只需两步:
针对 Kubernetes 仪表板和 Web UI 的浏览器自动化。适用于与 Kubernetes Dashboard、Grafana、ArgoCD UI 或其他 Web 界面交互。需要设置 MCP_BROWSER_ENABLED=true。
- 在 Task 中运行
ko apply -f config/deployment.yaml --base-import-paths ./...,其中deployment.yaml里用image: ko://github.com/user/repo/cmd/server占位 -
ko会自动编译该包、构建镜像、推送、再把真实镜像地址注入 YAML 并kubectl apply - 注意:Task 容器需安装
ko(推荐用ghcr.io/google/ko:v0.19.0镜像)和kubectl,且GOOS=linux GOARCH=amd64必须显式设置(避免 macOS 构建失败)
示例 Task 中关键片段:
steps:
- name: build-and-deploy
image: ghcr.io/google/ko:v0.19.0
env:
- name: KO_DOCKER_REPO
value: "us-east1-docker.pkg.dev/myproject/myrepo"
command: ["/ko"]
args:
- apply
- "-f"
- "config/deployment.yaml"ServiceAccount 权限和镜像仓库认证怎么配才不翻车
Tekton PipelineRun 默认用 default ServiceAccount,它没有权限创建 Deployment 或拉取私有镜像——这是最常卡住的点。
- 给 ServiceAccount 绑定
editClusterRole(开发环境)或最小化 Role(生产环境,至少含deployments/*,services/*,configmaps/*) - 镜像仓库认证不能靠
~/.docker/config.json:Tekton 不读宿主机文件。必须创建 Secret 类型为kubernetes.io/dockerconfigjson,然后在 PipelineRun 的serviceAccountName对应 SA 中引用它 - 若用 Google Artifact Registry,Secret 的
.dockerconfigjson字段需由gcloud auth configure-docker生成后 base64 编码,不是简单填用户名密码
如何让 Tekton 自动触发 Go 应用的滚动更新
Tekton 本身不管理应用状态,滚动更新靠 Kubernetes 原生机制。关键是让每次 PipelineRun 生成的镜像 Tag 可区分且稳定:
- 别用
latest:Tag 必须唯一,推荐$(context.pipelineRun.uid)或$(params.commit_id)(通过gitTask 提取) - Deployment 的
image字段必须用变量替换(如image: $(params.image_repo)/server:$(params.image_tag)),再由ko resolve或sed注入 - Kubernetes 会自动检测镜像变更并触发滚动更新,前提是 Deployment 的
spec.strategy.type == RollingUpdate(默认就是) - 验证是否生效:检查
kubectl rollout status deploy/myapp是否返回successfully rolled out
真正容易被忽略的是健康探针配置——如果 Go 应用没实现 /livez 和 /readyz,Kubernetes 会在新 Pod 就绪前就终止旧 Pod,造成请求中断。这和 Tekton 无关,但部署后立刻出问题,往往误以为是流水线故障。

















