본문 바로가기
K8S

Kubernetes 기술 개념 정리 3

by 나하니인데 2024. 12. 5.
반응형

17.  Kubernetes에서 Pod의 재시작 정책

Pod 재시작 정책(RestartPolicy)은 Pod 내의 모든 컨테이너에 적용되며, 해당 Pod가 위치한 노드에서 kubelet에 의해 판단되고 재시작 작업이 이루어집니다. 어떤 컨테이너가 비정상적으로 종료되거나 헬스 체크에 실패하면, kubelet은 RestartPolicy의 설정에 따라 적절한 조치를 취합니다.

Pod의 재시작 정책에는 Always, OnFailure, Never가 있으며, 기본값은 Always입니다.

  • Always: 컨테이너가 실패할 때, kubelet이 자동으로 해당 컨테이너를 재시작합니다.
  • OnFailure: 컨테이너가 종료되고 종료 코드가 0이 아닐 때, kubelet이 자동으로 해당 컨테이너를 재시작합니다.
  • Never: 컨테이너의 실행 상태와 관계없이, kubelet은 해당 컨테이너를 재시작하지 않습니다.

또한 Pod의 재시작 정책은 컨트롤러 유형과 연관되어 있으며, 현재 Pod를 관리할 수 있는 컨트롤러에는 ReplicationController, Job, DaemonSet 및 kubelet이 직접 관리하는 static Pod가 있습니다.

각 컨트롤러에 따른 재시작 정책 제한은 다음과 같습니다:

  • ReplicationController(RC)와 DaemonSet: 반드시 Always로 설정해야 하며, 해당 컨테이너가 지속적으로 실행되도록 보장합니다.
  • Job: OnFailure 또는 Never로 설정하여, 컨테이너 실행이 완료된 후 재시작되지 않도록 합니다.
apiVersion: batch/v1
kind: Job
metadata:
  name: simple-job
spec:
  completions: 1  # 작업이 성공적으로 완료되어야 하는 횟수
  parallelism: 1  # 동시에 실행할 Pod 수
  template:
    metadata:
      labels:
        app: job-example
    spec:
      containers:
      - name: job-container
        image: busybox
        command: ["sh", "-c", "echo 'Hello from Job!' && sleep 10"]
      restartPolicy: OnFailure // 해당 부분 OnFailure, Always, Never
  • kubelet: Pod가 실패할 때 재시작하며, RestartPolicy 설정과 관계없이 헬스 체크를 수행하지 않습니다.

 

18. Kubernetes에서 Pod의 상태를 확인하는 건강 체크 방법

Kubernetes에서 Pod의 건강 상태는 두 가지 주요 Probe(프로브) 를 통해 확인할 수 있습니다: LivenessProbeReadinessProbe. 또한, 애플리케이션의 초기화 시간을 고려하는 StartupProbe도 사용할 수 있습니다.

 

LivenessProbe:

  • 컨테이너가 "살아있는 상태"인지 확인.
  • 실패 시 컨테이너를 종료하고, 재시작 정책에 따라 처리.
  • LivenessProbe 예제 (HTTP 기반):
apiVersion: v1
kind: Pod
metadata:
  name: liveness-example
spec:
  containers:
  - name: my-app
    image: my-app-image:latest
    ports:
    - containerPort: 8080
    livenessProbe:
      httpGet:          # HTTP 요청을 사용
        path: /healthz  # 애플리케이션에서 제공하는 헬스 체크 경로
        port: 8080
      initialDelaySeconds: 5   # 초기화 후 5초 대기
      periodSeconds: 10        # 10초마다 체크
      timeoutSeconds: 1        # 응답 대기 시간
      failureThreshold: 3      # 3회 실패 시 비정상으로 간주

 

ReadinessProbe:

  • 컨테이너가 트래픽을 받을 준비가 되었는지 확인.
  • 실패 시 Pod를 서비스 엔드포인트에서 제외.
  • ReadinessProbe 예제 (TCP 소켓 기반):
apiVersion: v1
kind: Pod
metadata:
  name: readiness-example
spec:
  containers:
  - name: my-app
    image: my-app-image:latest
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:        # TCP 소켓을 통해 헬스 체크
        port: 8080
      initialDelaySeconds: 5   # 초기화 후 5초 대기
      periodSeconds: 10        # 10초마다 체크
      successThreshold: 1      # 성공하면 바로 준비 상태로 변경
      failureThreshold: 3      # 3회 실패 시 준비되지 않은 상태로 간주

 

StartupProbe:

  • 애플리케이션의 시작 시간을 보호.
  • 시작 시간이 오래 걸리는 서비스에서 중요한 역할.
  • StartupProbe 예제 (명령 실행 기반):
apiVersion: v1
kind: Pod
metadata:
  name: startup-example
spec:
  containers:
  - name: my-app
    image: my-app-image:latest
    startupProbe:
      exec:             # 실행 명령을 사용
        command:
        - cat
        - /tmp/healthy  # 이 파일이 존재하면 성공으로 간주
      initialDelaySeconds: 5   # 초기화 후 5초 대기
      periodSeconds: 10        # 10초마다 체크
      failureThreshold: 30     # 30회 실패하면 비정상으로 간주

 

19. Kubernetes Pod의 LivenessProbe 탐침의 일반적인 방식

kubelet은 LivenessProbe를 주기적으로 실행하여 컨테이너의 건강 상태를 진단합니다. 일반적으로 다음 세 가지 방식이 있습니다:

  1. ExecAction:
    • 컨테이너 내부에서 명령어를 실행하고, 반환 코드가 0이면 컨테이너가 건강한 것으로 간주합니다.
  2. TCPSocketAction:
    • 컨테이너의 IP 주소와 포트 번호를 사용하여 TCP 연결을 시도합니다. TCP 연결이 성공하면 컨테이너가 건강한 것으로 간주합니다.
  3. HTTPGetAction:
    • 컨테이너의 IP 주소, 포트 번호, 경로를 사용하여 HTTP GET 요청을 보냅니다. 응답 상태 코드가 200 이상 400 미만이면 컨테이너가 건강한 것으로 간주합니다.

 

20. Kubernetes Pod의 일반적인 스케줄링 방식

Kubernetes에서 Pod는 컨테이너를 실행하는 기본 단위이며, 일반적으로 다음과 같은 스케줄링 방식이 있습니다:

 

Deployment 또는 ReplicationController(RC):

  • 이 스케줄링 방식은 컨테이너 애플리케이션의 다중 복제본을 자동으로 배포하고 지속적으로 복제본의 개수를 모니터링합니다.
  • 클러스터 내에서 사용자가 지정한 복제본 수를 항상 유지하도록 보장합니다.

NodeSelector:

  • 특정 노드에 Pod를 배치하려고 할 때 사용하는 방법입니다.
  • Node의 **라벨(Label)**과 Pod의 nodeSelector 속성을 일치시켜 Pod를 특정 노드로 스케줄링합니다.
apiVersion: v1
kind: Pod
metadata:
  name: node-selector-example
spec:
  nodeSelector:
    disktype: ssd  # 라벨이 "disktype=ssd"인 노드에만 배치
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80

NodeAffinity (노드 친화도 스케줄링):

  • 친화도 스케줄링은 Pod의 스케줄링 능력을 크게 확장합니다.
  • 현재 다음 두 가지 친화도 표현 방식이 있습니다:
    • requiredDuringSchedulingIgnoredDuringExecution (필수 규칙):
      • "강제 규칙"으로, 지정된 조건이 만족되어야만 스케줄러가 Pod를 해당 노드로 배치할 수 있습니다. (nodeSelector와 유사하지만 문법이 다름)
    • preferredDuringSchedulingIgnoredDuringExecution (우선 규칙):
      • "선호 규칙"으로, 지정된 조건을 만족하는 노드로 우선 배치하지만, 반드시 강제되지는 않습니다. 여러 우선 규칙의 경우 가중치를 설정할 수도 있습니다.
apiVersion: v1
kind: Pod
metadata:
  name: node-affinity-example
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  # 강제 규칙
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
      preferredDuringSchedulingIgnoredDuringExecution:  # 우선 규칙
        preference:
          matchExpressions:
          - key: region
            operator: In
            values:
            - us-east
        weight: 1
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80

 

Taints와 Tolerations (노드 오염 및 Pod의 허용):

  • Taint:
    • 노드에 특정 Taint(오염)를 설정하여 특정 Pod가 해당 노드에서 실행되지 못하도록 방지합니다.
    • Taint 설정 (노드 레벨):
kubectl taint nodes node1 key=value:NoSchedule

 

node1 노드에 key=value:NoSchedule이라는 Taint를 추가합니다.

기본적으로 해당 Taint가 설정된 노드에서는 Pod가 스케줄링되지 않습니다.

 

  • Toleration:
    • Pod의 속성으로, 특정 Taint가 설정된 노드에서도 실행될 수 있음을 나타냅니다. 이를 통해 Pod가 해당 노드에서 실행될 수 있도록 허용합니다.
    • Toleration을 가진 Pod 예제:
apiVersion: v1
kind: Pod
metadata:
  name: toleration-example
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80

Pod는 key=value:NoSchedule이라는 Taint를 가진 노드에서도 실행될 수 있습니다.

 

21.  Kubernetes 초기화 컨테이너 (Init Container) 란?

Init Container는 애플리케이션 컨테이너와는 다르게 동작하며, 반드시 애플리케이션 컨테이너가 실행되기 전에 완료되어야 합니다. 여러 Init Container가 설정된 경우, 순차적으로 실행되며, 이전 Init Container가 성공적으로 실행 완료된 후에만 다음 Init Container가 실행됩니다. 모든 Init Container가 성공적으로 실행된 후에야 Kubernetes는 Pod의 각종 정보를 초기화하고, 애플리케이션 컨테이너를 생성 및 실행합니다.

 

예제:

apiVersion: v1
kind: Pod
metadata:
  name: init-container-example
spec:
  containers:
  - name: app-container
    image: busybox
    command: ["sh", "-c", "echo 'Application started' && sleep 3600"]
  initContainers:
  - name: init-container-1
    image: busybox
    command: ["sh", "-c", "echo 'Initializing step 1...' && sleep 5"]
  - name: init-container-2
    image: busybox
    command: ["sh", "-c", "echo 'Initializing step 2...' && sleep 5"]

 

Pod 구성 요소

  • initContainers:
    • 두 개의 Init Container가 설정되어 있음.
    • 순서대로 실행:
      1. init-container-1 → "Initializing step 1..." 출력 후 5초 대기.
      2. init-container-2 → "Initializing step 2..." 출력 후 5초 대기.
    • 두 Init Container가 모두 성공적으로 완료되면 애플리케이션 컨테이너 실행.
  • containers:
    • app-container는 실제 애플리케이션 컨테이너로, Init Container가 완료된 후 실행됨.
    • echo 명령을 출력한 뒤 3600초(1시간) 동안 실행 상태를 유지.
  • Init Container 실행 순서
    • Init Container는 반드시 설정된 순서대로 실행되며, 하나라도 실패하면 Pod는 실행되지 않음.
    • 모든 Init Container가 성공적으로 완료되어야 애플리케이션 컨테이너가 실행됨.

Init Container의 주요 용도

  1. 애플리케이션 초기화 작업:
    • 애플리케이션 컨테이너가 실행되기 전에 초기 설정 작업 수행.
    • 예: 데이터 다운로드, 설정 파일 생성, 권한 초기화 등.
  2. 의존성 처리:
    • 애플리케이션 실행 전에 외부 서비스나 리소스가 준비되었는지 확인.
    • 예: 데이터베이스 연결 준비 확인.
  3. 환경 검사 및 설정:
    • 애플리케이션 실행 환경의 조건을 사전에 검사하거나 수정.

22. Kubernetes Deployment 업그레이드 과정

Deployment를 처음 생성하면, 시스템은 하나의 ReplicaSet을 생성하고 사용자가 요청한 개수만큼 Pod 복제본을 생성합니다.

Deployment를 업데이트하면, 시스템은 새로운 ReplicaSet을 생성하고, 이 ReplicaSet의 복제본 수를 1로 확장합니다. 동시에 기존 ReplicaSet의 복제본 수는 2로 줄어듭니다. 이후, 시스템은 설정된 업데이트 정책에 따라 새로운 ReplicaSet과 기존 ReplicaSet의 복제본 수를 순차적으로 조정합니다. 최종적으로, 새로운 ReplicaSet은 요청된 수의 새로운 버전 Pod 복제본을 실행하게 되고, 기존 ReplicaSet의 복제본 수는 0으로 감소합니다.

 

초기 Deployment 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
      - name: example-container
        image: nginx:1.19  # 초기 이미지 버전
        ports:
        - containerPort: 80

 

 

 

  • Deployment는 nginx:1.19 이미지를 사용해 Pod 3개를 생성합니다.
  • 시스템은 이를 관리하기 위해 1개의 ReplicaSet을 생성합니다.

Deployment 업데이트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
      - name: example-container
        image: nginx:1.21  # 업데이트된 이미지 버전
        ports:
        - containerPort: 80

 

  1. image를 nginx:1.21로 업데이트합니다.
  2. 시스템은 새로운 ReplicaSet을 생성하고, 기존 ReplicaSet과 순차적으로 Pod의 수를 조정합니다.
    • 새 ReplicaSet의 Pod 수를 점진적으로 증가.
    • 기존 ReplicaSet의 Pod 수를 점진적으로 감소.

Deployment 업그레이드 과정

  1. Deployment가 업데이트되면, 새로운 ReplicaSet이 생성됩니다.
  2. 새 ReplicaSet의 Pod 복제본이 순차적으로 생성되며, 롤링 업데이트 방식으로 기존 ReplicaSet의 Pod 복제본은 점진적으로 삭제됩니다.
  3. 새 ReplicaSet의 Pod 복제본 수가 설정한 replicas 개수에 도달하면, 기존 ReplicaSet은 Pod 복제본 수를 0으로 줄이고 비활성화 상태가 됩니다.

 

23. Kubernetes Deployment 업그레이드 전략

Deployment의 정의에서 spec.strategy를 통해 Pod 업데이트 전략을 지정할 수 있습니다. 현재 두 가지 전략을 지원하며, 기본값은 RollingUpdate(롤링 업데이트) 입니다.

  1. Recreate(재생성):
    • spec.strategy.type=Recreate로 설정하면, Deployment는 Pod를 업데이트할 때 실행 중인 모든 Pod를 먼저 종료한 후 새로운 Pod를 생성합니다.
  2. RollingUpdate(롤링 업데이트):
    • spec.strategy.type=RollingUpdate로 설정하면, Deployment는 롤링 업데이트 방식을 사용해 Pod를 하나씩 순차적으로 업데이트합니다.
    • 롤링 업데이트 과정은 spec.strategy.rollingUpdate 아래의 두 가지 매개변수로 제어할 수 있습니다:
      • maxUnavailable: 업데이트 중 사용할 수 없는 Pod의 최대 개수.
      • maxSurge: 업데이트 중 기존 Pod 수보다 추가로 생성할 수 있는 Pod의 최대 개수.
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 1  # 최대 1개의 Pod가 비가용 상태
    maxSurge: 2        # 최대 2개의 새로운 Pod 추가 생성

Pod 복제본 수: replicas: 5

업데이트 진행 방식

  1. 초기 상태:
    • 기존 Pod 5개가 모두 실행 중.
  2. 1단계:
    • 기존 Pod 중 1개를 종료(maxUnavailable: 1 설정에 따라).
    • 새로운 Pod 2개 생성(maxSurge: 2 설정에 따라).
    • 총 Pod 수는 최대 5 + 2 = 7개.
  3. 2단계:
    • 기존 Pod를 순차적으로 종료하고, 새로운 Pod를 추가 생성.
  4. 최종 상태:
    • 새로운 Pod 5개가 모두 실행되고, 기존 Pod는 모두 종료.

 

24. Kubernetes DaemonSet 타입의 리소스 특성

DaemonSet 리소스 객체는 Kubernetes 클러스터의 모든 노드에서 하나의 Pod만 실행합니다. 이는 Deployment 리소스 객체와의 가장 큰 차이점이자 고유한 특징입니다. 따라서 DaemonSet의 YAML 파일에서는 replicas를 정의할 수 없습니다.

일반적인 사용 사례:

  1. 각 노드의 로그 수집 작업 수행:
    • 모든 노드에서 개별적으로 로그를 수집하기 위해 사용됩니다.
  2. 각 노드의 상태 모니터링:
    • 모든 노드의 실행 상태를 지속적으로 확인하고 모니터링하는 데 활용됩니다.
반응형

'K8S' 카테고리의 다른 글

Kubernetes 기술 개념 정리 6  (2) 2024.12.12
Kubernetes 기술 개념 정리 5  (0) 2024.12.11
Kubernetes 기술 개념 정리 4  (1) 2024.12.07
Kubernetes 기술 개념 정리 2  (2) 2024.12.05
Kubernetes 기술 개념 정리 1  (1) 2024.12.03

댓글