使用Docker-EE上的Kubernetes无法从pod中进行Pod标记

Mar*_*ert 6 kubernetes docker-ee

我们在Kubernetes上使用Apache-Kafka部署,该部署基于在创建pod之后标记pod的功能(请参阅https://github.com/Yolean/kubernetes-kafka).代理pod的init容器利用此功能在其自身上设置标签,并将其自己的数字索引(例如"0","1"等)作为值.标签在服务描述符中用于精确选择一个pod.

这种方法适用于我们的DIND-Kubernetes环境.但是,当尝试将部署移植到Docker-EE Kubernetes环境时,我们遇到了麻烦,因为该命令会kubectl label pod产生运行时错误,这完全是误导性的(另请参阅https://github.com/fabric8io/kubernetes-client/issues/ 853).

为了在最小设置中验证运行时错误,我们创建了以下部署脚本.

第一步:使用Docker-EE-Host成功标记pod

# create a simple pod as a test target for labeling
> kubectl run -ti -n default --image alpine sh

# get the pod name for all further steps
> kubectl -n default get pods

NAME                                READY     STATUS    RESTARTS   AGE
nfs-provisioner-7d49cdcb4f-8qx95    1/1       Running   1          7d
nginx-deployment-76dcc8c697-ng4kb   1/1       Running   1          7d
nginx-deployment-76dcc8c697-vs24j   1/1       Running   0          20d
sh-777f6db646-hrm65                 1/1       Running   0          3m      <--- This is the test pod
test-76bbdb4654-9wd9t               1/1       Running   2          6d
test4-76dbf847d5-9qck2              1/1       Running   0          5d

# get client and server versions
> kubectl version
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.5", 
GitCommit:"32ac1c9073b132b8ba18aa830f46b77dcceb0723", GitTreeState:"clean", 
BuildDate:"2018-06-21T11:46:00Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"8+", GitVersion:"v1.8.11- docker-8d637ae", GitCommit:"8d637aedf46b9c21dde723e29c645b9f27106fa5", 
GitTreeState:"clean", BuildDate:"2018-04-26T16:51:21Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

# set label 
kubectl -n default label pod sh-777f6db646-hrm65 "mylabel=hallo"
pod "sh-777f6db646-hrm65" labeled                   <---- successful execution
Run Code Online (Sandbox Code Playgroud)

一切都按预期工作正常.

第二步:从pod中重现运行时错误

创建包含kubectl1.10.5的Docker镜像

FROM debian:stretch- 
slim@sha256:ea42520331a55094b90f6f6663211d4f5a62c5781673935fe17a4dfced777029

ENV KUBERNETES_VERSION=1.10.5

RUN set -ex; \
  export DEBIAN_FRONTEND=noninteractive; \
  runDeps='curl ca-certificates procps netcat'; \
  buildDeps=''; \
  apt-get update && apt-get install -y $runDeps $buildDeps --no-install- recommends; \
  rm -rf /var/lib/apt/lists/*; \
  \
  curl -sLS -o k.tar.gz -k https://dl.k8s.io/v${KUBERNETES_VERSION}/kubernetes-client-linux-amd64.tar.gz; \
  tar -xvzf k.tar.gz -C /usr/local/bin/ --strip-components=3 kubernetes/client/bin/kubectl; \
  rm k.tar.gz; \
  \
  apt-get purge -y --auto-remove $buildDeps; \
  rm /var/log/dpkg.log /var/log/apt/*.log 
Run Code Online (Sandbox Code Playgroud)

此映像部署10.100.180.74:5000/test/kubectl-client-1.10.5在站点本地注册表中,将在下面引用.

使用上面的容器创建一个pod

apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
  name: pod-labeler
  namespace: default
spec:
  selector:
    matchLabels:
      app: pod-labeler
  replicas: 1
  serviceName: pod-labeler
  updateStrategy:
    type: OnDelete
  template:
    metadata:
      labels:
        app: pod-labeler
      annotations:
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: check-version
        image: 10.100.180.74:5000/test/kubectl-client-1.10.5
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: POD_NAME
          value: sh-777f6db646-hrm65
        command: ["/usr/local/bin/kubectl", "version" ]
      - name: label-pod
        image: 10.100.180.74:5000/test/kubectl-client-1.10.5
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: POD_NAME
          value: sh-777f6db646-hrm65
        command: ["/bin/bash",  "-c", "/usr/local/bin/kubectl -n default label pod $POD_NAME 'mylabel2=hallo'" ]
Run Code Online (Sandbox Code Playgroud)

记录输出

我们得到以下日志记录输出

# Log of the container "check-version"
2018-07-18T11:11:10.791011157Z Client Version: version.Info{Major:"1", 
Minor:"10", GitVersion:"v1.10.5", 
GitCommit:"32ac1c9073b132b8ba18aa830f46b77dcceb0723", GitTreeState:"clean", 
BuildDate:"2018-\
06-21T11:46:00Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
2018-07-18T11:11:10.791058997Z Server Version: version.Info{Major:"1", 
Minor:"8+", GitVersion:"v1.8.11-docker-8d637ae", 
GitCommit:"8d637aedf46b9c21dde723e29c645b9f27106fa5", GitTreeState:"clean", 
BuildDate:"2018-04-26T16:51:21Z", GoVersion:"go1.8.3", Compiler:"gc", 
Platform:"linux/amd64"}
Run Code Online (Sandbox Code Playgroud)

和运行时错误

2018-07-18T11:24:15.448695813Z The Pod "sh-777f6db646-hrm65" is invalid: 
spec.tolerations: Forbidden: existing toleration can not be modified except its tolerationSeconds
Run Code Online (Sandbox Code Playgroud)

笔记

  • 这不是授权问题,因为我们已经为默认命名空间的默认用户提供了完全管理权限.如果我们不这样做,我们会收到一条错误消息,指出缺少权限.
  • 客户端和服务器版本"在外部"(例如在docker主机上)和"inside"(例如pod)都是相同的,直到GIT提交标签
  • 我们使用的是通用控制平面3.0.2版

有任何想法吗?

Mar*_*ert 2

其中一条评论指出,该问题可能是由于缺少权限引起的,尽管错误消息并未暗示这一点。我们正式向 Docker 提交了一份票证,实际上得到了这样的结果:为了能够在 pod 内设置/修改标签,必须为命名空间的默认用户授予 swarm 资源上的“调度程序”角色(稍后会介绍)如\GUI 中所示)。授予此权限可以解决问题。请参阅下面在 Docker-EE-GUI 中添加的授权。

Docker-EE-GUI 的新资助

从我的角度来看,这远非显而易见。Docker 支持代表主动提出调查这是否确实是预期行为或错误的结果。一旦我们了解了这个问题的更多信息,我就会将其纳入我们的答案中。

至于使用更多调试输出:不幸的是,添加--v=9到 的调用中kubectl不会返回任何有用的信息。这里要显示的输出太多,但两种情况下的总体日志记录非常相似:它由大量 GET API 请求组成,这些请求全部成功,然后是最终的 PATCH API 请求,该请求在一种情况下成功,但在另一种情况下失败,如下所示如上所述。