(MLOps-4) kubernetes 정리 - 2

dddwsd·2022년 5월 11일
0

Kubernetes kind

Pod

Pod는 kubernetes에서 관리하는 가장 작은 배포 단위이다.
컨테이너를 만드는 docker와는 다르게 kubernetes는 pod을 생성하고 pod은 한 개 이상의 컨테이너를 포함한다.

Pod을 생성하면 minikube cluster안에 pod이 생기고 pod안에 컨테이너가 생기게 된다.

Pod이 생성되는 과정은 아래와 같다.

  1. 스케줄러는 API 서버를 감시하면서 unassigned pod이 있는지 확인
  2. 스케줄러는 할당되지 않은 pod을 감지하고 적절한 node에 할당
  3. node에 설치된 kubelet은 자신의 노드에 할당된 pod이 있는지 체크
  4. kubelet은 스케줄러에 의해 자신에게 할당된 pod의 정보를 확인하고 컨테이너 생성
  5. kubelet은 자신에게 할당된 pod의 상태를 API 서버에 전달

pod은 단독으로 사용하는 경우가 거의없고 다른 controller가 pod을 관리한다.

livenessProbe

컨테이너가 정상적으로 동작하는지 체크하고 정상적으로 동작하지 않는다면 restart를 통해 문제를 해결한다.

container를 체크하는 방법은 여러가지가 있다.

  • http get
  • tcpSocket
  • exec

readinessProbe

컨테이너가 준비되었는지 체크하고 정상적으로 준비되지 않았다면 Pod으로 들어오는 요청을 제외한다.

livenessProbe와 차이점은 문제가 있어도 Pod을 재시작하지 않고 요청만 제외한다.

multi container

대부분 1 pod = 1 container지만, 여러개의 container를 가질 수도 있다.
하나의 pod에 속한 컨테이너는 서로 네트워크를 localhost로 공유하고 동일한 디렉토리를 공유할 수 있다.

docker에서는 multi container를 실행할 수 없고, kubernetes에서만 가능한데, 다양한 패턴으로 설정할 수 있다.

example

  • log를 수집하는 별도의 container를 같은 pod에 배포
  • 서버가 실행되기 전 데이터베이스를 migration하는 intialize container

ReplicaSet

Pod을 단독으로 만들면 Pod에 어떤 문제가 생겼을 때 자동으로 복구되지 않는다. 이런 경우 Pod을 정해진 수만큼 복제하고 관리하는 것이 ReplicaSet이다.

ReplicaSet은 label을 체크해서 원하는 수의 Pod이 없으면 새로운 Pod을 생성한다.

  • spec.selector - label 체크 조건
  • spec.replicas - 원하는 pod의 개수
  • spec.template - 생성할 pod의 명세

label을 이용하여 Pod을 체크하기 때문에 label이 겹치지 않게 신경써서 정의해야 한다.

실제로 ReplicaSet을 단독으로 쓰는 경우는 거의 없고 Deployment에서 주로 사용한다.

ReplicaSet 동작원리

  1. ReplicaSet Controller는 ReplicaSet 조건을 감시하면서 현재 상태와 원하는 상태가 다른 것을 체크
  2. ReplicaSet Controller가 원하는 상태가 되도록 Pod을 생성하거나 제거
  3. Scheduler는 API서버를 감시하면서 할당되지 않은 Pod이 있는지 체크
  4. Scheduler는 할당되지 않은 새로운 Pod을 감지하고 적절한 node에 배치
  5. 이후 노드는 기존대로 동작

ReplicaSet은 ReplicaSet Controller가 관리하고 Pod의 할당은 여전히 Scheduler가 관리한다.

Deployment

Deployment는 kubernetes에서 가장 널리 사용되는 오브젝트로 ReplicaSet을 이용하여 Pod을 업데이트하고 이력을 관리하여 Rollback하거나 특정 버전(revision)으로 돌아갈 수 있다.

Deployment는 새로운 이미지로 업데이트 하기 위해 ReplicaSet을 사용한다. 이미지를 업데이트 하면 새로운 ReplicaSet을 생성하고 해당 ReplicaSet이 새로운 버전의 Pod을 생성한다. 새로운 ReplicaSet의 수만큼 기존의 pod이 제거되고 업데이트 된 이미지의 Pod이 생성된다.

Deployment 동작원리

  1. Deployment Controller는 Deployment 조건을 감시하면서 현재 상태와 원하는 상태가 다른 것을 체크
  2. Deployment Controller가 원하는 상태가 되도록 ReplicaSet 설정
  3. ReplicaSet Controller는 ReplicaSet 조건을 감시하면서 현재 상태와 원하는 상태가 다른 것을 체크
  4. ReplicaSet Controller가 원하는 상태가 되도록 Pod을 생성하거나 제거
  5. Scheduler는 API서버를 감시하면서 할당되지 않은 Pod이 있는지 체크
  6. Scheduler는 할당되지 않은 새로운 Pod을 감지하고 적절한 node에 배치
  7. 이후 노드는 기존대로 동작.

버전관리

Deployment는 변경된 상태를 기록한다.

# 히스토리 확인
kubectl rollout history deploy/echo-deploy

# revision 상세 확인
kubectl rollout history deploy/echo-deploy --revision=n

# 바로 전 버전으로 rollback
kubectl rollout undo deploy/echo-deploy

# 특정 버전으로 rollback
kubectl rollout undo deploy/echo-deploy --to-revision=n

배포 전략

kubernets에는 다양한 배포 전략이 존재한다.

RollingUpdate


RollingUpdate는 kubernetes의 가장 큰 장점인 무중단 배포를 위한 전략이다. 무중단 배포란 서버를 실제로 서비스할 때 서비스적인 장애와 배포에 있어서 부담감을 최소화하고, 서비스가 중단되지 않도록 배포하는 기술이다.
배포된 전체 Pod를 한꺼번에 교체하는 것이 아닌 일정 개수씩 교체하면서 배포하는 방식으로 이는 Deployment의 기본 배포 방법이기도 하다.
Pod를 하나씩 죽이고 새로 띄우는 순차적인 교체방법이지만, 업데이트 프로세스 동안 두 가지 버전의 컨테이너가 동시에 실행되어서 버전 호환성 문제가 발생할 수 있다.

Blue/Green


기존에 실행된 Pod 개수만큼 신규 Pod를 실행하고 신규 Pod가 정상적으로 실행되면 한꺼번에 트래픽을 옮긴다.
신버전과 구버전이 같이 존재하는 시간 없이 순간적인 교체가 가능하지만 RollingUpdate보다 리소스가 많이 필요하다.

Canary


기존 버전을 유지한 채로 일부 버전만 신규 Pod로 교체한다.
구버전과 신버전이 같이 존재해서 버그확인, 사용자 반응을 확인할 때 유용하다.

Service


Pod는 자체 IP를 가지고 다른 Pod과 통신할 수 있지만, 쉽게 사라지고 생성되는 특성 때문에 직접 Pod와 통신하는 방법은 권장하지 않는다.
그래서 kubernetes는 Pod와 직접 통신하는 방법 대신, 별도의 고정된 IP를 가진 서비스를 만들고 그 서비스를 통해 Pod에 접근하는 방식을 사용한다.

ClusterIP

ClusterIP는 클러스터 내부에 새로운 IP를 할당하고 여러 개의 Pod를 바라보는 LoadBalancer 기능을 제공한다. 그리고 service 이름을 내부 domain server에 등록하여 Pod간에 service 이름으로 통신할 수 있다.

동작원리


Service는 각 Pod를 바라보는 LoadBalancer 역할을 하면서 내부 도메인서버에 새로운 도메인을 생성한다.
1. Endpoint Controller는 Service와 Pod을 감시하면서 조건에 맞는 Pod의 IP를 수집
2. Endpoint Controller가 수집한 IP를 가지고 Endpoint 생성
3. Kube-Proxy는 Endpoint 변화를 감시하고 노드의 iptables을 설정 (iptables는 kernel level의 네트워크 도구로 여러 IP에 트래픽을 전달함)
4. CoreDNS는 Service를 감시하고 서비스 이름과 IP를 CoreDNS에 추가. (CoreDNS는 빠르고 편리하게 사용할 수 있는 클러스터 내부용 Domain Name Server로 IP대신 domain 이름 사용)

NodePort

클러스터 외부에서도 접근할 수 있도록 하는 service는 type을 NodePort로 설정하고 같은 상위 네트워크 상에서 주로 사용한다.

NodePort는 클러스터의 모든 node에 port를 오픈한다. 여러 개의 NodePort를 설정한다면 아무 node로 접근해도 지정한 Pod에 접근할 수 있다.

NodePort의 단점은 노드가 사라졌을 때 자동으로 다른 노드를 통해 접근이 불가능하다. 예를들어 3개의 노드가 있다면 3개 중에 아무 노드로 접근해도 NodePort로 연결할 수 있지만 어떤 노드가 살아 있는지는 알 수가 없다.

LoadBalancer

LoadBalancer는 살아 있는 노드에 접근하기 위해 모든 노드를 바라본다.
브라우저는 LoadBalancer에 요청을 보내면 LoadBalancer가 살아 있는 노드에 접근하게 한다.
LoadBalancer는 외부 인터넷(AWS, GCP, Azure와 같은 클라우드 환경)과 연결을 담당한다.

refer

profile
Github - https://github.com/dddwsd

0개의 댓글