고급 Pod 구성

고급 Pod 구성 (Advanced Pod Configuration)

이 페이지는 PriorityClass, RuntimeClass, Pod 안의 보안 컨텍스트 같은 고급 Pod 구성 주제를 다루고, 스케줄링 관련 측면을 소개해요.

PriorityClass

PriorityClass는 Pod가 다른 Pod에 비해 얼마나 중요한지 설정할 수 있게 해줘요. Pod에 우선순위 클래스를 할당하면, 쿠버네티스는 지정한 PriorityClass를 기반으로 그 Pod의 .spec.priority 필드를 설정합니다 (.spec.priority를 직접 설정할 수는 없어요). Pod를 스케줄할 수 없고, 그 원인이 리소스 부족이라면, [kube-scheduler]는 더 높은 우선순위 Pod의 스케줄링을 가능하게 하기 위해 더 낮은 우선순위 Pod를 [선점(preempt)]하려고 시도해요.

PriorityClass는 우선순위 클래스 이름을 정수 우선순위 값에 매핑하는 클러스터 범위(cluster-scoped) API 객체예요. 숫자가 높을수록 우선순위가 높음을 나타냅니다.

PriorityClass 정의하기

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 10000
globalDefault: false
description: "Priority class for high-priority workloads"

PriorityClass를 사용해 Pod 우선순위 지정하기

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
  priorityClassName: high-priority

내장 PriorityClass (Built-in PriorityClasses)

쿠버네티스는 두 가지 내장 PriorityClass를 제공해요.

  • system-cluster-critical: 클러스터에 중요한 시스템 컴포넌트용
  • system-node-critical: 개별 노드에 중요한 시스템 컴포넌트용. 이것은 Pod가 가질 수 있는 최고 우선순위예요.

자세한 내용은 [Pod Priority and Preemption] 문서를 참고하세요.

RuntimeClass

RuntimeClass는 Pod의 저수준 컨테이너 런타임을 지정할 수 있게 해줍니다. 서로 다른 격리 수준이나 런타임 기능이 필요할 때처럼, 종류가 다른 Pod에 서로 다른 컨테이너 런타임을 지정하고 싶을 때 유용해요.

예시 Pod

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  runtimeClassName: myclass
  containers:
  - name: mycontainer
    image: nginx

[RuntimeClass]는 노드의 일부 또는 전체에서 사용 가능한 컨테이너 런타임을 나타내는 클러스터 범위 객체예요.

클러스터 관리자는 RuntimeClass를 뒷받침하는 구체적인 런타임을 설치하고 구성합니다. 그 특수 컨테이너 런타임 구성을 모든 노드에 설정하거나, 일부 노드에만 설정할 수도 있어요.

자세한 내용은 [RuntimeClass] 문서를 참고하세요.

Pod 및 컨테이너 수준 보안 컨텍스트 구성

Pod 스펙의 Security context 필드는 Pod와 컨테이너의 보안 설정을 세밀하게 제어할 수 있게 해줘요.

Pod 전체 securityContext

보안의 어떤 측면은 전체 Pod에 적용되고, 다른 측면에서는 컨테이너 수준 재정의 없이 기본값을 설정하고 싶을 수 있어요. 다음은 Pod 수준에서 securityContext를 사용하는 예시입니다.

예시 Pod

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:  # 이는 전체 Pod에 적용됩니다
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  containers:
  - name: sec-ctx-demo
    image: registry.k8s.io/e2e-test-images/agnhost:2.45
    command: ["sh", "-c", "sleep 1h"]

컨테이너 수준 보안 컨텍스트

특정 컨테이너에 대해서만 보안 컨텍스트를 지정할 수 있어요. 다음은 그 예시입니다.

예시 Pod

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-2
spec:
  containers:
  - name: sec-ctx-demo-2
    image: gcr.io/google-samples/node-hello:1.0
    securityContext:
      allowPrivilegeEscalation: false
      runAsNonRoot: true
      runAsUser: 1000
      capabilities:
        drop:
        - ALL
      seccompProfile:
        type: RuntimeDefault

보안 컨텍스트 옵션

  • 사용자 및 그룹 ID (User and Group IDs): 컨테이너를 어떤 사용자/그룹으로 실행할지 제어해요
  • Capabilities: Linux capabilities를 추가하거나 제거해요
  • Seccomp 프로필 (Seccomp Profiles): 보안 컴퓨팅 프로필을 설정해요
  • SELinux 옵션 (SELinux Options): SELinux 컨텍스트를 구성해요
  • AppArmor: 추가 접근 제어를 위한 AppArmor 프로필을 구성해요
  • Windows 옵션 (Windows Options): Windows 전용 보안 설정을 구성해요

주의: Pod securityContext를 사용해 Linux 컨테이너에서 [privileged mode]를 허용할 수도 있어요. Privileged mode는 securityContext의 다른 많은 보안 설정을 재정의합니다. securityContext의 다른 필드로 동등한 권한을 부여할 수 없다면 이 설정 사용을 피하세요. Pod 수준 보안 컨텍스트에서 windowsOptions.hostProcess 플래그를 설정하면 Windows 컨테이너도 비슷하게 privileged mode로 실행할 수 있어요. 자세한 내용과 지침은 [Create a Windows HostProcess Pod] 문서를 참고하세요.

자세한 내용은 [Configure a Security Context for a Pod or Container] 문서를 참고하세요.

Pod 스케줄링 결정에 영향 주기

쿠버네티스는 Pod가 어떤 노드에 스케줄될지 제어하는 여러 메커니즘을 제공해요.

Node selectors

가장 단순한 형태의 노드 선택 제약입니다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
  nodeSelector:
    disktype: ssd

Node affinity

Node affinity는 Pod가 스케줄될 수 있는 노드를 제한하는 규칙을 지정할 수 있게 해줍니다. 다음은 특정 대륙으로 레이블된 노드에서 실행되는 것을 선호하는, [topology.kubernetes.io/zone] 레이블 값을 기준으로 선택하는 Pod 예시예요.

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - antarctica-east1
            - antarctica-west1
  containers:
  - name: with-node-affinity
    image: registry.k8s.io/pause:3.8

Pod affinity와 anti-affinity

Node affinity 외에도, 이미 노드에서 실행 중인 다른 Pod의 레이블을 기준으로 Pod가 스케줄될 수 있는 노드를 제한할 수 있어요. Pod affinity는 Pod가 다른 Pod와의 상대적 위치를 어디에 두어야 하는지에 대한 규칙을 지정할 수 있게 해줍니다.

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - database
        topologyKey: topology.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: registry.k8s.io/pause:3.8

Tolerations

Tolerations는 일치하는 taint가 있는 노드에 Pod가 스케줄될 수 있게 해줍니다.

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: myapp
    image: nginx
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"

자세한 내용은 [Assign Pods to Nodes] 문서를 참고하세요.

Pod overhead

Pod overhead는 컨테이너 requests와 limits 위에 Pod 인프라가 소비하는 리소스를 고려할 수 있게 해줘요.

---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: kvisor-runtime
handler: kvisor-runtime
overhead:
  podFixed:
    memory: "2Gi"
    cpu: "500m"
---
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  runtimeClassName: kvisor-runtime
  containers:
  - name: myapp
    image: nginx
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

다음 내용 (What's next)

  • [Pod Priority and Preemption]에 대해 읽어보기
  • [RuntimeClasses]에 대해 읽어보기
  • [Configure a Security Context for a Pod or Container] 살펴보기
  • 쿠버네티스가 [Pods를 Nodes에 어떻게 할당하는지] 배우기
  • [Pod Overhead]