Kubernetes 클러스터와 GitLab CI/CD 사용하기

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

GitLab CI/CD를 사용하여 Kubernetes 클러스터를 안전하게 연결, 배포 및 업데이트할 수 있습니다.

이를 위해 클러스터에 에이전트를 설치합니다. 설치 후에 Kubernetes 컨텍스트가 생기며 GitLab CI/CD 파이프라인에서 Kubernetes API 명령을 실행할 수 있습니다.

클러스터 액세스가 안전하다는 것을 보장하기 위해:

  • 각 에이전트에는 별도의 컨텍스트(kubecontext)가 있습니다.
  • 에이전트가 구성된 프로젝트와 추가로 허용한 프로젝트만 클러스터의 에이전트에 액세스할 수 있습니다.

GitLab CI/CD를 사용하여 클러스터와 상호작용하려면 러너를 GitLab에 등록해야 합니다. 그러나 이러한 러너는 에이전트가 있는 클러스터에 있을 필요는 없습니다.

필수 조건:

클러스터와 함께 GitLab CI/CD 사용하기

GitLab CI/CD를 사용하여 Kubernetes 클러스터를 업데이트하려면:

  1. 작동하는 Kubernetes 클러스터가 있고 manifest 파일이 GitLab 프로젝트에 있는지 확인합니다.
  2. 동일한 GitLab 프로젝트에서 GitLab 에이전트를 등록 및 설치합니다.
  3. .gitlab-ci.yml 파일을 업데이트하여 에이전트의 Kubernetes 컨텍스트를 선택하고 Kubernetes API 명령을 실행합니다.
  4. 파이프라인을 실행하여 클러스터에 배포하거나 업데이트합니다.

여러 GitLab 프로젝트에 Kubernetes manifest가 포함되어 있는 경우:

  1. 자체 프로젝트나 Kubernetes manifest를 보관하는 GitLab 프로젝트 중 하나에 GitLab 에이전트를 설치합니다.
  2. 에이전트에 권한 부여하여 GitLab 프로젝트에 액세스합니다.
  3. 추가 보안을 위해 가장하려면 선택합니다.
  4. .gitlab-ci.yml 파일을 업데이트하여 에이전트의 Kubernetes 컨텍스트를 선택하고 Kubernetes API 명령을 실행합니다.
  5. 파이프라인을 실행하여 클러스터에 배포하거나 업데이트합니다.

에이전트 권한 부여

여러 GitLab 프로젝트를 보유하는 경우 에이전트에게 Kubernetes manifest를 보관하는 프로젝트에 액세스할 수 있도록 권한을 부여해야 합니다. 에이전트를 개별 프로젝트에 액세스할 수 있도록 권한을 부여하거나 그룹 또는 서브그룹에 권한을 부여할 수 있습니다. 추가 보안을 위해 가장하려면 선택할 수도 있습니다.

권한 구성이 전파되기까지 1~2분가량 소요될 수 있습니다.

에이전트가 프로젝트에 액세스하도록 권한 부여

Kubernetes manifest를 보관하는 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 명령을 실행할 컨텍스트를 선택합니다.

그룹 내 프로젝트에 액세스하도록 에이전트 권한 부여

그룹 또는 서브그룹의 모든 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 명령을 실행할 컨텍스트를 선택합니다.

.gitlab-ci.yml 파일을 업데이트하여 kubectl 명령 실행

Kubernetes 명령을 실행하기 위해 프로젝트에서 프로젝트의 .gitlab-ci.yml 파일을 편집합니다.

script 키워드 아래 첫 번째 명령에서 에이전트의 컨텍스트를 설정합니다. 형식은 <에이전트 프로젝트 경로>:<에이전트 이름>을 사용합니다. 예:

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

에이전트의 컨텍스트가 무엇인지 확실하지 않다면 터미널을 열고 클러스터에 연결합니다. kubectl config get-contexts 명령을 실행합니다.

Auto DevOps를 사용하는 환경

Auto DevOps가 활성화된 경우 CI/CD 변수 KUBE_CONTEXT를 정의해야 합니다. KUBE_CONTEXT의 값을 Auto DevOps에서 사용하고자 하는 에이전트의 컨텍스트로 설정하십시오:

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

여러 개의 Auto DevOps 작업에 별도의 에이전트를 할당할 수 있습니다. 예를 들어, Auto DevOps는 staging 작업에는 한 에이전트를 사용하고 production 작업에는 다른 에이전트를 사용할 수 있습니다. 여러 개의 에이전트를 사용하려면 각각의 에이전트에 대한 환경별 CI/CD 변수를 정의하십시오. 예를 들어:

  1. KUBE_CONTEXT라는 이름의 두 변수를 정의합니다.
  2. 첫 번째 변수에 대해:
    1. environmentstaging으로 설정합니다.
    2. 값을 스테이징 에이전트의 컨텍스트로 설정합니다.
  3. 두 번째 변수에 대해:
    1. environmentproduction으로 설정합니다.
    2. 값을 프로덕션 에이전트의 컨텍스트로 설정합니다.

인증 기반 및 에이전트 기반 연결을 사용하는 환경

인증 기반 클러스터(폐기됨) 및 에이전트 연결이 모두 있는 환경으로 배포하는 경우:

  • 인증 기반 클러스터의 컨텍스트는 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)용(깃랩닷컴의 경우 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를 사용하고 자체 서명 인증서를 사용하는 환경에서는 인증서 기관(CA)이 서명한 인증서를 Kubernetes 클라이언트에서 신뢰하도록 설정해야 합니다.

클라이언트를 구성하려면 다음 중 하나를 수행하십시오:

  • PEM 형식으로 KAS 인증서가 포함된 CI/CD 변수 SSL_CERT_FILE을 설정합니다.
  • Kubernetes 클라이언트를 --certificate-authority=$KAS_CERTIFICATE와 같이 구성합니다. 여기서 KAS_CERTIFICATE은 KAS의 CA 인증서가 있는 CI/CD 변수입니다.
  • 작업 컨테이너의 적절한 위치에 인증서를 배치하거나 이미지를 업데이트하거나 러너를 통해 마운트합니다.
  • 권장되지 않음. Kubernetes 클라이언트를 --insecure-skip-tls-verify=true와 같이 구성합니다.

거래자 및 그룹 접근 제한을 위해 표정화 사용

Tier: 프리미엄, 얼티메이트 Offering: GitLab.com, Self-managed, GitLab Dedicated
  • 기능_변경 GitLab 15.5에서 환경 계층을 위한 표정화 지원을 추가했습니다.

기본적으로 CI/CD 작업은 클러스터에 설치된 서비스 계정의 모든 권한을 상속합니다. 클러스터의 액세스를 제한하려면 표정화를 사용할 수 있습니다.

표정화를 지정하려면 에이전트 구성 파일에서 access_as 속성을 사용하고 Kubernetes RBAC 규칙을 사용하여 표정화된 계정 권한을 관리하십시오.

다음을 표정화할 수 있습니다:

  • 에이전트 자체(기본값).
  • 클러스터에 액세스하는 CI/CD 작업.
  • 클러스터 내에 정의된 특정 사용자 또는 시스템 계정.

권한 구성은 1~2분 정도 소요될 수 있습니다.

에이전트를 표정화

에이전트는 기본적으로 표정화됩니다. 표정화하기 위해 별도의 작업을 수행할 필요가 없습니다.

클러스터에 액세스하는 CI/CD 작업을 표정화

클러스터에 액세스하는 CI/CD 작업을 표정화하려면 access_as 키 아래에 ci_job: {} 키-값을 추가하십시오.

에이전트가 실제 Kubernetes API에 요청을 하는 경우, 표정화 자격 증명을 다음과 같이 설정합니다:

  • UserNamegitlab:ci_job:<job id>로 설정됩니다. 예: gitlab:ci_job:1074499489.
  • Groups는 다음을 설정합니다:

    • 모든 CI 작업에서 오는 모든 요청을 식별하기 위한 gitlab:ci_job.
    • 프로젝트가 속한 그룹들의 ID 목록.
    • 프로젝트 ID.
    • 이 작업이 속한 환경의 슬러그 및 티어.

      예: group1/group1-1/project1에서 실행되는 CI 작업의 경우:

      • 그룹 group1의 ID는 23입니다.
      • 그룹 group1/group1-1의 ID는 25입니다.
      • 프로젝트 group1/group1-1/project1의 ID는 150입니다.
      • production 환경 티어를 가진 prod 환경에서 실행되는 작업인 경우.

    그룹 목록은 [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 작업의 ID로 액세스를 제한하는 config.yaml 예제:

ci_access:
  projects:
    - id: path/to/project
      access_as:
        ci_job: {}
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: 그룹

정적 ID로 변장하기

특정 연결에 대해 변장을 위해 정적 ID를 사용할 수 있습니다.

access_as 키 아래에 제공된 ID를 사용하여 요청하는 impersonate 키를 추가하세요.

다음 키로 ID를 지정할 수 있습니다:

  • username (필수)
  • uid
  • groups
  • extra

자세한 내용은 공식 Kubernetes 문서를 참조하세요.

프로젝트 및 그룹 액세스를 특정 환경에 제한하는 방법

자세한 내용: Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

기본적으로, 에이전트가 프로젝트에 사용 가능한 경우, 프로젝트의 모든 CI/CD 작업이 해당 에이전트를 사용할 수 있습니다.

특정 환경을 가진 작업만 에이전트에 액세스하도록 제한하려면 ci_access.projects 또는 ci_access.groupsenvironments를 추가하세요. 예:

  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 작업이 에이전트에 액세스할 수 있습니다.
  • staging 또는 review/* 환경을 갖는 project-2의 CI/CD 작업이 에이전트에 액세스할 수 있습니다.
    • *는 와일드카드이므로 review/ 하위의 모든 환경과 일치합니다.
  • production 환경을 갖는 group-1의 프로젝트의 CI/CD 작업이 에이전트에 액세스할 수 있습니다.

에이전트 액세스를 보호된 브랜치로 제한하는 방법

자세한 내용: Tier: Free, Premium, Ultimate Offering: Self-managed, GitLab Dedicated

  • GitLab 17.3에서 소개되었으며 기본적으로 kubernetes_agent_protected_branches라는 플래그가 비활성화되어 있습니다.

플래그: 이 기능의 가용성은 플래그에 의해 제어됩니다. 자세한 내용은 히스토리를 참조하세요. 이 기능은 테스트용으로 제공되지만 프로덕션 환경에서는 사용할 수 없습니다.

에이전트 액세스를 보호된 브랜치에서 실행되는 작업에만 제한하려면:

  • ci_access.projects 또는 ci_access.groupsprotected_branches_only: true를 추가하세요. 예:

    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_onlyfalse로 설정되어 있으며, 보호되지 않은 브랜치 및 보호된 브랜치에서 에이전트에 액세스할 수 있습니다.

추가 보안을 위해 이 기능을 환경 제한과 함께 사용할 수 있습니다.

프로젝트에 여러 구성이 있는 경우, 가장 구체적인 구성만 사용됩니다. 예를 들어, 다음 구성은 example 그룹이 보호된 브랜치에만 액세스하도록 구성되었지만, example/my-project의 보호되지 않은 브랜치에 액세스할 수 있도록 허용합니다:

# .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에서 Kubernetes에 액세스를 참조하세요.

관련 주제

문제 해결

~/.kube/cache에 쓰기 권한 부여

kubectl, Helm, kpt, kustomize 등의 도구는 클러스터에 대한 정보를 ~/.kube/cache에 캐시합니다. 이 디렉토리에 쓰기 권한이 없으면 도구는 호출마다 정보를 검색하여 상호작용이 느려지고 클러스터에 불필요한 부하를 일으킵니다. 최상의 경험을 위해 .gitlab-ci.yml 파일에서 사용하는 이미지에서 이 디렉토리에 대한 쓰기 권한을 설정하세요.

TLS 활성화

자체 호스팅된 GitLab 인스턴스를 사용하는 경우, 인스턴스가 전송 계층 보안 (TLS)으로 구성되어 있는지 확인하세요.

TLS 없이 kubectl을 사용하려고 시도하면 다음과 같은 오류가 발생할 수 있습니다:

$ kubectl get pods
error: 서버에 로그인해야 합니다 (서버가 사용자에게 자격 증명을 제공하라고 요청함)

서명되지 않은 권한자에 의해 서명된 인증서

KAS와 자체 서명된 인증서를 사용하는 환경에서 kubectl 호출을 하면 다음과 같은 오류가 발생할 수 있습니다:

kubectl get pods
서버에 연결할 수 없음: x509: 알 수 없는 권한에 의해 서명된 인증서

이 오류는 작업이 KAS 인증서를 서명한 인증 기관 (CA)를 신뢰하지 않기 때문에 발생합니다.

이 문제를 해결하려면 서명자 CA를 신뢰하도록 kubectl을 구성하세요.

유효성 오류

kubectl 버전 v1.27.0 또는 v1.27.1을 사용하면 다음과 같은 오류가 발생할 수 있습니다:

error: "file.yml"의 유효성을 검증하는 중 오류 발생: 서버가 상태 코드 426로 응답했지만 더 많은 정보를 반환하지 않았습니다; 이 오류를 무시하려면 --validate=false로 유효성 검사를 끄세요

이 문제는 kubectl 및 Kubernetes 라이브러리를 공유하는 다른 도구에서 발생하는 버그로 인해 발생합니다.

이 문제를 해결하려면 다른 버전의 kubectl을 사용하세요. ```