无法在单节点 kubernetes(在 centos 上)上通过“emptyDir”创建共享卷挂载,但这适用于多节点 k8s 安装

2024-01-05

TL;DR - 问题的解决方案,感谢 Paul

如果您遇到下面描述的问题,最简单的解决方法是在运行 Recipe 启动单节点 k8s 之前执行以下命令:

   sudo chcon -Rt svirt_sandbox_file_t /var/lib/kubelet

原始问题描述

我正在尝试根据此配方构建一个 k8s 环境 >https://github.com/kubernetes/kubernetes/blob/release-1.1/docs/getting-started-guides/docker.md https://github.com/kubernetes/kubernetes/blob/release-1.1/docs/getting-started-guides/docker.md为了集成测试我们的代码库,该代码库在 k8s 集群中配置容器。 为了复制/粘贴方便,我将配方中的所有命令包含在下面的“运行配方”部分中

我有一个简单的复制控制器定义(在下面的“复制控制器定义”中复制) 对于非常标准的图像(nginx)。在此 RC 定义中,我尝试使用“emptyDir”挂载共享文件夹。
为简单起见,我在代表控制器定义中只有一个容器(因此实际上没有太多共享。)

现在,当我通过命令“kubectl create -f shared.folder.json”针对我们的多节点集群配置此 RC 时
我可以登录容器“nginx”并执行以下操作:

touch /backup-folder/fooFile

我们的多节点集群的版本信息是:

Server Version: 
    version.Info{
        Major:"1", 
        Minor:"1+", 
        GitVersion:"v1.1.3-beta.0.308+71b088a96ee101-dirty", 
        GitCommit:"71b088a96ee101967fc06e1f95b1cade8f6e30f9", GitTreeState:"dirty"}

但是...当我使用“运行配方”中的步骤启动单节点 k8s 集群并配置时 使用命令“kubectl create -f shared.folder.json”针对该集群,然后生成一个 bash shell 在 nginx 容器中并尝试与上面相同的 touch 命令,但在单节点情况下我得到一个 错误:触摸:无法触摸“/backup-folder/fooo”:权限被拒绝

如果它有用,这里是我在两种情况下运行 mount -l 获得的信息:

1)单节点k8s

  root@foo-hzxd6:/# mount -l  | grep backup-folder
  /dev/mapper/cl-root on /backup-folder type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

2)多节点k8s

  root@foo-vcbc9:/# mount -l  | grep backup-folder
 /dev/vdb on /backup-folder type ext3 (rw,relatime,data=ordered)

复制控制器定义

shared.folder.json

{
  "kind": "ReplicationController",
  "apiVersion": "v1",
  "metadata":{
      "name":"foo",
      "labels":{
         "app":"foo",
         "role":"foo"
      }
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "name": "nginx"
    },
    "template": {
          "metadata": {
            "name": "nginx",
            "labels": {
              "name": "nginx"
            }
          },
          "spec": {
            "containers": [
              {
                "name": "nginx",
                "image": "nginx",
                        "imagePullPolicy": "Always",
                "ports": [
                  {
                    "containerPort": 8080
                  },
                  {
                    "containerPort": 8081
                  }
                ],
                        "command": ["sleep", "10000"],
                        "volumeMounts": [
                      {
                        "name": "shared-volume",
                        "mountPath": "/backup-folder"
                      }
                    ]
              }
            ],
            "volumes": [
              {
                "name": "shared-volume",
                "emptyDir": { }
              }
            ]
          }
    }
  }
} 

运行食谱

docker run --net=host -d gcr.io/google_containers/etcd:2.0.12 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data


docker run \
    --volume=/:/rootfs:ro \
    --volume=/sys:/sys:ro \
    --volume=/dev:/dev \
    --volume=/var/lib/docker/:/var/lib/docker:ro \
    --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \
    --volume=/var/run:/var/run:rw \
    --net=host \
    --pid=host \
    --privileged=true \
    -d \
    gcr.io/google_containers/hyperkube:v1.0.1 \
    /hyperkube kubelet --containerized --hostname-override="127.0.0.1" --address="0.0.0.0" --api-servers=http://localhost:8080 --config=/etc/kubernetes/manifests


docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube proxy --master=http://127.0.0.1:8080 --v=2

边注

(我们的 k8s 版本——我们用于多节点情况——在“库存”kubernetes 之上进行了一些更改,但我很确定这些更改都与安装文件夹无关)。

尾声 - 有关 SELinux 拒绝访问共享文件夹的更多详细信息

为了回答保罗提供更多细节的要求,我们在这里:

首先,通过“setenforce 1”将强制执行恢复为“是”

接下来,终止所有 docker 容器,然后通过上面提供的 3 步配方重新启动 k8s 单节点。

接下来,通过“kubectl create -f shared.folder.json”配置 pod

接下来,通过以下方式将 shell 放入容器中:“kubectl exec -i -t foo-podxxx -c nginx -- bash ”

在 bash shell 中:“touch /backup-folder/blah”

RESULTS:

> sudo ausearch -ts recent -m AVC
----
time->Tue Jan 19 11:33:19 2016
type=SYSCALL msg=audit(1453231999.925:865015): arch=c000003e syscall=2 success=no exit=-13 a0=7ffd65fc1e45 a1=941 a2=1b6 a3=7ffd65fc09f0 items=0 ppid=25089 pid=25127 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts4 ses=4294967295 comm="touch" exe="/bin/touch" subj=system_u:system_r:svirt_lxc_net_t:s0:c202,c694 key=(null)
type=AVC msg=audit(1453231999.925:865015): avc:  denied  { create } for  pid=25127 comm="touch" name="blah" scontext=system_u:system_r:svirt_lxc_net_t:s0:c202,c694 tcontext=system_u:object_r:docker_var_lib_t:s0 tclass=file
(backup-agent-scripts) /home/chris/dev/krylov/scripts > 

kubelet的日志:https://dl.dropboxusercontent.com/u/9940067/kubelet.log https://dl.dropboxusercontent.com/u/9940067/kubelet.log


这是完整的单节点 k8s 启动脚本,可以解决我的问题。 感谢 Paul Morie 为我提供了解决方案(脚本中神奇的第一行)。

Update以下是 Paul 发给我的关于为什么使用 chcon 的更新: 基本上它所做的就是更改保存所有 Pod 的卷目录的 SELinux 类型 卷到 svirt_sandbox_file_t,这是大多数 SELinux 策略允许容器的上下文 (通常与 svirt_lxc_net_t 一起运行)来使用。
所以,TLDR,该命令使 kube 卷目录可供 docker 容器使用(当然容器 只能访问在其 pod 中消耗然后安装到容器中的卷)。

我对此的理解是,通常Docker容器是隔离运行的,并且不能互相看到 文件系统中,chcon 允许我们以受控的方式打破这种隔离,这样 只有使用卷安装指令才允许发生这种共享。这个解释 http://www.projectatomic.io/blog/2015/06/using-volumes-with-docker-can-cause-problems-with-selinux/似乎相关。

#   magic selinux context set command is required. for details, see: http://stackoverflow.com/questions/34777111/cannot-create-a-shared-volume-mount-via-emptydir-on-single-node-kubernetes-on
#
sudo chcon -Rt svirt_sandbox_file_t /var/lib/kubelet


docker run --net=host -d gcr.io/google_containers/etcd:2.0.12 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data


docker run \
    --volume=/:/rootfs:ro \
    --volume=/sys:/sys:ro \
    --volume=/dev:/dev \
    --volume=/var/lib/docker/:/var/lib/docker:ro \
    --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \
    --volume=/var/run:/var/run:rw \
    --net=host \
    --pid=host \
    --privileged=true \
    -d \
    gcr.io/google_containers/hyperkube:v1.0.1 \
    /hyperkube kubelet --containerized --hostname-override="127.0.0.1" --address="0.0.0.0" --api-servers=http://localhost:8080 --config=/etc/kubernetes/manifests

docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube proxy --master=http://127.0.0.1:8080 --v=2

sleep 20   # give everything time to launch
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法在单节点 kubernetes(在 centos 上)上通过“emptyDir”创建共享卷挂载,但这适用于多节点 k8s 安装 的相关文章

随机推荐

  • Spring Security有Ip地址问题

    我在控制器中有一个使用以下配置的方法 RequestMapping value encore userName token method RequestMethod GET ResponseBody PreAuthorize hasIpAd
  • 使用新的 Google Jetpack 组件的最低 Android API 级别是多少

    我已经开始学习 RxJava 我知道有一些新的 Google 组件 如 LiveData 数据绑定等 我想知道使用它们的最低 Android API 级别是多少 我可以在 21 或 23 等较旧的 API 中利用它们吗 直接从文档中http
  • 无法使用 EPPlus 删除工作表

    我正在使用这段代码 ExcelPackage pck new ExcelPackage newFile var wk pck Workbook Worksheets SingleOrDefault x gt x Name Content p
  • jquery validate 添加方法来验证日期时间

    我正在使用我找到的日期时间选择器插件here http trentrichardson com examples timepicker 效果很好 现在唯一的问题是它破坏了包含的标准日期验证jquery 验证插件 http docs jque
  • 在调试器中查看 DLL 中的 pimpl

    我使用 pimpl 习惯用法来隐藏接口的实现细节 以便我可以采取某种 ABI 保护措施 我不太熟悉 MS 的来龙去脉 我的大部分开发生涯都使用 Linux 我无法从调试器检查窗口查看 pimpl 的内部 我的类型仅扩展至 impl 的原始指
  • Google App Engine ( Java ):URL 提取响应太大问题

    我正在尝试在谷歌应用程序上构建某种网络服务 现在的问题是 我需要从网站获取数据 HTML 抓取 该请求如下所示 URL url new URL p url con HttpURLConnection url openConnection I
  • 计算循环空间复杂度的基础是什么? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 想象一下 您循环 n 次 并且每次迭代都会创建一个空间 n 的字符串 其范围仅在该迭代内 因此在下一次迭代中不再可访问 我会说我使用 O
  • 在插入大量数据时关闭node.js中的mongodb连接

    我正在尝试编写一个程序来解析 iis 日志数据并将其插入到 mongodb 中 文件不是那么大 大约 600 行 试图说服我的管理 Nodejs 和 mongodb 比 net 和 sql server 更好 在nodejs中看一下下面的代
  • 在 React Bootstrap 中设置 Form.Check(复选框)控件的样式

    我是反应和引导程序的初学者 我想知道 如何设计 Form Check 复选框 的样式 以便可以用更好的样式覆盖默认的外观和感觉 比如开关或任何其他外观和感觉 这就是我尝试过的 我使用了 css 样式 但它没有按预期工作 MyForm js
  • iOS 5 JSON 解析导致 Cocoa 错误 3840

    我很难在 iOS 5 上解析下面的 JSON 字符串 States Name Arizona Cities Name Phoenix Name California Cities Name Orange County Name Rivers
  • 如何访问Android应用程序的classes.dex?

    当活动启动时 系统会加载classes dex文件并开始执行指令 我需要对当前活动正在执行的同一应用程序的classes dex 进行只读访问 在网上搜索了几个小时后 我只能推断Android安全系统不允许访问应用程序沙箱 但是 我需要对c
  • WebMethod 自动将类对象返回为 JSON

    谁能解释一下 ASP NET 如何处理从类对象到 WebMethods 中的 JSON 对象的转换 例如 您有以下 WebMethod 它返回一个Person object WebMethod public static Person Ge
  • scala:跟踪隐式选择和其他代码魔法

    当试图弄清楚库如何工作时 隐式转换会令人困惑 例如 查看像 val foo Foo 1 这样的表达式 什么将 1 转换为 Foo 是否可以指示 scala 库 或 REPL 打印出在计算表达式时正在执行的代码路径 您可以将 Xprint t
  • 正确计算发送到死信SQS队列的消息数

    我希望 grafana 报告在任何给定时间死信队列中有多少消息 由于最终在此队列中的消息的性质 将评估和解析最终在此队列中的消息 我已将 grafana 配置为读取NumberOfMessagesSent from a dead lette
  • 方法在哪里?堆栈还是堆?

    我知道方法的局部变量和参数位于堆栈中 但我无法弄清楚在 Java 中方法实际上位于哪里 如果我声明任何 Thread 对象 例如 Thread t new Thread t start 所以这意味着我已经创建了除主方法之外的单独的方法调用
  • 找不到 TypeScript 编译器

    我正在使用 Visual Studio 2012 和 TypeScript 版本 0 9 5 我也在使用 web Essentials 2 8 当我尝试保存 TypeScript 文件后 它显示 编译错误 详细信息请参见错误列表 找不到 T
  • 取代 Soft-deprecated funs() 的独特挑战

    问题 我有一个仅由数字数据类型的变量组成的 DataFrame 我有一个例程 过去在检查 DataFrame 中的每个变量是否有统计异常值并用 NA 值替换任何已识别的异常值方面做得很好 然而 这个例程利用了最近被软弃用的 funs 研究过
  • NSURLConnection 和 NSURLSession 最大的区别是什么

    NSURL会话 https developer apple com library ios documentation Cocoa Conceptual URLLoadingSystem Articles UsingNSURLSession
  • 相当于 ES6 import 中需要一个子属性

    我有一个现有的require const dialog require electron remote 我开始在 ES6 中使用 Babel 并且想要import这个代替 到目前为止我有 import electron from elect
  • 无法在单节点 kubernetes(在 centos 上)上通过“emptyDir”创建共享卷挂载,但这适用于多节点 k8s 安装

    TL DR 问题的解决方案 感谢 Paul 如果您遇到下面描述的问题 最简单的解决方法是在运行 Recipe 启动单节点 k8s 之前执行以下命令 sudo chcon Rt svirt sandbox file t var lib kub