【问题标题】:How to run kubectl commands inside a container?如何在容器内运行 kubectl 命令?
【发布时间】:2017-07-27 07:11:15
【问题描述】:

在 pod 内的容器中,如何使用 kubectl 运行命令?例如,如果我需要在容器内做这样的事情:

kubectl 获取 pod

我试过这个:在我的 dockerfile 中,我有这些命令:

RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
RUN chmod +x ./kubectl
RUN sudo mv ./kubectl /usr/local/bin/kubectl

编辑:我正在尝试 OSX 文件,我已将其更正为 linux 二进制文件。 (由@svenwltr 更正

在创建 docker 文件时,这是成功的,但是当我在容器中运行 kubectl get pods 时,

kubectl get pods

我收到此错误:

与服务器的连接:被拒绝 - 您是否指定了正确的主机或端口?

当我在本地部署时,如果我的 docker-machine 没有运行,我会遇到此错误,但在容器中如何运行 docker-machine?

在本地,我通过运行以下命令来解决此错误: (dev 是 docker-machine 的名称)

docker-machine env dev
eval $(docker-machine env dev)

谁能告诉我我需要做什么?

【问题讨论】:

  • 我很困惑。您是在 Kubernetes 还是在 Docker 机器中运行该容器?
  • @svenwltr - 我在 minikube 上本地运行 kubernetes,它建议在 kubernetes VM 中使用 docker 守护进程。

标签: docker kubernetes dockerfile


【解决方案1】:

我会使用kubernetes api,你只需要安装curl,而不是kubectl,其余的就安静了。

curl http://localhost:8080/api/v1/namespaces/default/pods

我在我的一个 apiserver 上运行上面的命令。将 localhost 更改为 apiserver ip 地址/dns 名称

根据您的配置,您可能需要使用 ssl 或提供客户端证书。

为了找到 api 端点,您可以使用 --v=8kubectl

示例:

kubectl get pods --v=8

资源:

Kubernetes API documentation

RBAC 更新:

我假设您已经配置了 rbac,为您的 pod 创建了一个服务帐户并使用它运行。此服务帐户应具有所需命名空间中 pod 的列表权限。为此,您需要为该服务帐号创建角色和角色绑定。

集群中的每个容器都填充了一个令牌,该令牌可用于对 API 服务器进行身份验证。为了验证,在容器内运行:

cat /var/run/secrets/kubernetes.io/serviceaccount/token

要向 apiserver 发出请求,在容器内运行:

curl -ik \
     -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
     https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/pods

【讨论】:

  • 我尝试了您建议的答案,但它给了我另一个错误 - curl: (7) 无法连接到 192.168.99.100 端口 8080:连接被拒绝。虽然我能够做一个 kubectl get pods。另外,当我运行命令 netstat -atn 来检查打开的端口时,特定 ip 上没有显示打开的端口。
  • @Tarun 192.168.99.100 是api服务器IP地址吗?顺便说一句,我刚刚在我的设置上对其进行了测试,它工作正常。
  • 是的,我在 minikube 上运行 kubernetes。它的minikube ip。我犯了一个错误,我正在尝试端口 8080。但是,当我尝试 kubectl 配置视图时,它显示端口 8443。此外,当我检查 api 端点时,它显示我的“https”。你也一样吗?当我尝试使用 https 时,我收到一个 ssl 错误(curl:(60)SSL 证书问题:证书链无效)。我正在尝试解决它,将在我解决错误后立即更新。
  • @Tarun 我在生产环境中,用你的 curl 试试--insecure,你有你的ca.pemclient.pemclient-key.pem吗?如果是这样,您可以尝试:curl https://ip:8443/api/v1/namespaces/default/pods --cacert ca.pem --insecure --key client-key.pem --cert client.pem
  • 我试过 --insecure 但它不能解决问题,是的,我没有 .pem 文件,将尝试添加它们并尽快更新。再次,非常感谢:)
【解决方案2】:

在这里聚会有点晚了,但这是我的两分钱:

我发现在容器中使用kubectl 比调用集群的 api 容易得多

(为什么?自动认证!)

假设您正在部署一个需要使用 kubectl 的 Node.js 项目。

  1. 在容器内下载并构建kubectl
  2. 构建您的应用程序,将kubectl 复制到您的容器中
  3. 瞧!kubectl 提供了一个丰富的 cli 来管理您的 kubernetes 集群

Helpful documentation

--- 编辑 ---

在我的集群 Pod 中使用 kubectl 之后,我发现了一种更有效的方法来验证 Pod 以便能够进行 k8s API 调用。此方法提供更严格的身份验证。

  1. 为您的 pod 创建一个 ServiceAccount,并将您的 pod 配置为使用该帐户。 k8s Service Account docs
  2. 配置RoleBindingClusterRoleBinding 以允许服务具有与k8s API 通信的权限。 k8s Role Binding docs
  3. 直接调用 API,或使用k8s-client 为您管理 API 调用。我强烈建议使用客户端,它具有自动配置 pod 的功能,消除了正常请求所需的身份验证令牌步骤。

完成后,您将拥有以下内容: ServiceAccountClusterRoleBindingDeployment(你的豆荚)

如果您需要更清晰的方向,请随时发表评论,我会尽力提供帮助:)

综合例子

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: k8s-101
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: k8s-101
    spec:
      serviceAccountName: k8s-101-role
      containers:
      - name: k8s-101
        imagePullPolicy: Always
        image: salathielgenese/k8s-101
        ports:
        - name: app
          containerPort: 3000
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: k8s-101-role
subjects:
- kind: ServiceAccount
  name: k8s-101-role
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: k8s-101-role

salathielgenese/k8s-101 图像包含 kubectl。所以一个人可以登录到一个 pod 容器并执行kubectl,就好像他在 k8s 主机上运行它一样:kubectl exec -it pod-container-id -- kubectl get pods

【讨论】:

  • 你能详细描述一下如何连接api的部分吗?
  • @Berndinox 确定!所有kubectl 命令都可以通过命令行输入。使用 Node 的 fork 子进程,您可以执行这些命令。确保在执行其他命令之前初始化kubectl proxy。使用kubectl构建docker镜像:pastebin.com/6a8kp6aR
  • 作为一个 k8s 初学者,上面的这些指令听起来很神奇,但我找到了一些帮助来将其转换为一些配置 - kubernetes.slack.com/archives/C09NXKJKA/…。因此,我将进行编辑以提供示例。
  • @mster 你能帮我处理一下 Dockerfile 吗?我想在出现错误的容器中安装 kubectl:failed to solve with frontend dockerfile.v0: failed to create LLB definition: circular dependency detected on stage: kubectl。这是我的 Dockerfile:pastebin.com/Lqb1py64
  • 如果不需要,永远不要给集群管理员。除此之外,该解决方案似乎是可行的。
【解决方案3】:

第一个问题

/usr/local/bin/kubectl: cannot execute binary file

您似乎下载了kubectl 的 OSX 二进制文件。在 Docker 中运行时,您可能需要 Linux 的:

https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl

第二个问题

如果您在正确配置的 Kubernetes 集群中运行 kubectl,它应该能够连接到 apiserver。

kubectl基本上就是用这段代码来查找apiserver并进行认证:github.com/kubernetes/client-go/rest.InClusterConfig

这意味着:

  • apiserver的主机和端口存放在环境变量KUBERNETES_SERVICE_HOSTKUBERNETES_SERVICE_PORT中。
  • 访问令牌挂载到var/run/secrets/kubernetes.io/serviceaccount/token
  • 服务器证书挂载到/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

这是kubectl连接到apiserver需要知道的所有数据。

为什么这可能行不通的一些想法:

  • 容器不在 Kubernetes 中运行。
    • 使用同一个Docker主机是不够的;容器需要作为 pod 定义的一部分运行。
  • 使用authorization plugin(不是默认值)限制访问。
  • 服务帐户凭据被pod definition (spec.serviceAccountName) 覆盖。

【讨论】:

  • 是的,感谢您指出。我为 linux 做了必要的更改。但是,我仍然收到另一个错误,将更新问题。 :)
  • 我更新了答案。不确定我是否正确理解了这个问题。
  • 这个没试过,尽快更新。但是,感谢您的回复,这无疑让我对这个问题有了更好的理解:)
  • 有趣的是,我发现 linux kubectl(根据你提到的链接)可以在 big sur 上运行...
【解决方案4】:

我刚刚再次面对这个概念。这是绝对可能的,但出于安全原因,我们不要在 ClusterRole 容器中授予“cluster-admin 权限。

假设我们想在集群中部署一个 pod,它只能在集群中的特定命名空间中访问 viewcreate pod。在这种情况下,ServiceAccount 可能如下所示:

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: spinupcontainers
subjects:
- kind: ServiceAccount
  name: spinupcontainers
  namespace: <YOUR_NAMESPACE>
roleRef:
  kind: Role
  name: spinupcontainers
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: spinupcontainers
  # "namespace" omitted if was ClusterRoles because are not namespaced
  namespace: <YOUR_NAMESPACE>
  labels:
    k8s-app: <YOUR_APP_LABEL>
rules:
#
# Give here only the privileges you need
#
- apiGroups: [""]
  resources:
  - pods
  verbs:
  - create
  - update
  - patch
  - delete
  - get
  - watch
  - list
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: spinupcontainers
  namespace: <MY_NAMESPACE>
  labels:
    k8s-app: <MY_APP_LABEL>
---

如果您在容器规范中使用 serviceAccountName: spinupcontainers 在部署中应用服务帐户,则无需挂载任何额外的卷机密或附加手动认证。 kubectl 客户端将从/var/run/secrets/kubernetes.io/serviceaccount 获取所需的令牌。然后你可以测试是否正在使用类似的东西:

$ kubectl exec -it <your-container-with-the-attached-privs> -- /kubectl get pods -n <YOUR_NAMESPACE>
NAME.        READY   STATUS    RESTARTS   AGE
pod1-0       1/1     Running   0          6d17h
pod2-0       1/1     Running   0          6d16h
pod3-0       1/1     Running   0          6d17h
pod3-2       1/1     Running   0          67s

或权限被拒绝:

$ kubectl exec -it <your-container-with-the-attached-privs> -- /kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:spinupcontainers" cannot list resource "pods" in API group "" in the namespace "kube-system"
command terminated with exit code 1

测试日期:

$ kubectl exec -it <your-container-with-the-attached-privs> -- /kubectl versionClient Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:20:10Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:12:17Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}

【讨论】:

    【解决方案5】:

    综合以上。这对我有用。 从容器中检索所有 pod。

    curl --insecure -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"  https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/default/pods
    

    请参阅https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#-strong-read-operations-pod-v1-core-strong- 了解 REST API。

    【讨论】:

      【解决方案6】:

      在容器内运行 kubectl 命令。 需要3个步骤

      1. 安装 kubectl
      RUN printf '[kubernetes] \nname = Kubernetes\nbaseurl = https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64\nenabled = 1\ngpgcheck = 1\nrepo_gpgcheck=1\ngpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg' \
        | tee /etc/yum.repos.d/kubernetes.repo \
        && cat  /etc/yum.repos.d/kubernetes.repo \
        && yum install -y kubectl
      
      
      1. 为服务帐户创建 ClusterAdminRole 绑定角色
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: mysa-admin-sa
        namespace: mysa
      ---
      apiVersion: rbac.authorization.k8s.io/v1beta1
      kind: ClusterRoleBinding
      metadata:
        name: mysa-admin-sa
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: cluster-admin
      subjects:
        - kind: ServiceAccount
          name: mysa-admin-sa
          namespace: mysa
      

      3- cronjob 配置示例

      apiVersion: batch/v1beta1
      kind: CronJob
      metadata:
        name: scaleup
        namespace: myapp
      spec:
        schedule: "00 5 * * 1-5"
        jobTemplate:
          spec:
            template:
              spec:
                serviceAccountName: mysa-admin-sa
                restartPolicy: OnFailure
                containers:
                - name: scale-up
                  image: myimage:test
                  imagePullPolicy: Always
                  command: ["/bin/sh"]
                  args: ["-c", "mykubcmd_script >>/mylog.log"]
      

      【讨论】:

        【解决方案7】:
        1. 要在具有单个容器的 pod 内运行命令,请使用以下命令

        kubectl --exec -it --

        1. 要在具有多个容器的 pod 中运行命令,请使用以下命令

        kubectl --exec -it -c --

        【讨论】:

          猜你喜欢
          • 2018-05-12
          • 1970-01-01
          • 2019-06-03
          • 2022-10-26
          • 1970-01-01
          • 2021-07-10
          • 2020-04-21
          • 2016-11-11
          • 1970-01-01
          相关资源
          最近更新 更多