gitlab CICD

k8s 安装 GitLab

​ GitLab 具有三个需要进行持久化的目录,它们分别是 /etc/gitlab、/var/log/gitlab、/var/opt/gitlab,它们分别为 Gitlab 的运行提供配置、日志、数据的持久化。我们使用 nfs 来作为 GitLab 的持久化方式(当然,你也可以选择其他方式),为此,我们需要先安装 NFS,并且在 NFS 的配置文件中进行如下修改:

vim /etc/exports
# 注意,用户的访问权限一定要设置为 no_root_squash,因为 gitlab 需要 root 权限来操作这些文件。
/data/nfs/gitlab/config 172.17.33.152(rw,insecure,sync,no_root_squash,subtree_check)
/data/nfs/gitlab/logs 172.17.33.152(rw,insecure,sync,no_root_squash,subtree_check)
/data/nfs/gitlab/data 172.17.33.152(rw,insecure,sync,no_root_squash,subtree_check)

# 启用新的配置文件
exportfs -r

​ 随后在 k8s 中安装 gitlab 及其各个组件

kubectl apply -f - << EOF
apiVersion: v1
kind: Service
metadata:
  name: gitlab-svc
  namespace: gitlab
spec:
  type: NodePort
  ports:
  - port: 443
    targetPort: 443
    nodePort: 31443
    name: https
  - port: 80
    nodePort: 31080
    targetPort: 80
    name: http
  selector:
    app: gitlab
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-dep
  namespace: gitlab
spec:
  selector:
    matchLabels:
      app: gitlab
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: gitlab
    spec:
      containers:
      - image: gitlab/gitlab-ce
        name: gitlab
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 443
          name: https
        - containerPort: 80
          name: http
        - containerPort: 22
          name: ssh
        volumeMounts:
        - name: gitlab-config
          mountPath: /etc/gitlab
        - name: gitlab-logs
          mountPath: /var/log/gitlab
        - name: gitlab-data
          mountPath: /var/opt/gitlab
      volumes:
      - name: gitlab-config
        nfs:
          server: 172.17.33.149
          path: /data/nfs/gitlab/config
      - name: gitlab-logs
        nfs:
          server: 172.17.33.149
          path: /data/nfs/gitlab/logs
      - name: gitlab-data
        nfs:
          server: 172.17.33.149
          path: /data/nfs/gitlab/data

​ 完成后,查看 gitlab 网页暴露在哪个端口:

kubectl get svc -n gitlab
########################################## 返回结果 #########################################
# NAME         TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE  #
# gitlab-svc   NodePort   10.102.48.248   <none>        443:31443/TCP,80:31080/TCP   153m #
###########################################################################################

​ 访问 gitlab 页面,进入登录界面

登录界面

​ 管理员用户为 root,其登录密码在容器目录 /etc/gitlab/initial_root_password 文件中,即 nfs 服务器的 /data/nfs/gitlab/config/initial_root_password 文件。获取初始密码:

kubectl exec -it -n gitlab $(kubectl get pods -n gitlab | grep gitlab | awk '{print$1}') -- cat /etc/gitlab/initial_root_password | grep Password:

​ 登录进入系统,修改初始密码(一定要修改,因为这个临时密码的有效时间只有 24 小时)。页面路径为:右上角头像->Edit profile->左边导航栏->Password
修改初始密码
​ 随后可以创建一个普通用户,测试是否能正常使用 git 进行操作。

修改外部 URL

​ 通常情况下,gitlab 会根据机器内部的 FQCN 来标记一个仓库的 url。这就导致了在 gitlab 中复制 clone url 时,其使用的不是 IP 而是一个域名。如果在局域网内部署 gitlab,这个 DNS 显然是不可以使用的。如果我们希望 gitlab 中的 url 直接使用 IP 地址,那么就需要修改配置文件 gitlab.rb

# 由于我们之前将 gitlab 的配置文件挂载到了 /data/nfs/gitlab/config 上,因此通过修改宿主机的配置文件即可
vim gitlab.rb
# 在其中添加一行:
external_url 'http://<ip>:<port>'
# 例如: external_url 'http://172.17.33.149:31080'

# 修改完配置文件后,删除原本的 gitlab pod,让其自动重启,加载配置文件
kubectl delete pod -n gitlab gitlab-5xjfiosd2jn

​ 执行完上述操作后,我们尝试登录在外网登录 gitlab,发现无法登录。这是因为 external_url 修改后,导致 Pod 内部,gitlab 的端口也发生了变化。在没有设置之前,gitlab 是暴露在 80 端口,修改之后,gitlab 就暴露在我们设置的那个端口。因此,还需要修改 service 的 tagetPort 字段,才能让外部正常访问到 gitlab:

kubectl edit svc -n gitlab gitlab-svc
# 将 targetPort 设置为之前修改的端口

​ 此时,我们已经可以正常访问 gitlab,查看 clone 中的 url,如下图所示:
gitlab-url

安装 Harbor

​ 由于 Harbor 的组件实在是太多,因此,使用 helm 作为安装手段来简化安装过程。具体过程参照文档:https://goharbor.io/docs/2.7.0/install-config/harbor-ha-helm/

helm 是一种 k8s 安装工具,它通过模板化的方式,一次性构造出一个大型项目。

# 下载 harbor chart
helm repo add harbor https://helm.goharbor.io
# 将 chart 下载至本地,执行完这一步后,当前路径会出现一个 harbor 文件夹,里面是各种安装文件
helm fetch harbor/harbor --untar

​ 为了简化过程,我们不对其中的任何一个组件进行外部定制,只为这些组件提供必要的持久化手段。
我们先自行创建 pv 和 pvc:

# 此处使用 nfs 支持持久卷,为此需要创建多个目录以供挂载
for i in chartmuseum database jobservice redis registry trivy;do mkdir -p /data/nfs/harbor/$i; done
cat >> /etc/exports << EOF
/data/nfs/harbor/registry *(rw,insecure,sync,no_root_squash,subtree_check)
/data/nfs/harbor/chartmuseum *(rw,insecure,sync,no_root_squash,subtree_check)
/data/nfs/harbor/jobservice *(rw,insecure,sync,no_root_squash,subtree_check)
/data/nfs/harbor/database *(rw,insecure,sync,no_root_squash,subtree_check)
/data/nfs/harbor/trivy *(rw,insecure,sync,no_root_squash,subtree_check)
/data/nfs/harbor/redis *(rw,insecure,sync,no_root_squash,subtree_check)
EOF
# 更新 nfs
exportfs -r
# 查看 nfs 当前提供的挂载点
showmount -e

# 创建 pv + pvc
cat >> pvc-pv-chartmuseum.yaml << EOF
apiVersion: v1
kind: PersistentVolume
# pv 没有命名空间的限制
metadata:
  name: harbor-chartmuseum-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteMany
  nfs:
    server: 172.17.33.149
    path: /data/nfs/harbor/chartmuseum
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: harbor-chartmuseum-pvc
  namespace: harbor 
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 5Gi
EOF
for i in database jobservice redis registry trivy;do cat pvc-pv-chartmuseum.yaml | sed "s/chartmuseum/$i/g" > pvc-pv-$i.yaml; done
kubectl apply -f .
# 查看 pvc、pv
kubectl get pv
kubectl get pvc -n harbor

​ 现在,我们需要让 helm 创建的 harbor 组件使用我们的 pvc,因此,我们需要定制化这一部分功能。helm 的 chart 安装包,通常的文件结构如下:

<chart>--- conf               # 通常不需要关心
        |
        |- template           # 模板文件,就是 k8s 的 yaml 文件,在调用 helm install 指令时,helm 会根据这些模板,生成真正的 yaml 文件,并调用 kubectl apply 来启动
        |
        |- values.yaml        # 重点关心的文件,这个文件里面存放了所有可以定制化的参数。所谓的定制化,实际上就是将模板中的一些默认参数修改为我们希望的值,而这些值,就存放在 values.yaml 文件中。

​ 我们进入到 harbor 安装包,修改 value.yaml 文件,让 harbor 的组件使用我们自己的持久卷——不要被 value.yaml 文件的内容吓到了,我们关心的只有很小的一部分。

  1. 修改服务暴露方式。在自行搭建的小集群内,通常使用的暴露方式是 NodePort,因此我们修改 expose.type: nodePort,如下图:
    修改服务暴露方式

  2. 修改外部 URL,即 externalURL:http://<your_k8s_ip>:30002 。如果不修改,成功部署 harbor 之后,无法登录到 harbor 管理界面,因为 harbor 只信任以这个 URL 访问的 http 请求。这也意味着,之后你也只能使用这个 url 才能登录到 harbor 中。

修改外部访问 url

  1. 修改持久化方式。重点是修改 persistence 字段下的各个 existingClaim 字段为我们之前创建的 PVC 名称

修改 PVC
修改完成后,保存退出。最后安装即可:

# helm install 命令的格式是这样的:
# helm install <name> -n <namespace> <chart_path>
# 	name: 名称,不重要,给人看的
#   namespace: 命名空间,指定后,所有组件都会被安装到这个命名空间下
#	chart_path: 安装包的路径
helm install harbor -n harbor harbor/

你可能遇到的问题:

  • 执行完安装程序后,过了很久后,pod 一直处在 CrashLoopxxx 状态:创建 harbor 是一个很久的过程,你需要耐心等待,如果 10 分钟后还有大量 Pod 没有安装成功,建议从网络、集群状态方向入手解决问题。如果只有个别 Pod 没有启动成功,你可以尝试把这些 Pod 删除,让它们自动重建。

安装 gitlab runner

​config.toml 文件中的配置项及其功能可以查看官方文档: https://docs.gitlab.com/runner/executors/kubernetes.html#default-annotations-for-job-pods

概述

​gitlab-runner 是 gitlab 提供的一种执行 CICD pipline 的组件。它有多种执行器,每一个执行器都提供一种实现 pipline 的方式,例如:shell 执行器是使用 shell 指令实现,docker 执行器是使用 docker api 实现。其中,最有难度的一种是 kubernetes 执行器。这种执行器会使用 k8s api 来实现 CICD pipline。

​ runner 的 k8s 执行器是这样执行 pipline 的:

  • 首先,runner 会通过 RBAC 认证获取到调用 k8s 集群 API 的权限。
  • runner 会监听 gitlab,当有合适的 job 时,runner 会自动抓取任务执行。请注意,一个流水线中可以有很多个 stage,这些 stage 是串行执行的,而一个 stage 中又可以有多个并行的 job,runner 抓取的任务是以 job 为单位,而不是 stage,更不是 pipline
  • 随后,runner 会调用 k8s API,创建一个用于执行该 job 的 pod。通常来说,runner 创建的所有 pod 有一个通用模板,我们需要在 runner 的 config.toml 配置文件中配置这个模板。但 pod 中具体使用什么镜像、在 pod 中执行什么命令,这些都是在后续的 .gitlab-ci.yml 文件中配置,并且随着 job 的不同而不同。
  • 在完成了 job 内的工作后,runner 会将这个临时 pod 删除。

配置 ConfigMap

​ 将主节点 kubeconfig 内容添加到 secret 中。这个文件的内容是 kubectl 访问 k8s 集群的准入 Token,只有在指定了该 Token 后,才能使用 kubectl 指令来对集群内的各种资源进行增删改查。由于 runner 在 CICD 过程中需要对 k8s 集群进行操作,因此,每一个 runner 中都必须具备 Token以供 gitrunner 的 k8s 执行器使用。

​ 使用 secrete 将这个 Token 以卷挂载的方式加入到 runner 创建的 pod 中。

温馨提示:请务必保证 config 文件中包含的证书与密钥没有过期

kubectl create secrete generic -n gitlab --from-file ~/.kube/config

​ 接下来配置 runner 的 config.toml 文件

apiVersion: v1
kind: ConfigMap
metadata:
  name: gitlab-runner-config
  namespace: gitlab
data:
  # 以下是 gitlab-runner 的配置文件模板,gitlab-runner 会实时读取 config.toml 配置文件并热加载,因此,在 gitlab-runner 部署后,可以直接通过修改 config.toml 文件来更新配置
  config-template.toml: |-
    [[runners]]
    
      # cache 不是必要的。它的作用是缓存项目的依赖包,从而大大减少项目构建的时间
      [runners.cache]
        # Type 可以选择 s3 和 gc3 两种对象存储协议
        Type = "s3"
        # Shared 字段控制不同 runner 之间的缓存是否共享,默认是 false
        Shared = false
        [runners.cache.s3]
          ServerAddress = <s3_host:s3_port>
          # 相当于用户名
          AccessKey = <key>
          # 相当于密码
          SecretKey = <secret>
          # 桶名
          BucketName = <bucket_name>
          Insecure = true
          
      # 重要,用于配置 kubernetes 执行器。
      [runners.kubernetes]
        # 容器镜像拉取规则
        pull_policy = "if-not-present"
        # CICD 产生的 Pod 所在的命名空间,这个 namespace 需要和后续创建的所有资源所在 namespace 保持一致,否则会导致角色和它需要创建的资源不在同一个 namespace 从而失败
        namespace = "gitlab"
        poll_time = 600
        cpu_request = "1"
        service_cpu_request = "200m"
        dns_policy = "none"
      # 用于配置该 Executor 生成的 Pod 中的 /etc/hosts 文件
      [[runners.kubernetes.host_aliases]]
        ip = "127.0.0.1"
        hostnames = ["localhost"]
      # 用于配置 Pod 的 DNS 配置
      [runners.kubernetes.dns_config]
        nameserver = [
          <DNS_1>
          <DNS_2>
          ...
        ]
        searches = [
          <searches_1>
          <searches_2>
          ...
        ]
      # 共用宿主机的 docker
      [runners.kubernetes.volumes]
         [[runners.kubernetes.volumes.host_path]]
           name = "docker"
           mount_path = "/var/run/docker.sock"
           read_only = true
           host_path = "/var/run/docker.sock"
         # 将 kubeconfig 内容挂载在
         [[runners.kubernetes.volumes.secret]]
           name = "kube-config"
           mount_path = "/home/"
           read_only = true

  # 以下这些配置是用于后续注册 runner 时使用
  group_runner_concurrent: "10"
  group_runner_executor: "kubernetes"
  group_runner_name: "gitlab-runner"
  group_runner_tag: "gitlab-runner"
  # 这个地方需要修改为 gitlab 的地址
  group_runner_url: "http://bdcgit.cuc.edu.cn:8089/"
  # 修改为 gitrunner 注册的 token
  group_runner_token: "UwYRJp8vw4S-MbbJxgoT"

获取上述配置中的 token 如下:

  1. 如果要将 runner 注册在全局下(所有项目都能使用):

    a. 登录 root 管理员账户

    b. Admin --> CI/CD --> Register an instance runner

    如下图所示:

    注册全局runner

  2. 如果要将 runner 注册在一个组下:

    a. 只要你是组管理员即可,进入组管理界面

    b. CI/CD --> Register a group runner

​ 如下图所示:

注册组内runner

配置 gitlab-runner 注册脚本

​将 runner 部署到 k8s 上之后还需要将 runner 注册到 gitlab 上才能使用,为此,我们需要写一个脚本,让 runner 部署完成后自行执行,从而完成注册。我们通过 configmap 来将这个脚本挂载到 runner 所在的 Pod 中,这样,只要在之后创建容器时使用启动脚本就能自动执行。

apiVersion: v1
kind: ConfigMap
metadata:
  name: gitlab-runner-register
  namespace: gitlab
data:
  run.sh: |
  # !/bin/bash
  # 这里的 --non-interactive 是指使用非交互模式注册,如果不用该限定符,就会使用交互式注册,那需要我们手动键入所有必要的配置,这显然不符合自动化的宗旨
  # 下面所涉及到的所有环境变量都是在后续的 Deployment 中配置的
  gitlab-runner register --non-interactive --name $GROUP_RUNNER_NAME --url $GROUP_RUNNER_URL --registration-token $GROUP_RUNNER_TOKEN --executor $GROUP_RUNNER_EXECUTOR --template-config /config/config-template.toml --tag-list $GROUP_RUNNER_TAG --locked

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-runner
  namespace: gitlab
spec:
  replicas: 1
  selector:
    matchLabels:
      name: gitlab-runner
  template:
    metadata:
      labels:
        name: gitlab-runner
    spec:
      #nodeName: bdcenter-k8s-worker9
      serviceAccountName: gitlab-runner-admin
      imagePullSecrets:
        - name: harbor-secret
      containers:
        - image: gitlab/gitlab-runner:latest
          imagePullPolicy: IfNotPresent
          name: gitlab-runner
          env:
            # 将我们之前在 configmap 中设置的项通过环境变量的方式注入到容器中
            - name: GROUP_RUNNER_CONCURRENT
              valueFrom:
                configMapKeyRef:
                  name: gitlab-runner-config 
                  key: group_runner_concurrent
            - name: GROUP_RUNNER_NAME
              valueFrom:
                configMapKeyRef:
                  name: gitlab-runner-config
                  key: group_runner_name
            - name: GROUP_RUNNER_TAG
              valueFrom:
                configMapKeyRef:
                  name: gitlab-runner-config
                  key: group_runner_tag
            - name: GROUP_RUNNER_TOKEN
              valueFrom:
                configMapKeyRef:
                  name: gitlab-runner-config
                  key: group_runner_token
            - name: GROUP_RUNNER_URL
              valueFrom:
                configMapKeyRef:
                  name: gitlab-runner-config
                  key: group_runner_url
            - name: GROUP_RUNNER_EXECUTOR
              valueFrom:
                configMapKeyRef:
                  name: gitlab-runner-config
                  key: group_runner_executor
          lifecycle:
            # 在容器启动之后,执行注册脚本
            postStart:
              exec:
                command: ["/bin/sh", "-c", "sh /foo/run.sh && sed -i 's/concurrent = 1/concurrent = '$GROUP_RUNNER_CONCURRENT'/g' /etc/gitlab-runner/config.toml"]
          resources:
            requests:
              cpu: "100m"
            limits:
              cpu: "100m"
          volumeMounts:
          - name: gitlab-runner-config
            mountPath: /config
          - name: script-volume
            mountPath: /foo
      volumes:
        - name: gitlab-runner-config
          configMap:
            name: gitlab-runner-config
            items:
            - key: config-template.toml
              path: config-template.toml
        - name: script-volume
          configMap:
            name: gitlab-runner-register
            items:
            - key: run.sh
              path: run.sh
              mode: 0755
---
# 创建角色,runner 生成的 pod 会使用下述角色信息通过 k8s 的 RBAC,从而能够创建 k8s 的相应资源
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab-runner-admin
  namespace: gitlab
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: gitlab
  name: gitlab-admin
rules:
  - apiGroups: [""]
    resources: ["*"] 
    verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: gitlab-admin
  namespace: gitlabE
subjects:
  - kind: ServiceAccount
    name: gitlab-runner-admin
    namespace: gitlab
roleRef:
  kind: Role
  name: gitlab-admin
  apiGroup: rbac.authorization.k8s.io

最后,将上述所有资源应用到 k8s 集群中,等待 runner 启动完成。

如果能够在 gitlab 管理员界面查看到 runner,说明 runner 安装注册成功。

runner

使用 gitlab CICD

配置 gitlab 环境变量

在 Group——>Your Group——>Settings——>CI/CD——>Variables 中填入相关环境变量

这些环境变量可以在后续的 .gitlab-ci.yml 文件中使用。
在这里插入图片描述

# 镜像仓库密码
REGISTRY_PASSWORD: Harbor12345
# 镜像仓库 url,例如:172.17.33.146:1180
REGISTRY_URL: <your_harbor_url>
# 镜像仓库用户名
REGISTRY_USERNAME: admin

请注意,添加变量时默认会将其设置为 “Protected”,这会让该变量只能被保护分支使用(保护分支通常是 default 分支),如果我们想要所有分支都能使用这个变量,应当将取消其 Protected 属性,如下图:

取消环境变量保护模式

配置 .gitlab-ci.yml Pipeline 文件

下例为 npm 前端项目部署的 .gitlab-ci.yml 演示,对该文件有以下几点需要说明:

  • 每个 stage 都会选择一个 runner 来执行,这意味着可以根据 stage 的不同,选择具有特定功能的 runner
  • 在 kubernetes executor 模式中,每一个 stage,runner 都会使用 k8s api 在指定的命名空间中创建一个专用于 pipline 的临时 Pod,在这个 Pod 中执行完当前 stage 的所有 script,随后自动销毁
  • CI 过程中,可以简单的认为,runner 将当前 git 代码仓库整个拷贝到了容器当中,而工作目录则是项目的根目录,因此,如果有什么文件需要进行拷贝、修改、删除,请尤其注意这一点。
# .gitlab-ci.yaml
# 选取全局基础镜像为node:latest
image: $REGISTRY_URL/library/node:latest

# 表示 pipeline 分几个阶段进行,下例中表示 pipeline 分 package - build - depoly 三个阶段依次执行
stages:
  - package
  - build
  - deploy

# 表示package阶段的开始
package:
  stage: package
  # 表示此阶段的基础镜像为node
  image: $REGISTRY_URL/library/node:latest
  
  # (可选)使用cache进行缓存
  # cache:
    # 缓存git中没有被跟踪的文件
    # untracked: true
    # key表示指定分支的指定Job使用此cache
    # key: "$CI_COMMIT_REF_SLUG"
    # 表示要缓存的目录,这里的node_modules目录是安装的依赖包目录
    # paths:
    #  - node_modules/
    # 表示缓存的拉取策略
    # policy: pull-push
    
  # 表示要执行的脚本
  script:
    - npm install --registry=https://registry.npm.taobao.org
    # 将项目打包
    - npm run build
    
  # tag 表示执行此阶段的 gitlab-runner
  tags: 
    - [group_runner_name]
    
  # 使用 artifacts 来传递 stage 间的文件,这里需要将 build 生成的 dist 文件夹传至下一阶段进行镜像的制作
  artifacts:
    paths:
      - dist
      
build:
  # 使用docker作为基础镜像,使用 docker 的目的是生成镜像,并推送到本地镜像仓库
  image: $REGISTRY_URL/library/docker:19.03.0-dind
  # 声明一些参数
  services:
    - name: docker:19.03.0-dind
      command: ["--registry-mirror=https://dockerhub.azk8s.cn/"]
      command: ["--insecure-registry=$REGISTRY_URL"]

  stage: build
  script:
    # 查看docker信息
    - docker info
    
    # 登录Harbor私有仓库
    - docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD $REGISTRY_URL
    
    # docker build命令制作镜像,注意-t后面为镜像名称,此镜像名称需和deployment.yaml文件中的镜像名称对应。
    # 确保项目根目录中已经存在一个 Dockerfile
    - docker build -t $REGISTRY_URL/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME:v$CI_PIPELINE_ID .
    
    # 将制作的镜像push到远程私有仓库
    - docker push $REGISTRY_URL/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME:v$CI_PIPELINE_ID
  tags: 
    - [group_runner_name]
    

deploy:
  stage: deploy
  tags:
    - [group_runner_name]
  # 使用kubectl基础镜像,dockerhub 的 kubectl 基础镜像由于遵循最简化的原则,往往不符合我们的要求,因此,这个 kubectl 镜像是我们自己构建的,Dockerfile 在后文中会展示
  image: $REGISTRY_URL/kubectl:latest
  script:
	
    - kubectl version
    
    # 使用 kubectl apply命令部署应用,至于 kubectl 的构建文件,此处不再展示,只是
    - kubectl apply -f deployments/

当做好这一切的工作之后,就可以在 gitlab 上运行流水线了,如下图所示:
流水线运作

kubectl 镜像 Dockerfile

# alpine 镜像是一个轻量级的调试容器,它具有比 busybox 更完善的工具
FROM alpine:latest
# 这里的 KUBECONFIG 环境变量为 kubectl 指示出证书、密钥文件的路径
ENV KUBECONFIG=/home/config
# 将 kubectl 可执行文件拷贝到镜像中。这里是在主节点中执行的,你也可以在网上下载 kubectl 再复制到镜像中
COPY kubectl /usr/local/bin/
# 将 kubectl 设置为可执行权限
RUN chmod +x /usr/local/bin/kubectl
Logo

开源、云原生的融合云平台

更多推荐