강의
준비
실행 환경: intel 맥북 (M1, M2는 강의에서 제공하는 환경 그대로 설치하기 어려움)
vagrant 및 virtualbox를 통한 Masternode 1개, Worker node 3개 설치(강의에서 제공하는 스크립트 사용)
터미널: Tabby (https://tabby.sh/)
- 구성 노드 확인 (마스터 노드 1개, 워커 노드 3개)
$ kubectl get nodes
- 파드 생성 (nginx)
$ kubectl run nginx --image=nginx
- 파드 확인
$ kubectl get pod -o wide
- nginx 서버 접속 (위에서 확인한 파드의 IP로 접속)
$ curl 172.16.132.1
- 외부 (Mac)에서는 위 nginx 주소로 접속할 수 없음
- 외부에서의 k8s 클러스터 접근을 위해서는 service를 설정해줘야 함
- NodePort Type의 서비스 생성 (80번은 nginx 서버의 http 포트)
$ kubectl expose pod nginx -type=NodePort --port=80
- 생성한 서비스 확인
$ kubectl get service
>>> 밖으로 노출된 port를 확인 가능. 80번이 아닌 이 port를 통해 외부에서 접근
- 파드 확인 (NodePort로 접근하기 위해서 Pod의 IP를 알아야 함)
$ kubectl get nodes -o wide
>>> INTERNAL-IP 확인
>>> nginx Pod가 deploy된 노드의 IP 확인
>>> 실제로는 다른 노드의 IP를 사용해도 되지만 이는 k8s의 동작방식 때문
>>> 해당 노드에 Pod가 없다면 다른 노드로 가서 Pod를 찾는다고 함
>>> https://coffeewhale.com/packet-network3 내용 확인
- Mac의 크롬에서 192.168.1.101:32630 으로 접속 가능 확인
- Mac 터미널에서 curl도 가능
- deployment 형태로 Pod 생성
$ kubectl create deployment deploy-nginx --image=nginx
- Pod 개수를 3개로 늘림 (scale up)
$ kubectl scale deployment deploy-nginx --replicas=3
- Pod 확인
$ kubectl get pods
>>> Pod 3개 확인
- deployment를 NodePort 형태로 노출 및 확인
$ kubectl expose deployment deploy-nginx --type=NodePort --port=80
$ kubectl get services
>>> 크롬으로 접속 확인 (192.17.1.12:32663)
- Service를 Loadbalancer 타입으로 생성 (MetalLB를 사용)
- 외부 접속할 때 3개의 pod 중에서 어떤 pod로 접속될지는 모름 (LB가 정함)
- LB는 별개의 IP를 사용하므로 접속시 노드의 IP를 알 필요 없음
- MetalLB delploy
$ kubectl apply -f ~/.../metallb.yaml
- chk-hn pod 생성 (chk-hn: 노드의 hostname을 보여주는 웹서버. 어느 pod로 접속 했는지 알 수 있음)
$ kubectl create deployment chk-hn --image=sysnet4admin/chk-hn
$ kubectl scale deployment chk-hn --replicas=3
$ kubectl get pods
- LB Service 생성
$ kubectl expose deployment chk-hn --type=LoadBalancer --port=80
>>> 이때는 접속시에도 80번 port로 접속 함
>>> --port=80 에서 80은 Pod의 Port
$ kubectl get services
>>> 서비스의 EXTERNAL-IP 확인
>>> PORT(S)에 80:32462/TCP 에서 32462는 Node Port, 80은 Service Port
>>> 크롬으로 접속 확인 (192.168.1.11)
- 배포한 오브젝트 삭제
$ kubectl delete service chk-hn
$ kubectl delete service deploy-nginx
$ kubectl delete service nginx
$ kubectl get service
$ kubectl delete deployment chk-hn
$ kubectl delete deploymnet deploy-nginx
$ kubectl delete pod nginx
$ kubectl get pods
$ kubectl delete -f ~/.../metallb.yaml
$ kubectl get pods -n kube-system (네임스페이스 사용)
<Pod 삭제 실습>
$ kubectl apply -f .../4.1
>>> 해당 디렉토리에 있는 2개의 yaml에 대해 pod를 구성
>>> pod 1개와, pod 3개짜리 deployment
- Pod 삭제
$ kubectl delete pod del-pod
$ kubectl delete pod del-deploy-sds13123dad
$ kubectl get pods
>>> Pod가 지워졌으나, deploymnet는 3개를 유지해야하므로 바로 새로운 Pod 1개를 다시 생성함
<kubelet 중단 실습>
- 워커노드 1번에서 kubelet 중단
$ systemtl stop kubelet
$ systemctl status kubelet
>>> inactive (dead) 상태 확인
$ kubectl apply -f 4.1/del-deploy.yaml
$ kubectl get pods -o wide
>>> 워커노드 1의 Pod가 Pending 상태. 배포가 되지 않음
- 다시 kubelet 시작
$ systemctl start kubelet
$ kubectl get pods -o wide -w
<컨테이너 런타임 중단 실습 (1.25 에서는 ContainerD)>
- 현재 배포 상태 확인 (3개 pod delpoyment 실행 중)
$ kubectl get pods
- W1에서 containerd 중단
$ systemctl stop containerd
$ systemctl status containerd
$ kubectl get pods
>>> 3개 다 Running 상태
$ kubectl scale deployment del-deploy --replicas=6
$ kubectl get pods -o wide
>>> Pod가 워커 노드 1로는 배포가 안됨
>>> 기존 W1에 있는 pod는 5분 정도 지나면 컨테이너런타임 동작X를 인식하고 Pod를 지우고 다른 노드에 생성함
- W1에서 다시 containerd 시작
$ kubectl start containerd
$ kubectl scale deployment del-deploy --replicas=9
>>> 스케줄러는 best effort로 균등하게 배포하려고 함
>>> 균등을 보장하는 토폴로지 분배 제약조건은 나중에 배움
>>> 현재 W1의 containerd가 살아난지 얼마안되서 w2,w3 에만 pod가 생성됨
$ kubectl scale deployment del-deploy --replicas=0
>>> 모든 Pod를 죽이고 다시 배포
$ kubectl scale deployment del-deploy --replicas=9
>>> W1,2,3에 균등하게 배포됨을 확인
<마스터 노드가 문제인 상황 실습>
$ kubectl get pods -n kube-system -o wide
>>> 주요한 etcd, APIserver, 컨트롤러, 스케줄러 Pod 들은 다 마스터노드에 있음
$ kubectl delete pod kube-scheduler-m-k8s -n kube-system
$ kubectl get pods -n kube-system
>>> 스케줄러 Pod 종료되긴 하나, 바로 다시 생성됨
<마스터 노드 Kubelet이 중단되면?>
$ systemctl stop kubelet
$ kubectl deleted pod kube-scheduler-m-k8s -n kube-system
>>> 프롬프트가 멈춰버림
$ kubectl get pods -n kube-system
>>> 스케줄러 Pod는 Terminating 상태
>>> kubelet에 명령이 날아가서 삭제가 되어야하는데, 중지니까 실제 삭제가 이루어지지 않음
- 이 상태에서 워커 노드에 deploy가 될까?
$ kubectl create deployment nginx --image=nginx
$ kubectl get pod
>>> 정상적으로 생성됨
$ kubectl scale deplloyment nginx --replicas=3
>>> 정상적으로 3개 생성됨
>>> 스케줄러가 정상동작되고 있다는 뜻
$ curl 172.16.132.32
>>> nginx 도 정상 동작
$ systemctl start kubelet
$ kubectl get pods -n kube-system -w
>>> 스케줄러 다시 올라옴
>>> 결론: 마스터 노드의 kubelet이 중지되도 k8s 시스템이 정상적으로 동작한다 (?)
>>> 그럼 안되는건 뭘까?
<마스터 노드 컨테이너 런타임이 중지되면?>
$ systemctl stop containerd
$ systemctl status containerd
$ kubectl get pod
>>> 정상 출력
$ kubectl get pods -n kube-system
>>> 정상 출력
$ kubectl delete deployment nginx
$ kubectl get pods
>>> 정상적으로 지워짐
>>> Pod 배포도 됨
$ kubectl delete pod kube-scheduler-m-k8s -n kube-system
$ kubectl get pods -n kube-system
>>> 스케줄러가 Terminating 상태로 멈춤
>>> 그니까 마스터 노드에 대한 Pod (컨테이너) 생성, 실행은 문제가 되고
>>> 워커 노드에 대한 Pod 생성, 실행은 정상 동작 하는거 같음
$ systemctl restart containerd
$ kubectl get pods -n kube-system
>>> 스케줄러 재기동
>>> 기존 런타임 (도커)보다 Containerd가 더 시스템 안정적
- 배포 상태 확인
$ kubectl get pods
$ kubectl edit deployment del-deploy
>>> vim 화면이 나옴
>>> spec (선언한 상태, 추구하는 상태), status (현재 상태) 가 존재
>>> spec에서 replicas 값을 바꾸면 적용돔 (status는 바꿔도 변화 없음)
$ kubectl get pods
- 기본 오브젝트: Pod, Service, 네임스페이스, 볼륨
- k8s 오브젝트는 상태를 가지고 있음
<볼륨 오브젝트 실습 >
- .../5.2/nfs-exporter.sh log (마스터 서버에서)
>>> NFS 서비스 구동
$ cat /etc/exports
>>> 마스터 노드, 워커 노드에서 볼 수 있음 NFS
$ ls /nfs_shared/
$ cat 5.2/dpy-chk-log.yaml
>>> NFS 볼륨 설정이 있음. 볼륨을 구성해서 Pod 컨테이너의 /audit에 볼륨을 마운트 함.
$ kubectl apply -f 5.2/dpy-chk-log.yaml
>>> NFS 경로에 접속 기록을 기록하는 app
$ kubectl get pods -o wide
# curl 172.16.221.142
>>> 접속된 Pod와 Pod가 배포된 노드의 IP를 보여줌
- Pod에 접속
$ kubectl exec dpy-chk-log-123123213 -it -- /bin/bash
$ ls
>>> audit 이 있음
$ ls audit
>>> 생성된 로그가 있음
- Pod 지우기
$ kubectl delete -f dpy-chk-log.yaml
$ kubectl get pods -o wide -w
- Pod 다시 Up
$ kubectl apply -f dpy-chk-log.yaml
- 새로 만들어진 Pod에 접속
$ kubectl exec dpy-chk-log-4454544 -it -- /bin/bash
$ ls /audit
>>> 이전 Pod에 대한 접속 기록 로그가 그대로 남아있는 것을 확인 가능
>>> Pod는 ephemeral 하므로 볼륨이 영구 저장소로 사용됨
댓글