date
related_level
slug
type
relate_date
summary
status
tags
category
last_updated
Jan 5, 2026 01:47 PM
是否已更新
orginal_page
是否推荐
buildkit 简介
MediumIntroducing BuildKit

Introducing BuildKit
BuildKit is a new project under the Moby umbrella for building and packaging software using containers. It’s a new codebase meant to…
buildkit用于将源代码转换为以高效、富有表现力和可重复的方式构建工件- 前端/后端分离,支持多种前端,可输出为镜像、OCI tarball、Docker tar、本地文件系统等
- 支持无 root 构建(rootless)、隔离构建上下文
buildctl是 BuildKit 官方提供的命令行客户端,用于与buildkitd守护进程通信
buildkitd 有多种部署模式,这里选择 Deployment + Service 的 rootless 模式
kustomize 配置 buildkit-rootless deployment
mkdir -p ~/.config/k3s/workloads/deployment/buildkit-rootless/{ns,base,cred,network,tls,overlay}
cd ~/.config/k3s/workloads/deployment/buildkit-rootless
- rootless 样例
curl -o buildkit-rootless.yaml https://raw.githubusercontent.com/moby/buildkit/refs/heads/master/examples/kubernetes/deployment%2Bservice.rootless.yaml
namespace
vim ns/kustomization.yaml
vim ns/ns.yaml
base
vim base/kustomization.yaml
vim base/buildkit-deploy.yaml
cred
mkdir cred/{config,secrets}
- 如果需要自定义配置 buildkit 可以配置 buildkitd.toml
vim cred/kustomization.yaml
vim cred/secrets/.dockerconfigjson
- 用于访问私有 harbor 的凭据
- 生成 auth 字符串
echo -n "username:password" | base64
network
vim network/kustomization.yaml
vim network/buildkit-svc.yaml
vim network/buildkit-ingressroutetcp.yaml
- 外部端口使用 443
- 有自身的 TLS 所以不终止
- HostSNI 需要与签发的证书保持一致
tls
vim tls/kustomization.yaml
vim tls/buildkit-cert.yaml
overlay
mkdir -p overlay/{init,prod}
vim overlay/init/kustomization.yaml
vim overlay/prod/kustomization.yaml
vim overlay/prod/patch-docker-cred.yaml
- rootless 显示指定
DOCKER_CONFIG
vim overlay/prod/patch-nodeslector.yaml
vim overlay/prod/patch-probes.yaml
vim overlay/prod/patch-resources.yaml
kustomize 安装 buildkit-rootless deployment
vim ~/.config/k3s/buildkit-rootless.yaml
- 修改默认端口 1234 为 11234
- 未使用持久化缓存,通过 buildctl 指定
--export-cache,--import-cache来共享缓存
- 修改 TLS 部分,通过外部 step-ca 服务和 step-issuer 自动提供并续签 tls 证书
- step-issuer 原理及运作详见相关文章
制品库等使用自签 CA 时需要加载 CA 证书到内部证书库
kubectl apply -k ~/.config/k3s/workloads/deployment/buildkit-rootless/overlay/init- 初始化配置相关资源
kubectl apply -k ~/.config/k3s/workloads/deployment/buildkit-rootless/overlay/prod
查看运行情况
kubectl get deployment -n registry buildkitd -o wide
kubectl get Certificate -n registry buildkitd-registry-svc-cluster-local-cert -o yaml
kubectl get pod -n registry -l app.kubernetes.io/name=buildkitd
kubectl describe pod -n registry -l app.kubernetes.io/name=buildkitd
kubectl logs -n registry deploy/buildkitd
kubectl describe -n kube-system deploy/traefik | grep namespace- 查看 traefik 是否为 registry 命名空间提供路由
外部 openssl 测试
添加 DNS 记录到 /etc/hosts
- 获取 traefik 的 external-ip
kubectl get svc -n kube-system traefik -o wide
openssl s_client -connect buildkitd.registry.svc.cluster.local:443 -servername buildkitd.registry.svc.cluster.local | grep "subject="
由于采用了 mtls,buildctl 也需要签发客户端证书才能正常构筑
创建客户端证书 CSR
step certificate create --csr buildctl.client ~/.step/certs/buildctl.client.csr ~/.step/certs/buildctl.client.key --no-password --insecure- 不支持加密密钥所以需要添加
--no-password --insecure - subject name 无所谓,关键是由同 CA 签发的客户端证书
CSR_B64=$(cat ~/.step/certs/buildctl.client.csr | step base64)
- 不支持二进制格式密钥还需要转换 key 为 pem 格式
step crypto key format ~/.step/certs/buildctl.client.key --out ~/.step/certs/buildctl.clientkey.pem --pem
配置 CertificateRequest 资源文件
- 使用
StepClusterIssuer跨命名空间签发
创建 CertificateRequest 资源
kubectl apply -f ~/.step/csr.buildctl.client.yaml
查看 CSR 签发情况
kubectl get certificaterequests -n registry buildctl-client-csr -o yaml
- 查看签发情况
- step-issuer 会等待 CertificateReques 满足已批准条件后再进行签名
- Cert-Manager 默认不会自动批准 step-issuer 的 CertificateReques
- 但 step-issuer 会生成 rolebinding 使其符合要求
kubectl get clusterrole step-issuer-approver-rolekubectl describe clusterrole step-issuer-approver-rolekubectl get clusterrolebinding step-issuer-approver-rolebindingkubectl describe clusterrolebinding step-issuer-approver-rolebinding
获取 CSR 中的证书
kubectl get certificaterequests -n registry buildctl-client-csr -o jsonpath='{.status.certificate}'| base64 -d > ~/.step/certs/buildctl.client.crt- 有效期过了需要重新获取
重新申请脚本
step certificate inspect ~/.step/certs/buildctl.client.crt
外部 openssl 测试 mtls 连接
openssl s_client -connect buildkitd.registry.svc.cluster.local:443 \ -servername buildkitd.registry.svc.cluster.local \ -cert ~/.step/certs/buildctl.client.crt \ -key ~/.step/certs/buildctl.client.key \ -CAfile ~/.step/certs/root_ca.crt- 假设已经设置了 DNS 记录
- 需要输入之前填写的密码用于解密私钥
- buildctl 客户端使用下发的证书
buildctl \ --addr tcp://buildkitd.registry.svc.cluster.local:443 \ --tlscacert ~/.step/certs/root_ca.crt \ --tlscert ~/.step/certs/buildctl.client.crt \ --tlskey ~/.step/certs/buildctl.clientkey.pem \ build ...- 需要输入之前填写的密码用于解密私钥
- 这部分可以写成 alias 简化 buildctl 调用
buildctl 构筑测试项目 hellobuild
mkdir -p ~/project/hellobuild && cd ~/project/hellobuild
vim Dockerfile
vim hello.sh
- 缓存共享使用了 truesnas 的 garage s3 存储,配置参考 truenas 存储配置
创建 s3 凭据 secret
echo -n "AWS Access Key: " && read -s AWS_ACCESS_KEY_ID; echo
echo -n "AWS Secret Key: " && read -s AWS_SECRET_ACCESS_KEY; echo
kubectl create secret generic s3-credentials \ --namespace=registry \ --from-literal=access_key="$AWS_ACCESS_KEY_ID" \ --from-literal=secret_key="$AWS_SECRET_ACCESS_KEY"
kubectl get secret -n registry s3-credentials -o yaml
unset AWS_ACCESS_KEY_ID && unset AWS_SECRET_ACCESS_KEY
export AWS_ACCESS_KEY_ID=$(kubectl get secret s3-credentials -n registry -o jsonpath='{.data.access_key}' | base64 --decode)
export AWS_SECRET_ACCESS_KEY=$(kubectl get secret s3-credentials -n registry -o jsonpath='{.data.secret_key}' | base64 --decode)
- 使用 minio client 测试 s3 连接
mc alias set buildkit http://<truenas_ip>:30188 $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEYmc ls buildkit
构筑本地 oci 镜像
buildctl build --frontend dockerfile.v0 \ --local context=. \ --local dockerfile=. \ --opt platform=linux/amd64 \ --export-cache type=s3,endpoint_url=http://<truenas_ip>:30188,bucket=buildkit,region=garage,access_key_id=$AWS_ACCESS_KEY_ID,secret_access_key=$AWS_SECRET_ACCESS_KEY,mode=max,,name=hellobuild \ --import-cache type=s3,endpoint_url=http://<truenas_ip>:30188,bucket=buildkit,region=garage,access_key_id=$AWS_ACCESS_KEY_ID,secret_access_key=$AWS_SECRET_ACCESS_KEY,name=hellobuild \ --output type=oci,name=hellobuild:v1.0.0,dest=./hellobuild_v1.0.0.oci.tar- 假设已经设置了 alias,不再添加对应 addr 和 tls 选项
- 客户端通过 access_key_id, secret_access_key, session_token 来静态传递 s3 凭据给 buildkitd
- 缓存 name 默认为 buildkit
- 测试镜像
nerdctl --namespace k8s.io run --rm --net=none hellobuild:v1.0.0 hello
导入本地镜像并在 k8s 集群上进行部署
- 假设 k8s 运行时为 containerd 而非 docker
nerdctl --namespace k8s.io load --all-platforms -i ./hellobuild_v1.0.0.oci.tar- OCI tar 直接使用
load -i而非image import
nerdctl --namespace k8s.io image ls | grep hellobuild
nerdctl --namespace k8s.io image inspect hellobuild:v1.0.0
nerdctl 测试镜像
nerdctl --namespace k8s.io run --rm --net=none -it hellobuild:v1.0.0 /usr/local/bin/hello
如果存在问题可以通过 nerdctl 导出容器文件系统,查看对应路径是否存在
nerdctl --namespace k8s.io create --net=none --name temphello hellobuild:v1.0.0
nerdctl --namespace k8s.io export temphello -o temp.tar
nerdctl --namespace k8s.io rm temphello
mkdir -p ./tmp-rootfs && tar -xf temp.tar -C ./tmp-rootfs
vim ./job.hellobuild.yaml
- 因为未上传到镜像仓库,需要指定节点为当前节点
kubectl apply -f ./job.hellobuild.yaml
kubectl describe job hellobuild
kubectl logs job/hellobuild- 应该看到 Hello from BuildKit!
清理测试项目
kubectl delete -f ./job.hellobuild.yaml
nerdctl --namespace k8s.io image rm hellobuild:v1.0.0
- buildkit 不会热重载证书,需要通过 rollout restart 来更新证书
- 可以通过
stakater/reloader来检测证书更新并自动重载
- Author:白鸟3
- URL:https://blog.kun2peng.top/operation/k8s_buildkit
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
