我决定使用Buildkit的无根版本来构建Docker映像,并将其从Kubernetes的容器中推送到GCR(Google Container Registry(。
我偶然发现了这个错误:
/moby.buildkit.v1.Control/Solve returned error: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to read dockerfile: failed to mount /home/user/.local/tmp/buildkit-mount859701112: [{Type:bind Source:/home/user/.local/share/buildkit/runc-native/snapshots/snapshots/2 Options:[rbind ro]}]: operation not permitted
我将buildkitd
作为链接到构建工具包文档中指定的service
的deployment
运行这些资源在Google Kubernetes引擎上托管的Kubernete集群中运行。
我正在使用以下YAML进行部署和服务
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: buildkitd
name: buildkitd
spec:
replicas: 1
selector:
matchLabels:
app: buildkitd
template:
metadata:
labels:
app: buildkitd
annotations:
container.apparmor.security.beta.kubernetes.io/buildkitd: unconfined
container.seccomp.security.alpha.kubernetes.io/buildkitd: unconfined
spec:
containers:
- name: buildkitd
image: moby/buildkit:master-rootless
args:
- --addr
- unix:///run/user/1000/buildkit/buildkitd.sock
- --addr
- tcp://0.0.0.0:1234
- --oci-worker-no-process-sandbox
readinessProbe:
exec:
command:
- buildctl
- debug
- workers
initialDelaySeconds: 5
periodSeconds: 30
livenessProbe:
exec:
command:
- buildctl
- debug
- workers
initialDelaySeconds: 5
periodSeconds: 30
securityContext:
runAsUser: 1000
runAsGroup: 1000
ports:
- containerPort: 1234
---
apiVersion: v1
kind: Service
metadata:
labels:
app: buildkitd
name: buildkitd
spec:
ports:
- port: 1234
protocol: TCP
selector:
app: buildkitd
它与没有TLS证书设置的buildkit文档相同。
在另一个Pod中,我使用以下命令联系Buildkit守护程序:
./bin/buildctl
--addr tcp://buildkitd:1234
build
--frontend=dockerfile.v0
--local context=.
--local dockerfile=.
--output type=image,name=eu.gcr.io/$PROJECT_ID/test-image,push=true
buildkitd
容器成功接收到请求,但抛出上述错误。
buildctl
命令的输出如下:
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.1s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 120B done
#2 DONE 0.1s
error: failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to read dockerfile: failed to mount /home/user/.local/tmp/buildkit-mount859701112: [{Type:bind Source:/home/user/.local/share/buildkit/runc-native/snapshots/snapshots/2 Options:[rbind ro]}]: operation not permitted
这是来自守护进程的错误。
让我印象深刻的是,我能够使用完全相同的YAML文件将buildkitd
容器化到minikube
集群中:
NAME READY STATUS RESTARTS AGE
pod/buildkitd-5b46d94f5d-xvnbv 1/1 Running 0 36m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/buildkitd ClusterIP 10.100.72.194 <none> 1234/TCP 36m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 36m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/buildkitd 1/1 1 1 36m
NAME DESIRED CURRENT READY AGE
replicaset.apps/buildkitd-5b46d94f5d 1 1 1 36m
我在minikube
内部部署服务和部署,并使用以下命令转发服务端口,以便能够访问minikube
外部的部署。
kubectl port-forward service/buildkitd 2000:1234
有了这个设置,我就可以毫无问题地执行buildctl
命令(图像构建和推送到GCR(。
我想知道为什么它在minikube
上有效,而在Google Kubernetes引擎上无效。
这是容器启动日志,如果这对有任何帮助的话
auto snapshotter: using native
NoProcessSandbox is enabled. Note that NoProcessSandbox allows build containers to kill (and potentially ptrace) an arbitrary process in the BuildKit host namespace. NoProcessSandbox should be enabled only when the BuildKit is running in a container as an unprivileged user.
found worker "wdukby0uwmjyvf2ngj4e71s4m", labels=map[org.mobyproject.buildkit.worker.executor:oci org.mobyproject.buildkit.worker.hostname:buildkitd-5b46d94f5d-xvnbv org.mobyproject.buildkit.worker.snapshotter:native], platforms=[linux/amd64 linux/386]"
rootless mode is not supported for containerd workers. disabling containerd worker.
found 1 workers, default="wdukby0uwmjyvf2ngj4e71s4m"
currently, only the default worker can be used.
TLS is not enabled for tcp://0.0.0.0:1234. enabling mutual TLS authentication is highly recommended
running server on /run/user/1000/buildkit/buildkitd.sock
running server on [::]:1234
Rootless需要在主机上执行各种准备步骤(这需要在运行Kubernetes节点的VM主机上的Kubernetes之外执行(。有关步骤的完整列表,请参阅无根文档。请注意,这些步骤因Linux发行版而异,因为不同的发行版已经执行了部分或全部这些先决条件步骤。
Ubuntu
无需任何准备。
overlay2存储驱动程序默认启用(Ubuntu特定的内核补丁(。
已知可在Ubuntu 16.04、18.04和20.04上运行。
Debian GNU/Linux
将kernel.unprivileged_userns_clone=1添加到/etc/sysctl.conf(或/etc/sysctl.d(并运行sudo sysctl--system。
要使用overlay2存储驱动程序(推荐(,请运行sudo modprobe overlay permit_mounts_in_userns=1(Debian特定内核Debian 10中介绍的补丁(。将配置添加到/etc/modprobe.d用于持久性。
已知用于Debian 9和10。overlay2仅在Debian 10之后才被支持,并且需要如上所述的modprobe配置。
Arch Linux
- 将kernel.unprivileged_userns_clone=1添加到/etc/sysctl.conf(或/etc/sysctl.d(并运行sudo sysctl--system
openSUSE
sudo modprobe ip_tables iptable_mangle iptable_nat iptable_filter是必需的。这可能在其他发行版上也是必需的,具体取决于关于配置。
已知在openSUSE 15上工作。
Fedora 31和更高版本的
Fedora 31默认使用cgroup v2,但containerd运行时还不支持它。运行sudo gruby--update kernel=ALL--args=";systemd.unified_group_hierarchy=0";使用cgroupv1。
您可能需要sudo dnf install-y iptables。
CentOS 8
- 您可能需要sudo dnf install-y iptables
CentOS 7
将user.max_user_namespaces=28633添加到/etc/sysctl.conf(或/etc/sysctl.d(并运行sudo sysctl--system。
systemctl——默认情况下,用户不工作。不使用systemd:dockerd-rootless.sh--实验--存储驱动程序vfs 直接运行守护程序
已知可在CentOS 7.7上工作。旧版本需要额外的配置步骤。
CentOS 7.6及更早版本需要安装COPR包vbatts/shadow-utils-newxidmap。
CentOS 7.5及更早版本要求运行sudo gruby--update kernel=ALL--args="user_namespace.enable=1";然后重新启动。
您可能遇到了以下问题:https://github.com/moby/buildkit/issues/879
请使用GKE Ubuntu节点,而不是谷歌容器优化操作系统节点。