{{< details >}}

  • Tier: 基础版,专业版,旗舰版
  • Offering: JihuLab.com, 私有化部署

{{< /details >}}

{{< history >}}

  • 在极狐GitLab 17.0中,代理连接共享限制从 500 更改为 1000。

{{< /history >}}

你可以使用极狐 GitLab CI/CD 安全地连接、部署和更新你的 Kubernetes 集群。

为此,在你的集群中安装代理。完成后,你将拥有一个 Kubernetes 上下文,并可以在极狐 GitLab CI/CD 流水线中运行 Kubernetes API 命令。

为了确保对集群的访问是安全的:

  • 每个代理都有一个独立的上下文 (kubecontext)。
  • 只有配置代理的项目,以及你授权的任何其他项目,才能访问集群中的代理。

要使用极狐 GitLab CI/CD 与集群交互,runner 必须注册到极狐 GitLab。不过,这些 runner 不必位于代理所在的集群中。

先决条件:

使用极狐 GitLab CI/CD 与您的集群

要使用极狐 GitLab CI/CD 更新 Kubernetes 集群:

  1. 确保你有一个正常运行的 Kubernetes 集群,并且清单位于极狐 GitLab 项目中。
  2. 在同一个极狐 GitLab 项目中,注册并安装极狐 GitLab 代理
  3. 更新你的 .gitlab-ci.yml 文件,选择代理的 Kubernetes 上下文并运行 Kubernetes API 命令。
  4. 运行你的流水线以部署或更新集群。

如果你有多个极狐 GitLab 项目包含 Kubernetes 清单:

  1. 在自己的项目中安装极狐 GitLab 代理,或者在一个保存 Kubernetes 清单的极狐 GitLab 项目中安装。
  2. 在你的极狐 GitLab 项目中授权代理访问
  3. 可选。为了增加安全性,使用模拟
  4. 更新你的 .gitlab-ci.yml 文件,选择代理的 Kubernetes 上下文并运行 Kubernetes API 命令。
  5. 运行你的流水线以部署或更新集群。

授权代理访问

如果你有多个项目包含 Kubernetes 清单,你必须授权这些项目访问代理。你可以为单个项目、群组或子群组授权代理访问,以便所有项目都能访问。为了增加安全性,你还可以使用模拟

授权配置可能需要一到两分钟才能传播。

授权项目访问代理

{{< history >}}

  • 在极狐GitLab 15.6 中,进行了移除继承限制的变更。
  • 在极狐GitLab 15.7 中,允许在用户命名空间中授权项目。

{{< /history >}}

要授权保存 Kubernetes 清单的极狐 GitLab 项目访问代理:

  1. 在左侧边栏中,选择 搜索或转到,找到包含代理配置文件 (config.yaml) 的项目。
  2. 编辑 config.yaml 文件。在 ci_access 关键字下,添加 projects 属性。
  3. 对于 id,添加项目的路径。

    ci_access:
      projects:
        - id: path/to/project
    
    • 授权项目必须与代理的配置项目具有相同的顶级群组或用户命名空间。
    • 你可以在同一个集群中安装额外的代理以适应额外的层次结构。
    • 你可以授权最多 500 个项目。

进行这些更改后:

  • 所有 CI/CD 作业现在都包含一个 kubeconfig 文件,其中包含每个共享代理连接的上下文。
  • kubeconfig 路径在 $KUBECONFIG 环境变量中可用。
  • 你可以选择上下文从你的 CI/CD 脚本中运行 kubectl 命令。

授权群组中的项目访问代理

{{< history >}}

  • 在极狐GitLab 15.6 中移除了层级限制。

{{< /history >}}

要授权群组或子群组中的所有极狐 GitLab 项目访问代理:

  1. 在左侧边栏中,选择 搜索或转到,找到包含代理配置文件 (config.yaml) 的项目。
  2. 编辑 config.yaml 文件。在 ci_access 关键字下,添加 groups 属性。
  3. 对于 id,添加路径:

    ci_access:
      groups:
        - id: path/to/group/subgroup
    
    • 授权群组必须与代理的配置项目具有相同的顶级群组。
    • 你可以在同一个集群中安装额外的代理以适应额外的层次结构。
    • 授权群组的所有子群组也可以访问同一个代理(无需单独指定)。
    • 你可以授权最多 500 个群组。

进行这些更改后:

  • 属于群组及其子群组的所有项目现在都被授权访问代理。
  • 所有 CI/CD 作业现在都包含一个 kubeconfig 文件,其中包含每个共享代理连接的上下文。
  • kubeconfig 路径在 $KUBECONFIG 环境变量中可用。
  • 你可以选择上下文从你的 CI/CD 脚本中运行 kubectl 命令。

授权实例中的所有项目访问代理

{{< details >}}

  • Tier: 基础版,专业版,旗舰版
  • Offering: 私有化部署

{{< /details >}}

{{< history >}}

  • 引入于极狐GitLab 17.11。

{{< /history >}}

先决条件:

  • 你必须是管理员。

允许代理配置为授权实例中的所有项目:

{{< tabs >}}

{{< tab title=”Using the UI” >}}

  1. 管理员 区域,选择 设置 > 常规,并展开 极狐 GitLab Kubernetes 代理 部分。
  2. 选择 启用实例级授权
  3. 选择 保存更改

{{< /tab >}}

{{< tab title=”Using the API” >}}

  1. 更新应用程序设置 organization_cluster_agent_authorization_enabledtrue

{{< /tab >}}

{{< /tabs >}}

要授权代理访问实例中的所有极狐 GitLab 项目:

  1. 在左侧边栏中,选择 搜索或转到,找到包含代理配置文件 (config.yaml) 的项目。
  2. 编辑 config.yaml 文件。在 ci_access 关键字下,添加 instance 属性:

    ci_access:
      instance: {}
    

进行这些代理配置文件更改后:

  • 代理被授权访问实例中的所有项目。
  • 所有 CI/CD 作业都包含一个 kubeconfig 文件,其中包含每个共享代理连接的上下文。
  • kubeconfig 路径在 $KUBECONFIG 环境变量中可用。
  • 你可以选择上下文从你的 CI/CD 脚本中运行 kubectl 命令。

更新你的 .gitlab-ci.yml 文件以运行 kubectl 命令

在你希望运行 Kubernetes 命令的项目中,编辑项目的 .gitlab-ci.yml 文件。

script 关键字下的第一个命令中,设置代理的上下文。使用格式 <path/to/agent/project>:<agent-name>。例如:

deploy:
  image:
    name: bitnami/kubectl:latest
    entrypoint: ['']
  script:
    - kubectl config get-contexts
    - kubectl config use-context path/to/agent/project:agent-name
    - kubectl get pods

如果你不确定代理的上下文是什么,可以在希望访问代理的 CI/CD 作业中运行 kubectl config get-contexts

使用自动 DevOps 的环境

如果启用了自动 DevOps,你必须定义 CI/CD 变量 KUBE_CONTEXT。将 KUBE_CONTEXT 的值设置为你希望自动 DevOps 使用的代理的上下文:

deploy:
  variables:
    KUBE_CONTEXT: path/to/agent/project:agent-name

你可以为不同的自动 DevOps 作业分配不同的代理。例如,自动 DevOps 可以为 staging 作业使用一个代理,为 production 作业使用另一个代理。要使用多个代理,为每个代理定义一个环境范围的 CI/CD 变量。例如:

  1. 定义两个变量 KUBE_CONTEXT
  2. 对于第一个变量:
    1. 设置 environmentstaging
    2. 将值设置为你的 staging 代理的上下文。
  3. 对于第二个变量:
    1. 设置 environmentproduction
    2. 将值设置为你的 production 代理的上下文。

具有证书和代理连接的环境

当你部署到一个同时具有基于证书的集群(已弃用)和代理连接的环境时:

  • 基于证书的集群的上下文称为 gitlab-deploy。此上下文总是默认选择。
  • 代理上下文包含在 $KUBECONFIG 中。你可以通过使用 kubectl config use-context <path/to/agent/project>:<agent-name> 选择它们。

要在存在基于证书的连接时使用代理连接,你可以手动配置一个新的 kubectl 配置上下文。例如:

deploy:
  variables:
    KUBE_CONTEXT: my-context # 要使用的新上下文的名称
    AGENT_ID: 1234 # 用你的代理的数字 ID 替换
    K8S_PROXY_URL: https://<KAS_DOMAIN>/k8s-proxy/ # 对于部署在 Kubernetes 集群中的代理服务器 (KAS)(对于极狐 GitLab.com 使用 kas.gitlab.com);替换为你的 URL
    # K8S_PROXY_URL: https://<GITLAB_DOMAIN>/-/kubernetes-agent/k8s-proxy/ # 对于 Omnibus 中的代理服务器 (KAS)
    # 包含任何额外的变量
  before_script:
    - kubectl config set-credentials agent:$AGENT_ID --token="ci:${AGENT_ID}:${CI_JOB_TOKEN}"
    - kubectl config set-cluster gitlab --server="${K8S_PROXY_URL}"
    - kubectl config set-context "$KUBE_CONTEXT" --cluster=gitlab --user="agent:${AGENT_ID}"
    - kubectl config use-context "$KUBE_CONTEXT"
  # 包含剩余的作业配置

使用自签名证书的 KAS 环境

如果你使用的环境具有 KAS 和自签名证书,你必须配置你的 Kubernetes 客户端以信任签署你证书的证书颁发机构 (CA)。

要配置你的客户端,请执行以下操作之一:

  • 设置一个 CI/CD 变量 SSL_CERT_FILE,并将 KAS 证书以 PEM 格式放入其中。
  • 使用 --certificate-authority=$KAS_CERTIFICATE 配置 Kubernetes 客户端,其中 KAS_CERTIFICATE 是一个 CI/CD 变量,包含 KAS 的 CA 证书。
  • 通过更新容器镜像或通过 runner 挂载,将证书放在作业容器中的适当位置。
  • 不推荐。使用 --insecure-skip-tls-verify=true 配置 Kubernetes 客户端。

通过使用模拟限制项目和群组访问

{{< details >}}

  • Tier: 专业版,旗舰版
  • Offering: JihuLab.com,私有化部署

{{< /details >}}

{{< history >}}

  • 在极狐GitLab 15.5 中增加了对环境层级的模拟支持。

{{< /history >}}

默认情况下,你的 CI/CD 作业继承用于在集群中安装代理的服务帐户的所有权限。为了限制对集群的访问,你可以使用模拟

要指定模拟,请在代理配置文件中使用 access_as 属性,并使用 Kubernetes RBAC 规则来管理模拟帐户权限。

你可以模拟:

  • 代理本身(默认)。
  • 访问集群的 CI/CD 作业。
  • 在集群中定义的特定用户或系统帐户。

授权配置可能需要一到两分钟才能传播。

模拟代理

代理默认被模拟。你不需要做任何事情来模拟它。

模拟访问集群的 CI/CD 作业

要模拟访问集群的 CI/CD 作业,请在 access_as 键下添加 ci_job: {} 键值。

当代理向实际的 Kubernetes API 发出请求时,它以下列方式设置模拟凭据:

  • UserName 设置为 gitlab:ci_job:<job id>。例如:gitlab:ci_job:1074499489
  • Groups 设置为:

    • gitlab:ci_job,用于标识所有来自 CI 作业的请求。
    • 项目所在群组的 ID 列表。
    • 项目 ID。
    • 作业所属环境的 slug 和级别。

      例如:对于 group1/group1-1/project1 中的 CI 作业,其中:

      • 群组 group1 的 ID 为 23。
      • 群组 group1/group1-1 的 ID 为 25。
      • 项目 group1/group1-1/project1 的 ID 为 150。
      • 作业运行在 prod 环境中,该环境具有 production 环境级别。

    群组列表为 [gitlab:ci_job, gitlab:group:23, gitlab:group_env_tier:23:production, gitlab:group:25, gitlab:group_env_tier:25:production, gitlab:project:150, gitlab:project_env:150:prod, gitlab:project_env_tier:150:production]

  • Extra 携带有关请求的额外信息。以下属性设置在模拟身份上:
Property Description
agent.gitlab.com/id 包含代理 ID。
agent.gitlab.com/config_project_id 包含代理的配置项目 ID。
agent.gitlab.com/project_id 包含 CI 项目 ID。
agent.gitlab.com/ci_pipeline_id 包含 CI 流水线 ID。
agent.gitlab.com/ci_job_id 包含 CI 作业 ID。
agent.gitlab.com/username 包含运行 CI 作业的用户的用户名。
agent.gitlab.com/environment_slug 包含环境的 slug。仅在环境中运行时设置。
agent.gitlab.com/environment_tier 包含环境的级别。仅在环境中运行时设置。

示例 config.yaml,以限制访问 CI/CD 作业的身份:

ci_access:
  projects:
    - id: path/to/project
      access_as:
        ci_job: {}

限制 CI/CD 作业的示例 RBAC

以下 RoleBinding 资源限制所有 CI/CD 作业仅具有查看权限。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ci-job-view
roleRef:
  name: view
  kind: ClusterRole
  apiGroup: rbac.authorization.k8s.io
subjects:
  - name: gitlab:ci_job
    kind: Group

模拟静态身份

对于给定的连接,你可以使用静态身份进行模拟。

access_as 键下,添加 impersonate 键以使用提供的身份进行请求。

身份可以用以下键指定:

  • username(必需)
  • uid
  • groups
  • extra

通过模拟限制项目和群组访问特定环境

{{< details >}}

  • Tier: 基础版,专业版,旗舰版
  • Offering: JihuLab.com,私有化部署

{{< /details >}}

{{< history >}}

  • 引入于极狐GitLab 15.7。

{{< /history >}}

默认情况下,如果你的代理可用于项目,所有项目的 CI/CD 作业都可以使用该代理。

要限制代理仅用于特定环境的作业,请将 environments 添加到 ci_access.projectsci_access.groups。例如:

  ci_access:
    projects:
      - id: path/to/project-1
      - id: path/to/project-2
        environments:
          - staging
          - review/*
    groups:
      - id: path/to/group-1
        environments:
          - production

在此示例中:

  • project-1 下的所有 CI/CD 作业都可以访问代理。
  • project-2 下具有 stagingreview/* 环境的 CI/CD 作业可以访问代理。
    • * 是通配符,因此 review/* 匹配 review 下的所有环境。
  • group-1 下的项目具有 production 环境的 CI/CD 作业可以访问代理。

限制代理访问到受保护分支

{{< details >}}

  • Tier: 基础版,专业版,旗舰版
  • Offering: 私有化部署

{{< /details >}}

{{< history >}}

  • 引入于极狐GitLab 17.3,使用名为 kubernetes_agent_protected_branches功能标志。默认禁用。
  • 在极狐GitLab 17.10 中 GA。功能标志 kubernetes_agent_protected_branches 被移除。

{{< /history >}}

{{< alert type=”flag” >}}

该功能的可用性由功能标志控制。有关详细信息,请参阅历史记录。此功能可用于测试,但尚未准备好用于生产。

{{< /alert >}}

要限制代理访问仅运行在受保护分支上的作业:

  • protected_branches_only: true 添加到 ci_access.projectsci_access.groups 中。例如:

    ci_access:
      projects:
        - id: path/to/project-1
          protected_branches_only: true
      groups:
        - id: path/to/group-1
          protected_branches_only: true
          environments:
            - production
    

默认情况下,protected_branches_only 设置为 false,代理可以从未受保护和受保护的分支访问。

为了额外的安全性,你可以将此功能与环境限制结合使用。

如果项目有多个配置,则仅使用最具体的配置。例如,以下配置授予 example/my-project 中未受保护的分支访问权限,即使 example 群组配置为仅授予受保护分支访问权限:

# .gitlab/agents/my-agent/config.yaml
ci_access:
  project:
    - id: example/my-project # 群组中的项目
      protected_branches_only: false # 此配置优于群组配置
      environments:
        - dev
  groups:
    - id: example
      protected_branches_only: true
      environments:
        - dev

相关主题

故障排除

授予 ~/.kube/cache 的写权限

工具如 kubectl、Helm、kptkustomize~/.kube/cache 中缓存有关集群的信息。如果此目录不可写,则工具在每次调用时获取信息,使交互变得更慢并在集群上产生不必要的负载。为了获得最佳体验,请确保你在 .gitlab-ci.yml 文件中使用的镜像可以写入此目录。

启用 TLS

如果你使用的是私有化部署的极狐 GitLab,请确保你的实例配置了传输层安全性 (TLS)。

如果你尝试在没有 TLS 的情况下使用 kubectl,你可能会收到如下错误:

$ kubectl get pods
error: You must be logged in to the server (the server has asked for the client to provide credentials)

无法连接到服务器:由未知机构签署的证书

如果你使用的环境具有 KAS 和自签名证书,kubectl 调用可能会返回此错误:

kubectl get pods
Unable to connect to the server: x509: certificate signed by unknown authority

该错误发生是因为作业不信任签署 KAS 证书的证书颁发机构 (CA)。

要解决此问题,请配置 kubectl 以信任 CA

验证错误

如果你使用 kubectl 版本 v1.27.0 或 v.1.27.1,可能会遇到以下错误:

error: error validating "file.yml": error validating data: the server responded with the status code 426 but did not return more information; if you choose to ignore these errors, turn validation off with --validate=false

此问题是由 kubectl 和其他使用共享 Kubernetes 库的工具中的错误引起的。

要解决此问题,请使用另一个版本的 kubectl