极狐GitLab CI/CD 与 Kubernetes 集群一起使用
- 引入于 14.1 版本。
- 预配置的
KUBECONFIG
引入于 14.2 版本。ci_access
属性引入于 14.3 版本。- 授权群组的能力引入于 14.3 版本。
- 移动到免费版于 14.5 版本。
- 对 Omnibus 安装实例的支持引入于 14.5 版本。
- 在基于证书的集群和代理之间切换的能力引入于 14.9 版本。基于证书的集群上下文始终称为
gitlab-deploy
。
您可以使用极狐GitLab CI/CD 工作流安全地部署到和更新您的 Kubernetes 集群。
为此,您必须首先在集群中安装代理。完成后,您将拥有 Kubernetes 上下文,并且可以在极狐GitLab CI/CD 流水线中运行 Kubernetes API 命令。
为确保对集群的访问安全:
- 每个代理都有一个单独的上下文(
kubecontext
)。 - 只有配置了代理的项目,以及您授权的任何其它项目,才能访问集群中的代理。
您不需要在具有代理的集群中拥有 runner。
极狐GitLab CI/CD 工作流步骤
要使用极狐GitLab CI/CD 更新 Kubernetes 集群,请完成以下步骤。
- 确保您有一个正常工作的 Kubernetes 集群,并且 manifests 位于极狐GitLab 项目中。
- 在同一个极狐GitLab 项目中,注册并安装极狐GitLab 代理。
-
更新您的
.gitlab-ci.yml
文件,选择代理的 Kubernetes 上下文并运行 Kubernetes API 命令。 - 运行您的流水线,部署或更新集群。
如果您有多个包含 Kubernetes manifests 的极狐GitLab 项目:
- 在其自己的项目中安装极狐GitLab 代理,或在您保留 Kubernetes manifests 的项目之一中。
- 授权代理访问您的极狐GitLab 项目。
- 可选。为了增加安全性,使用模拟。
-
更新您的
.gitlab-ci.yml
文件,选择代理的 Kubernetes 上下文并运行 Kubernetes API 命令。 - 运行您的流水线,部署或更新集群。
授权代理
如果您有多个极狐GitLab 项目,您必须授权代理访问您保存 Kubernetes manifests 的项目。 您可以授权代理访问单个项目,或授权一个群组或子组,以便其中的所有项目都具有访问权限。为了增加安全性,您还可以使用模拟。
授权配置可能需要一到两分钟才能传播。
授权代理访问您的项目
引入于 14.4 版本。
要授权代理访问您保存 Kubernetes manifests 的极狐GitLab 项目:
- 在顶部栏,选择 主菜单 > 项目 并找到包含代理配置文件(
config.yaml
)的项目。 - 编辑
config.yaml
文件。 在ci_access
关键字下,添加projects
属性。 -
对于
id
,添加路径:ci_access: projects: - id: path/to/project
- Kubernetes 项目必须与代理配置所在的项目位于同一群组层次结构中。
- 您可以将其它代理安装到同一集群中,来适应其它层次结构。
- 您最多可以授权 100 个项目。
现在,所有 CI/CD 作业都包含一个 kubeconfig
文件,其中包含每个共享代理连接的上下文。
kubeconfig
路径在环境变量 $KUBECONFIG
中可用。
从 CI/CD 脚本中选择运行 kubectl
命令的上下文。
授权代理访问您群组中的项目
引入于 14.3 版本。
要授权代理访问群组或子组中的所有极狐GitLab 项目:
- 在顶部栏,选择 主菜单 > 项目 并找到包含代理配置文件(
config.yaml
)的项目。 - 编辑
config.yaml
文件。在ci_access
关键字下,添加groups
属性。 -
对于
id
,添加路径:ci_access: groups: - id: path/to/group/subgroup
- Kubernetes 项目必须与代理配置所在的项目位于同一群组层次结构中。
- 您可以将其它代理安装到同一集群中,来适应其它层次结构。
- 授权群组的所有子组也可以访问同一代理(无需单独指定)。
- 您最多可以授权 100 个群组。
属于该群组及其子组的所有项目现在都有权访问该代理。
现在,所有 CI/CD 作业都包含一个 kubeconfig
文件,其中包含每个共享代理连接的上下文。
kubeconfig
路径在环境变量 $KUBECONFIG
中可用。
从 CI/CD 脚本中选择运行 kubectl
命令的上下文。
更新 .gitlab-ci.yml
文件以运行 kubectl
命令
在要运行 Kubernetes 命令的项目中,编辑项目的 .gitlab-ci.yml
文件。
在 script
关键字下的第一个命令中,设置代理的上下文。
使用 path/to/agent/repository:agent-name
格式。例如:
deploy:
image:
name: bitnami/kubectl:latest
entrypoint: ['']
script:
- kubectl config get-contexts
- kubectl config use-context path/to/agent/repository:agent-name
- kubectl get pods
如果您不确定代理的上下文是什么,请打开一个终端并连接到您的集群。
运行 kubectl config get-contexts
。
具有基于证书和基于代理的连接的环境
当您部署到同时具有基于证书的集群(已弃用)和代理连接的环境时:
- 基于证书的集群的上下文称为
gitlab-deploy
。默认情况下始终选择此上下文。 - 在 14.9 及更高版本中,代理上下文包含在
KUBECONFIG
中。您可以使用kubectl config use-context path/to/agent/repository:agent-name
来选择它们。 - 在 14.8 及更早版本中,您仍然可以使用代理连接,但对于已经具有基于证书的集群的环境,代理连接不包含在
KUBECONFIG
中。
要在存在基于证书的连接时使用代理连接,您可以手动配置新的 kubectl
配置上下文。例如:
deploy:
variables:
KUBE_CONTEXT: my-context # The name to use for the new context
AGENT_ID: 1234 # replace with your agent's numeric ID
K8S_PROXY_URL: https://<KAS_DOMAIN>/k8s-proxy/ # For agent server (KAS) deployed in Kubernetes cluster (for gitlab.com use kas.gitlab.com); replace with your URL
# K8S_PROXY_URL: https://<GITLAB_DOMAIN>/-/kubernetes-agent/k8s-proxy/ # For agent server (KAS) in Omnibus
# ... any other variables you have configured
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"
# ... rest of your job configuration
将代理与 Auto DevOps 结合使用
如果启用了 Auto DevOps,则必须定义 KUBE_CONTEXT
CI/CD 变量。将 KUBE_CONTEXT
的值设置为您要在 Auto DevOps 流水线作业中使用的代理的上下文 (<PATH_TO_AGENT_CONFIG_REPOSITORY>:<AGENT_NAME>
)。
您还可以为不同的 Auto DevOps 作业使用不同的代理。例如,您可以将一个代理用于 staging
作业,而将另一个代理用于 production
作业。要使用多个代理,请为每个代理定义一个唯一的 CI/CD 变量。
例如:
- 添加两个环境范围的 CI/CD 变量,并将两者命名为
KUBE_CONTEXT
。 - 将第一个变量的
environment
设置为staging
。将变量的值设置为<PATH_TO_AGENT_CONFIGURATION_PROJECT>:<STAGING_AGENT_NAME>
。 - 将第二个变量的
environment
设置为production
。将变量的值设置为<PATH_TO_AGENT_CONFIGURATION_PROJECT>:<PRODUCTION_AGENT_NAME>
。
当 staging
作业运行时,它将通过名为 <STAGING_AGENT_NAME>
的代理连接到集群,当 production
作业运行时,它将通过名为 <PRODUCTION_AGENT_NAME>
的代理连接到集群。
具有使用自签名证书的 KAS 的环境
如果您使用具有 KAS 和自签名证书的环境,则必须将 Kubernetes 客户端配置为信任为您的证书签名的证书颁发机构 (CA)。
要配置您的客户端,请执行以下操作之一:
- 使用 PEM 格式的 KAS 证书设置 CI/CD 变量
SSL_CERT_FILE
。 - 使用
--certificate-authority=$KAS_CERTIFICATE
配置 Kubernetes 客户端,其中KAS_CERTIFICATE
是带有 KAS CA 证书的 CI/CD 变量。 - 通过更新容器镜像或通过 runner 安装,将证书放置在作业容器中的适当位置。
- (不建议)使用
--insecure-skip-tls-verify=true
配置 Kubernetes 客户端。
使用模拟限制项目和群组访问
引入于 14.5 版本。
默认情况下,您的 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 和级别。
示例:对于
group 1/group 1-1/project 1
中的 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
| 包含代理的 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
| 包含环境的别名。只有在环境中运行时才设置。 |
agent.gitlab.com/environment_tier
| 包含环境级别。只有在环境中运行时才设置。 |
通过 CI/CD 作业的身份限制访问的示例 config.yaml
:
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
详见 Kubernetes 官方文档。
故障排除
不支持 kubectl
命令
不支持命令 kubectl exec
、kubectl cp
、kubectl attach
、kubectl run --attach=true
和 kubectl port-forward
。
任何使用了这些 API 端点的都不起作用,因为它们使用了已弃用的 SPDY 协议。
授予对 ~/.kube/cache
的写入权限
kubectl
、Helm、kpt
和 kustomize
等工具会在 ~/.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 库的工具的 bug 引起的。
要解决此问题,请使用另一个版本的 kubectl
。