K8s 2. Pod

skh951225·2023년 3월 20일
0

K8s

목록 보기
3/3

출처 : 따배쿠 5-1~ (Youtube)

Pod

컨테이너를 표현하는 K8s API의 최소 단위
pod life cycle

Pod 의 생성

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

multipod 생성

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로)

livenessProbe를 이용해 self-healing Pod

kubelet으로 컨테이너를 진단하고 문제가 있으면 self healing

continaers:
 - ~~~
   livenessProbe: # livenessProbe를 통해서
    httpGet: # httpGet pobe 로 (web기반의 서비스의 경우)
     path: / # root page로
     port: 80 # 80포트로 접속
     # 응답이 잘오면 건강한 컨테이너, 아니면 건강하지않은..

컨테이너는 본인의 역할이 존재하며 그러한 역할이 잘 수행되는지 확인을 하려면 역할에 맞는 진단방법이 필요하다. 그래서 livenessProbe는 다양한 종류를 가진다.

  • httpGet : 지정한 IP주소, port,path에 HTTP GET 요청을 보내, 해당 컨테이너가 응답하는지를 확인한다. 반환코드가 200이 아닌 값이 나오면 오류,(3번 연속) 오류가 나면 컨테이너를 다시 시작한다.
# http://ip:80/ 로 GET 요청, 200이 아닌 값이 나오면 오류, 컨테이너를 다시 시작
 livenessProbe: # livenessProbe를 통해서
  httpGet:
   path: /
   port: 80
  • tcpScoket : 지정된 포트에 TCP연결을 시도, (3번 연속)연결되지 않으면 컨테이너를 다시 시작
livenessProbe:
 tcpSocket:
  port: 22
  • exec : exec 명령을 전달하고 (3번 연속)명령의 종료코드가 0이 아니면 컨테이너를 다시 시작
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

init container & infra container

init container

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

infra container(pause)

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라는 컨테이너가 추가적으로 실행된걸 확인할 수 있다.

static pod

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해줘야한다.

Pod에 리소스(cpu,memory) 할당하기

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상태에서 빠져나가지 못한다.

Pod 환경변수 설정과 실행 패턴

환경변수

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 로 확인할 수 있다.

Pod 실행 패턴


Sidecar : Pod내부에서 컨테이너가 유기적으로 실행됨
Adapter : Pod외부에서 정보를 받아와 실행
Ambassador : Pod에서 생성된 정보를 외부로 뿌려줌

0개의 댓글