인프라 (Infra)

쿠버네티스 기초

Wibaek 2025. 8. 16. 15:48
728x90

실습 환경 설치

VirtualBox v7.1.10

  • 컴퓨터 안에 또 다른 가상 컴퓨터를 만들 수 있게 해주는 가상화 소프트웨어

Vagrant v2.4.1

  • VirtualBox와 같은 가상화 소프트웨어를 더 쉽고 편리하게 관리해주는 개발 환경 구축 자동화 도구
vagrant up

Tabby v1.0.207

  • 터미널 에뮬레이터

실습

  • 어플리케이션을 배포하는 쿠버네티스의 단위 파드**(pod)**
    • pod은 컨테이너의 집합으로 이루어진다
    • 그러나 대부분은 하나의 pod이 하나의 컨테이너로 이루어지는 경우가 많다
    • pod은 한가지 일을 하는 걸 모아둔 것
kubectl run nginx --image=nginx

kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          17s

kubectl get pod -o wide

curl 172.16.221.129
  • 쿠버네티스 클러스트 외부로 나가려면 문을 통과해야 한다
    • → 서비스 영역과 배포한 pod을 연결한다
kubectl expose pod nginx --type=NodePort --port=80

kubectl get service
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        8m21s
nginx        NodePort    10.96.193.71   <none>        80:30531/TCP   18s

kubectl get nodes -o wide
NAME     STATUS   ROLES           AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
cp-k8s   Ready    control-plane   8m56s   v1.30.0   192.168.1.10    <none>        Ubuntu 22.04.5 LTS   5.15.0-142-generic   containerd://1.6.31
w1-k8s   Ready    <none>          7m28s   v1.30.0   192.168.1.101   <none>        Ubuntu 22.04.5 LTS   5.15.0-142-generic   containerd://1.6.31
w2-k8s   Ready    <none>          6m34s   v1.30.0   192.168.1.102   <none>        Ubuntu 22.04.5 LTS   5.15.0-142-generic   containerd://1.6.31
w3-k8s   Ready    <none>          5m25s   v1.30.0   192.168.1.103   <none>        Ubuntu 22.04.5 LTS   5.15.0-142-generic   containerd://1.6.31
  • pod과 디플로이먼트(Deployment) 차이
    • 디플로이먼트는 pod을 여러개 모아둔 단위
    • 옛날에는 kubectl run으로 디플로이먼트 배포가 가능했는데, 지금은 불가능하고
    • kubectl create나 kubectl apply를 써야한다
kubectl create deployment deploy-nginx --image=nginx
deployment.apps/deploy-nginx created

kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
deploy-nginx-74d7d6d848-hxm2t   1/1     Running   0          53s
nginx                           1/1     Running   0          12m

# 레플리카 늘여주기
kubectl scale deployment deploy-nginx --replicas=3
deployment.apps/deploy-nginx scaled
  • 외부로 노출하기 위해 서비스말고 로드밸런서를 사용할 수도 있다
kubectl expose deployment deploy-nginx --type=NodePort --port=80
service/deploy-nginx exposed

kubectl get services
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
deploy-nginx   NodePort    10.106.26.238   <none>        80:31377/TCP   22s
  • 디플로이먼트를 노출하기 위해 노드포트를 쓰는건 좋지 않은 방법
    • 그래서 로드밸런서를 쓰는게 좋다
    • 이를 위해 CNCF에서 제일 잘나가는 MetalLB를 이용해 로드밸런서 타입을 선언할것이다
  • 노드포트보다 로드밸런서가 좋은점
    • 노드의 ip가 노출되지 않는다
    • 가야할 경로를 최적화해서 보내줄 수 있다
kubectl apply -f metallb.yaml

kubectl create deployment chk-hn --image=sysnet4admin/chk-hn
deployment.apps/chk-hn created

kubectl scale deployment chk-hn --replicas=3
deployment.apps/chk-hn scaled

kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
chk-hn-5f676987b7-46fpf         1/1     Running   0          10s
chk-hn-5f676987b7-cxflg         1/1     Running   0          10s
chk-hn-5f676987b7-gwmh7         1/1     Running   0          63s

kubectl expose deployment chk-hn --type=LoadBalancer --port=80
service/chk-hn exposed

kubectl get services
NAME           TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)        AGE
chk-hn         LoadBalancer   10.108.138.148   192.168.1.11   80:31924/TCP   16s
  • 배포한것들 삭제
kubectl delete service chk-hn
kubectl delete service deploy-nginx
kubectl delete service nginx
kubectl delete deployment chk-hn
kubectl delete deployment deploy-nginx
kubectl delete pod nginx
kubectl delete -f metallb.yaml

쿠버네티스 인사이드

  • 쿠버네티스는 namespace가 존재
    • 이때까지는 default안에서 다루어왔다
    • k8s를 이루는 다른것들은 kube-system 내에 존재한다
    • MetalLB도 metallb-system으로 나누어져있어 보이지 않았다
kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS      AGE
calico-kube-controllers-546f76d588-mvwvf   1/1     Running   0             44m
calico-node-d84xl                          1/1     Running   0             41m
calico-node-hsfmx                          1/1     Running   0             44m
calico-node-jz6nn                          1/1     Running   0             43m
calico-node-r6cdc                          1/1     Running   0             42m
coredns-7db6d8ff4d-9jd7x                   1/1     Running   0             44m
coredns-7db6d8ff4d-rfqwv                   1/1     Running   0             44m
etcd-cp-k8s                                1/1     Running   1 (45m ago)   45m
kube-apiserver-cp-k8s                      1/1     Running   1 (45m ago)   45m
kube-controller-manager-cp-k8s             1/1     Running   1 (45m ago)   45m
kube-proxy-r2gmj                           1/1     Running   0             42m
kube-proxy-tc6rg                           1/1     Running   0             43m
kube-proxy-vtxm4                           1/1     Running   0             41m
kube-proxy-zcm5j                           1/1     Running   0             44m
kube-scheduler-cp-k8s                      1/1     Running   1 (45m ago)   45m
  • 그렇다면 네이티브 쿠버네티스도 이럴까?
    • AWS, Azure, GCP를 보아도 똑같다
  • pod 배포시에 k8s 구성 요소가 하는 일
    • API 서버는 항상 중심에 있다
    1. API 서버로 pod 생성 요청을 보낸다
    2. 컨트롤러 매니저가 API 서버를 보고 pod를 생성한다
    3. 스케쥴러가 API 서버를 보고 워커 노드에 스케쥴한다
      1. 즉 pod이 가기 가장 적절한 node를 선택하고 할당한다
    4. Kubelet이 API 서버를 보고 파드가 노드에 소속되게 한다, 그리고 파드 상태 정보를 전달
      1. Kublet이 컨테이너 런타임을 통해 pod을 동작하거나 생성한다
      2. 컨테이너 런타임이 컨테이너를 생성한다
  • 이렇게 API 서버가 선언하는 방식, 선언하는 시스템을 사용한다
    • 즉 추구하는 상태와 현재 상태를 계속 맞추려고 한다
  • API 서버와 etcd의 관계
    • etcd에 API 서버가 클러스터의 업데이트 된 정보를 기록한다
    • 그럼 etcd는 API서버에 업데이트가 완료됐다고 알린다

문제를 통해 배우는 쿠버네티스

  • 디플로이먼트에서 pod가 지워져도 자동생성된다
kubectl apply -f ~/_Lecture_k8s_starter.kit/ch5/5.1
deployment.apps/del-deploy created
pod/del-pod created

kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
del-deploy-d6c48dfbf-78ljt   1/1     Running   0          14s
del-deploy-d6c48dfbf-7d2bm   1/1     Running   0          14s
del-deploy-d6c48dfbf-kgsgl   1/1     Running   0          14s
del-pod                      1/1     Running   0          14s

kubectl delete pod del-pod
pod "del-pod" deleted

kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
del-deploy-d6c48dfbf-78ljt   1/1     Running   0          35s
del-deploy-d6c48dfbf-7d2bm   1/1     Running   0          35s
del-deploy-d6c48dfbf-kgsgl   1/1     Running   0          35s

kubectl delete pod del-deploy-d6c48dfbf-78ljt 
pod "del-deploy-d6c48dfbf-78ljt" deleted

kubectl get pods
NAME                         READY   STATUS              RESTARTS   AGE
del-deploy-d6c48dfbf-7d2bm   1/1     Running             0          71s
del-deploy-d6c48dfbf-gnmjj   0/1     ContainerCreating   0          2s
del-deploy-d6c48dfbf-kgsgl   1/1     Running             0          71s

kubectl delete deployment del-deploy
deployment.apps "del-deploy" deleted

kubectl get pods
  • Kubelet에 문제가 생기면 바로 복구가 되지 않는다
# 워커 노드에서
systemctl stop kubelet

# 메인 노드에서
kubectl apply -f ~/_Lecture_k8s_starter.kit/ch5/5.1/del-deploy.yaml
deployment.apps/del-deploy created

kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
del-deploy-d6c48dfbf-hdhg4   1/1     Running   0          14s   172.16.103.134   w2-k8s   <none>           <none>
del-deploy-d6c48dfbf-mm8sx   1/1     Running   0          14s   172.16.132.6     w3-k8s   <none>           <none>
del-deploy-d6c48dfbf-znz2w   1/1     Running   0          14s   172.16.103.133   w2-k8s   <none>           <none>
# 보면 2번 노드가 없다
  • 컨테이너 런타임(ContainerD)에 문제가 생길 경우
# 워커 노드에서
systemctl stop systemd

# 메인 노드에서
kubectl scale deployment del-deploy --replicas=6

kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
del-deploy-d6c48dfbf-6zhqr   1/1     Running   0          8s      172.16.103.135   w2-k8s   <none>           <none>
del-deploy-d6c48dfbf-f4gc6   1/1     Running   0          88s     172.16.221.133   w1-k8s   <none>           <none>
del-deploy-d6c48dfbf-jpd8f   1/1     Running   0          8s      172.16.132.7     w3-k8s   <none>           <none>
del-deploy-d6c48dfbf-mm8sx   1/1     Running   0          6h27m   172.16.132.6     w3-k8s   <none>           <none>
del-deploy-d6c48dfbf-sm4z6   1/1     Running   0          8s      172.16.132.8     w3-k8s   <none>           <none>
del-deploy-d6c48dfbf-znz2w   1/1     Running   0          6h27m   172.16.103.133   w2-k8s   <none>           <none>
# 워커 1번으로는 배포가 되지 않는다
# 5분정도 지나면 기존에 작동하던것도 작동이 멈춘걸 인지하고 교체한다
  • 스케쥴러가 삭제된다면?
kubectl delete pod kube-scheduler-cp-k8s -n kube-system
  • 삭제해도 바로 다시 생성됨
  • 워커 노드가 아닌 마스터 노드의 Kubelet이 중단된다면?
systemctl stop kubelet

kubectl delete pod kube-scheduler-cp-k8s -n kube-system
kube-scheduler-cp-k8s                      1/1     Terminating   1 (7h52m ago)   114s
  • Kubelet이 멈춰있기 때문에 실제로 삭제가 진행되지 않는다
kubectl create deployment nginx --image=nginx
kubectl scale deployment nginx --replicas=3
  • 위는 정상작동 된다. 스케쥴러는 정상이기 때문
  • 마스터 노드의 Kubelet이 중단되도 별다른 영향을 받지 않는다
  • 그럼 마스터 노드의 ContainerD가 중단된다면?
kubectl delete deployment nginx

kubectl get pods -n kube-system
  • 조회/생성/삭제가 여전히 가능하다

쿠버네티스 오브젝트

  • 쿠버네티스의 요소들이 상태를 가지고 있는 것 - 오브젝트?
  • 오브젝트 → 추구하는 상태를 기록해둔 것
kubectl edit deployment del-deploy
# 이후 spec.replicas 3으로 변경

# pods가 9 -> 3개로 변경된다
  • k8s의 기본 오브젝트
    1. pod
    2. 서비스
    3. 네임스페이스(default, kube-system)
    4. 볼륨(영속적인 데이터를 보존)
  • 볼륨 실습
kubectl apply -f ~/_Lecture_k8s_starter.kit/ch6/6.2/dpy-chk-log.yaml
# 접속이 일어나면 로그를 저장

# 로그 남기기
curl 172.16.221.137

kubectl exec dpy-chk-log-6b765b4569-z59qb -it -- /bin/bash



728x90