가상환경 플랫폼 실행 단위
가상머신: Instance
도커: Container
쿠버네티스: Pod
Containers in Pod
기본적으로 하나의 Pod 당 1개의 컨테이너를 갖게 하는 걸 권장한다. 사이드카로 보조 컨테이너를 넣어 2개의 컨테이너를 돌아가게 하는 경우도 있지만, 3개부터는 권장하지 않는다.
쿠버네티스에서는 NAT 통신 없이도 Pod 고유의 IP + 컨테이너 별 Port 주소를 통해 각 컨테이너에 접근할 수 있다. 같은 Pod 내의 컨테이너들은 사실 상 모두 같은 IP 주소를 가진 상태이기에 서로 localhost와 개별 포트넘버를 통해 네트워크 접근을 한다.
같은 Pod 내의 컨테이너들은 반드시 동일 노드에 할당되며 동일한 생명 주기를 가진다. Pod 삭제 시, 그 Pod 내의 모든 컨테이너가 전부 같이 삭제된다. 또한 모두 같은 볼륨에 연결되어 있어 파일 시스템을 기반으로 서로 파일을 주고 받을 수 있다.
[labels] in [metadata]
# 원래 상태
kubectl get pod mynginx -o yaml
# 라벨 추가
kubectl label pod mynginx hello=world
# 변경점 확인
kubectl get pod mynginx -o yaml
# 라벨 확인
kubectl get pod mynginx --show-labels
# run label이 다른 또 하나의 Pod 생성
kubectl run yournginx --image nginx
# key가 run인 Pod 출력
kubectl get pod mynginx -l run
-l = label
# key가 run, value가 mynginx인 Pod 출력
kubectl get pod mynginx -l run=mynginx
# 워커 노드1에 라벨 부여
kubectl label node k8s-w1 disktype=ssd
# 워커 노드2에 라벨 부여
kubectl label node k8s-w2 disktype=hdd
# 워커 노드3에 라벨 부여
kubectl label node k8s-w3 disktype=hdd
# disktype에 대해 노드들의 라벨 확인
kubectl get node --show-labels | grep disktype
# 새로 만들 Pod(node-selector)의 yaml 파일 생성
nano node-selector.yaml
# node-selector.yaml
apiVersion: v1
kind: Pod
metadata:
name: node-selector
spec:
containers:
- name: nginx
image: nginx
# 특정 노드 라벨 선택
nodeSelector:
disktype: ssd
# nodeSelector 프로퍼티로 인해 이 Pod는 disktype이 ssd인 노드에서 실행될 것이다.
# node-selector Pod 생성
kubectl apply -f node-selector.yaml
# Pod가 어느 노드에서 실행되고 있는지 확인 : disktype을 ssd로 지정해뒀던 k8s-w1에서 실행되고 있을 것이다.
kubectl get pod node-selector -o wide
# node-selector.yaml 수정
nano node-selector.yaml
# node-selector.yaml
apiVersion: v1
kind: Pod
metadata:
name: node-selector
spec:
containers:
- name: nginx
image: nginx
# 특정 노드 라벨 선택
nodeSelector:
disktype: hdd
# disktype이 hdd인 노드는 2개이기 때문에 쿠버네티스 마스터가 알아서 판단해서 할당한다.
# yaml 파일 재적용
kubectl apply -f node-selector.yaml
# Pod가 어느 노드에서 실행되고 있는지 확인 : k8s-w2, k8s-w3 중 하나일 것이다.
kubectl get pod node-selector -o wide
[command], [args] in [spec]
# vi editor 사용해보기 - i로 편집 모드 진입 → 수정 후 esc키 → :wq 입력으로 저장 & 나가기
vi cmd.yaml
# cmd.yaml
apiVersion: v1
kind: Pod
metadata:
name: cmd
spec:
restartPolicy: OnFailure
containers:
- name: nginx
image: nginx
# 실행명령
command: ["/bin/echo"]
# 파라미터
args: ["hello"]
# 여기서 눈여겨 봐야 하는 부분은 restartPolicy인데, Always, Never, OnFailure 3가지 값을 줄 수 있다.
# Always: Pod 종료 시 항상 재시작(default), Never: 재시작을 시도하지 않음, OnFailure: 실패 시 재시작
# 그런데 여기서 echo 명령은 웹 서버와 다르게 실행 후 종료되기 때문에 OnFailure로 주어야 하는 것.
# Pod 생성
kubectl apply -f cmd.yaml
-f = file
# 로그 확인 : 만약 restartPolicy를 Always로 했다면 무수히 많은 hello가 찍힐 것이다.
kubectl logs -f cmd
-f = flow
Volume Mounting
# volume.yaml 파일 생성
vi volume.yaml
# volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume
spec:
containers:
- name: nginx
image: nginx
# 컨테이너 내부의 연결 위치 지정
volumeMounts:
- mountPath: /container-volume
name: my-volume
# host 서버의 연결 위치 지정
volumes:
- name: my-volume
hostPath:
path: /home
# [spec]-[containers]-[volumeMounts] 부분에 컨테이너 내부의 경로와 이름을 잡고,
# [spec]-[volumes] 부분에 노드(호스트 서버) 쪽의 경로와 이름을 잡는다.
# Pod 생성
kubectl apply -f volume.yaml
# volume Pod 안으로 접속해 연결시켜준 위치를 ls 명령어를 통해 확인한다.
kubectl exec volume -- ls /container-volume
# 호스트 서버의 디렉토리에서 목록 출력
ls /home
[resources]-[limits]-[cpu], [memory] in [spec] for Resource Management
# limits.yaml 파일 생성
vi limits.yaml
# limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: limits
spec:
restartPolicy: OnFailure
containers:
- name: mynginx
image: python:3.7
command: [ "python" ]
args: [ "-c", "arr = []\nwhile True: arr.append(range(1000))" ]
resources:
limits:
cpu: "500m"
memory: "1Gi"
# 파이썬 이미지를 사용해 파이썬 코드를 작성하고 수행하는 컨테이너를 만들 수 있다.
# limits Pod 생성
kubectl apply -f limits.yaml
# watch 명령어의 지속적인 체크로 STATUS 변화 확인 : Running → OOMKilled
watch -d 'kubectl get pod limits'
[livenessProbe] in [spec] for Health Check
# yaml 파일 생성
vi liveness.yaml
# liveness.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
httpGet:
path: /live
port: 80
# 상태 확인 및 자가치유 부분은 확인 과정이 복잡하기 때문에 단순히 위의 속성을 주게 되면
#정상적으로 작동하는지 실시간으로 체크하고 자가치유를 수행한다는 것만 알면 될 것 같다.
2개의 컨테이너 실행 (Sidecar)
# yaml 파일 생성
vi second.yaml
# second.yaml
apiVersion: v1
kind: Pod
metadata:
name: second
spec:
containers:
- name: nginx
image: nginx
- name: curl
image: curlimages/curl
command: ["/bin/sh"]
args: ["-c", "while true; do sleep 5; curl -s localhost; done"]
# containers 아래에 name이 두 개가 있는 모습. 하나의 Pod 안에 두 개의 Container를 생성하는 것이다.
# 아래의 명령어는 5초마다 로컬호스트로 시그널을 보내며, 응답을 받지 못하면 에러가 뜨게 되는 코드이다.
# Pod 생성
kubectl apply -f second.yaml
# 생성 확인. 그리고 다른 Pod들과는 다르게 second는 READY 컬럼에 2개가 있는 것을 볼 수 있다.
kubectl get pod
# second 컨테이너의 (nginx 컨테이너에 대한) 로그를 출력
kubectl logs second -f -c nginx
-f = flow
-c = container
# Pods 확인 명령어
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\sort
Init Container
# yaml 파일 생성
vi init-container.yaml
# init-container.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-container
spec:
restartPolicy: OnFailure
containers:
- name: busybox
image: k8s.gcr.io/busybox
command: [ "ls" ]
args: [ "/tmp/moby" ]
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"
volumeMounts:
- name: workdir
mountPath: "/tmp"
volumes:
- name: workdir
emptyDir: {}
# 메인 컨테이너가 실행되기 전에 초기화 컨테이너에서 미리 git pull을 받아서
# 컨테이너끼리의 공유 공간인 emptyDir volume(/tmp)를 통해 git 레파지토리를 전달한다.
# Pod 생성
kubectl apply -f init-container.yaml
# initContainer 로그 확인
kubectl logs init-container -f -c git
# 메인 컨테이너(busybox) 로그 확인
kubectl logs init-container
Delete all Pods
kubectl delete pod --all
'IT > Kubernetes' 카테고리의 다른 글
Kubernetes Components & Operation (0) | 2021.10.29 |
---|---|
[Lab] Kubernetes Pod YAML file / Namespace (0) | 2021.10.28 |
Configure of Kubernetes on VMware (Windows10) (0) | 2021.10.28 |
Kubernetes 기능과 용어 (0) | 2021.10.27 |