使用 GitLab CI/CD 与 Kubernetes 集群
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
您可以使用 GitLab CI/CD 安全地连接、部署和更新您的 Kubernetes 集群。
为此,在您的集群中安装一个 agent。完成后,您将拥有一个 Kubernetes 上下文,并可以在 GitLab CI/CD 管道中运行 Kubernetes API 命令。
为确保对集群的访问安全:
- 每个 agent 都有独立的上下文(
kubecontext)。 - 只有配置了 agent 的项目以及您授权的任何其他项目才能访问您集群中的 agent。
要使用 GitLab CI/CD 与您的集群交互,runners 必须在 GitLab 中注册。但是,这些 runners 不必在 agent 所在的集群中。
先决条件:
- 确保 已启用 GitLab CI/CD。
使用 GitLab CI/CD 与您的集群
使用 GitLab CI/CD 更新 Kubernetes 集群:
- 确保您有一个可工作的 Kubernetes 集群,并且清单文件位于 GitLab 项目中。
- 在同一个 GitLab 项目中,注册并安装 GitLab agent for Kubernetes。
- 更新您的
.gitlab-ci.yml文件 以 选择 agent 的 Kubernetes 上下文并运行 Kubernetes API 命令。 - 运行您的管道以部署到或更新集群。
如果您有多个包含 Kubernetes 清单文件的 GitLab 项目:
- 在其自己的项目中安装 GitLab agent for Kubernetes,或者安装在您保存 Kubernetes 清单文件的 GitLab 项目之一中。
- 在您的 GitLab 项目中 授权 agent 访问。
- 可选。为了增强安全性,使用身份模拟。
- 更新您的
.gitlab-ci.yml文件 以 选择 agent 的 Kubernetes 上下文并运行 Kubernetes API 命令。 - 运行您的管道以部署到或更新集群。
授权 agent 访问
如果您有多个包含 Kubernetes 清单文件的项目,您必须授权这些项目访问 agent。您可以授权单个项目、组或子组访问 agent,以便所有项目都能访问。为了增强安全性,您还可以 使用身份模拟。
授权配置可能需要一到两分钟才能传播。
授权您的项目访问 agent
授权保存 Kubernetes 清单文件的 GitLab 项目访问 agent:
-
在左侧边栏,选择 搜索或跳转至 并找到包含 agent 配置文件 (
config.yaml) 的项目。 -
编辑
config.yaml文件。在ci_access关键字下,添加projects属性。 -
对于
id,添加项目路径。ci_access: projects: - id: path/to/project- 授权的项目必须与 agent 配置项目具有相同的顶级组或用户命名空间,除非启用了 实例级别授权 应用设置。
- 您可以在同一个集群中安装额外的 agent 以适应额外的层次结构。
- 您可以授权最多 500 个项目。
进行这些更改后:
- 所有 CI/CD 作业现在都包含一个
kubeconfig文件,其中包含每个共享 agent 连接的上下文。 kubeconfig路径在$KUBECONFIG环境变量中可用。- 您可以从 CI/CD 脚本中选择上下文来运行
kubectl命令。
授权您的组中的项目访问 agent
授权组或子组中的所有 GitLab 项目访问 agent:
-
在左侧边栏,选择 搜索或跳转至 并找到包含 agent 配置文件 (
config.yaml) 的项目。 -
编辑
config.yaml文件。在ci_access关键字下,添加groups属性。 -
对于
id,添加路径:ci_access: groups: - id: path/to/group/subgroup- 授权的组必须与 agent 配置项目具有相同的顶级组,除非启用了 实例级别授权 应用设置。
- 您可以在同一个集群中安装额外的 agent 以适应额外的层次结构。
- 授权组的所有子组也可以访问同一个 agent(无需单独指定)。
- 您可以授权最多 500 个组。
进行这些更改后:
- 属于该组及其子组的所有项目现在都被授权访问 agent。
- 所有 CI/CD 作业现在都包含一个
kubeconfig文件,其中包含每个共享 agent 连接的上下文。 kubeconfig路径在$KUBECONFIG环境变量中可用。- 您可以从 CI/CD 脚本中选择上下文来运行
kubectl命令。
授权您的 GitLab 实例中的所有项目访问 agent
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed
先决条件:
- 您必须是管理员。
允许 agent 配置为授权您的 GitLab 实例中的所有项目:
- 在 Admin 区域,选择 设置 > 常规,然后展开 GitLab agent for Kubernetes 部分。
- 选择 启用实例级别授权。
- 选择 保存更改。
- 更新应用设置
organization_cluster_agent_authorization_enabled为true。
授权 agent 访问所有 GitLab 项目:
-
在左侧边栏,选择 搜索或跳转至 并找到包含 agent 配置文件 (
config.yaml) 的项目。 -
编辑
config.yaml文件。在ci_access关键字下,添加instance属性:ci_access: instance: {}
对 agent 配置文件进行这些更改后:
- 您实例中所有项目的所有 CI/CD 作业都被授权访问 agent。 您可以使用 CI/CD 作业身份模拟与 RBAC 结合来根据需要授予或限制访问。 有关更多信息,请参阅 使用身份模拟限制项目和组访问。
- 所有 CI/CD 作业都包含一个
kubeconfig文件,其中包含每个共享 agent 连接的上下文。 kubeconfig路径在$KUBECONFIG环境变量中可用。- 您可以从 CI/CD 脚本中选择上下文来运行
kubectl命令。
更新您的 .gitlab-ci.yml 文件以运行 kubectl 命令
在您要运行 Kubernetes 命令的项目中,编辑您项目的 .gitlab-ci.yml 文件。
在 script 关键字下的第一个命令中,设置您的 agent 上下文。
使用格式 <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如果您不确定 agent 的上下文是什么,请从您要访问 agent 的 CI/CD 作业中运行 kubectl config get-contexts。
使用 Auto DevOps 的环境
如果启用了 Auto DevOps,您必须定义 CI/CD 变量 KUBE_CONTEXT。
将 KUBE_CONTEXT 的值设置为您希望 Auto DevOps 使用的 agent 上下文:
deploy:
variables:
KUBE_CONTEXT: path/to/agent/project:agent-name您可以将不同的 agent 分配给单独的 Auto DevOps 作业。例如,
Auto DevOps 可以使用一个 agent 用于 staging 作业,另一个 agent 用于 production 作业。
要使用多个 agent,为每个 agent 定义一个 环境范围的 CI/CD 变量。
例如:
- 定义两个名为
KUBE_CONTEXT的变量。 - 对于第一个变量:
- 将
environment设置为staging。 - 将值设置为您的 staging agent 的上下文。
- 将
- 对于第二个变量:
- 将
environment设置为production。 - 将值设置为您的 production agent 的上下文。
- 将
同时使用证书连接和 agent 连接的环境
当您部署到同时具有 基于证书的集群(已弃用)和 agent 连接的环境时:
- 基于证书的集群的上下文称为
gitlab-deploy。此上下文 始终被默认选择。 - Agent 上下文包含在
$KUBECONFIG中。 您可以使用kubectl config use-context <path/to/agent/project>:<agent-name>来选择它们。
当存在基于证书的连接时使用 agent 连接,您可以手动配置新的 kubectl
配置上下文。例如:
deploy:
variables:
KUBE_CONTEXT: my-context # 新上下文使用的名称
AGENT_ID: 1234 # 替换为您的 agent 的数字 ID
K8S_PROXY_URL: https://<KAS_DOMAIN>/k8s-proxy/ # 对于在 Kubernetes 集群中部署的 agent 服务器(KAS);替换为您的 URL
# K8S_PROXY_URL: https://<GITLAB_DOMAIN>/-/kubernetes-agent/k8s-proxy/ # 对于 Omnibus 中的 agent 服务器(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,其中包含 PEM 格式的 KAS 证书。 - 使用
--certificate-authority=$KAS_CERTIFICATE配置 Kubernetes 客户端,其中KAS_CERTIFICATE是带有 KAS CA 证书的 CI/CD 变量。 - 通过更新容器镜像或通过 runner 挂载,将证书放置在作业容器中的适当位置。
- 不推荐。使用
--insecure-skip-tls-verify=true配置 Kubernetes 客户端。
使用身份模拟限制项目和组访问
- Tier: Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
默认情况下,您的 CI/CD 作业继承用于在集群中安装 agent 的服务帐户的所有权限。 要限制对集群的访问,您可以使用 身份模拟。
要指定身份模拟,请在您的 agent 配置文件中使用 access_as 属性,并使用 Kubernetes RBAC 规则来管理被模拟帐户的权限。
您可以模拟:
- Agent 本身(默认)。
- 访问集群的 CI/CD 作业。
- 在集群内定义的特定用户或系统帐户。
授权配置可能需要一到两分钟才能传播。
模拟 agent
默认情况下模拟 agent。您不需要执行任何操作来模拟它。
模拟访问集群的 CI/CD 作业
要模拟访问集群的 CI/CD 作业,在 access_as 键下,添加 ci_job: {} 键值。
当 agent 向实际的 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携带有关请求的额外信息。以下属性设置在被模拟的身份上:
| 属性 | 描述 |
|---|---|
agent.gitlab.com/id |
包含 agent ID。 |
agent.gitlab.com/config_project_id |
包含 agent 的配置项目 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(必需)uidgroupsextra
有关详细信息,请参阅 官方 Kubernetes 文档。
限制项目和组访问特定环境
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
默认情况下,如果您的 agent 对项目可用,该项目的所有 CI/CD 作业都可以使用该 agent。
要将 agent 的访问限制为仅具有特定环境的作业,将 environments 添加到 ci_access.projects 或 ci_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 作业都可以访问 agent。project-2中具有staging或review/*环境的 CI/CD 作业可以访问 agent。*是通配符,因此review/*匹配review下的所有环境。
group-1下项目的 CI/CD 作业,具有production环境的可以访问 agent。
将 agent 访问限制为受保护分支
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed, GitLab Dedicated
此功能的可用性由功能标志控制。 有关更多信息,请参阅历史记录。 此功能可用于测试,但尚未准备好用于生产环境。
要将 agent 访问限制为仅在 受保护分支 上运行的作业:
-
将
protected_branches_only: true添加到ci_access.projects或ci_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,agent 可以从未受保护和受保护的分支访问。
为了额外的安全性,您可以将此功能与 环境限制 结合使用。
如果项目有多个配置,仅使用最具体的配置。
例如,以下配置授予 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有关更多详细信息,请参阅 从 CI/CD 访问 Kubernetes。
相关主题
- 自定进度的课堂研讨会(使用 AWS EKS,但可用于其他 Kubernetes 集群)
- 配置 Auto DevOps
故障排除
向 ~/.kube/cache 授予写入权限
诸如 kubectl、Helm、kpt 和 kustomize 之类的工具将有关集群的信息缓存到 ~/.kube/cache 中。如果此目录不可写,该工具会在每次调用时获取信息,使交互变慢并在集群上造成不必要的负载。为了获得最佳体验,在您 .gitlab-ci.yml 文件中使用的镜像中,确保此目录可写。
启用 TLS
如果您使用 GitLab Self-Managed,请确保您的实例配置了传输层安全协议(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。