首页 > 解决方案 > 在 dockerimage 中运行 kubectl

问题描述

我有一个带有 DockerFile 的应用程序。这个 DockerFile 需要运行一个包含 curl 命令和 kubectl 命令的 shell 脚本。

我将 dockerFile 设计为

FROM ubuntu:16.04

WORKDIR /build

RUN apt-get update && apt-get install -y curl && apt-get install -y jq
COPY ./ ./
RUN chmod +x script.sh
ENTRYPOINT ["./script.sh"]

script.sh文件包含 curl 命令和 kubectl 命令。

如果您看到我使用命令在 docker 容器中安装了 curl 命令RUN apt-get update && apt-get install -y curl

为了运行 kubectl 命令,我需要做什么?因为当我构建并运行上面的图像时,它会抛出一个错误,说kubectl: command not found.

谁能帮我这个 ?

标签: dockershellkubernetesdockerfile

解决方案


您可以下载任何您想要的二进制文件并使用它,而不是使用 apt-get 安装。

这将使您有更多的控制权,并且将来出现问题的机会更少。

有关如何从官方存储库下载它的步骤可以在文档中找到。

在 Linux 上使用 curl 安装 kubectl 二进制文件

  1. 使用以下命令下载最新版本:

    curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
    

    要下载特定版本,请将 $(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt) 命令的部分替换为特定版本。

    例如,要在 Linux 上下载 v1.18.0 版本,请键入:

    curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl
    
  2. 使 kubectl 二进制可执行文件。

    chmod +x ./kubectl
    
  3. 将二进制文件移动到您的 PATH 中。

    sudo mv ./kubectl /usr/local/bin/kubectl
    
  4. 测试以确保您安装的版本是最新的:

    kubectl version --client
    

考虑到这一点,您可以拥有一个类似于此的 Dockerfile:

FROM debian:buster
RUN apt update && \
      apt install -y curl && \
      curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl && \
      chmod +x ./kubectl && \
      mv ./kubectl /usr/local/bin/kubectl
CMD kubectl get po

在此之后,我们可以使用以下清单创建一个 pod:

apiVersion: v1
kind: Pod
metadata:
  name: internal-kubectl
spec:
  containers:
    - name: internal-kubectl
      image: myrep/internal-kubectl:latest
      command: ['sh', '-c', "kubectl get pod; sleep 36000"]

运行这个 pod 会给你一个错误,这会发生,因为你没有创建必要的RBAC规则。

告诉 Kubernetes 我们希望这个 pod 有一个可以列出这些 pod 的身份的方法是通过组合几个不同的资源……</p>

apiVersion: v1
kind: ServiceAccount
metadata:
  name: internal-kubectl

我们要分配给我们的 pod 的身份对象将是一个服务帐户。但它本身没有权限。这就是角色发挥作用的地方。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: modify-pods
rules:
  - apiGroups: [""]
    resources:
      - pods
    verbs:
      - get
      - list
      - delete

上面的角色指定我们希望能够获取、列出和删除 pod。但是我们需要一种方法来将我们的新服务帐户与我们的新角色相关联。角色绑定是实现这一目标的桥梁……</p>

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: modify-pods-to-sa
subjects:
  - kind: ServiceAccount
    name: internal-kubectl
roleRef:
  kind: Role
  name: modify-pods
  apiGroup: rbac.authorization.k8s.io

此角色绑定将我们的服务帐户连接到具有我们所需权限的角色。现在我们只需要修改我们的 pod 配置以包含服务帐户……</p>

apiVersion: v1
kind: Pod
metadata:
  name: internal-kubectl
spec:
  serviceAccountName: internal-kubectl
  containers:
    - name: internal-kubectl
      image: myrep/internal-kubectl:latest
      command: ['sh', '-c', "kubectl get pod; sleep 36000"]

通过指定 spec.serviceAccountName 这将我们从使用默认服务帐户更改为具有正确权限的新帐户。运行我们的新 pod,我们应该会看到正确的输出……</p>

$ kubectl logs internal-kubectl
NAME               READY   STATUS    RESTARTS   AGE
internal-kubectl   1/1     Running   1          5s

推荐阅读