[에스넷시스템 부트캠프] TIL Day 32 - 쿠버네티스 Pod 2

2025. 7. 3. 21:53·TIL
728x90
반응형

1. [실습] 각각의 프로브를 사용한 livenessProbe 구성해보기 

쿠버네티스에서 livenessProbe는 컨테이너가 정상적으로 동작 중인지 여부를 주기적으로 확인하여 비정상일 경우 자동으로 재시작해주는 메커니즘이다. 이 실습에서는 exec 프로브를 활용하여 /tmp/healthy 파일 존재 여부를 기준으로 헬스 체크를 수행한다.

 

파라미터 종류

initialDelaySeconds : 컨테이너 시작 후 헬스체크까지 대기 시간

periodSeconds : 헬스 체크 주기

timeoutSeconds : 헬스체크 명령 실행 제한 시간

successThreshold : n회 이상 성공하면 정상으로 간주

failureThreshold : n회 연속 실패시 비정상으로 간주하고 컨테이너 재시작 트리거 됨

 

# vi exec-liveness.yaml

apiVersion: v1
kind: Pod
metadata:
  name: exec-liveness
spec:
  containers:
  - name: liveness
    image: docker.io/library/rockylinux:9.2
    args:
    - /bin/sh
    - -c
    - "dnf install -y coreutiles && touch /tmp/healthy && sleep 15 && rm -f /tmp/healthy && sleep 300"
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      periodSeconds: 3
      initialDelaySeconds: 30
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 3
  1. 컨테이너 시작 시 coreutils 설치
  2. /tmp/healthy 파일 생성
  3. 15초 후 해당 파일 삭제
  4. 이후 300초간 sleep
  5. /tmp/healthy 파일이 존재하는지 주기적으로 확인 → 없으면 liveness 실패로 간주하고 컨테이너 재시작

 

동작 로그 예시 

---- Thu Jul  3 07:18:40 PM KST 2025 ----
Events:
  Type     Reason     Age                 From               Message
  ----     ------     ----                ----               -------
  Normal   Scheduled  101s                default-scheduler  Successfully assigned default/exec-liveness to node1.example.com
  Normal   Killing    65s                 kubelet            Container liveness failed liveness probe, will be restarted
  Normal   Pulled     35s (x2 over 101s)  kubelet            Container image "docker.io/library/rockylinux:9.2" already present on machine
  Normal   Created    35s (x2 over 101s)  kubelet            Created container: liveness
  Normal   Started    35s (x2 over 101s)  kubelet            Started container liveness
  Warning  Unhealthy  2s (x5 over 71s)    kubelet            Liveness probe failed: cat: /tmp/healthy: No such file or directory

 

 

2. [실습] httpGet 명령을 사용하는 livnessProbe 실습

httpGet 프로브는 컨테이너 내부에서 HTTP 요청을 보내 해당 애플리케이션이 응답 가능한 상태인지 확인한다.

가장 일반적으로 사용되는 헬스체크 방식이다. 

 

# vi httpd-liveness.yaml

apiVersion: v1
kind: Pod
metadata:
  name: http-liveness
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/e2e-test-images/agnhost:2.40
    args:
    - liveness
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      periodSeconds: 3

 

동작 로그 예시 

 

---- Thu Jul  3 07:32:20 PM KST 2025 ----
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  2m6s                 default-scheduler  Successfully assigned default/http-liveness to node1.example.com
  Normal   Pulled     71s (x4 over 2m5s)   kubelet            Container image "registry.k8s.io/e2e-test-images/agnhost:2.40" already present on machine
  Normal   Created    71s (x4 over 2m5s)   kubelet            Created container: liveness
  Normal   Started    71s (x4 over 2m5s)   kubelet            Started container liveness
  Normal   Killing    71s (x3 over 107s)   kubelet            Container liveness failed liveness probe, will be restarted
  Warning  Unhealthy  59s (x10 over 113s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500

 

 

3. [실습] tcpSocket 명령을 사용하는 livenessProbe 실습

tcpSocket 방식은 HTTP 요청 없이, 단순히 TCP 연결이 가능한지만 확인하는 방식이다. 

주로 간단한 포트 레벨의 헬스체크에 사용된다.

 

# vi tcp-liveness.yaml

apiVersion: v1
kind: Pod
metadata:
  name: tcp-liveness
spec:
  containers:
  - name: goproxy
    image: registry.k8s.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8081
      initialDelaySeconds: 15
      timeoutSeconds: 1
      periodSeconds: 10
      successThreshold: 1
      failureThreshold: 3

 

동작 로그 예시 

---- Thu Jul  3 07:46:40 PM KST 2025 ----
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  93s                default-scheduler  Successfully assigned default/tcp-liveness to node1.example.com
  Normal   Pulled     12s (x3 over 92s)  kubelet            Container image "registry.k8s.io/goproxy:0.1" already present on machine
  Normal   Created    12s (x3 over 92s)  kubelet            Created container: goproxy
  Normal   Started    12s (x3 over 92s)  kubelet            Started container goproxy
  Warning  Unhealthy  12s (x6 over 72s)  kubelet            Liveness probe failed: dial tcp 10.10.11.93:8081: connect: connection refused
  Normal   Killing    12s (x2 over 52s)  kubelet            Container goproxy failed liveness probe, will be restarted

 

 

4. 초기화 컨테이너 (Init Container) 

  • 앱 컨테이너 실행 전에 먼저 순차적으로 실행되는 컨테이너
  • 일반 컨테이너와 동일한 spec을 사용하지만, 반드시 완료(완료 상태 종료)되어야 다음 단계로 진행
  • 앱 컨테이너 실행 전 사전 작업 (예: 설정 파일 생성, 외부 의존성 체크 등)에 사용
  • 실패 시 성공할 때까지 재시작 반복
  • restartPolicy: Never일 경우 초기화 컨테이너 실패 시 파드 전체가 실패 상태로 종료

 

 

5. 정적 파드 (Static Pod) 

  • API 서버와 무관하게 kubelet이 직접 관리하는 파드
  • 주로 노드에 고정적으로 동작해야 하는 시스템 컴포넌트나 관리 목적 파드에 사용
  • Kubelet은 /etc/kubernetes/manifests/ 디렉토리를 주기적으로 감시하며, 여기에 YAML 파일이 생성되면 자동 실행
  • 정적 파드의 이름에는 호스트 이름 앞에 하이픈(-)을 붙여 접미사로 추가됨

 

6. 자원 요청 & 제한

  • requests: 파드가 최소한으로 보장받아야 할 리소스
  • limits: 파드가 사용할 수 있는 최대 리소스 한도
  • Pod에서 컨테이너에 대한 리소스 요청을 지정하면 kube-scheduler는 이 정보를 사용하여 Pod가 배치될 노드를 결정

 

1) CPU 자원 요청과 상한 제한

  • Pod 스케줄링은 CPU 자원 요청을 충분히 만족하는 경우에만 노드에 스케줄링됨
  • CPU는 탄력적인 자원으로, 제한을 초과해도 OOM처럼 종료되지는 않지만, 성능 저하가 발생할 수 있음
  • requests를 만족하지 못하는 경우 파드는 Pending 상태에 머무름

 

2) MEM 자원 요청과 상한 제한

  • Memory는 고정 자원으로 초과 사용이 불가하며, limit 초과 시 즉시 종료됨
  • 종료된 컨테이너는 kubelet에 의해 자동 재시작
  • requests를 만족하지 못하면 마찬가지로 파드는 Pending 상태로 남음

 

3) 예시 

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-resource
spec:
  containers:
  - name: nginx-container
    image: nginx:1.14
    ports:
    - containerPort: 80
      protocol: TCP
    resources:
      requests: 
        cpu: 200m
        memory: 250Mi
      limits:
        cpu: 1
        memory: 500Mi

 

# kubectl describe pod nginx-pod-resource

 

7. 파드 환경변수

  • 파드 내 컨테이너가 실행될 때 필요한 값을 환경변수(env) 형태로 선언
  • 실행 시점에 앱 설정, 외부 정보, 비밀값 등을 주입하기 위해 사용
  • 파드 필드 또는 컨테이너 필드 정보를 노출할 수 있음
  • 환경 변수 선언 방법
    • yaml 파일에 env:에 선언
    • kubectl run 명령어에 --env=에 선언

 

8. 다중 컨테이너 Pod 디자인 패턴

Kubernetes는 여러 컨테이너를 하나의 파드에 묶어서 구성할 수 있으며, 이때 각 컨테이너의 역할에 따라 설계 패턴을 적용한다.

대표적으로 Sidecar, Adapter, Ambassador 패턴이 있다. 

1) Sidecar 패턴

  • 보조 역할 컨테이너가 메인 애플리케이션을 보완
  • 로깅, 모니터링, 설정 동기화 등에 사용

예제 YAML 

 

apiVersion: v1
kind: Pod
metadata:
  name: sidecar
spec:
  volumes:
  - name: sharedlogs
    emptyDir: {}
  containers:
  - name: app-container
    image: alpine
    command: ["/bin/sh"]
    args: ["-c", "while true; do date >> /var/log/app.log; sleep 5; done"]
    volumeMounts:
    - name: sharedlogs
      mountPath: /var/log
  - name: sidecar-container
    image: nginx:1.14
    ports:
    - containerPort: 80
    volumeMounts:
    - name: sharedlogs
      mountPath: /usr/share/nginx/html

 

로그 파일을 출력하는 화면

 

2) Adapter 패턴

  • 출력 데이터를 표준 포맷으로 가공하는 중간 컨테이너
  • 모니터링, 수집기 시스템과 연동 시 주로 사용

 

예시 YAML 

apiVersion: v1
kind: Pod
metadata:
  name: adapter
spec:
  volumes:
  - name: sharedlogs
    emptyDir: {}
  containers:
  - name: app-container
    image: alpine
    command: ["/bin/sh"]
    args: ["-c", "while true; do date > /var/log/top.txt && top -n 1 -b >> /var/log/top.txt; sleep 5; done"]
    volumeMounts:
    - name: sharedlogs
      mountPath: /var/log
  - name: adapter-container
    image: alpine
    command: ["/bin/sh"]
    args: ["-c", "while true; do (echo '<pre>' > /var/log/status.html) && \
      (cat /var/log/top.txt | head -1 >> /var/log/status.html) && \
      (cat /var/log/top.txt | grep '^Mem:' | awk -F, '{print $1}' >> /var/log/status.html) && \
      (cat /var/log/top.txt | grep '^CPU:' | awk '{print $1, $8, $9}' >> /var/log/status.html) && \
      (echo '</pre>' >> /var/log/status.html); sleep 5; done"]
    volumeMounts:
    - name: sharedlogs
      mountPath: /var/log
  - name: sidecar-container
    image: nginx:1.14
    ports:
    - containerPort: 80
    volumeMounts:
    - name: sharedlogs
      mountPath: /usr/share/nginx/html
  • app-container 
    • 생산자 역할
    • 5초마다 시스템의 현재 시간과 top 명령어 결과를 /var/log/top.txt에 저장
    • top -n 1 -b  명령어로 현재 CPU, 메모리 등 자원 사용 상태 출력
  • adapter-container
    • 어댑터 역할
    • top.txt 파일을 읽고 원하는 정보만 추출하며 status.html 파일로 가공
    • 포함되는 정보: 현재 시간, 메모리 사용량, CPU 사용량
    • 출력 형식은 HTML -> 웹 브라우저에서 보기 좋게 출력
  • sidecar-container
    • 웹 서버 역할
    • nginx가 실행되며 /usr/share/nginx/html 디렉토리를 서비스
    • adapter-container가 생성한 status.html 파일을 웹 페이지로 제공

=> app-container가 데이터를 만들고, adapter-container가 가공하며, sidecar-container가 사용자에게 제공하는

Producer-Adapter-Viewer 구조 

 

3) Ambassador 패턴

  • 애플리케이션과 외부 세계 사이에서 프록시 역할 수행
  • 외부 API 요청시 Ambassador 컨테이너가 API 게이트웨이처럼 중계 
  • 인증, 보안, 트래픽 조정 등을 담당하는 프록시/브로커 컨테이너

 

✍️ 하루 회고

오늘은 어제 개념만 훑어봤던 프로브 실습을 시작으로 환경 변수, 초기화 컨테이너, 정적 파드, 자원 요청과 제한, 그리고 다중 컨테이너 파드 디자인 패턴까지 정말 다양한 쿠버네티스 개념들을 학습하고 실습해보았다.

단순히 문서로 개념만 보는 것과 실제로 손으로 YAML을 작성하고 파드 상태를 확인하는 경험은 확실히 다르다.
직접 실습을 통해 눈으로 확인하고 손으로 쳐보는 과정이 반복되니, 처음엔 낯설게 느껴졌던 쿠버네티스 코드와 구조도 점점 익숙해지는 것 같다.

아직 복습이 부족해서 개념을 바로바로 설명하긴 어렵지만, 부트캠프에서 제공된 서적과 함께 자격증 준비를 병행하면서 더 탄탄히 다져나갈 계획이다.
이런 과정을 통해 더 능숙하게 쿠버네티스를 다룰 수 있을 거라는 확신이 생긴 하루였다. 💪

728x90
반응형

'TIL' 카테고리의 다른 글

[에스넷시스템 부트캠프] TIL Day 34 - Kubernetes DaemonSet, StatefulSet, Service, Job, CronJob, Volume  (2) 2025.07.07
[에스넷시스템 부트캠프] TIL Day 33 - ReplicationController, ReplicaSet, Deployment, RollingUpdate & RollingBack, Label, Selector, ConfigMap  (0) 2025.07.04
[에스넷시스템 부트캠프] TIL Day 31 - 쿠버네티스 Pod 1  (1) 2025.07.02
[에스넷시스템 부트캠프] TIL Day 30 - 쿠버네티스 아키텍처  (0) 2025.07.01
[에스넷시스템 부트캠프] TIL Day 29 - Podman Volume, Compose, 쿠버네티스  (0) 2025.06.30
'TIL' 카테고리의 다른 글
  • [에스넷시스템 부트캠프] TIL Day 34 - Kubernetes DaemonSet, StatefulSet, Service, Job, CronJob, Volume
  • [에스넷시스템 부트캠프] TIL Day 33 - ReplicationController, ReplicaSet, Deployment, RollingUpdate & RollingBack, Label, Selector, ConfigMap
  • [에스넷시스템 부트캠프] TIL Day 31 - 쿠버네티스 Pod 1
  • [에스넷시스템 부트캠프] TIL Day 30 - 쿠버네티스 아키텍처
yulee_to
yulee_to
  • yulee_to
    yulee
    yulee_to
  • 전체
    오늘
    어제
    • 전체 글 (170)
      • CS (2)
        • OS (0)
        • DB (0)
        • Network (2)
      • Develop (1)
        • Spring (9)
        • Java (12)
        • Python (0)
        • Algorithm (0)
        • 기타 (0)
      • PS (39)
        • C++ (39)
        • Java (0)
      • TIL (61)
      • Book (39)
        • 자바의 신 (32)
        • 스프링 입문을 위한 자바 객체 지향의 원리와 이해 (7)
      • ETC (4)
        • Blog (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    1일1백준
    에스넷시스템
    C++
    TiL
    Java
    클라우드 활용 네트워크 엔지니어 부트캠프
    멀티캠퍼스it부트캠프
    aws
    boj
    부트캠프후기
    스프링 입문
    자바
    백준
    객체지향
    스터디
    에스넷시스템 부트캠프
    알고리즘
    EC2
    GodOfJava
    자바의 신
  • 최근 댓글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
yulee_to
[에스넷시스템 부트캠프] TIL Day 32 - 쿠버네티스 Pod 2
상단으로

티스토리툴바