✔️

Pod 기본

Pod

컨테이너를 표현하는 K8S API의 최소단위.

직접 CLI run실행

# web1이란 pod를 nginx1.14 이미지로 80포트 서비스 하겠다
kubectl run web1 --image=nginx:1.14 --port=80

yaml로 create 실행

cat pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - image: nginx:1.14
    name: web2
    ports:
    - containerPort: 80
      protocol: TCP

kubectl create -f pod-nginx.yaml

pod 조회

kubectl get pods
kubectl get pods -o wide
kubectl get pods web1 -o yaml
kubectl get pods web1 -o json
kubectl describe pod web1
kubectl get pods -o wide --watch
watch kubectl get pods -o wide

multi-container pod 생성

cat multipod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: multipod
spec:
  containers:
  - image: nginx:1.14
    name: nginx-container
    ports:
    - containerPort: 80
  - name: centos-container
    image: centos:7
    command:
    - sleep
    - "10000"

kubectl apply -f multipod.yaml

kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
multipod    2/2     Running   0          28s   10.36.0.2   node2.example.com   <none>           <none>
nginx-pod   1/1     Running   0          27m   10.44.0.1   node1.example.com   <none>           <none>
web1        1/1     Running   0          34m   10.36.0.1   node2.example.com   <none>           <none>

multi pod에 접속

#이름이 multipod라는 pod안에 nginx-container이름의 컨테이너에
#인터렉티브하고 터미널로 bash쉘을 사용해서 접속
kubectl exec multipod -c nginx-container -it -- /bin/bash
root@multipod:/# exit

#이름이 multipod라는 pod안에 centos-container이름의 컨테이너에
#인터렉티브하고 터미널로 bash쉘을 사용해서 접속
kubectl exec multipod -c centos-container -it -- /bin/bash   <-- 
[root@multipod /]# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 08:02 ?        00:00:00 sleep 10000
root           7       0  0 08:15 pts/0    00:00:00 /bin/bash
root          22       7  0 08:15 pts/0    00:00:00 ps -ef

#multipod에서 nginx-container가 사용한 로그를 보여줘
kubectl logs multipod -c nginx-container
👏
kubectl run busy1 --image=busybox:1.28 -it --rm -- /bin/sh
—> busybox 1.28 이미지를 가진 pod busy1을 실행하는데
—> 인터렉티브한 터미널 모드로 sh shell을 가지고 바로 진입.
—> 터미널을 빠져나오면 pod가 삭제되도록

pod 수정/삭제

kubectl delete pod webserver

#모든 pod 삭제
kubectl delete pod --all

#동작중인 pod 수정
kubectl edit pod nginx-pod

Self-healing Pod

livenessProbe 이용해 self-healing Pod, kubelet으로 컨테이너 진단
📌
livenessProbe 매커니즘
  1. httpGet - 지정된 ip,port,path의 반환코드가 200이 아니면 오류(연속 3번시도). 컨테이너를 다시 시작한다.
    livenessProbe:
    httpGet:
    path:/
    port: 80
  1. tcpSoket - 지정된 포트에 tcp연결을 시도, 연결되지 않으면 컨테이너를 다시 시작한다.
    livenessProbe:
    tcpSocket:
    port: 22
  1. exec - exec명령을 전달하고 명령의 종료코드가 0이 아니면 컨테이너를 다시 시작한다.
    livenessProbe:
    exec:
    command:

- ls

- /data/file

# 예시1)
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:1.14
    livenessProbe:
      httpGet:
        path:/
        port: 80


# 예시2)
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-liveness
spec:
  containers:
  - image: nginx:1.14
    name: nginx-container
    ports:
    - containerPort: 80
      protocol: TCP
    livenessProbe:
      httpGet:
        path: /
        port: 80
        
# 예시3)
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exam
spec:
  containers:
  - name: busybox-container
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      failureThreshold: 2
      periodSeconds: 5
      successThreshold: 1
      timeoutSeconds: 10
      exec:
        command:
        - ls
        - /tmp/healthy

kubectl create -f pod-nginx-liveness.yaml

# Containers.nginx-container.Liveness 항목 확인
kubectl describe pod nginx-pod-liveness

init container를 적용한 Pod

메인 컨테이너 실행 전에 사전작업으로 미리 동작시킬 컨테이너.
초기화 컨테이너가 모두 실행 된 후에 메인컨테이너가 실행됨

참고 : https://kubernetes.io/ko/docs/concepts/workloads/pods/init-containers/

#예시
cat init-container-exam.yaml
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"]

kubectl create -f init-container-exam.yaml

#init:0/2로 컨테이너가 제대로 시작되지 않았다.
kubectl get pods -o wide
NAME        READY   STATUS     RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
myapp-pod   0/1     Init:0/2   0          11m   10.44.0.1   node1.example.com   <none>           <none>
# 아래 서비스들을 동작시켜 보자
cat service1.yaml
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376

cat serivce2.yaml
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377

kubectl create -f service1.yaml
kubectl create -f service2.yaml

# 정상적으로 본 컨테이너가 올라온 것을 알 수 있다
kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
myapp-pod   1/1     Running   0          13m   10.44.0.1   node1.example.com   <none>           <none>

static Pod

API서버없이 kubelet 데몬에 의해 동작되는 pod를 static Pod라고 한다.
📌
worker node에서

/etc/kubernetes/manifests 디렉토리에 pod yaml파일을 저장시 kubelet 데몬에 의해 실행된다.
🌟해당 디렉토리는 /var/lib/kubelet/config.yaml에 staticPodPath항목으로 정의된 디렉토리이다.

여기에 yaml파일을 생성하면 바로 pod가 생성, yaml을 지우면 pod가 삭제된다.

root@node1:/etc/kubernetes/manifests# cat > nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:1.14
    ports:
    - containerPort: 80
      protocol: TCP
💡
팁1) kubelet 데몬이 관장하는 static파일의 위치를 바꾸려면, /var/lib/kubelet/config.yaml 수정 후 kubelet Daemon을 리스타트 해야한다.
팁2) master의 /etc/kubernetes/manifests 에 사용자 생성 yaml파일을 넣게되면, 워커노드중 하나에서 실행된다.