Help us learn about your current experience with the documentation. Take the survey.

开始部署到 Kubernetes

本页面介绍如何使用 GitLab 支持的方法部署到 Kubernetes。 阅读完成后,您将了解:

  • 如何使用 Flux 进行部署
  • 如何从 GitLab CI/CD 管道对集群执行部署或命令操作
  • 如何结合使用 Flux 和 GitLab CI/CD 以获得最佳效果

开始之前

本教程基于您在开始将 Kubernetes 集群连接到 GitLab中创建的项目。您将使用在该教程中创建的相同项目。但是,您也可以使用任何已连接 Kubernetes 集群并引导安装了 Flux 的项目。

从 GitLab CI/CD 对集群执行命令

Kubernetes 代理与 GitLab CI/CD 管道集成。您可以使用 CI/CD 以安全且可扩展的方式对集群执行 kubectl applyhelm upgrade 等命令。

在本节中,您将使用 GitLab 管道集成在集群中创建一个 secret,并使用它来访问 GitLab 容器注册表。本教程的其余部分将使用已部署的 secret。

  1. 使用 read_registry 范围创建一个部署令牌

  2. 将您的部署令牌和用户名保存为名为 CONTAINER_REGISTRY_ACCESS_TOKENCONTAINER_REGISTRY_ACCESS_USERNAME 的 CI/CD 变量。

    • 对于这两个变量,将环境设置为 container-registry-secret*
    • 对于 CONTAINER_REGISTRY_ACCESS_TOKEN
  3. 将以下代码段添加到您的 .gitlab-ci.yml 文件中,并更新两个 AGENT_KUBECONTEXT 变量以匹配您的项目路径:

    stages:
    - setup
    - deploy
    - stop
    
    create-registry-secret:
      stage: setup
      image: "portainer/kubectl-shell:latest"
      variables:
        AGENT_KUBECONTEXT: my-group/optional-subgroup/my-repository:testing
      before_script:
        # The available agents are automatically injected into the runner environment
        # We need to select the agent to use
        - kubectl config use-context $AGENT_KUBECONTEXT
      script:
        - kubectl delete secret gitlab-registry-auth -n flux-system --ignore-not-found
        - kubectl create secret docker-registry gitlab-registry-auth -n flux-system
          --docker-password="${CONTAINER_REGISTRY_ACCESS_TOKEN}" --docker-username="${CONTAINER_REGISTRY_ACCESS_USERNAME}" --docker-server="${CI_REGISTRY}"
      environment:
        name: container-registry-secret
        on_stop: delete-registry-secret
    
    delete-registry-secret:
      stage: stop
      image: ""
      variables:
        AGENT_KUBECONTEXT: my-group/optional-subgroup/my-repository:testing
      before_script:
        # The available agents are automatically injected into the runner environment
        # We need to select the agent to use
        - kubectl config use-context $AGENT_KUBECONTEXT
      script:
        - kubectl delete secret -n flux-system gitlab-registry-auth
      environment:
        name: container-registry-secret
        action: stop
      when: manual

继续之前,请考虑如何使用 CI/CD 运行其他命令。

将简单清单构建为 OCI 镜像并部署到集群

对于生产用例,最佳实践是使用 OCI 仓库作为 Git 仓库和 FluxCD 之间的缓存层。 FluxCD 检查 OCI 仓库中的新镜像,而 GitLab 管道构建符合 Flux 的 OCI 镜像。 要了解企业最佳实践的更多信息,请参阅企业注意事项

在本节中,您将构建一个简单的 Kubernetes 清单作为 OCI 工件,然后将其部署到您的集群。

  1. 运行以下 flux CLI 命令,告诉 Flux 从何处检索指定的 OCI 镜像并部署其内容。 根据您的 GitLab 实例调整 --url 值。您可以在 Deploy > Container registry 下找到容器注册表 URL。 您可以检查创建的 clusters/testing/nginx.yaml 文件,以更好地理解 Flux 如何查找要部署的清单。

    flux create source oci nginx-example \
     --url oci://registry.gitlab.example.org/my-group/optional-subgroup/my-repository/nginx-example \
     --tag latest \
     --secret-ref gitlab-registry-auth \
     --interval 1m \
     --namespace flux-system \
     --export > clusters/testing/nginx.yaml
     flux create kustomization nginx-example \
     --source OCIRepository/nginx-example \
     --path "." \
     --prune true \
     --target-namespace default \
     --interval 1m \
     --namespace flux-system \
     --export >> clusters/testing/nginx.yaml
  2. 我们将以 NGINX 为例进行部署。将以下 YAML 添加到 clusters/applications/nginx/nginx.yaml

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: nginx-example
       namespace: default
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: nginx-example
       template:
         metadata:
           labels:
             app: nginx-example
         spec:
           containers:
             - name: nginx
               image: nginx:1.25
               ports:
                 - containerPort: 80
                   protocol: TCP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: nginx-example
       namespace: default
     spec:
       ports:
         - port: 80
           targetPort: 80
           protocol: TCP
       selector:
         app: nginx-example
  3. 现在,让我们将前面的 YAML 打包为 OCI 镜像。 使用以下代码段扩展您的 .gitlab-ci.yml 文件,并再次更新 AGENT_KUBECONTEXT 变量:

     nginx-deployment:
         stage: deploy
         variables:
             IMAGE_NAME: nginx-example   # Image name to push
             IMAGE_TAG: latest
             MANIFEST_PATH: "./clusters/applications/nginx"
             IMAGE_TITLE: NGINX example   # Image title to use in OCI annotation
             AGENT_KUBECONTEXT: my-group/optional-subgroup/my-repository:testing
             FLUX_OCI_REPO_NAME: nginx-example  # Flux OCIRepository to reconcile
             NAMESPACE: flux-system  # Namespace for the OCIRepository resource
         # This section configures a GitLab environment for the nginx deployment specifically
         environment:
             name: applications/nginx
             kubernetes:
                 agent: $AGENT_KUBECONTEXT
                 namespace: default
                 flux_resource_path: kustomize.toolkit.fluxcd.io/v1/namespaces/flux-system/kustomizations/nginx-example  # We will deploy this resource in the next step
         image:
             name: "fluxcd/flux-cli:v2.4.0"
             entrypoint: [""]
         before_script:
             - kubectl config use-context $AGENT_KUBECONTEXT
         script:
             # This line builds and pushes the OCI container to the GitLab container registry.
             # You can read more about this command in https://fluxcd.io/flux/cmd/flux_push_artifact/
             - flux push artifact oci://${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}
                 --source="${CI_REPOSITORY_URL}"
                 --path="${MANIFEST_PATH}"
                 --revision="${CI_COMMIT_SHORT_SHA}"
                 --creds="${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}"
                 --annotations="org.opencontainers.image.url=${CI_PROJECT_URL}"
                 --annotations="org.opencontainers.image.title=${IMAGE_TITLE}"
                 --annotations="com.gitlab.job.id=${CI_JOB_ID}"
                 --annotations="com.gitlab.job.url=${CI_JOB_URL}"
             # This line triggers an immediate reconciliation of the resource. Otherwise Flux would reconcile following its configured reconciliation period.
             # You can read more about the various reconcile commands in https://fluxcd.io/flux/cmd/flux_reconcile/
             - flux reconcile source oci -n ${NAMESPACE} ${FLUX_OCI_REPO_NAME}
  4. 提交并推送更改到您的项目,然后等待构建管道完成。

  5. 在左侧边栏,选择 Operate > Environments 并检查可用的 Kubernetes 仪表板applications/nginx 环境应该是健康的。

保护 GitLab 管道访问权限

  • Tier: Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

之前部署的代理使用 .gitlab/agents/testing/config.yaml 文件进行配置。 默认情况下,该配置启用了对运行 GitLab 管道的项目中配置的集群的访问。 默认情况下,此访问使用已部署代理的服务账户来对集群执行命令。 可以通过将访问权限限制为静态服务账户身份,或使用 CI/CD 作业作为集群中的身份来限制此访问。 最后,可以使用常规的 Kubernetes RBAC 来限制 CI/CD 作业在集群中的访问权限。

在本节中,我们将通过为每个 CI/CD 作业添加身份并在集群中模拟该作业来限制 CI/CD 访问。

  1. 要配置 CI/CD 作业模拟,请编辑 .gitlab/agents/testing/config.yaml 文件,并向其中添加以下代码段(替换 path/to/project):

    ci_access:
       projects:
          - id: my-group/optional-subgroup/my-repository
            access_as:
               ci_job: {}
  2. 由于 CI/CD 作业还没有任何集群绑定,我们无法从 GitLab CI/CD 运行任何 Kubernetes 命令。 让我们启用 CI/CD 作业在 flux-system 命名空间中创建 Secret 对象。 使用以下内容创建 clusters/testing/gitlab-ci-job-secret-write.yaml 文件:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
       name: secret-manager
       namespace: default
    rules:
       - apiGroups: [""]
         resources: ["secrets"]
         verbs: ["create", "delete"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
       name: gitlab-ci-secrets-binding
       namespace: default
    subjects:
       - kind: Group
         name: gitlab:ci_job
         apiGroup: rbac.authorization.k8s.io
    roleRef:
       kind: Role
       name: secret-manager
       apiGroup: rbac.authorization.k8s.io
  3. 让我们启用 CI/CD 作业来触发 FluxCD 协调。 使用以下内容创建 clusters/testing/gitlab-ci-job-flux-reconciler.yaml 文件:

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

有关 CI/CD 访问的更多信息,请参阅将 GitLab CI/CD 与 Kubernetes 集群一起使用

清理资源

最后,让我们删除已部署的资源并删除用于访问容器注册表的 secret:

  1. 删除 clusters/testing/nginx.yaml 文件。 Flux 将负责从集群中删除相关资源。
  2. 停止 container-registry-secret 环境。 停止环境将触发其 on_stop 作业,从集群中删除 secret。

下一步

您可以使用本教程中的技术在多个项目中扩展部署。OCI 镜像可以在不同的项目中构建,只要 Flux 指向正确的注册表,Flux 就会检索它。这个练习留给读者完成。

为了获得更多实践,尝试将原始的 Flux GitRepository(在 /clusters/testing/flux-system/gotk-sync.yaml 中)更改为 OCIRepository

最后,请参阅以下资源以获取有关 Flux 和 GitLab 与 Kubernetes 集成的更多信息: