1

我决定使用无根版本的 Buildkit 从 Kubernetes 的容器中构建 Docker 映像并将其推送到 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作为deployment链接到buildkit 文档service指定的链接运行 这些资源在托管在 Google Kubernetes Engine 上的 Kubernetes 集群中运行。

我正在使用以下 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 Daemon:

./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)。

我想了解为什么它可以在 Google Kubernetes Engine 上运行minikube而不是在 Google Kubernetes Engine 上运行。

如果有任何帮助,这是容器启动日志

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
4

2 回答 2

2

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 上工作。仅从 Debian 10 开始支持 overlay2,并且需要上述 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 grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0" 以使用 cgroup v1。

  • 您可能需要 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 --user 默认不工作。不使用 systemd 直接运行守护进程:dockerd-rootless.sh --experimental --storage-driver vfs

  • 已知在 CentOS 7.7 上工作。旧版本需要额外的配置步骤。

  • CentOS 7.6 和更早的版本需要安装 COPR 包 vbatts/shadow-utils-newxidmap。

  • CentOS 7.5 和更早的版本需要运行 sudo grubby --update-kernel=ALL --args="user_namespace.enable=1" 并在此之后重新启动。

于 2020-10-20T15:57:17.587 回答
1

您可能会遇到这个问题:https ://github.com/moby/buildkit/issues/879

请使用 GKE Ubuntu 节点而不是 Google Container-Optimized OS 节点。

于 2020-10-29T05:25:31.007 回答