출처 : 따배쿠 5-1~ (Youtube)
컨테이너를 표현하는 K8s API의 최소 단위
pod life cycle
cli 명령어로 pod 생성하기
kubectl run web1 --image=nginx:1.14 --por=80
kubectl create -f web1.yaml
# web1.yaml
apiVersion: v1
kind: Pod
metadata:
name: web1
spec:
container:
- name: nginx-container
image: ngiginx:1.14
ports:
- containerPort: 80
protocol: TCP
실행중인 Pod 확인하기 : kubectl get pods
-o wide
: 자세히
-o yaml/json
: yaml/json 형식으로
watch kubectl get pods
: watch는 리눅스 명령어로 2초마다 한번씩 명령어를 실행해줌
kubectl get pod web1 -o json | grep -i podip
apiVersion: v1
kind: Pod
metadata:
name: multipod
spec:
containers:
- name: nginx-container
image: nginx:1.14
ports:
- containerPort: 80
- name: centos-container
image: centos:7
command:
- sleep
- "100"
kubectl get pods
# READY 는 컨테이너 기준이였음
NAME READY STATUS RESTARTS AGE
multipod 2/2 Running 0 27s
kubectl exec -it multipod -- /bin/bash
: pod에 /bin/bash
kubectl exec -it multipod -c nginx-contaienr -- /bin/bash
: pod의 container에 /bin/bash
pod 내의 컨테이너는 동일한 ip를 가지게 되어 centos-container에 접속해서 curl localhost해도 응답이옴
kubectl logs multipod -c nginx-container
: multi contaienr pod 의 log를 볼땐 컨테이너를 지정해줘야함
kubectl delete pod --all
: 전부 삭제
kubectl get pods -o wide --watch
: pod 상태가 변할때마다 보여줌
kubectl edit pod webserver
: 동작중인 파드를 수정(vi editor로)
kubelet으로 컨테이너를 진단하고 문제가 있으면 self healing
continaers:
- ~~~
livenessProbe: # livenessProbe를 통해서
httpGet: # httpGet pobe 로 (web기반의 서비스의 경우)
path: / # root page로
port: 80 # 80포트로 접속
# 응답이 잘오면 건강한 컨테이너, 아니면 건강하지않은..
컨테이너는 본인의 역할이 존재하며 그러한 역할이 잘 수행되는지 확인을 하려면 역할에 맞는 진단방법이 필요하다. 그래서 livenessProbe는 다양한 종류를 가진다.
# http://ip:80/ 로 GET 요청, 200이 아닌 값이 나오면 오류, 컨테이너를 다시 시작
livenessProbe: # livenessProbe를 통해서
httpGet:
path: /
port: 80
livenessProbe:
tcpSocket:
port: 22
livenessProbe:
exec:
command:
- ls
- /data/file
livenessProbe를 통해 컨테이너를 restart 시키기 때문에 IP address에 대한 걱정할 필요가 없다.(IP는 Pod에 할당되니까)
apiVersion: v1
kind: Pod
metadata:
labels:
run: webserver
name: webserver
spec:
containers:
- image: nginx:1.14
name: webserver
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 15 # 컨테이너가 시작되고 얼마 후 부터 검진할 것인지
periodSeconds: 20 # 검진 주기
timeoutSeconds: 1 # 응답 제한시간
successThreshold: 1 # 몇번 연속 성공해야 성공인지
failureThreshold: 3 # 몇번 연속 실패해야 실패인지
실습
smlinux/unhealthy 는 5번의 요청까지는 200번 상태코드, 그 후부터는 쭉 에러 메시지를 응답하는 이미지이다. initialdelayseconds를 1초, periodSeconds를 2초로 설정하면 약 15초마다 컨테이너가 restart 한다.
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
containers:
- image: smlinux/unhealthy
name: unhealth-container
ports:
- containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
main container가 실행되기 위해 선행되어야 하는 작업을 담당하는 것이 init container이다.(docker-compose 의 depends-on 과 유사한 역할을 하는듯?)
init container 공식문서
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: MyApp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
결과
: myservice가 동작하고 있지 않아 실행안됨
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 16s
myservice Service 실행
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
결과
: myservice 가 실행되어 status가 바뀜
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 2m19s
myapp-pod 0/1 Init:1/2 0 2m37s
myapp-pod 0/1 Init:1/2 0 2m38s
mydb Service 실행
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
결과
: mydb가 실행되어 비로소 main container 실행
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 2m19s
myapp-pod 0/1 Init:1/2 0 2m37s
myapp-pod 0/1 Init:1/2 0 2m38s
myapp-pod 0/1 PodInitializing 0 6m39s
myapp-pod 1/1 Running 0 6m40s
pod를 생성하면 pod 안에는 기본적으로 infra container 하나가 생성된다. infra container는 pod에 대한 infra(ip,hostname...)를 관리하고 생성하는 컨테이너다.
IMAGE COMMAND CREATED
7bbc8783b8ec "nginx -g 'daemon of…" 2 minutes ago
registry.k8s.io/pause:3.6 "/pause" 2 minutes ago
실제로 nginx container하나를 실행하는 pod를 생성하였는데 pause라는 컨테이너가 추가적으로 실행된걸 확인할 수 있다.
API에게 요청을 보내지않고 worker node의 kubelet에게 요청을 보내서 pod 를 생성할 수 있는데 이러한 Pod는 static pod라고 부른다. kubelet의static pod directory(/etc/kubernetes/manifests/
, 보통 이곳에 위치, 아닐수도 있음)에 yaml파일을 저장하여 생성할 수 있다.
static pod directory 확인하기
kubelet daemon이 실행중이라면 /var/lib/kubelet/config.yaml
파일이 있다. 이 파일은 kubelet daemon이 동작될때 어떻게 동작될지에 대한 정보를 가지고있다. static pod directory에 대한 정보도 확인할 수 있다.
cat /var/lib/kubelet/config.yaml | grep -i staticPodPath
를 실행하면 static pod directory가 어디 존재하는지 알 수 있다.
static Pod의 가장 큰 특징은 API의 도움없이 pod를 실행할 수 있다는 점이다. 또 yaml파일을 생성하는 동시에 pod가 생성되고 삭제하면 pod 또한 삭제되게 된다.
master node에도 static pod directory가 존재하며 그 안에는 기본적으로
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
가 존재한다.(쿠버네티스를 동작시키기 위해 기본적으로 필요한 Pod) master node에 static pod를 생성하면 자동으로 다른 worker node에서 실행된다고 한다.(minikube를 사용해서 그런지 나는 master node에서 실행된다...)
쿠버네티스 자격증 문제에 static pod생성하는 문제가 자주 나온다. 그 중 static pod directory의 경로를 변경하는 문제도 나오는데 config.yaml의 staticPodPath를 수정해주고 꼭! kubelet을 restart
해줘야한다.
Request
: 파드를 실행하기 위한 최소 리소스 양을 요청
Limit
: 파드가 사용할 수 있는 최대 리소스 양을 제한, Memory limit을 초과해서 사용되는 파드는 종료(OOM kill)되며 다시 스케줄링 된다.
apiVersion: v1
kind: Pod
metadata:
labels:
run: webserver
name: webserver
spec:
containers:
- image: nginx:1.14
name: webserver
ports:
- containerPort: 80
resources:
requests:
cpu: 200m
memory: 250Mi
limits:
cpu: 1
memory: 500Mi
원래 1M=1000K 이다. 그래서 K8s에서는 단위를 표현할때 1Mi(Mebi)=1024Ki(Kibi) 와 같이 쓴다. cpu의 사용량을 표현할때는 1(core), 2(core).. 혹은 core하나를 1000m(milicore)라고하는 milicore단위를 사용한다. limits만 걸면 requests가 동일한 설정으로 자동으로 저장된다. requsts만 걸면 requests만 걸린다. 만약 request를 worker node의 가용자원이상으로 설정하면 pod는 pending상태에서 빠져나가지 못한다.
apiVersion: v1
kind: Pod
metadata:
labels:
run: webserver
name: webserver
spec:
containers:
- image: nginx:1.14
name: webserver
ports:
- containerPort: 80
env:
- name: MYVAR
value: "testvalue"
kubectl exec webserver -- env
로 확인할 수 있다.
Sidecar
: Pod내부에서 컨테이너가 유기적으로 실행됨
Adapter
: Pod외부에서 정보를 받아와 실행
Ambassador
: Pod에서 생성된 정보를 외부로 뿌려줌