웹 파이프라인/Kubernetes
쿠버네티스 사용방법 정리
thinktank911
2025. 12. 15. 11:31
쿠버네티스 기본 사용법
- 포드 생성과 컨테이너 실행
- 디플로이먼트 이용해 동일한 기능을 하는 포드의 레플리카셋 실행
- 클러스터 외부로부터 접근이 가능하도록 서비스를 실행
- 생성된 현재 관리되고 있는 k8s 오브젝트들 삭제
k8s 클러스터 현재 상태 조회 하는 방법
오브젝트 스펙을 작성하는 기초를 익히고 실습
노드와 포드 정보를 조회
- 명령어
- kubctl get nodes
- kubctl get pods (all-namespace)
- 어떤 정보를 파악할 수 있는지 알아보자
- 옵션 "-o wide"를 적용하여 무엇이 더 출력되는지 살펴보자.
컨테이너 이미지를 이용한 포드의 생성
- 명령어
- kubectl run <포드 이름> --image=<이미지 지정>
- ex. kubectl run nginx-pod --image=nginx
쿠버네티스 디플로이먼트
- 응용의 배포를 위하여 많이 이용되는 k8s 오브젝트 형태
- 동일한 모습의 포드들의 복제본 모음인 레플리카셋을 이용하는 것이 일반적
- 단순한 레플리카셋에 비하여 동적 업데이트 및 롤백, 배포 버전의 관리 등이 유연하여 응용의 배포에 널리 이용
- 보통은 상태가 없는(stateless) 응용의 배포에 이용
- 포드는 언제하도 사멸할 수 있음
- 동작 방식
- 디플로이먼트의 상태를 선언하면 k8s가 동적으로 의도된 상태(desired state)가 되도록 레플리카셋을 관리
- 명령어
- 디플로이먼트 오브젝트 생성 : kubectl create deployment dpy-nginx --image=nginx
- 디플로이먼트 오브젝트 조회 : kubectl get deployment -o wide
- 디플로이먼트 오브젝트 상세 설명 : kubectl describe deployment dpy-nginx
- 동적으로 포드 늘리기 : kubectl scale deployment dpy-nginx --replicas=3
- 컨테이너도 수만큼 는다.
클러스터 바깥으로 응용을 노출해보자
- k8s 서비스(service)
- 클러스터 내부의 포드에 의하여 실행되는 응용을 외부에 접근 가능하도록 노출하는 기능을 하는 오브젝트
- 노출하는 대상
- 특정 포드(또는 포드들의 집합)에서 실행하는 컨테이너의 특정 포트
- 서비스의 서로 다른 형태들
- ClusterIP
- NodePort [o]
- LoadBalancer
- ExternalName
- 명령어
- 외부포트에 노출 : kubectl expose pod nginx-pod --type=NodePort --name=pod-svc --port=80
- 서비스 포트 조회 : kubectl get svc
- 외부 포트로 웹페이지 조회 : curl http://localhost:<포트번호>
- 디플로이먼트 외부 노출
- 외부포트에 노출 : kubectl expose deployment dpy-nginx --type=NodePort --name=dpy-svc --port=80
- 서비스 포트 조회 : kubectl get services
- 외부 포트로 웹페이지 조회 : curl http://localhost:32576
오브젝트 삭제
- 서비스 삭제 : kubectl delete service pod-svc
- 포드 삭제 : kubectl delete pods nginx-pod
- 디플로이먼트 삭제 : kubectl delete deployment dpy-nginx
- 디플로이먼트로 생성된 포드들은 상태를 유지하려는 성질때문에 삭제해도 다시 살아난다.
매니페스트
- k8s 오브젝트에 대한 명세를 파일로 기록한 것
- YAML 형태 이용
- 파일에 각 오브젝트에 의도하는 상태(desired state)를 기술
- 이것을 오브젝트 스펙이라고 부름
- 이 파일을 이용하여
- 오브젝트를 생성할 수 있고
- (파일의 내용을 변경하여) 오브젝트 상태를 변경할 수 있음
- 물론, 파일의 내용을 변경하지 않고 다른 파일을 이용하여 오브젝트 상태를 변경하는 것도 가능
- 자동화가 필요한 환경에서 당연히 명령어 라인에 일일이 입력하는 것보다 많이 이용됨
매니페스트 이용한 오브젝트 생성
- 명령어
- kubectl apply -f <매니페스트 파일>
- kubectl create -f 를 이용할 수도 있으나 위의 명령을 더 널리 이용함
- (왜 그럴까?) 이후 실습에서 두 가지 방법을 모두 적용해보고 생각해볼 것
=> kubectl apply -f 는 선언적 관리 : 쿠버네티스가 알아서 현재 상태를 맞추게 하는 방식
kubectl create -f는 1회성 명령, 리소스 상태 관리에 부적합
- kubectl apply -f <매니페스트 파일>
쿠버네티스를 이용한 서비스 운용
도커 이미지 작성
- docker build -t hostname:latest
이미지 태그하고 레포지토리에 푸시
- docker tag hostname:latest <도커허브username>/hostname:latest
- docker push <도커허브username>/hostname:latest
테스트 응용의 (수동) 배포
- deployment.yaml에 지정된 대로 포드 생성해서 컨테이너 실행
- 포드의 이름들 IP주소 체크
- kubectl apply -f deployment.yaml
- ubectl get pods -o wide
- 서비스 노출
- kubectl apply -f service.yaml
주기적인 요청을 이용해 테스트
- 주기적으로 요청을 반복하는 스트립트 작성
- Linux/MacOS:bash 스크립트
- Windows:PowerShell 스크립트
- 요청이 반복적으로 도착하고 있는 상태에서, 클러스터 내에 예외상황이 발생하는 경우
k8s가 어떻게 대응하는지 관찰- 디플로이먼트의 레플리카셋에 포함된 포드가 사멸하는 경우
- 특정 포드에서 실행하는 컨테이너에 오류가 발생하는 경우
디플로이먼트의 상태 유지
- 다플로이먼트에 의하여 포드들이 배포된 상태에서 이 중 하나 이상의 포드가 (어떤 이유로든) 사멸하면
- k8s는 새로운 포드를 생성하고 같은 종류 (이미지가 동일한)의 컨테이너를 실행함
- 포드가 사멸하면 새로운 포드를 생성함으로써 디플로이먼트에 선언된 의도된 상태를 유지하려고 함
- 클러스터 외부에는 별도의 서비스에 의하여 노출되므로 개별 포드의 클러스터 내 동적 할당되는 IP 주소 등에 대해서는
사용자가 관리할 필요 없음 - 단, 포드는 언제든지 죽을 수 있는 오브젝트이므로 컨테이너에 기반한 응용을 개발함에 있어 상태를 띠지 않는(stateless) 방식으로 만들어야 함
컨테이너에 오류 발생
- 컨테이너에 셀 접속을 얻어
- 이 응용 (flask 기반)을 실행하고 있는 프로세스의 PID를 알아내고
- kill을 이용해서 이 프로세스 강제 종료
- 관측할 사항
- 주기적으로 이 서비스에 요청을 보내고 있는 스크립트가 어떤 응답 받게 되는지 확인
쉘 접속 명령어 : kubectl exec -it <포드이름> -- /bin/bash
프로세스 PID 검색 : ps ax | grep flask
kill 로 프로세스 강제 종료 : kill -9
포드의 동작 보증
- 다플로이먼트에 의하여 배포된 포드의 컨테이너 실행에 문제가 생기면 오류 발생
- k8s는 이 포드에서 실행하던 컨테이너를 삭제하고 다시 컨테이너를 생성해 응용을 지속 실행
- k8s에 의하여 관리되는 포드는 복구할 수 없는 오류를 맞닥뜨리는 경우에도 재시작에 의하여 정해진 동작 지속하도록 보장
- 컨테이너에 기반한 응용은 상태를 띠지 않는(stateless) 방식으로 구현되어야 함
포드의 업데이트와 복구
소프트웨어 업데이트가 발생함에 따라 동적 업데이트 필요
빠르고 유연한 복구
롤아웃 정보의 열람
- 롤아웃 정보와 이력을 조회
- 디플로이먼트의 배포 상태를 조회 : kubectl rollout status deployment <디플로이먼트 이름>
- 디플로이먼트의 배포 이력을 조회 : kubectl rollout history deployment <디플로이먼트 이름>
- 파일 수정 후 다시 배포 할 때 : kubectl apply -f rollout.yaml --record
배포 이력의 기록 : kubectl annotate
순서
- kubectl delete deployment dpy-nginx
- rollout.yaml 파일에 지정된 nginx 이미지 버전은 다시 1.16.0 으로 파일 수정
- kubectl apply -f rollout.yaml
- kubectl set image deployment dpy-nginx nginx=nginx:1.17.0
- kubectl annotate deployment dpy-nginx kubernetes.io/change-cause="설명"
- kubctl rollout history deployment dpy-nginx
롤백하기
- kubectl rollout undo deployment dpy-nginx
- 특정 시점으로 디플로이먼트 복구
- kubectl rollout undo deployment <디플로이먼트이름> --to-revision=<리비전 번호>