Kubernetes 기본 개념

2020. 10. 5. 17:49cloud&platform

 

Container를 orchestration 하기 위한 가상화 플랫폼.

Container는 무수히 많이 생성되고 소멸되며, 이로 인한 다수의 클러스터를 구성하기 때문에, 이를 관리하기 위한 플랫폼에 대한 요구가 많아지게 되었으며, kubernetes는 그 중 가장 핫한 플랫폼이다.

 

> Node

1개 이상의 Docker Container를 호스팅하는 work machines

 

· important process

1. Kubelet

특수한 백그라운드 프로세스 (마스터의 명령에 응답하여 해당 호스트의 컨테이너를 작성, 삭제 및 모니터하는 작업을 수행하는 각 노드에서 실행되는 데몬)

2. Proxy

대상 컨테이너의 IP 주소와 제공하는 서비스의 이름을 구분하는 데 사용되는 간단한 네트워크 프록시입니다.

3. cAdvisor(Container Advisor) - Optional

컨테이너 사용자에게 실행중인 컨테이너의 자원 사용 및 성능 특성에 대한 이해를 제공

 

 

 

> Master

node의 Container를 스케쥴링하는 특수한 software가 실행되는 machines

 

· 주요 구성 요소

1. API Server

master 및 node의 거의 모든 구성요소는 API 호출을 통해 수행됨

master에서 실행되는 API서버에 의해 처리

2. Etcd

클러스터의 현재 구성 및 실행 상태를 유지하고 복제하는 작업

경량 분산 key-value Repository

3. Scheduler and Controller Manager

대상 node의 Container를 스케쥴링 및 실행상태 확인

 

cluster = collestions of masters and nodes

 

 

 

 

> Pod

IP나 파일시스템과 같은 자원을 공유하기 위한, 함께 관리되는 Container 및 Volume 모음.

공유 IP 주소를 Pod에 할당 - IP자원의 단순화 (일단 Docker기준에서는 Container마다 자신의 IP를 가진다. 하지만 kubernetes에서는 pop이 기준이다.).

Pod의 Container들은 IP를 공유하고, Container들끼리 localhost통신을 한다.

Kubernetes의 Ochestration은 Container Level이 아니라, Pod Level에서 이루어 진다. 즉, 같은 Pod에서 실행되는 Container는 같이 관리 된다. '공유된 운명'이라고 불리는 이것은 모든 clustering의 핵심 개념이다.

 

 

 

> Volume

Docker의 경우 Container가 접근하고 사용하는 virtual filesystem.

Kubernetes는 Pod Level에서 정의됨.

- Container가 죽어도 Pod Level에서 정의되므로 data는 건재하다.

- Pod에 있는 모든 Container는 volume을 공유한다.

 

종류(types)

- EmptyDir

: 비어 있는 Volume으로 생성 됨.

Pod과 Life Cycle을 공유 - Pod이 소멸되면, 데이터를 모두 잃는다.

Pod의 모든 Container는 여기에 읽고 쓸 수 있다.

임시 저장소로 쓰인다. default 저장소.

- Network File System (NFS)

: Persistent Volume(PV)을 구성하기 위한 타입 제공.

Ceph, GlusterFS 등을 이용한 Logical 구성 지원.

Pod의 Life Cycle과는 별개의 File System 제공.

중요한 파일 기반 데이터를 영구적으로 저장 가능.

- GCEPersistentDisk (PD)

: Google Cloud Platform을 사용할 경우 Kubernetes에 제공됨.

Life Cycle과 영구성에 대한 걱정이 없음.

 

기본 구성도

 

 

> Label

Pod에 할당하는 Key / Value pair로 구성되는 Label.

 

Label Selector

Label은 queryable 하다. 즉, 특정 Pod을 select하기 위한 용도이다.

1. equality-based (IS or IS NOT)

- key = value

- key != value

2. set-based (IN or NOT IN)

- environment in (production, qa) : environment 의 값이 production, qa인Pods

- tier notin (frontend, backend) : tier 값이 frontend, backend 가 아닌 Pods

- partition : partition Label을 가진 모든 Pods

- 서로 조합 가능 : environment in (production, qa), tier notin (frontend, backend), partition

 

 

> Annotation

pod (or cluster, node, etc.) 에 저장하려는 유용한 정보 (빌드 날짜 등등)

key / value pair, but not queryable

 

 

 

> Replication Controller

replica (Multiple copies of a pod)를 관리하는 프로세스.

올바른 수의 replica 가 항상 실행되고 있는지 확인하는 것.

Controller에서 어떤 Pod을 관리할 것인지 직접 지정하지 않는다. 대신 LabelSelector에 의해 match되는 pod 관리한다.

* 실제로 Pod을 죽이지 않고도 서비스에서 뺄 수 있다. 즉, Label을 변경하여 query에서 매치 되지 않도록 한다. 이러면, 여기서 빠진 Pod 대신 Controller는 새로운 replica를 채울 것이다. (debugging등의 임시용으로 Pod을 하나 서비스에 슬쩍 끼어 넣었는데, 이렇게 다시 슬쩍 뺄 수 있는 것이다)

* Controller가 사용하는 Label Selector를 변경하여, 실시간으로 완전히 다른 Pod Cluster를 관리할 수 있다.

 

Replication Controller를 죽이는 것은 관리되고 있는 replica에 영향을 주지 않는다. (명시적으로 controller의 replica filed를 0으로 셋 해야함).

> Pod에 영향 없이 replication controller를 죽이고 새로 시작할 수 있다.

 

zero-downtime rolling updates much easier 하게 한다.

* 업데이트 된 replica 1 개가있는 새 controller를 가져온 다음 이전 controller에서 1 개의 replica를 제거.

* 새 Controller에 필요한 replica가 있고 이전 controller가 empty 될 때까지 이 + 1 / -1 을 계속 한다.

* 마지막으로 old controller를 삭제한다.

* 이미 default 로 이렇게 동작한다.

 

 

 

 

> Service

cluster의 pod 세트를 가리키는 long-lived end-point proxy.

 

1. 필요성

- 새로운 pod과 기존 pod의 교체에 IP 주소는 동일함을 보장하지 않음.

- 한 클라이언트의 요청을 처리한 Pod이 다음 요청을 처리한다는 보장은 없으며, 심지어 사라질 수도 있다. (Replication Controller에 의해 새로운 Pod으로 대체).

- 따라서 로드밸런서(zuul 등)에서 Pod 목록을 지정할때 IP주소를 이용하는것이 어렵다.

- 오토스케일링으로 인한 Pod가 동적으로 추가/삭제되는 과정에서 이렇게 추가/삭제된 Pod목록을 로드밸런스가 유연하게 선택해줘야 한다.

- 이런 문제를 해결하고자, Service Object가 Label Selector를 통해, 개별 pod과 무관하게, pod의 세트를 관리하는 개념이다.

- 개별 Pod의 Label 을 수정하거나, Label Selector를 조작하여, 언제든 요구되는 Pod Service를 고칠 수 있다. - Real-time A/B TEST

 

 

2. Service type

1) Cluster IP

- 가장 기본적 설정으로 클러스터를 구성하는 Pod의 내부 대표 IP를 할당한다.

- 서비스의 IP는 서비스를 재생성할때까지 변경되지 않는다. 하지만, 보통 서비스 네임을 통해 접근한다. (DNS)

- 쿠베네티스 클러스터 내부에서만 이 서비스에 접근이 가능. (externalIPs나 proxy를 통한다면 외부 접근 가능)

 

2) Node Port

- 모든 노드의 특정 포트를 열고, 이 포트로 보내지는 모든 트래픽을 서비스로 전달.

- 외부 트래픽을 서비스에 직접 전달하는 가장 기본적인 방법.

- kube-proxy에 --nodeport-addresses 플래그를 지정하여, 특정 IP를 지정하여 포트를 프록시 할 수 있다. (k8s v1.10 이상). > 이를 통해, 공개할 IP Group을 지정하여, 외부 스위치 장비에 연결하는 방식의 Entry point HA를 구현 할 수 있다.

 

3) Load Balancer

- 서비스를 인터넷에 노출시키는 표준 방법.

- 외부 로드 밸런서를 지원하는 클라우드 공급자의 경우, Type을 LoadBalancer로 설정하면 동적으로 프로비저닝된 로드 밸런서가 서비스를 노출하게 된다.

- On-Prem 환경에서는 외부 로드밸런서가 없는 경우, 로드 밸런서의 IP 할당이 되지 않으므로 NodePort로만 동작 한다.

- externalIPs는 단순 ip만을 노출시키는 것이고, 이 방식은 외부 로드밸런서를 통한 L4 규약을 준수하는 스위치를 생성시키는 것이다. (할당된 ip는 스위치 장비가 되는 개념)

- metallb와 같은 On-Prem 환경을 위한 외부 로드밸런서 구현체가 존재한다.

 

4) External Name

- 외부서비스를 쿠버네티스 내부에서 정적 네이밍을 통해 호출하고자 할때 사용.

- 예를 들어, 외부 데이터 호출을 위해, 주소를(externalName) my.database.example.com 으로 설정하게되면, service로 들어오는 모든 요청이 my.database.example.com으로 포워딩된다.

kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  type: ExternalName
  externalName: my.database.example.com

- 이제, pod 내부에서는 저 긴 URL대신, mydb를 호출하면 된다.

- 보통, AWS나 외부 자원을 접속할때, 이 URL은 instance 관리에 따라 변동이 될 수 있는데, 이런 식으로 Bridge를 두면, application을 하나하나 고치지 않고 Service정의만 고치면 된다.

 

※ host name을 ip에 매칭시키는 방법

외부 자원을 External Name말고도, ip와 기타 정보를 host name으로 매핑시킬 수 도 있다.

kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  ports:
    -
      name: mydb
      protocol: TCP
      port: 3306
      targetPort: 3306
      nodePort: 0
---
kind: Endpoints
apiVersion: v1
metadata:
  name: mydb
subsets:
  -
    addresses:
      -
        ip: "1.1.1.1"
    ports:
      -
        port: 3306
        name: mydb

이렇게 IP 1.1.1.1을 Endpoints로 정의하고, 이를 서비스 mydb에 연결함으로써, 특정 외부 ip를 도메인 서비스처럼 사용할 수 있다.

 

 

 

> Ingress

Ingress는 Kubernetes Service는 아니지만, 외부 사용자가 Kubernetes 클러스터에서 실행중인 서비스에 액세스하는 방법을 제어하는 라우팅 규칙 모음.

즉, LoadBalancer Type의 Service는 Single Service를 프로비저닝된 로드 밸런서가 노출하는 것이며, Ingress를 정의한다는 것은 LoadBalancer와 기본적으로는 같지만, 여기에 추가적인 규칙이 적용될 수 있는 것이다.

따라서, 이 규칙은 Single서비스도 유효하지만, 여러 서비스 앞에 위치하여 하나의 IP로 도메인주소단위, 또는 path단위로 Multi서비스에 분산시킬 수도 있다. 한마디로, 클러스터에 "스마트 라우터" 또는 진입점 역할을 하는 것이다.

즉, 특별한 라우팅 규칙을 적용하려고 하는 경우 (요청 url을 통한 여러 서비스로 분산 등) 유용하다. 요청과 Service Object가 1:1 관계이며 단순 리버스 프록시라면 LoadBalancer Type을 그냥 사용하면 된다.

 

 

 

> Headless Service

로드밸런싱이나, 단일 서비스 IP가 필요 없는 경우 clusterIp를 None으로 설정하여 생성.

Kubernetes 시스템에 비교적 자율적으로 개별 pod에 접근. (kube-proxy는 이 type의 서비스를 처리하지 않는다.).

보통, 특정 pod군이 하나의 Cluster군을 구성하고, 이 Cluster를 별도로 관리하고자 할때 사용한다. (kafka cluster 구성, zookeeper cluster 구성 등)

 

 

 

> Namespace

쿠버네티스 클러스터 내부 객체 관리를 위한 논리적인 분리 단위.

 

1. 기본 Namespace

- default : 다른 네임스페이스가 없는 객체의 기본 네임스페이스.

- kube-public : 퍼블릭은 자동으로 만들어지며 모든 사용자 (인증되지 않은 사용자 포함)가 읽을 수 있음.

일부 리소스를 전체 클러스터에서 공개적으로 표시하고 읽을 수 있어야 할 경우를 대비하여 대부분 클러스터 사용을 위해 기본 설정 되어 있음.

- kube-system : Kubernetes 시스템에 의해 생성 된 객체의 네임 스페이스

 

 

 

 

> Sidecar

more complcated alogorithm than just “round robin”, “random”, “sticky-session” 일 경우, 보통 Client Side Load-balancer를 사용.

Load balancing을 위한 라이브러리가 application에 침투하는 것을 방지. > custom load-balancing algorithm을 분리.

 

'cloud&platform' 카테고리의 다른 글

Docker 기본 개념  (0) 2020.10.26
Kubernetes 설치 가이드 - v1.11.3  (0) 2020.10.23
Spring Core - IoC, DI, Context And Bean  (0) 2020.10.22
Spring Overview  (0) 2020.10.20
Kubectl command  (0) 2020.10.16