LabHub

블로그

etcd와 Kubernetes: API Server 통합 분석

한국어English日本語

etcd와 Kubernetes: API Server 통합 분석

Kubernetes API Server는 etcd를 유일한 데이터 저장소로 사용합니다. 이 글에서는 API Server가 etcd를 어떻게 활용하는지, 키 구조, Watch Cache, 사이징, 암호화 등을 분석합니다.


1. kube-apiserver의 etcd 사용

1.1 Storage Backend

kube-apiserver는 etcd v3 API를 사용하여 모든 Kubernetes 리소스를 저장합니다:

// storage backend 인터페이스 (간략화)
type Interface interface {
    Create(ctx context.Context, key string, obj runtime.Object, ...) error
    Delete(ctx context.Context, key string, ...) error
    Get(ctx context.Context, key string, ...) error
    List(ctx context.Context, key string, ...) error
    Watch(ctx context.Context, key string, ...) (watch.Interface, error)
    GuaranteedUpdate(ctx context.Context, key string, ...) error
}

1.2 Codec (직렬화/역직렬화)

Kubernetes 리소스는 etcd에 저장되기 전에 직렬화됩니다:

API Server는 리소스를 저장할 때 내부 버전(internal version)에서 저장 버전(storage version)으로 변환한 뒤 직렬화합니다.

1.3 Transformer (암호화)

Transformer는 etcd에 저장되기 전/후에 데이터를 변환합니다:

Write: Object -> Serialize -> Encrypt -> etcd
Read:  etcd -> Decrypt -> Deserialize -> Object

2. etcd 키 계층 구조

2.1 /registry/ 접두사

모든 Kubernetes 리소스는 /registry/ 접두사 아래에 저장됩니다:

/registry/pods/default/my-pod
/registry/pods/kube-system/coredns-xxx
/registry/services/specs/default/kubernetes
/registry/deployments/default/my-deployment
/registry/configmaps/default/my-config
/registry/secrets/default/my-secret
/registry/namespaces/default
/registry/nodes/node-1

2.2 키 구조 패턴

네임스페이스 리소스:

/registry/RESOURCE_TYPE/NAMESPACE/NAME

클러스터 리소스:

/registry/RESOURCE_TYPE/NAME

2.3 리소스 인코딩

etcd에 저장된 데이터의 구조:

# etcdctl로 실제 저장된 데이터 확인
etcdctl get /registry/pods/default/my-pod --print-value-only | \
  head -c 50
# k8s(protobuf binary prefix)...

protobuf로 인코딩된 바이너리 데이터입니다. 디코딩하면 PodSpec, PodStatus 등의 구조체를 확인할 수 있습니다.

2.4 키 목록 확인

# 모든 키 접두사 확인
etcdctl get /registry --prefix --keys-only | head -30

# 특정 리소스 타입의 키 확인
etcdctl get /registry/deployments --prefix --keys-only

3. Watch Cache

3.1 Watch Cache가 필요한 이유

API Server가 모든 Watch 요청을 직접 etcd에 전달하면:

Watch Cache는 API Server 내부에서 etcd Watch를 캐싱하여 이 문제를 해결합니다.

3.2 Cacher 구조

// Cacher는 etcd watch를 캐싱하는 계층
type Cacher struct {
    storage     storage.Interface    // 실제 etcd backend
    watchCache  *watchCache          // 캐시된 이벤트 히스토리
    reflector   *cache.Reflector     // etcd watch 리플렉터
    watchers    indexedWatchers       // 등록된 watcher 목록
}

3.3 동작 방식

  1. Reflector: API Server 시작 시 각 리소스 타입에 대해 etcd Watch를 설정
  2. Watch Cache: etcd에서 수신한 이벤트를 링 버퍼에 캐싱
  3. 클라이언트 Watch: 클라이언트의 Watch 요청은 캐시에서 서비스
etcd --[watch]--> Reflector --[events]--> Watch Cache --[events]--> Client Watchers

3.4 Watch Cache 크기

Watch Cache의 링 버퍼 크기는 리소스 타입별로 설정됩니다:

3.5 List 요청 처리

List 요청도 Watch Cache에서 서비스됩니다:


4. etcd 사이징

4.1 오브젝트 수 기반 사이징

Kubernetes 클러스터 규모에 따른 etcd 사이징:

클러스터 규모노드 수Pod 수권장 etcd디스크
소규모10-501000 이하3노드, 2 CPU, 8GB50GB SSD
중규모50-2005000 이하3노드, 4 CPU, 16GB100GB SSD
대규모200-100050000 이하5노드, 8 CPU, 32GB200GB SSD

4.2 요청 빈도 고려

etcd 부하에 영향을 미치는 요인:

4.3 DB 크기 관리


5. Encryption at Rest

5.1 EncryptionConfiguration

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: BASE64_ENCODED_KEY
      - identity: {}

5.2 프로바이더 우선순위

providers 배열에서 첫 번째 프로바이더가 쓰기에 사용되고, 모든 프로바이더가 읽기에 사용됩니다. 이를 통해 키 순환이 가능합니다:

  1. 새 키를 첫 번째 위치에 추가
  2. kube-apiserver 재시작
  3. 기존 Secret을 모두 다시 쓰기 (새 키로 암호화)
  4. 이전 키 제거

5.3 KMS 프로바이더 (v2)

KMS v2 프로바이더는 더 효율적인 키 관리를 제공합니다:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - kms:
          apiVersion: v2
          name: my-kms-plugin
          endpoint: unix:///var/run/kms-plugin/socket.sock

KMS v2의 장점:

5.4 암호화 상태 확인

# Secret이 암호화되어 있는지 확인
etcdctl get /registry/secrets/default/my-secret | hexdump -C | head

# 암호화된 경우 'k8s:enc:aescbc:v1:key1' 같은 접두사가 보임
# 암호화되지 않은 경우 'k8s' protobuf 접두사가 보임

6. API Server와 etcd 연결 설정

6.1 주요 플래그

kube-apiserver \
  --etcd-servers=https://etcd1:2379,https://etcd2:2379,https://etcd3:2379 \
  --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt \
  --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt \
  --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key \
  --etcd-compaction-interval=5m \
  --encryption-provider-config=/etc/kubernetes/encryption-config.yaml \
  --watch-cache=true \
  --default-watch-cache-size=100

6.2 연결 상태 모니터링

# API Server의 etcd 연결 메트릭
- etcd_request_duration_seconds # etcd 요청 지연
- etcd_object_counts # 리소스별 오브젝트 수
- apiserver_storage_size_bytes # 저장소 크기

7. 정리

Kubernetes API Server와 etcd의 통합은 클러스터 운영의 핵심입니다. Watch Cache를 통한 효율적인 캐싱, 적절한 키 구조 이해, Encryption at Rest 설정, etcd 사이징은 안정적인 클러스터 운영에 필수적입니다. etcd의 건강 상태를 지속적으로 모니터링하고, 정기적인 백업과 유지보수를 수행하는 것이 중요합니다.

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다