微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无根buildkitd在容器内引发权限错误

如何解决无根buildkitd在容器内引发权限错误

我决定使用Buildkit的无根版本从kubernetes的容器内部构建并将Docker映像推送到GCR(Google容器注册表)。

我偶然发现了这个错误

/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 documentation指定的service 这些资源在Google Kubernetes引擎上托管的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 documentation相同。

然后从另一个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

解决方法

无根需要在主机上执行各种准备步骤(这需要在运行kubernetes节点的VM主机上的Kubernetes外部完成)。有关步骤的完整列表,请参见rootless documentation。请注意,这些步骤因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 allow_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,但容器运行时尚不支持。运行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-用户默认情况下不工作。不使用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”,然后重新启动。

,

您可能正在点击:https://github.com/moby/buildkit/issues/879

请使用GKE Ubuntu节点,而不要使用Google容器优化的OS节点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?