Pod란?
- 컨테이너 애플리케이션의 기본 실행단위.
- 배포할 수 있는 가장 작고 간단한 단위
- 파드 내부에는 여러개의 컨테이너가 있음. 보통 2개, 많으면 3개
- 같은 목적으로 자원을 공유하기 위해서 동일한 워커노드에서 실행
- 동일 IP로 접근하며, Pod 안 컨테이너와 통신할 때는 포트를 통해 접속
- .yaml파일을 통해 pod를 생성한다.
yaml 파일 예시 (app.yaml)
apiVersion: v1
kind: Pod
metadata:
name: app
labels:
app: app
spec:
containers:
- image: takytaky/app:v1
name: app-container
ports:
- containerPort: 80
protocol: TCP
이 yaml 파일을 실행하려면 다음과 같이 입력한다.
kubectl apply -f app.yaml
pod의 실행현황을 보고싶다면 다음과 같이 입력한다.
kubectl get pods -o wide # 전체 pod 확인
kube describe pod app # 특정 pod 확인
pod에 bash로 붙고싶다면 다음과 같이 입력한다.
kubectl exec -it app -- /bin/bash
pod를 지우고 싶다면 다음과 같이 입력한다.
kubectl delete pod app # app이란 pod 지우기
kubectl delete pods --all -n cpu-example # 특정 namespace의 pods 전부 지우기
yaml에서 환경변수 설정하기
yaml에서 환경변수를 설정할 수 있다.
apiVersion: v1
kind: Pod
metadata:
name: app-env
labels:
app: app-env
spec:
containers:
- name: container-env
image: takytaky/app:v1
ports:
- containerPort: 80
env:
- name: ENV01
value: "value01"
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: container-env
resource: requests.cpu
- name: CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: container-env
resource: limits.cpu
liveness probe : 컨테이너가 동작중인지 확인. 이 진단이 실패하면 정책에 따라 컨데이터 재 시작
liveness probe 예시 (exec-liveness.yaml)
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: registry.k8s.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Readiness probe : 이 probe가 존재한다면 초기상태는 failure로 시작한다. 무조건 통과해야 하는 절차가 됨. 진단이 실패하면 pod의 ip주소를 제거한다. 그러면 master가 다른 pod에게 해당 업무를 전달할 것이다.
Readiness probe 예시 (tcp-liveness-readiness-failure.yaml) : 이 pod는 port 8181이 잘못입력되어 바로 제거될 것이다.
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: registry.k8s.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8181
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8181
initialDelaySeconds: 15
periodSeconds: 20
pod resource(cpu, memory 할당)
- momory는 컨테이너에 2GB가 있고, 물리적으로는 4GB가 있으면 4GB를 다 쓸 수 있다. 이로 인해 OOM에러가 발생하는 것을 막기 위해 .spec.containers[].resources.limits.memory 설정을 해야 한다.
- CPU는 자원을 쪼개서 사용이 가능하다.
apiVersion: v1
kind: Pod
metadata:
name: app
labels:
app: app
spec:
containers:
- name: app
image: takytaky/app
resources:
requests:
cpu: 0.1
memory: 200M
limits:
cpu: 0.5
memory: 1G
ports:
- containerPort: 8080
초기화 컨테이너 (initContainer)
- 초기화 할 목적으로
- 보안상의 이유로 이미자와 같이 두면 안되는 앱 소스 코드를 별도로 관리할 때 유용
- initContainer가 실패하면 계속 재시작되며, init container가 모두 실행된 후 앱 컨테이너가 실행된다.
apiVersion: v1
kind: Pod
metadata:
name: init-demo
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: workdir
mountPath: /usr/share/nginx/html
initContainers:
- name: install
image: busybox
command:
- wget
- "-O"
- "/work-dir/index.html"
- http://info.cern.ch
volumeMounts:
- name: workdir
mountPath: "/work-dir"
dnsPolicy: Default
volumes:
- name: workdir
emptyDir: {}
멀티 컨테이너 파드 디자인 패턴
- SideCar Pattern : 확장, 강화용도로 컨테이너를 추가
- Ambassador Pattern : 프록시 역할을 하는 컨테이너를 추가
- Adapter Pattern : 파드 외부로 노출되는 정보를 표준화 하기 위해 컨테이너를 추가
Label, Selector, Annotation
labels: 에 정의된 것들을 key-value로 구성(key만 있어도 됨)
Selector : kubectl get pods {pod name}이 아닌 label을 기반으로 검색할 수 있다.
Annotation : k8s에서 필요한 사항을 메타데이터에 기록하는 추가정보(주석)
# label01.yaml
apiVersion: v1
kind: Pod
metadata:
name: label-app01
labels:
app: nodejs
environment: develop
release: beta
spec:
containers:
- name: nodejs
image: takytaky/app:v1
ports:
- containerPort: 80
# label02.yaml
apiVersion: v1
kind: Pod
metadata:
name: label-app02
labels:
app: nodejs
environment: production
release: beta
spec:
containers:
- name: nodejs
image: takytaky/app:v1
ports:
- containerPort: 80
# label03.yaml
apiVersion: v1
kind: Pod
metadata:
name: label-app03
labels:
app: nodejs
environment: develop
release: stable
spec:
containers:
- name: nodejs
image: takytaky/app:v1
ports:
- containerPort: 80
# label04.yaml
apiVersion: v1
kind: Pod
metadata:
name: label-app04
labels:
app: nodejs
environment: production
release: stable
spec:
containers:
- name: nodejs
image: takytaky/app:v1
ports:
- containerPort: 80
이 모든 것을 실행하면 4개의 pod가 생성된다.
pods의 label을 전체 보려면 다음과 같다.
kubectl get pods --show-labels
pod들을 selector를 통해 검색하려면 다음과 같다.
kubectl get pods -l app=nodejs
노드에도 label이 있다.
kubectl get nodes --show-labels
노드에 label을 추가하려면 다음과 같다.
kubectl label nodes {node name} {key}={value}
노드에 label을 삭제하고 싶으면 다음과 같다.
kubestl label node {node name} {key}-
annotation은 다음과 같이 yaml에서 작성될 수 있다.
apiVersion: v1
kind: Pod
metadata:
name: annotation-nodejs
labels:
app: nodejs
annotations:
manufacturer: "takytaky"
e-mail: "takytaky@example.com"
release-version: "v1"
spec:
containers:
- name: nodejs
image: takytaky/app:v1
ports:
- containerPort: 80
조회는 json형태, describe 형태 2가지가 있다.
kubectl get pod annotation-nodejs -o jsonpath='{.metadata.annotations}'
kubectl describe pod {pod name}
Controller
Pod를 배포, 관리하는 도구 (Replicaset, Deployment, DaemonSet)
Replicaset
지정한 숫자만큼 항상 클러스터 안에서 실행되도록 관리 (복제를 통한 pod 수량 유지)
Replicaset의 3요소
- Label selector : (name은 중복되면 안되니까 name은 지정하지 않고, label만 지정)
- replicas : 유지할 pod 수. 기본값은 1
- pod template : pod의 정의(metadata, spec 등)
Repolicaset 예제
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-nginx
spec:
selector:
matchLabels:
app: rs-nginx
template:
metadata:
labels:
app: rs-nginx
spec:
containers:
- name: replicaset-nginx-container
image: nginx
ports:
- containerPort: 80
replicas: 3
replica의 scale을 늘리거나 줄이고 싶은 경우
kubectl scale rs replicaset-nginx --replicas={count}
replicaset이 생성한 pod은 지울 수 없다 replicaset 자체를 지워야 한다.
kubectl delete rs {replicaset name}
replicaset만 지우고 pod를 유지하고 싶다면
kubectl delete replicaset --cascade=orphan {replicaset name}
Deployment(디플로이먼트)
레플리카셋을 통해서 복제된 pods를 관리하고 선언적 업데이트가 가능한 컨트롤러. 레플리카셋을 관리한다.
Deployment 예제
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
labels:
app: deploy-nginx
annotations:
kubernetes.io/change-cause: version 1.16.0
spec:
replicas: 3
strategy:
type: RollingUpdate
selector:
matchLabels:
app: deploy-nginx
template:
metadata:
labels:
app: deploy-nginx
spec:
containers:
- name: deploy-nginx
image: nginx:1.16.0
ports:
- containerPort: 80
Deployment로 replicaset의 pod 수를 조절 할 수 있다.
kubectl scale deploy {deployment_name} --replicas={count}
Deployment로 컨테이너 image를 변경할 수도 있다.
1. set image (잘 안쓰는 명령)
# 현재 image 확인
kubectl get deploy {deployment_name} -o=jsonpath="{.spec.template.spec.containers[0].image}{'\n'}"
# 이미지 변경
kubectl set image deployment {deployment_name} {deployment_name}={image_name}
# 변경된 image 확인
kubectl get deploy {deployment_name} -o=jsonpath="{.spec.template.spec.containers[0].image}{'\n'}"
2. yaml 파일을 수정한 후 apply 실행
nano {deployment}.yaml
kubectl apploy -f {deployment}.yaml
Deployment를 삭제할 때는
kubectl delete deploy {deployment_name}
미사용중인 replicaset을 삭제할 수 있다.
kubectl delete rs {replicaset_name}
DaemonSet(데몬셋)
모든 노드에 pod를 실행해야 할 때(예 : 운영 cluster) 사용되는 컨트롤러. worker node 뿐만 아니라 master node에서도 실행된다.
예시 (deamonset.yaml)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-app
labels:
k8s-app: daemonset-app
spec:
selector:
matchLabels:
name: daemonset-app
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: daemonset-app
spec:
tolerations:
# this toleration is to have the daemonset runnable on master nodes
# remove it if your masters can't run pods
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
containers:
- name: daemonset-app
image: takytaky/app:v1
env:
- name: appenv
value: daemonset
DaemonSet 특징
* taint 속성은 오염되었다는 뜻으로, pod가 자동생성되지 않도록 Schedule에서 피해가는데, 이는 보통 Master node에만 있는 속성이다. 그런데 tolerations(관용, 무효)속성을 달아놓으면 master node에도 pod를 실행할 수 있다.
* master node의 taint 속성 보기
kubectl describe nodes master | grep Taints
* updateStrategy의 전략으로는 OnCreate가 없고 OnDelete가 있다. DaemonSet은 빈 노드가 없는것이 기본이라 뭔가를 생성하고 지울 수 없다. 그래서 선 삭제 후 생성하는 식으로 update가 이루어 지며, 이는 Replicaset과 반대로 동작(선 생성 후 삭제)한다.
Job(잡)
실행 후 종료될 pod를 생성하는 컨트롤러. pod가 실행 된 후 죽지 않기 위해 Always라는 기본 정책을 사용하지만, Job은 OnFailure나 Never로 정의한다. 종료된 Job 삭제는 수동으로 해야 하며, ttlSecondAfterFinished로 자동 종료 설정을 할 수 있다.
job 예시파일(job-batch.yaml)
apiVersion: batch/v1
kind: Job
metadata:
name: batch
spec:
template:
spec:
containers:
- name: batch
image: takytaky/batch
restartPolicy: Never
ttlSecondsAfterFinished: 100
Job 특징
* completions : 몇번의 완료가 필요한가? (몇개의 pod를 만들 것인가?) 기본값은 1개
* paralleism : 몇개를 동시에 실행할 것인가? 기본값은 1개
* crob job : 지정된 시간에 한 번만 Job을 실행하거나 지정한 시간동안 주기적으로 Job을 반복 실행하기 위해 생성. schedule을 적을 때 linux cron 표준을 따름 ("min hour date month 요일(0: 일요일)")
예 : "*/1 * * * *" : 매월 매일 매 시간 1분마다 실행
예시 파일 (cronjob-hello.yaml)
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
successfulJobsHistoryLimit: 5
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
* (cron job) startingDeadlineSeconds : 지정된 시간에 크론잡이 실행되지 못했을 때 설정한 시간이 지나면 시작하지 않는다.
* (cron job) concurrencyPolicy : 동시성 관리
- Allow : cron job을 동시에 실행 가능
- Forbid : 이전에 실행한 job이 아직 종료되지 않았다면 새로운 job을 생성하지 않는다.
- Replace : 이전에 실행한 job이 아직 종료도히지 않았다면 이전에 실행한 job을 삭제하고 새로운 job으로 대체
'Backend > Docker, k8s' 카테고리의 다른 글
Docker + Frontend(Nginx, React) + Backend(Nginx, Gunicorn, Django, PostgreSQL) (7) | 2023.06.20 |
---|---|
Docker Compose - tutorial (0) | 2023.06.18 |
Docker - Tutorial (0) | 2023.06.17 |
k8s - Service (0) | 2023.04.28 |
Docker - ubuntu에 Docker 설치 (0) | 2023.04.26 |