Pod
- 기본 설명은 해당 글에 정리
- 파드에 명령을 전달할 때 컨테이너를 지정하지 않으면 default 컨테이너가 수신
Pod Status
- Pending: Control Plane에 생성 명령 전달 완료
- ContainerCreating: 특정 노드에 스케줄링되어 컨테이너 생성 중
- Running: 실행 중
- Completed: 작업 완료 (배치 작업을 수행하는 Pod 한정)
- Error: Pod에 에러 발생
- CrashLoopBackOff: 지속적으로 에러가 발생하여 crash 반복
Pod 실행 예제
# nginx pod 실행
kubectl run nginx --image nginx
# 생성 확인
kubectl get pod
# 파드에 명령 전달
kubectl exec nginx -- apt-get update
# 컨테이너에 진입
kubectl exec -it nginx -- bash
Pod 정보 조회, 변경, 삭제 예제
# pod ip 확인
kubectl get pod nginx -o wide
# manifest 확인
kubectl get pod nginx - o yaml
# 상세 정보 확인
kubectl describe pod nginx
# 로그 확인
kubectl logs nginx
# 로그 스트림 유지
kubectl logs -f nginx
# 파드 수정
kubectl edit pod nginx
# 파드 삭제
kubectl delete pod nginx
Pod <-> 로컬 머신 데이터 교환 예제
# 예제 파일 생성
echo 'hello' > hello.txt
# 로컬 머신 -> 파드로 전송
kubectl cp hello.txt nginx:/tmp/hello.txt
# 파드에 명령 내려서 확인해보기
kubectl exec nginx -- cat /tmp/hello.txt
# 파드 -> 로컬 머신으로 전송
kubectl cp nginx:/tmp/hello.txt hello_from_container.txt
manifest 기반 pod 생성 예제
# nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
# file(-f)기반 파드 생성
kubectl apply -f nginx.yaml
# 파일 수정
vi nginx.yaml
# 파드 업데이트 (생성과 명령 같음)
kubectl apply -f nginx.yaml
manifest command, args 지정 예제
- command는 dockerfile의 ENTRYPOINT, args는 CMD를 override한다.
# test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
# 재시작 정책: 실패 시에만.
# 설정하지 않으면 command 이후 종료되면서 다시 재시작하기 때문에 설정해야 함.
restartPolicy: OnFailure
containers:
- image: nginx
name: nginx
# 실행 명령
command: ["/bin/echo"]
# 파라미터
args: ["hello"]
# 위의 manifest 사용
vi test.yaml
kubectl apply -f test.yaml
# command 확인
kubectl logs test
manifest env 지정 예제
# test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- image: nginx
name: nginx
# 환경 변수
env:
- name: hello
value: "world"
# 파드 생성
vi test.yaml
kubectl apply -f test.yaml
# 환경 변수 확인
kubectl exec test -- env | grep hello
볼륨 연결 예제
- pod의 host server는 node이다.
# test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- image: nginx
name: nginx
# 컨테이너에서 volume 설정
volumeMounts:
- mountPath: /data
name: vol
# node에서 volume 설정
volumes:
- name: vol
hostPath:
path: /tmp
# 위의 manifest 붙여넣기
vi test.yaml
# pod 생성
kubectl apply -f test.yaml
# pod 진입
kubectl exec -it test -- /bin/sh
# 마운트된 경로(/data) 이동
cd /data
# 파일 확인 (NODE의 /tmp 내부 파일이 있어야 함.)
ls
# 빈 파일 생성 후 exit
touch hello.txt
exit
# pod 정보(NODE) 확인
kubectl get pod test -o wide
# ssh를 통해 NODE로 진입
gcloud compute ssh gke-cluster-1-default-pool-0825305a-nxv2 --zone=us-central1-c
# /tmp 경로 확인 (hello.txt가 있는지)
ls /tmp
# 로컬 머신으로 복귀
exit
컴퓨팅 리소스 관리 예제
- requests: 최소 사용량 보장 (보통 지속적 작업에 주로 사용하는 듯 함.)
- limits: 최대 사용량 보장 (보통 단발성 작업에 주로 사용하는 듯 함.)
# requests.yaml
apiVersion: v1
kind: Pod
metadata:
name: requests
spec:
containers:
- image: nginx
name: nginx
resources:
# 최소 리소스 사용량
requests:
cpu: "250m" # 0.25core
memory: "500Mi" # 500MB
# limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: limits
spec:
restartPolicy: Never
containers:
- image: python:3.7
name: limits
command: ["python"]
# 무한히 배열에 1 넣기
args: ["-c","arr = []\nwhile True: arr.append(1)"]
resources:
# 최대 리소스 사용량 정리
limits:
cpu: "500m" # 0.5core
memory: "1Gi" # 1GB
# 위의 limits.yaml 파일 붙여넣기
vi limits.yaml
# 파드 생성
kubectl appliy -f limits.yaml
# 지속적으로 상태 확인. 일정 시간이 지나면 Out Of Memory Killed(OOMKilled) 발생 (혹은 cpu 에러)
watch kubectl get pod limits
Pod 라이프사이클
- 노드에 작업이 들어오면 새로운 Pod 생성
- 파드는 자가 치유 X
재시작 정책 (restartPolicy)
- Always: 항상
- OnFailure: 실패 시에만
- Never: 재시작 안 함.
파드 종료
- 파드 종료 시에는 SIGTERM 신호 전송
- 만약 컨테이너 이미지에 정의된 STOPSIGNAL이 SIGKILL이라면 SIGKILL 신호 전송
- 일반적으로 kubectl delete 명령은 30초 이내에 정상적으로 수행됨
- --grace-period 옵션을 지정하면 우아한 종료 유예 기간 재정의
grace-period 예제
# test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- image: nginx
name: nginx
# 위의 test.yaml 붙여넣기
vi test.yaml
# 파드 생성
kubectl apply -f test.yaml
# 파드 즉시 삭제
k delete --grace-period=0 pod test
Pod Label
- 레이블에 대한 기초적인 실습(pod, node에 레이블 추가)은 여기에서
nodeSelector
- manifest에 정의하여 파드가 특정 레이블인 노드에 배치되도록 함.
- 동일한 레이블인 노드가 여러 개라면 최적 노드로 배치됨
nodeSelector 예제
# test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- image: nginx
name: nginx
# 레이블로 노드 선택
nodeSelector:
nodeno: "1"
# 위의 manifest 붙여넣기
vi test.yaml
# 파드 생성
kubectl apply -f test.yaml
# nodeno == 1인 노드 확인
kubectl get nodes -L nodeno
# 파드가 속한 노드가 위에서 확인한 노드가 맞는지 확인
kubectl get pod test -o wide
nodeAffinity
- Pod가 레이블을 통해 특정 노드에 스케줄링되도록 하는 규칙을 정의
- requiredDuringSchedulingIgnoredDuringExecution: 반드시 충족돼야 하는 규칙
- preferredDuringSchedulingIgnoredDuringExecution: 선호하는 규칙
- IgnoredDuringExecution이므로 실행 중 레이블 변경에 대한 부분은 신경 쓰지 않음
- nodeSelectorTerms들을 OR로 묶어서 조건 확인
- matchExpressions는 key와 values에 대해 operator로 연산
# test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
# affinity 설정
affinity:
# nodeAffinity 설정
nodeAffinity:
# 필수 조건
requiredDuringSchedulingIgnoredDuringExecution:
# 내부 연산에 대해 OR로 묶어주는 nodeSelectorTerms
nodeSelectorTerms:
# 표현식 nodeno In ("1")에 대해 참인 노드를 match
- matchExpressions:
- key: nodeno
operator: In
values:
- "1"
containers:
- name: nginx
image: nginx
# 위의 manifest를 붙여넣기
vi test.yaml
# 파드 생성
kubectl apply -f test.yaml
# 노드 확인
# 만약 nodeno In ("3")으로 작성했다면 파드는 Pending됨
kubectl get pod test -o wide
Container Probe
- kubelet에 의해 주기적으로 수행되는 진단
- 컨테이너 내부에서 코드 실행 혹은 네트워크 요청 전송
- 지금까지 만들었던 파드들은 모두 probe를 통과했던 것
체크 방법
- exec: 지정된 명령어 실행. 상태 코드 0으로 종료되면 성공
- grpc: gRPC를 사용하여 원격 프로시저 호출 수행. 응답 status가 SERVING이면 성공
- httpGet: 컨테이너 IP를 통해 지정된 포트 및 경로로 HTTP GET 요청 수행. 상태 코드가 2~400번대면 성공
- tcpSocket: 컨테이너 IP를 통해 지정된 포트로 TCP 검사 수행. 포트 활성화 및 즉시 연결 해제되면 성공
프로브 결과
- Success: 성공
- Failure: 실패
- Unknown: 진단 자체가 실패
프로브 종류
- livenessProbe: 컨테이너가 동작 중인지 여부를 나타냄
- 실패 시: kubelet이 컨테이너를 kill하고 재시작 대상으로 바꿈
- 제공하지 않은 경우: 기본적으로 Success 반환
- readinessProbe: 컨테이너가 요청을 처리할 준비가 되었는지 여부를 나타냄
- 실패 시: 엔드포인트 컨트롤러가 파드에 연관된 모든 서비스들의 엔드포인트에서 파드 IP 주소 제거
- 기본 상태: Failure
- 지원하지 않는 경우: 기본적으로 Success 반환
- startupProbe: 컨테이너 내의 애플리케이션이 시작되었는지 나타냄
- 실패 시: kubelet이 컨테이너를 kill하고 재시작 정책에 따라 처리됨
- 성공 전까지: 다른 프로브 활성화 불가
- 없는 경우: 기본 상태는 Success
livenessProbe 예제
- 헬스 체크 기본값은 10초 동안 3번 실패하면 자가치유
# liveness.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
# 방법은 httpGet
httpGet:
# 기본적으로 nginx image는 /live경로를 제공하지 않기 때문에 실패할 것
path: /live
port: 80
# 위의 manifest 붙여넣기
vi liveness.yaml
# 파드 생성
kubectl apply -f liveness.yaml
# 로그 확인. failed가 떠야 정상
kubectl logs -f liveness
# 경로 생성
# 정상적이지 않지만, 암튼 liveness만 확인하므로 괜찮음
kubectl exec liveness -- touch /usr/share/nginx/html/live
# 상태 확인
kubectl logs -f liveness
kubectl get pod liveness
readinessProbe 예제 (+ exec)
# readiness.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness
spec:
containers:
- name: nginx
image: nginx
readinessProbe:
# exec를 사용하여 probe
exec:
command:
- cat
- /tmp/ready
# manifest 붙여넣기
vi readiness.yaml
# 파드 생성
kubectl apply -f readiness.yaml
# probe 확인 (Events를 확인했을 때, 실패해야 함)
kubectl describe pod readiness
# 경로를 생성해줌
kubectl exec readiness -- touch /tmp/ready
# probe 확인 (describe의 events가 최신화가 안 됐음. 이유를 찾아볼 것)
kubectl describe pod readiness
kubectl get pod readiness
Pod Multiple Container
- 하나의 파드에 여러 컨테이너를 실행시킬 수 있음
- initContainers: 초기화를 위해 먼저 실행되는 컨테이너
- emptyDir: 동일 파드 내 컨테이너끼리의 공유 공간. 파드 삭제 시 삭제됨
다수 컨테이너 실행 예제
# multiple.yaml
apiVersion: v1
kind: Pod
metadata:
name: multiple
spec:
containers:
# container 1
- name: nginx
image: nginx
# container 2
- name: curl
image: curlimages/curl
command: ["/bin/sh"]
args: ["-c", "while true; do sleep 5; curl -s localhost; done"]
# manifest 붙여넣기
vi multiple.yaml
# 파드 생성
kubectl apply -f multiple.yaml
# 로그 확인 (-c 옵션으로 nginx container 확인)
kubectl logs -f multiple -c nginx
초기화 컨테이너 예제
# init.yaml
apiVersion: v1
kind: Pod
metadata:
name: init
spec:
restartPolicy: OnFailure
containers:
- name: busybox
image: k8s.gcr.io/busybox
command: [ "ls" ]
args: [ "/tmp/moby" ]
# 컨테이너의 /tmp 경로에 마운트
volumeMounts:
- name: workdir
mountPath: /tmp
# 초기화 컨테이너
initContainers:
- name: git
image: alpine/git
command: ["sh"]
args:
- "-c"
- "git clone https://github.com/moby/moby.git /tmp/moby"
# 초기화 컨테이너의 /tmp 경로에도 마운트
volumeMounts:
- name: workdir
mountPath: "/tmp"
# 공유 볼륨
volumes:
- name: workdir
emptyDir: {}
# manifest 붙여넣기
vi init.yaml
# 파드 생성
kubectl apply -f init.yaml
# 파드 확인 (STATUS Init:0/1)
kubectl get pods
# 로그 확인 (git cloning 확인)
kubectl logs -f init-container -c git
# cloning 완료 확인 후 다시 파드 확인 (COMPLETED)
kubectl get pods
# 파드 로그 확인 (main container)
kubectl logs init
'GitOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Controller (0) | 2025.02.13 |
---|---|
[Kubernetes] 리소스 (0) | 2025.01.15 |
[Kubernetes] 클러스터 생성 (0) | 2025.01.14 |
[Kubernetes] 개념 (0) | 2025.01.13 |