본문 바로가기
WIKI 기술 지식 베이스

라벨과 어노테이션

원문 보기 위키 갱신

라벨과 어노테이션 (Labels and Annotations)

Kubernetes 리소스에 라벨(label)과 어노테이션(annotation)을 어떻게 활용하고, CloudNativePG가 관리하는 사전 정의된 라벨/어노테이션 목록 및 상속(inheritance) 설정 방법을 정리해 드릴게요.

출처: 문서

본문

Kubernetes의 리소스는 평면(flat) 구조로 구성되어 있어서 리소스 사이에 계층적 정보나 관계가 없어요. 하지만 이런 리소스와 객체들은 라벨과 어노테이션을 통해 서로 연결하고 관계를 맺을 수 있어요.

:::info 자세한 내용은 Kubernetes 문서의 어노테이션 및 라벨 문서를 참고해 주세요. :::

간단히 정리하면:

  • 어노테이션은 외부 도구와의 통합을 돕기 위해 리소스에 식별성이 없는 추가 정보를 부여하는 데 사용돼요.
  • 라벨은 객체를 그룹화하고 Kubernetes 네이티브 선택자(selector) 기능으로 조회하는 데 사용돼요.

CloudNativePG 배포에서 사용할 라벨이나 어노테이션을 하나 이상 선택할 수 있어요. 그리고 클러스터의 메타데이터에 이런 라벨이나 어노테이션을 정의하면, 오퍼레이터가 생성하는 모든 리소스(파드 포함)가 이를 상속받도록 오퍼레이터를 구성해야 해요.

:::note 라벨과 어노테이션 상속은 CloudNativePG가 파드 템플릿 같은 대안적 접근 방식 대신 채택한 기법이에요. :::

사전 정의된 라벨 (Predefined labels)

CloudNativePG는 다음과 같은 사전 정의된 라벨을 관리해요:

cnpg.io/backupDate : 백업 날짜를 ISO 8601 형식(YYYYMMDD)으로 나타낸 값. 이 라벨은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/backupName : 백업 식별자. 이 라벨은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/backupMonth : 백업이 수행된 연/월. 이 라벨은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/backupTimeline : 백업이 수행된 시점의 인스턴스 타임라인(timeline). 이 라벨은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/backupYear : 백업이 수행된 연도. 이 라벨은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/cluster : 클러스터 이름.

cnpg.io/immediateBackup : immediate가 true로 설정된 ScheduledBackup 객체에서 생성된 첫 번째 백업인 경우 Backup 리소스에 적용돼요.

cnpg.io/instanceName : PostgreSQL 인스턴스의 이름 (예전의, deprecated된 postgresql 라벨을 대체해요).

cnpg.io/jobRole : 잡(job)의 역할 (즉, major-upgrade).

cnpg.io/majorVersion : 백업 데이터 디렉토리의 PostgreSQL 정수 메이저 버전 (예: 17). 이 라벨은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/onlineBackup : 백업이 온라인(hot)인지, 아니면 Postgres가 내려간 상태(cold)에서 수행된 것인지 여부. 이 라벨은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/podRole : 풀러(pooler) 배포 전용 파드와 데이터베이스 인스턴스용 파드를 구분해요.

cnpg.io/poolerName : PgBouncer 풀러의 이름.

cnpg.io/pvcRole : PVC의 용도 (예: PG_DATA 또는 PG_WAL).

cnpg.io/reload : ConfigMap 및 Secret 리소스에서 사용 가능해요. true로 설정하면 리소스의 변경이 오퍼레이터에 의해 자동으로 리로드돼요.

cnpg.io/userType : Secret과 연관된 PostgreSQL 사용자 유형을 지정하며, superuser(Postgres 슈퍼유저 접근) 또는 app(CloudNativePG 용어상 애플리케이션 레벨 사용자) 중 하나예요. CloudNativePG가 만드는 기본 사용자(주로 postgres와 app)로 제한돼요.

role - deprecated(폐기 예정) : 파드에서 실행되는 인스턴스의 역할: primary, replica, 또는 unhealthy. unhealthy 값은 일시적이에요. 오퍼레이터는 페일오버(failover)나 스위치오버(switchover) 중에 이전 primary에 설정하고, 전환이 완료되면 자동으로 지워요. 이 라벨은 deprecated이므로 cnpg.io/instanceRole을 사용해야 해요.

cnpg.io/scheduled-backup : 사용 가능할 때, 특정 Backup 객체를 생성한 ScheduledBackup 리소스의 이름.

cnpg.io/instanceRole : 파드에서 실행되는 인스턴스의 역할: primary, replica, 또는 unhealthy. unhealthy 값은 일시적이에요. 오퍼레이터는 페일오버나 스위치오버 중에 이전 primary에 설정하고, 전환이 완료되면 자동으로 지워요.

app.kubernetes.io/managed-by : 관리자(manager)의 이름. 항상 cloudnative-pg예요. CloudNativePG가 관리하는 모든 리소스에서 사용 가능해요.

app.kubernetes.io/name : 애플리케이션 이름. 항상 postgresql이에요. 파드, 잡, 디플로이먼트, 서비스, persistentVolumeClaims, volumeSnapshots, podDisruptionBudgets, podMonitors에서 사용 가능해요.

app.kubernetes.io/component : 컴포넌트 이름 (database, pooler, ...). 파드, 잡, 디플로이먼트, 서비스, persistentVolumeClaims, volumeSnapshots, podDisruptionBudgets, podMonitors에서 사용 가능해요.

app.kubernetes.io/instance : 소유한 Cluster 리소스의 이름. 파드, 잡, 디플로이먼트, 서비스, volumeSnapshots, podDisruptionBudgets, podMonitors에서 사용 가능해요.

app.kubernetes.io/version : PostgreSQL 메이저 버전. 파드, 잡, 서비스, volumeSnapshots, podDisruptionBudgets, podMonitors에서 사용 가능해요.

사전 정의된 어노테이션 (Predefined annotations)

CloudNativePG는 다음과 같은 사전 정의된 어노테이션을 관리해요:

container.apparmor.security.beta.kubernetes.io/* : 이름이 지정된 컨테이너에 적용할 AppArmor 프로필 이름. 자세한 내용은 AppArmor를 참고해 주세요.

cnpg.io/backupEndTime : 백업이 종료된 시간. 이 어노테이션은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/backupEndWAL : 백업 종료 시점의 WAL. 이 어노테이션은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/backupStartTime : 백업이 시작된 시간.

cnpg.io/backupStartWAL : 백업 시작 시점의 WAL. 이 어노테이션은 VolumeSnapshot 리소스에서만 사용 가능해요.

cnpg.io/coredumpFilter : Postgres 프로세스의 코어 덤프(coredump)를 제어하는 필터로, 비트마스크(bitmask)로 표현돼요. 기본값은 공유 메모리 세그먼트를 덤프에서 제외하도록 0x31로 설정돼 있어요. 자세한 내용은 PostgreSQL 코어 덤프를 참고해 주세요.

cnpg.io/clusterManifest : 이 리소스(예: PVC)를 소유한 Cluster의 매니페스트. 이 라벨은 예전의, deprecated된 cnpg.io/hibernateClusterManifest 라벨을 대체해요.

cnpg.io/fencedInstances : 펜싱(fenced)해야 할 인스턴스 목록을 JSON 형식으로 나타낸 값. 목록에 * 요소가 있으면 전체 클러스터가 펜싱돼요.

cnpg.io/forceLegacyBackup : 테스트 목적으로만 Cluster 리소스에 적용해요. --name 옵션이 없던 3.4 버전(2023년 1월) 이전의 barman-cloud-backup 동작을 시뮬레이션하기 위한 것이에요.

cnpg.io/hash : 리소스의 해시 값.

cnpg.io/hibernation : 선언적 하이버네이션 기능을 제어하기 위해 Cluster 리소스에 적용돼요. 허용 값은 on과 off예요.

cnpg.io/managedSecrets : 오퍼레이터가 관리하고 각 Postgres 클러스터의 ServiceAccount 리소스에 자동으로 설정되는 풀 시크릿(pull secrets).

cnpg.io/nodeSerial : 파드 리소스에서 Postgres 클러스터 내 인스턴스의 시리얼 번호를 식별해요.

cnpg.io/operatorVersion : 오퍼레이터 버전.

cnpg.io/passwordPassthrough : 오퍼레이터가 사용하는 basic-auth Secret(슈퍼유저, 애플리케이션 사용자, 또는 managed-role 비밀번호 시크릿)에 enabled로 설정하면, 오퍼레이터는 비밀번호 값을 오퍼레이터 측에서 SCRAM-SHA-256으로 인코딩하지 않고 CREATE/ALTER ROLE 구문에 그대로 전달해요. 그러면 PostgreSQL이 자체 password_encryption 설정에 따라 값을 인코딩해요. 자세한 내용은 오퍼레이터 측 인코딩 탈퇴하기(Opting out of operator-side encoding)를 참고해 주세요.

cnpg.io/pgControldata : pg_controldata 명령의 출력. 이 어노테이션은 예전의, deprecated된 cnpg.io/hibernatePgControlData 어노테이션을 대체해요.

cnpg.io/podEnvHash : deprecated됨. cnpg.io/podSpec 어노테이션이 이제 파드 환경도 포함하기 때문이에요.

cnpg.io/podPatch : Cluster 리소스에 적용할 수 있는 어노테이션이에요.

JSON-patch 형식의 패치로 설정하면, 그 패치가 인스턴스 파드에 적용돼요. 패치는 보안에 민감한 필드를 포함한 파드 스펙의 모든 필드를 수정할 수 있어요. 오퍼레이터는 패치가 구문적으로 올바르고 적용 가능한지만 검증해요.

파드 스펙에 영향을 주는 모든 Cluster 필드와 마찬가지로, 보안 제약의 강제는 Kubernetes 어드미션 컨트롤 체인에 위임돼요. 자세한 내용은 [신뢰 모델과 보안 경계(Trust Model and Security Boundaries)](security.md#trust-model-and-security-boundaries) 섹션을 참고해 주세요.

**⚠️ 경고:** 이 기능은 오퍼레이터의 기대와 Kubernetes 동작 사이에 불일치를 만들 수 있어요. 주의해서, 그리고 최후의 수단으로만 사용해 주세요.

**중요**: 이 어노테이션을 추가하거나 변경해도 생성된 파드의 롤링 배포는 트리거되지 않아요. 롤링 배포는 사용자가 `kubectl cnpg restart`로 직접 트리거할 수 있어요.

cnpg.io/podSpec : 오퍼레이터가 생성한 파드의 spec 스냅샷. 이 어노테이션은 예전의, deprecated된 cnpg.io/podEnvHash 어노테이션을 대체해요.

cnpg.io/poolerSpecHash : 풀러 리소스의 해시.

cnpg.io/pvcStatus : PVC의 현재 상태: initializing, ready, 또는 detached.

cnpg.io/reconcilePodSpec : Cluster 또는 Pooler에 적용해 재시작을 방지할 수 있는 어노테이션이에요.

`Cluster`에 `disabled`로 설정하면 오퍼레이터는 PodSpec 변경으로 인한 인스턴스 재시작을 방지해요. 여기에는 다음 변경이 포함돼요:

  - 토폴로지 또는 어피니티(affinity)
  - 스케줄러
  - 볼륨 또는 컨테이너

`Pooler`에 `disabled`로 설정하면 오퍼레이터는 `spec.instances` 변경을 제외한 디플로이먼트 스펙의 모든 수정을 제한해요.

cnpg.io/reconciliationLoop : Cluster에 disabled로 설정하면 오퍼레이터는 리컨실리에이션 루프가 실행되지 않도록 방지해요.

cnpg.io/reloadedAt : 최신 클러스터 reload 시간을 담고 있어요. reload는 사용자가 플러그인을 통해 트리거해요.

cnpg.io/skipEmptyWalArchiveCheck : Cluster 리소스에 enabled로 설정하면 오퍼레이터는 데이터를 쓰기 전에 WAL 아카이브가 비어 있는지 확인하는 검사를 비활성화해요. 책임은 본인 몫이에요.

cnpg.io/skipWalArchiving : Cluster 리소스에 enabled로 설정하면 오퍼레이터는 WAL 아카이빙을 비활성화해요. 이렇게 하면 archive_mode가 off로 설정되고 모든 PostgreSQL 인스턴스의 재시작이 필요해요. 책임은 본인 몫이에요.

cnpg.io/snapshotStartTime : 스냅샷이 시작된 시간.

cnpg.io/snapshotEndTime : 스냅샷이 사용 준비가 된 것으로 표시된 시간.

cnpg.io/validation : CloudNativePG가 관리하는 커스텀 리소스에 disabled로 설정하면, 검증 웹훅이 모든 변경을 제한 없이 허용해요.

**⚠️ 경고:** 검증 비활성화는 안전하지 않거나 파괴적인 작업을 허용할 수 있어요. 주의해서, 그리고 본인 책임하에 사용해 주세요.

cnpg.io/volumeSnapshotDeadline : Backup 및 ScheduledBackup 리소스에 적용되며, 볼륨 스냅샷 백업이 실패로 간주되기 전에 오퍼레이터가 복구 가능한 오류를 재시도할 기간을 제어할 수 있게 해줘요. 분 단위이며 기본값은 10이에요.

kubectl.kubernetes.io/restartedAt : 사용 가능할 때, Postgres 클러스터의 마지막 요청된 재시작 시간.

alpha.cnpg.io/unrecoverable : PostgreSQL 인스턴스를 실행하는 Pod에 적용되는 실험적 어노테이션이에요. 오퍼레이터에게 Pod와 관련된 모든 PVC를 삭제하라고 지시해요. 그러면 인스턴스는 구성된 조인(join) 전략에 따라 다시 생성돼요. 이 어노테이션은 인스턴스 상태와 무관하게 적용되므로, Pending이거나 Running이지만 준비되지 않았거나 Terminating 상태인 Pod에서도 적용돼요. Terminating 상태의 Pod가 삭제 데드라인(삭제 요청 시간 + 종료 유예 기간)을 지나면 오퍼레이터는 강제로 제거해서 PVC를 삭제하고 인스턴스를 다시 만들 수 있게 해요. 이 어노테이션은 현재 primary도 아니고 지정된 대상 primary도 아닌 인스턴스에서만 사용할 수 있으며, unrecoverable로 표시돼도 이 둘은 제외돼요.

**⚠️ 경고:** 도달 불가능한 노드에서 `Pod`를 강제 제거해도 그곳에서 여전히 실행 중일 수 있는 프로세스는 중지되지 않으며, 기본 볼륨이 분리되는지 여부는 스토리지 드라이버에 달려 있어요. 이는 이미 인스턴스의 데이터를 포기하는 계약을 가지는 이 어노테이션에서는 허용 가능해요.

사전 조건 (Prerequisites)

기본적으로 클러스터 메타데이터에 정의된 라벨이나 어노테이션은 관련 리소스에 상속되지 않아요. 라벨/어노테이션 상속을 활성화하려면 Operator configuration(오퍼레이터 구성)에 제공된 지침을 따르세요.

다음은 그 예시에서 이어지는 것으로, 다음과 같이 제한해요:

  • 어노테이션: categories
  • 라벨: app, environment, workload

:::note 어노테이션과 라벨 모두 여러분의 상황에 가장 잘 맞는 이름을 자유롭게 선택해 주세요. 이름에 와일드카드(wildcards)를 사용하거나, 모든 라벨에 mycompany/*를 쓰거나, mycompany/로 시작하는 어노테이션을 상속되도록 설정하는 등의 전략을 채택할 수도 있어요. :::

클러스터 메타데이터 정의하기 (Defining cluster's metadata)

클러스터를 정의할 때, 어떤 리소스도 배포하기 전에 다음과 같이 메타데이터를 설정할 수 있어요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example
  annotations:
    categories: database
  labels:
    environment: production
    workload: database
    app: sso
spec:
     # ... <snip>

클러스터가 배포된 후에는, 예를 들어 라벨이 파드에 올바르게 설정되었는지 확인할 수 있어요:

kubectl get pods --show-labels

현재 제한 사항 (Current limitations)

현재 CloudNativePG는 라벨이나 어노테이션의 삭제를 자동으로 전파하지 않아요. 따라서 이전에 기본 파드에 전파되었던 어노테이션 또는 라벨이 클러스터에서 제거되어도, 오퍼레이터는 관련 리소스에서 이를 제거하지 않아요.