InfoGrab DocsInfoGrab Docs

쿠버네티스 통합 개발 가이드라인

요약

이 문서는 GitLab 쿠버네티스 통합 개발 시 다양한 가이드라인을 제공합니다. 제한된 프로젝트 네임스페이스 생성과 같은 일부 쿠버네티스 작업은 GitLab Rails 애플리케이션에서 수행됩니다. 클러스터 애플리케이션 설치와 같은 일부 쿠버네티스 작업은 쿠버네티스 클러스터 자체의 일회성 Pod에서 수행됩니다.

이 문서는 GitLab 쿠버네티스 통합 개발 시 다양한 가이드라인을 제공합니다.

개발#

아키텍처#

제한된 프로젝트 네임스페이스 생성과 같은 일부 쿠버네티스 작업은 GitLab Rails 애플리케이션에서 수행됩니다. 이러한 작업은 클라이언트 라이브러리를 사용하여 수행되며, 일정 수준의 위험 요소를 수반합니다. 해당 작업은 GitLab Rails 애플리케이션을 실행하는 것과 동일한 사용자로 실행됩니다. 자세한 내용은 아래 보안 섹션을 참조하세요.

클러스터 애플리케이션 설치와 같은 일부 쿠버네티스 작업은 쿠버네티스 클러스터 자체의 일회성 Pod에서 수행됩니다. 이러한 설치 Pod는 install-<application_name>으로 명명되며, gitlab-managed-apps 네임스페이스 내에 생성됩니다.

코드 구성 측면에서, 쿠버네티스 리소스를 나타내는 객체는 일반적으로 lib/gitlab/kubernetes에 추가합니다.

클라이언트 라이브러리#

쿠버네티스 API 호출을 수행하기 위해 kubeclient gem을 사용합니다. kubeclient gem은 단일 클라이언트에서 다른 API 그룹(예: apis/rbac.authorization.k8s.io)을 지원하지 않으므로, 이를 가능하게 하는 래퍼 클래스인 Gitlab::Kubernetes::KubeClient를 생성했습니다.

선택된 쿠버네티스 API 그룹이 지원됩니다. 새로운 API 그룹 또는 메서드를 사용해야 하는 경우, Gitlab::Kubernetes::KubeClient에 해당 API 그룹 또는 메서드 지원을 추가하세요. 새로운 API 그룹 또는 API 그룹 버전은 SUPPORTED_API_GROUPS에 추가할 수 있으며, 내부적으로 해당 그룹에 대한 내부 클라이언트가 생성됩니다. 새로운 메서드는 관련 내부 클라이언트에 대한 위임으로 추가할 수 있습니다.

성능 고려 사항#

쿠버네티스 API에 대한 모든 호출은 백그라운드 프로세스에서 수행되어야 합니다. 웹 요청 내에서 쿠버네티스 API 호출을 수행하지 마세요. 이는 웹 서버를 차단하며, 쿠버네티스 클러스터의 응답 시간이 우리의 통제 범위를 벗어나기 때문에 GitLab에서 서비스 거부(DoS) 공격으로 이어질 수 있습니다.

호출이 백그라운드 프로세스에서 수행되도록 하는 가장 쉬운 방법은 Sidekiq 워커에서 해당 작업이 수행되도록 위임하는 것입니다.

쿠버네티스를 호출하고 응답을 반환하고 싶지만 백그라운드 워커가 적합하지 않은 경우, reactive caching 사용을 고려하세요. 예시:

  def calculate_reactive_cache!
    { pods: cluster.platform_kubernetes.kubeclient.get_pods }
  end

  def pods
    with_reactive_cache do |data|
      data[:pods]
    end
  end

테스트#

KubernetesHelpers에 WebMock 스텁이 있으며, 이를 통해 테스트에서 쿠버네티스 API 호출을 모킹할 수 있습니다.

Amazon EKS 통합#

이 섹션에서는 GitLab 인스턴스가 EKS 클러스터를 생성할 수 있도록 허용하는 프로세스를 설명합니다.

다음 사전 요구 사항이 필요합니다:

Customer AWS 계정. EKS 클러스터는 이 계정에 생성됩니다. 다음 리소스가 있어야 합니다:

  • 클러스터 및 관련 리소스를 생성할 권한이 있는 프로비저닝 권한(role). 이 권한(role)은 GitLab AWS 계정을 신뢰할 수 있는 엔티티로 나열해야 합니다.

  • 클러스터에서 사용할 VPC, 관리 권한(role), 보안 그룹, 서브넷.

GitLab AWS 계정. 이는 프로비저닝 작업을 수행하는 계정입니다. 다음 리소스가 있어야 합니다:

  • 위의 Customer 계정에서 프로비저닝 권한(role)을 맡을 권한이 있는 서비스 계정.

  • gitlab.ymlkubernetes 섹션을 통해 GitLab에 구성된 이 서비스 계정의 자격 증명.

클러스터 생성 프로세스는 다음과 같습니다:

  • :provision_role_external_id를 사용하여 GitLab이 :provision_role_arn에서 제공한 권한(role)을 맡고, 공급자 레코드에 임시 자격 증명 세트를 저장합니다. 기본적으로 이 자격 증명은 1시간 동안 유효합니다.

  • AWS CloudFormation EKS 템플릿을 기반으로 CloudFormation 스택이 생성됩니다. 이를 통해 EKS 클러스터에 필요한 모든 리소스 생성이 트리거됩니다.

  • GitLab은 모든 리소스가 준비될 때까지 스택 상태를 폴링하며, 대부분의 경우 10~15분 정도 소요됩니다.

  • 스택이 준비되면 GitLab은 클러스터 세부 정보를 저장하고, 이번에는 kubeclient를 통해 클러스터에 연결할 수 있도록 또 다른 임시 자격 증명 세트를 생성합니다. 이 자격 증명은 1분 동안 유효합니다.

  • GitLab은 워커 노드가 클러스터에 인증할 수 있도록 구성하고, 향후 작업을 위해 자체 서비스 계정을 생성합니다.

  • 더 이상 필요하지 않은 자격 증명은 제거됩니다. 다음 속성이 삭제됩니다:

    access_key_id

    • secret_access_key

    • session_token

보안#

서버 사이드 요청 위조(SSRF) 공격#

쿠버네티스 클러스터의 URL은 사용자가 제어하므로 서버 사이드 요청 위조(Server Side Request Forgery, SSRF) 공격에 쉽게 노출될 수 있습니다. 클러스터에 API 호출을 추가하는 경우 완화 전략을 이해해야 합니다.

완화 전략은 다음과 같습니다:

  • 공격자가 제어하는 리소스로의 리다이렉트 허용하지 않기: Kubeclient::KubeClienthttp_max_redirects: 0 옵션을 전달하여 모든 리다이렉트를 방지하도록 구성할 수 있습니다.

  • 에러 메시지 노출하지 않기: 이를 통해 공격자가 에러를 트리거하여 공격자가 제어하는 요청의 결과가 노출되는 것을 방지합니다. 예를 들어, 원시 에러 메시지를 노출하거나 저장하지 않습니다:

rescue Kubernetes::HttpError => e
  # bad
  # app.make_errored!("Kubernetes error: #{e.message}")

  # good
  app.make_errored!("Kubernetes error: #{e.error_code}")

쿠버네티스 통합 디버깅#

쿠버네티스 통합과 관련된 로그는 kubernetes.log에서 확인할 수 있습니다. 로컬 GDK 설치에서는 이 로그가 log/kubernetes.log에 있습니다.

설치와 관련된 문제를 디버깅하기 위해 설치 로그를 팔로우할 수도 있습니다. 설치/업그레이드가 진행 중이면 Pod가 생성될 때까지 기다리세요. 그런 다음 다음 명령을 실행하여 Pod 로그를 실시간으로 확인합니다:

kubectl logs <pod_name> --follow -n gitlab-managed-apps

쿠버네티스 통합 개발 가이드라인

GitLab v19.1
원문 보기
요약

이 문서는 GitLab 쿠버네티스 통합 개발 시 다양한 가이드라인을 제공합니다. 제한된 프로젝트 네임스페이스 생성과 같은 일부 쿠버네티스 작업은 GitLab Rails 애플리케이션에서 수행됩니다. 클러스터 애플리케이션 설치와 같은 일부 쿠버네티스 작업은 쿠버네티스 클러스터 자체의 일회성 Pod에서 수행됩니다.

이 문서는 GitLab 쿠버네티스 통합 개발 시 다양한 가이드라인을 제공합니다.

개발#

아키텍처#

제한된 프로젝트 네임스페이스 생성과 같은 일부 쿠버네티스 작업은 GitLab Rails 애플리케이션에서 수행됩니다. 이러한 작업은 클라이언트 라이브러리를 사용하여 수행되며, 일정 수준의 위험 요소를 수반합니다. 해당 작업은 GitLab Rails 애플리케이션을 실행하는 것과 동일한 사용자로 실행됩니다. 자세한 내용은 아래 보안 섹션을 참조하세요.

클러스터 애플리케이션 설치와 같은 일부 쿠버네티스 작업은 쿠버네티스 클러스터 자체의 일회성 Pod에서 수행됩니다. 이러한 설치 Pod는 install-<application_name>으로 명명되며, gitlab-managed-apps 네임스페이스 내에 생성됩니다.

코드 구성 측면에서, 쿠버네티스 리소스를 나타내는 객체는 일반적으로 lib/gitlab/kubernetes에 추가합니다.

클라이언트 라이브러리#

쿠버네티스 API 호출을 수행하기 위해 kubeclient gem을 사용합니다. kubeclient gem은 단일 클라이언트에서 다른 API 그룹(예: apis/rbac.authorization.k8s.io)을 지원하지 않으므로, 이를 가능하게 하는 래퍼 클래스인 Gitlab::Kubernetes::KubeClient를 생성했습니다.

선택된 쿠버네티스 API 그룹이 지원됩니다. 새로운 API 그룹 또는 메서드를 사용해야 하는 경우, Gitlab::Kubernetes::KubeClient에 해당 API 그룹 또는 메서드 지원을 추가하세요. 새로운 API 그룹 또는 API 그룹 버전은 SUPPORTED_API_GROUPS에 추가할 수 있으며, 내부적으로 해당 그룹에 대한 내부 클라이언트가 생성됩니다. 새로운 메서드는 관련 내부 클라이언트에 대한 위임으로 추가할 수 있습니다.

성능 고려 사항#

쿠버네티스 API에 대한 모든 호출은 백그라운드 프로세스에서 수행되어야 합니다. 웹 요청 내에서 쿠버네티스 API 호출을 수행하지 마세요. 이는 웹 서버를 차단하며, 쿠버네티스 클러스터의 응답 시간이 우리의 통제 범위를 벗어나기 때문에 GitLab에서 서비스 거부(DoS) 공격으로 이어질 수 있습니다.

호출이 백그라운드 프로세스에서 수행되도록 하는 가장 쉬운 방법은 Sidekiq 워커에서 해당 작업이 수행되도록 위임하는 것입니다.

쿠버네티스를 호출하고 응답을 반환하고 싶지만 백그라운드 워커가 적합하지 않은 경우, reactive caching 사용을 고려하세요. 예시:

  def calculate_reactive_cache!
    { pods: cluster.platform_kubernetes.kubeclient.get_pods }
  end

  def pods
    with_reactive_cache do |data|
      data[:pods]
    end
  end

테스트#

KubernetesHelpers에 WebMock 스텁이 있으며, 이를 통해 테스트에서 쿠버네티스 API 호출을 모킹할 수 있습니다.

Amazon EKS 통합#

이 섹션에서는 GitLab 인스턴스가 EKS 클러스터를 생성할 수 있도록 허용하는 프로세스를 설명합니다.

다음 사전 요구 사항이 필요합니다:

Customer AWS 계정. EKS 클러스터는 이 계정에 생성됩니다. 다음 리소스가 있어야 합니다:

  • 클러스터 및 관련 리소스를 생성할 권한이 있는 프로비저닝 권한(role). 이 권한(role)은 GitLab AWS 계정을 신뢰할 수 있는 엔티티로 나열해야 합니다.

  • 클러스터에서 사용할 VPC, 관리 권한(role), 보안 그룹, 서브넷.

GitLab AWS 계정. 이는 프로비저닝 작업을 수행하는 계정입니다. 다음 리소스가 있어야 합니다:

  • 위의 Customer 계정에서 프로비저닝 권한(role)을 맡을 권한이 있는 서비스 계정.

  • gitlab.ymlkubernetes 섹션을 통해 GitLab에 구성된 이 서비스 계정의 자격 증명.

클러스터 생성 프로세스는 다음과 같습니다:

  • :provision_role_external_id를 사용하여 GitLab이 :provision_role_arn에서 제공한 권한(role)을 맡고, 공급자 레코드에 임시 자격 증명 세트를 저장합니다. 기본적으로 이 자격 증명은 1시간 동안 유효합니다.

  • AWS CloudFormation EKS 템플릿을 기반으로 CloudFormation 스택이 생성됩니다. 이를 통해 EKS 클러스터에 필요한 모든 리소스 생성이 트리거됩니다.

  • GitLab은 모든 리소스가 준비될 때까지 스택 상태를 폴링하며, 대부분의 경우 10~15분 정도 소요됩니다.

  • 스택이 준비되면 GitLab은 클러스터 세부 정보를 저장하고, 이번에는 kubeclient를 통해 클러스터에 연결할 수 있도록 또 다른 임시 자격 증명 세트를 생성합니다. 이 자격 증명은 1분 동안 유효합니다.

  • GitLab은 워커 노드가 클러스터에 인증할 수 있도록 구성하고, 향후 작업을 위해 자체 서비스 계정을 생성합니다.

  • 더 이상 필요하지 않은 자격 증명은 제거됩니다. 다음 속성이 삭제됩니다:

    access_key_id

    • secret_access_key

    • session_token

보안#

서버 사이드 요청 위조(SSRF) 공격#

쿠버네티스 클러스터의 URL은 사용자가 제어하므로 서버 사이드 요청 위조(Server Side Request Forgery, SSRF) 공격에 쉽게 노출될 수 있습니다. 클러스터에 API 호출을 추가하는 경우 완화 전략을 이해해야 합니다.

완화 전략은 다음과 같습니다:

  • 공격자가 제어하는 리소스로의 리다이렉트 허용하지 않기: Kubeclient::KubeClienthttp_max_redirects: 0 옵션을 전달하여 모든 리다이렉트를 방지하도록 구성할 수 있습니다.

  • 에러 메시지 노출하지 않기: 이를 통해 공격자가 에러를 트리거하여 공격자가 제어하는 요청의 결과가 노출되는 것을 방지합니다. 예를 들어, 원시 에러 메시지를 노출하거나 저장하지 않습니다:

rescue Kubernetes::HttpError => e
  # bad
  # app.make_errored!("Kubernetes error: #{e.message}")

  # good
  app.make_errored!("Kubernetes error: #{e.error_code}")

쿠버네티스 통합 디버깅#

쿠버네티스 통합과 관련된 로그는 kubernetes.log에서 확인할 수 있습니다. 로컬 GDK 설치에서는 이 로그가 log/kubernetes.log에 있습니다.

설치와 관련된 문제를 디버깅하기 위해 설치 로그를 팔로우할 수도 있습니다. 설치/업그레이드가 진행 중이면 Pod가 생성될 때까지 기다리세요. 그런 다음 다음 명령을 실행하여 Pod 로그를 실시간으로 확인합니다:

kubectl logs <pod_name> --follow -n gitlab-managed-apps