본문 바로가기
개발공부 개발새발/Kubernetes

Kubernetes ) 명령적 접근 방식으로 쿠버네티스 사용해보기

by 휴일이 2024. 4. 22.

Kubernetes 는 객체와 함께 작동한다.

Pods, Deployments Services, Volume …

  • 특정 명령을 실행해 이런 객체들을 만들 수 있고 쿠버가 이 객체들을 사용한다.
  • 객체에 인코딩된 명령을 기반으로 쿠버가 뭔가 수행함.
    • 명령적 방식과 선언적 방식

Pod

쿠버네티스가 상호작용하는 가장 작은 유닛

  • 쿠버네티스가 파드를 생성
  • 파드는 (하나 이상의)컨테이너 보유하고 실행
    • 일반적으로는 하나!
  • 쿠버네티스는 파드와 컨테이너 관리

쿠버네티스로 Pod 사용

  1. 컨테이너 실행 후 클러스터의 특정 워커 노드에서 수행
  2. 코드 또는 명령을 사용하여 pod 객체 생성
  3. 객체를 쿠버네티스에게 전송
  4. 쿠버에게 수행 지시

→ 파드는 컨테이너 생성뿐 아니라 컨테이너 리소스도 공유(볼륨 등)

파드 특징

  • 파드도 클러스터의 일부로, 다른 파드나 외부와 통신 가능
  • 파드는 디폴트로 클러스터 내부 IP 주소 보유 → 변경 가능
    • 클러스터 외부에서도 파드와 통신 가능
    • 파드나 파드에서 실행중인 컨테이너에 요청 보내기 가능 !
  • 통일한 파드 중 하나에 여러 컨테이너가 있다면 컨테이너는 localhost 주소를 이용해 서로 통신 가능.
    • AWS ECS 의 태스크와 쿠버 파드와 비슷함

꿀팁

파드는 임시직이다

  • 파드가 쿠버네티스로 교체되거나 제거되면 파드의 모든 리소스(컨테이너로 저장했던 데이터들)들이 손실
    • 물론 볼륨처럼 데이터를 유지하는 방법은 있긴 함. 디폴트로는 손실
  • 파드는 컨테이너를 둘러싼 작은 래퍼일 뿐임
    • 컨테이너랑 개념이 비슷하다.

자체적으로 파드를 만들어 클러스터의 특정 워커 노드에서 시작할 순 있지만, 일반적으론 그렇게 하지 않음.

  • 쿠버네티스가 파드를 관리하고 자동으로 생성, 제거, 교체하길 희망함.
  • 파드에서 실행중인 애플리케이션이 실패하면 쿠버가 제거하고 교체하고 재생성해야지! 수동으로 하기 싫자나.

Deployment

한 번의 여러 파드를 생성해 내부적으로 컨트롤러 객체를 생성할 수 있다. deployment 객체를 생성하고 관리해야하는 pod 와 컨테이너에 대한 지침을 제공하자.

  • 컨테이너가 쿠버네티스에 의해 시작

장점

수동으로 리모트 머신을 선택해서 파드를 배치할 필요 X 쿠버가 해줌

  • 쿠버네티스가 파드를 워커 노드에 비치
  • 워커노드는 새 파드를 위한 메모리와 CPU 보유!

deployment 롤백 가능

  • 애플리케이션에 문제가 생겼을 경우 코드를 변경하고 오류를 수정해야 하는데 급박함..!!
  • 하지만 실패한 deployment 를 롤백하고 이전 deployment로 되돌린 뒤
  • 버그를 수정 후 업데이트된 컨테이너 이미지로 새 deployment 를 시작하면 끝!

스케일링 가능

  • 더 많은 또는 적은 파드를 가지고 싶다고 쿠버에 알리기 가능
  • 특정 메트릭을 설정할 수 있는 오토 스케일링 기능
    • 메트릭에 수신 트래픽과 CPU 사용률이 있음.
    • 메트릭을 초과한 사용률이 있을 경우 쿠버네티스가 자동으로 더 많은 파드 생성 → 요청 처리를 위해 컨테이너 인스턴스 생성
    • 트래픽이 저하되면 불필요한 파드 자동 제거

Deployment 를 사용하자

  • 직접 pod 를 직접 생성하거나 직접 관리하지 말자.
  • 대신 deployment 객체를 사용하여 생성, 이를 쿠버네티스 클러스터에 전송하여 쿠버네티스가 수행하도록 하자.

쿠버네티스는 모두 컨테이너에 관한 것이니 도커는 필요하다! 그냥 자체적으로 컨테이너를 실행한다 vs 쿠버네티스가 관리한다 는 차이가 있을 뿐…

Deployment : 명령적 접근 방식 (실습)

kubectl create 로 명령해서 실행하는

docker build -t kub-first-app .
  • 이렇게 빌드한 이미지를 수동으로 쿠버로 보낼 수도 있겠지만…
  • pod 의 일부분 또는 Deployment의 일부분으로 pod 를 생성하면…
    • 파드에서 실행되는 컨테이너를 제공하고 그걸 관리해줌!

클러스터가 실행 중인지 확인

# 나는 minikube 를 이용해서 더미 클러스터를 사용중이기 때문에
# minikube 가 실행 중인지 확인한당.
minikube status

클러스터에 Deployment 를 생성

kubectl 이라는 큐브 컨트롤 명령으로 수행. 로컬 머신에서 실행하면 됨! ㅎㅅㅎ

### Deployment 생성
kubectl create deployment \\
# 이름
first-app \\
# --image= : deployment 에서 생성된 pod 컨테이너에 사용할 이미지 지정
--image=이미지이름

### 클러스터에 deployment 가 얼마나 있는지 확인
# 참고로 kubectl 은 minikube 에 의해 자동으로 minikube에 연결되도록 구성되어
# minikube 와 상호작용하는지 명시할 필요가 없음.
kubectl get deployments

 

READY 0/1

  • 하나의 deployment 중 하나가 실패함.
### deployment 에서 생성된 모든 것 확인하기
kubectl get pods

 

STATUS : ImpagePullBackOff

  • create deployment 명령으로 생성할 때 클러스터에서 우리가 준 이미지 이름으로 이미지를 찾았으나, 해당 이미지는 우리 로컬 머신에만 있고 클러스터 로컬에서는(클러스터 내에서는) 찾을 수 없음.

해결 방안

  • Docker hub 와 같은 이미지 레지스트리에 일부분인 이미지를 지정해야 함.

해결을 하자!

일단 도커 이미지와 deployment 삭제 후 → docker hub 에 레포 만들고 이미지 푸쉬!

docker rmi 이미지

kubectl delete deployment 이름

#도커 허브에 원격 repository 생성 후 ... ###

docker build -t holidaykang/kube-first-app .

docker push holidaykang/kube-first-app

그리고 다시 … deployment 를 생성한다.

# 도커 허브에 있는 파일로 deployment 생성
kubectl create deployment first-app --image=holidaykang/kube-first-
app

# deployment 생성 확인
kubectl get deployments

# pod 생성 확인
kubectl get pods

deployment 확인

pod 확인

  • READY 1/1 로 정상 동작 ^ㅅ^/
# 이제까지 생성했던 리소스들을 대쉬보드로 확인 !
minikube dashboard

 

우와아~~~~~~~^ㅇ^ 신기해!!!!

  • 같은 레이블로 디플로이먼트와 파드가 연관되어있음.

kubectl 의 작동 배경

kubectl create deployment --image ...
  • deployment 객체를 생성한 다음 자동으로 쿠버네티스 클러스터에 있는 마스터 노드, 즉 컨트롤 플레인으로 전송.
  • 마스터 노드의 스케쥴러가 클러스터에 필요한 모든 걸 생성
    • deployment 에 저징한 이미지를 기반한 컨테이너, pod 생성 후 워커 노드에 pod 배포
  • 이 워커노드에서 kublet 서비스 가능 → pod 관리, 컨테이너 시작, pod 모니터링

Service 객체

파드와 파드에서 실행되는 컨테이너에 접근하기 위해 필요한 객체

파드 내부 IP의 문제점

  1. 파드 IP는 클러스터 내에서 사용하는 내부 IP에 불과함. 외부에서 접근 불가.
  2. pod 가 교체될 때마다 변경

서비스가 해주는 일

pod 를 그룹화하고 공유 주소와 공유 IP 를 제공(public IP)

  • 서비스를 사용해서 여러 파드를 해당 서비스로 이동시키고 변경 불가한 IP 에 연결 가능
    • 이걸로 클러스터 외부에서 pod 에 엑세스 가능!

Service 만들기

# 서비스 생성, deployment 에 의해 생성된 pod 노출하는 명령어
kubectl expose deployment first-app \\
# 내장 유형
# --type=CluesterIP : default, 변경되지 않는 IP 얻을 수 있으나 클러스터 내부에서만 연결할 수 있음.
# --type=NodePort : 해당 deployment 가 실행 중인 워커 노드의 IP 주소로 노출
# 로드밸런서 유형, 서비스 고유 주소 생성하고 들어오는 트래픽을 모든 파드에 고르게 분산.
# 단, 클러스터와 클러스터가 실행되는 인프라가 지원하는 경우에만 사용 가능
--type=LoadBalancer \\
# 포트 노출
--port=8080 

내장 유형 종류

ClusterIP

default , 변경되지 않는 IP 얻을 수 있으나 클러스터 내부에서만 연결 가능

NodePort

해당 deployment가 실행 중인 워커 노드의 IP 주소로 노출

LoadBalancer

로드밸런서 유형, 서비스 고유 주소 생성하고 들어오는 트래픽을 모든 파드에 고르게 분산.

→ 단, 클러스터와 클러스터가 실행되는 인프라가 지원하는 경우에만 사용 가능 (minikube, AWS…)

# 서비스들 보기
kubectl get services

 

 

  • 성공적으로 생성됨!
  • kubernetes 는 자동으로 생성된 default service.

EXTERNAL-IP <pending> ?

  • 클라우드 프로바이더에 배포되면 실제 외부 IP 를 볼수 있으나, 지금은 minikube 사용중이어서 <pending>
  • 왜? minikube 도 결국 로컬에서 실행되는 가상머신일뿐이니까..
  • 그래도 minikube 에서 service 엑세스는 가능!
# minikube 로 서비스에 엑세스하기
# minikube 전용이라 클라우드 프로바이더에서는 IP 쓰면 됨!
minikube service 서비스이름

 

 

엑세스 성공 ! >.<

  • 쿠버네티스 클러스터로 보낸 deployment 기반으로 쿠버네티스가 생성한 pod 에서 실행.
  • 쿠버네티스 서비스로 인해서 볼 수 있음 ! !!

알아두기

  • 애플리케이션에서 오류가 나서 종료되더라도 deployment 가 컨테이너를 재시작 시켜줌
    • 재시작할때마다 다시 시작하는 시간이 길어질 순 있음, 반복 오류가 났을 수도 있어서

스케일링

오토스케일링 설정을 하지 않더라도 직접 스케일링 가능하고 로드밸런서로 트래픽을 분산시켜줌

# 원하는 파드 수를 3개로 지정
kubectl scale deployment/first-app --replicas=3

 

 

kubectl get pods 하면, 이렇게 세 개의 파드가 생긴 것을 확인 가능.

  • 어느 하나가 멈춰도 다른 곳으로 리디렉션 시켜줌
  • 스케일링을 수동으로 하더라도 알아서 트래픽 분산 시켜줌
# 참고로 이렇게 다시 복사본을 1로 축소시키면
kubectl scale deployment/first-app --replicas=1

 

 

  • 하나만 동작하고 나머진 종료됨. → 저거 두개는 나중에 삭제됨~!

Deployment 업데이트

docker build -t holidaykang/kube-first-app:2 .

docker push holidaykang/kube-first-app:2
  • 일단 도커 허브에 새 이미지를 업데이트 해줘야겠지?
  • 이 때 기존 컨테이너의 이미지와 태그가 변하면 업데이트하기때문에, 태그를 기존과 다르게 해줌
### 업데이트
# deployment/이름 으로 해당 deployment 를 업데이트해야한다고 알림
kubectl set image deployment/이름 \\
# 이전 이미지 이름=새로운이미지이름 추가 하여, deployment 업데이트
kube-first-app=holidaykang/kube-first-app:2

### 현재 업데이트 상태 확인
kubectl rollout status deployment/이름

# deployment "first-app" successfully rolled out -> 요게 뜨면 제대로 업데이트 됐다는 거!
  • minikube dashboard 해보면

  • 이렇게 업데이트 된 내역을 확인 가능 ㅎㅅㅎ/

Deployment 롤백 / 히스토리

# 일부러 존재하지 않는 이미지로 이미지 업데이트를 시도한다.
kubectl set image deployment/first-app kube-first-app=holidaykang/kube-first-app:4

# 롤아웃 진행 상황을 검사하면 ?
kuectl rollout status deployment/first-app

 

  • 뭔가 이런 게 뜨면서 deployment 가 완료되기를 기다린다고 뜨며, 실행중인 pod 가 종료..
  • 컨트롤 + c 로 일단 빠져나가기
  • dashboard 에서는 이미지가 풀링이 안 된다고 에러가 😞
  • 안되겠다. 롤백을 해보자 !
# 이전 상태로 롤백
kubectl rollout undo deployment/first-app

 

  • 문제가 있는 파드는 없어지고 다시 이전 상태로 돌아감!
# deployment history 보기
kubectl rollout history deployment/first-app

# 특정 히스토리 정보 보기
kubectl rollout history deployment/first-app --revision=2

# 특정 버전으로 돌아가기
kubectl rollout undo deployment/first-app --to-revision=1
728x90