구성 동기화를 사용하는 Kubernetes GitOps 권장사항

이 페이지를 참고하면 구성 동기화를 최대한 활용할 수 있도록 Kubernetes용 CI/CD GitOps 파이프라인을 계획하고 설계하는 데 도움이 됩니다.

GitOps 자체는 Kubernetes 구성을 대규모로 관리하는 조직을 위한 범용 권장사항입니다. 하지만 이 솔루션을 설계할 때는 많은 선택권이 있습니다. 선택 가능한 옵션과 이러한 결정의 장단점을 이해하면 나중에 아키텍처를 다시 만들 필요가 없습니다.

이 페이지에 나열된 권장사항을 모두 사용할 필요는 없습니다. 상황에 따라 권장사항을 다르게 채택할 수 있습니다. 이 페이지를 참조하면 GitOps 아키텍처를 설정할 때 정보를 바탕으로 결정을 내릴 수 있습니다.

중앙 집중식 비공개 패키지 저장소 사용

공개 또는 내부 패키지(예: Helm 또는 kpt)에 중앙 저장소를 사용하면 팀이 패키지를 더 쉽게 찾을 수 있습니다. Artifact Registry 또는 Git 저장소와 같은 서비스를 사용할 수 있습니다.

플랫폼팀은 애플리케이션팀이 중앙 저장소의 패키지만 사용할 수 있는 정책을 구현할 수 있습니다. 또는 중앙 저장소를 검증된 패키지 집합으로 사용할 수 있습니다.

저장소에 대한 쓰기 권한을 소수의 엔지니어로 제한할 수 있습니다. 조직 내 다른 부서는 읽기 액세스 권한을 가질 수 있습니다. 패키지를 중앙 저장소로 승격하고 업데이트를 브로드캐스트하는 프로세스를 구현하는 것이 좋습니다.

다음 표에는 중앙 집중식 비공개 패키지 저장소를 사용할 때의 이점과 단점이 나와 있습니다.

이점

단점

  • 정의된 주기로 공개 패키지를 수집하여 연결 또는 업스트림 앱 제거로 인해 손상되지 않도록 합니다.
  • 공유 패키지를 검토하고 스캔합니다.
  • 사용 중인 항목과 지원되는 항목을 찾을 수 있는 간단한 방법을 제공합니다. 예를 들어 팀은 중앙 저장소에 저장된 표준 Redis 배포를 더 쉽게 찾을 수 있습니다.
  • 기본값, 라벨 추가, 컨테이너 이미지 저장소와 같은 내부 표준을 충족하도록 업스트림 패키지를 변경합니다.
  • 누군가 중앙 저장소를 유지해야 합니다.
  • 애플리케이션팀을 위한 프로세스를 추가합니다.

wet 저장소 만들기

클러스터 또는 네임스페이스의 원하는 상태와 일치하는 YAML 출력으로 저장소를 만듭니다. diff를 사용하여 wet 저장소 또는 완전히 하이드레이션된 저장소의 변경사항을 쉽게 검토할 수 있어야 합니다. 검토 프로세스를 통해 wet 저장소만 변경하는 것이 좋습니다 (예: GitHub에서는 pull 요청).

다음 표에는 wet 저장소를 만들 때의 이점과 단점이 나와 있습니다.

이점

단점

  • diff를 더 쉽게 검사할 수 있습니다.
  • 의도된 구성 상태를 확인하는 데 별도의 처리가 필요하지 않습니다.
  • 구성을 완전히 하이드레이션하면 YAML이 반복될 수 있습니다.

구성 확인을 위한 원점 회귀

구성 동기화가 동기화되어 문제를 확인할 때까지 기다리면 불필요한 Git 커밋 및 긴 피드백 루프가 발생할 수 있습니다. kubeval과 같은 kpt 검사기 함수를 사용하여 구성을 클러스터에 적용하기 전에 많은 문제를 확인할 수 있습니다.

다음 표에는 구성을 적용하기 전 문제를 확인할 때의 이점과 단점이 나와 있습니다.

이점

단점

  • 변경 요청 시 구성 변경사항을 표시하면 저장소에서 오류가 발생하지 않도록 방지할 수 있습니다.
  • 공유 구성에 미치는 문제의 영향이 줄어듭니다.
  • 문제를 포착하려면 커밋 프로세스에 도구와 로직을 추가해야 합니다.

브랜치 대신 폴더 사용

구성 변형에 브랜치 대신 폴더를 사용합니다. 폴더에서 tree 명령어를 사용하여 변형을 볼 수 있습니다. 예를 들어 브랜치를 사용하면 prod 브랜치와 stage 브랜치 간의 델타가 예정된 구성 변경인지 아니면 stage와 prod 간의 차이가 영구적인지 알 수 없습니다.

다음 표에는 브랜치 대신 폴더를 사용할 때의 이점과 단점이 나와 있습니다.

이점

단점

  • 폴더 탐색이 브랜치 탐색보다 더 쉽습니다.
  • Git 제공업체 외부에서 브랜치 diff를 수행하는 것은 일반적이지 않지만, 많은 CLI 및 GUI 도구로 폴더에 대한 diff를 수행할 수 있습니다.
  • 폴더에서는 영구적인 차이와 승격되지 않은 차이를 쉽게 구분할 수 있습니다.
  • 하나의 변경 요청으로 여러 클러스터 및 네임스페이스에 변경사항을 적용할 수 있지만 브랜치의 경우 브랜치별로 서로 다른 변경 요청이 필요합니다.
  • 동일한 파일에 대해 하나의 변경 요청을 사용하여 구성 변경사항을 승격할 수 없습니다.

ClusterSelectors 사용 최소화

ClusterSelectors를 사용하면 구성의 특정 부분을 클러스터의 하위 집합에 적용할 수 있습니다. RootSync 또는 RepoSync를 구성하는 대신 적용 중인 리소스를 수정하거나 클러스터에 라벨을 추가할 수 있습니다. 하지만 시간이 지남에 따라 ClusterSelectors가 증가하면 클러스터의 최종 상태를 이해하기가 복잡해질 수 있습니다.

구성 동기화를 사용하면 여러 RootSyncsRepoSyncs를 한 번에 동기화할 수 있습니다. 즉, 관련 구성을 별도의 저장소에 추가한 후 원하는 클러스터에 동기화할 수 있습니다.

다음 표에는 ClusterSelectors를 사용하지 않을 때의 이점과 단점이 나와 있습니다.

이점

단점

  • 클러스터에서 결정을 내리는 대신 클러스터에서 수행하는 구성을 폴더로 더 쉽게 조합할 수 있습니다.
  • 클러스터에 실제로 적용되는 내용을 이해해야 하는 정신적 부하가 줄어듭니다.
  • 라벨은 클러스터에 특성을 추가하는 간단한 방법이며 새로운 'RepoSync'를 만드는 것이 더 복잡합니다.

구성 동기화로 작업 관리 방지

구성 동기화가 작업을 자동으로 적용할 수 있지만 다음과 같은 이유로 GitOps 배포에 작업이 적합하지 않습니다.

  • 변경할 수 없는 필드: 많은 작업 필드는 변경할 수 없습니다. 변경 불가능한 필드를 변경하려면 객체를 삭제하고 다시 만들어야 합니다. 하지만 소스에서 객체를 삭제하지 않는 한 구성 동기화는 객체를 삭제하지 않습니다.

  • 의도하지 않은 작업 실행: 구성 동기화로 작업을 동기화한 후 해당 작업이 클러스터에서 삭제되면 구성 동기화는 선택한 상태에서 드리프트를 고려하여 작업을 다시 만듭니다. 작업 TTL(수명)을 지정하면 작업이 자동으로 삭제되고 구성 동기화는 사용자가 정보 소스에서 작업을 삭제할 때까지 자동으로 작업을 다시 만들고 다시 시작합니다. 구성 동기화가 작업을 다시 실행하기 때문에 이는 의도한 결과가 아닌 경우가 많습니다.

  • 조정 문제: 구성 동기화는 일반적으로 객체가 적용된 후 조정될 때까지 기다립니다. 하지만 작업은 실행이 시작되면 조정된 것으로 간주됩니다. 즉, 구성 동기화는 작업이 완료될 때까지 기다리지 않고 다른 객체를 계속 적용합니다. 그러나 나중에 작업이 실패하면 조정 실패로 간주됩니다. 경우에 따라 이로 인해 다른 리소스가 동기화되지 않으며 해결될 때까지 오류가 발생할 수 있습니다. 다른 경우에는 동기화가 성공하고 조정만 실패할 수 있습니다.

이러한 이유로 구성 동기화로 작업을 동기화하지 않는 것이 좋습니다.

대부분의 경우 작업 및 기타 상황별 태스크는 수명 주기 관리를 처리하는 서비스에서 관리되어야 합니다. 그러면 작업 자체가 아닌 구성 동기화를 사용하여 서비스를 관리할 수 있습니다.

다음 표에는 작업을 관리하는 데 구성 동기화를 사용하지 않을 경우의 이점과 단점이 나와 있습니다.

혜택

단점

  • GitOps 호환성을 향상시킵니다. 작업은 변경할 수 없는 필드로 인해 GitOps의 선언적 버전 제어 방식과 함께 잘 작동하지 않습니다.
  • 의도하지 않은 결과가 감소합니다. 구성 동기화가 삭제된 작업을 자동으로 다시 만들어 잠재적으로 예기치 않게 실행될 위험이 사라집니다.
  • 동기화 오류가 적습니다. 잠재적인 동기화 충돌 및 실패한 작업으로 트리거되는 오류를 방지할 수 있습니다.
  • 수동 작업 관리. 작업을 관리하려면 다른 서비스를 찾아야 합니다.

구조화되지 않은 저장소 사용

구성 동기화는 저장소 구성을 위해 구조화되지 않은 형식과 계층 구조 형식의 두 가지 구조를 지원합니다. 구조화되지 않은 형식을 사용하면 가장 편리한 방식으로 저장소를 구성할 수 있으므로 권장됩니다. 반면에 계층적 저장소는 특정 구조를 적용합니다. 예를 들어 CRD는 특정 디렉터리에 있어야 합니다. 이로 인해 구성을 공유해야 할 때 문제가 발생할 수 있습니다. 예를 들어 한 팀에서 CRD가 포함된 패키지를 게시하면 해당 패키지를 사용해야 하는 다른 팀은 CRD를 cluster 디렉터리로 이동해야 하므로 프로세스에 더 많은 오버헤드가 추가됩니다.

다음 표에는 구조화되지 않은 저장소를 사용할 때의 이점과 단점이 나와 있습니다.

이점

단점

  • CRD 또는 다른 클러스터 전체 정의가 포함된 경우에도 공유 구성 패키지를 재사용할 수 있습니다.
  • 프로세스나 가이드라인이 없으면 저장소 구조가 팀마다 다를 수 있으므로 Fleet 차원의 도구를 구현하기가 더 어려워질 수 있습니다.

계층적 저장소를 변환하는 방법은 계층적 저장소를 구조화되지 않은 저장소로 변환을 참조하세요.

별도의 코드 및 구성 저장소

모노 저장소를 확장할 때는 각 폴더별 빌드가 필요합니다. 코드 작업자와 클러스터 구성 작업자의 권한과 우려사항은 일반적으로 다릅니다. 코드 및 구성 저장소를 분리하면 각 저장소에 자체 권한 및 구조가 있을 수 있습니다.

다음 표에는 코드 저장소와 구성 저장소를 분리할 때의 이점과 단점이 나와 있습니다.

이점

단점

  • 커밋을 '루프'하지 않습니다. 예를 들어 코드 저장소에 커밋할 경우 CI 요청을 트리거하여 이미지를 생성한 후에 코드 커밋이 필요할 수 있습니다.
  • 애플리케이션 코드 및 클러스터 구성 작업자에 대해 서로 다른 권한을 사용할 수 있습니다.
  • 애플리케이션 코드와 동일한 저장소에 있지 않으므로 앱 구성 검색이 줄어듭니다.
  • 많은 저장소를 관리하려면 시간이 오래 걸릴 수 있습니다.

별도의 저장소를 사용하여 변경사항 격리

모노 저장소를 확장할 때는 폴더마다 서로 다른 권한이 필요합니다. 따라서 저장소를 분리하면 보안, 플랫폼, 애플리케이션 구성 간에 보안 경계가 허용됩니다. 또한 프로덕션 저장소와 비프로덕션 저장소를 구분하는 것이 좋습니다.

다음 표에는 별도의 저장소로 변경사항을 격리할 때의 이점과 단점이 나와 있습니다.

이점

단점

  • 플랫폼, 보안, 애플리케이션팀이 있는 조직에서 변경 및 권한 주기는 서로 다릅니다.
  • 권한은 저장소 수준으로 유지됩니다. CODEOWNERS 파일을 사용하면 조직에서 쓰기 권한을 제한하면서 읽기 권한을 허용할 수 있습니다.
  • 구성 동기화는 네임스페이스당 여러 동기화를 지원하므로 여러 저장소에서 '혼합 효과'를 얻을 수 있습니다.
  • 많은 저장소를 관리하는 것은 그 자체로 태스크입니다. 따라서 클러스터당 새 저장소를 만드는 경우 이제 클러스터 설정/해제 문제에 저장소 관리를 포함해야 합니다.

패키지 버전 고정

Helm 또는 Git의 사용 여부에 관계없이 명시적 출시 없이 실수로 이동하지 않은 버전으로 구성 패키지 버전을 고정해야 합니다.

다음 표에는 패키지 버전을 고정할 때의 이점과 단점이 나와 있습니다.

이점

단점

  • 공유 구성 업데이트는 패키지 버전이 고정되지 않은 경우 의도한 것보다 더 큰 영향을 미칠 수 있습니다.
  • 공유 패키지가 업데이트될 때 출시에 대한 검사가 필요합니다.

워크로드 아이덴티티 사용

GKE 클러스터에서 워크로드 아이덴티티를 사용 설정하면 Kubernetes 워크로드가 안전하고 관리 가능한 방식으로 Google 서비스에 액세스할 수 있습니다.

다음 표에는 워크로드 아이덴티티를 사용할 때의 이점과 단점이 나와 있습니다.

이점

단점

  • 보안 비밀과 비밀번호의 복잡성과 잠재적인 문제가 줄어듭니다.
  • Google Cloud 외부의 서비스(예: GitHub 및 GitLab)는 워크로드 아이덴티티를 지원하지 않습니다.

대략적인 아키텍처

대략적으로 4개 이상의 저장소 유형이 필요합니다.

  1. 공유 구성이 저장되는 패키지 저장소. Artifact Registry에 저장된 Helm 차트일 수도 있습니다.
  2. 플랫폼팀이 클러스터 및 네임스페이스의 Fleet 차원 구성을 저장하는 플랫폼 저장소
  3. 애플리케이션 구성 저장소
  4. 애플리케이션 코드 저장소

다음 다이어그램은 이러한 저장소의 레이아웃을 보여줍니다.

애플리케이션 구성 저장소와 애플리케이션 코드 저장소로 전달되는 패키지 및 플랫폼 저장소의 추천 아키텍처

다음 다이어그램은 애플리케이션 코드 저장소에서 애플리케이션 구성 저장소로의 구성 흐름을 보여줍니다. 개발팀이 애플리케이션 및 애플리케이션 구성을 위한 코드를 저장소로 푸시합니다. 앱과 구성을 위한 코드가 같은 위치에 저장되고 애플리케이션팀이 이러한 저장소를 제어할 수 있습니다. 그러면 앱팀이 코드를 빌드에 푸시할 수 있습니다.

빌드에 푸시되는 애플리케이션 코드 및 애플리케이션 구성을 보여주는 추천 애플리케이션 빌드입니다.

다음 단계