Kubernetes

References

Kubernetes (K8s)

Kubernetes(K8s)는 container화된 application의 배포(deploy), 확장(scale), 운영(operate)을 자동화하는 오픈소스 container orchestration platform.

Kubernetes라는 명칭은 키잡이(Helmsman) 또는 파일럿(Pilot)을 뜻하는 그리스어에서 유래됨.

Kubernetes는 Google이 내부에서 15년 이상 사용한 시스템인 Borg(보그)의 노하우를 기반으로 만들어짐.

Google이 2014년에 kubernetes project를 오픈소스화 하였으며, 현재는 CNCF(Cloud Native Computing Foundation)가 관리하고 있음.

즉 kubernetes는 단순히 새로 만든게 아니라 Google이 실전에서 검증한 시스템을 세상에 공개한 것임.

K8s?

  • Kubernetes에서 첫글자 K와 마지막글자 s 사이에 글자가 8개 있기 때문.
  • 이러한 방식을 Numeronym(뉴머님) 이라고 부름.
    • Numeronym의 예시
      • i18n: internationalization
      • l10n: localization

K8s 필요 이유

Application을 container로 실행하는 방식이 보편화되면서, container가 하나, 둘이 아니라 수백, 수천개로 늘어나기 시작함. 그 많은 container들을 어떻게 관리해야 할지 문제가 생김.

container가 많아질수록 관리의 복잡도가 폭발적으로 증가하기 때문에, 이를 자동화하고 안정적으로 운영하기 위하여 kubernetes가 필요함.

Container만으로는 부족한 것들

문제설명
자가 복구 (self-healing)Container가 down될 시 누가 다시 살리나?
확장 (scaling)Traffic이 몰리면 누가 container를 늘리나?
배포 (deployment)새 버전을 무중단으로 어떻게 배포하나?
부하 분산 (load-balancing)요청을 여러 컨테이너에 어떻게 분산하나?
설정 관리 (configuration management)환경 변수, secret을 어떻게 안전하게 관리하나?
스케줄링 (scheduling)어떤 node에 container를 배치할지 누가 결정하나?

이 모든 것을 사람이 수동으로 하면 실수가 생기고(human error), 규모가 커질수록 불가능에 가까워짐.

K8s가 해결하는 것

K8s는 위 문제들을 선언적 방식(Declarative Approach)으로 해결.

개발자는 원하는 상태(Desired State)만 선언하고, K8s가 현재 상태(Current State)를 원하는 상태로 자동으로 맞춰줌.

예시:

replicas: 3    # container 3개를 항상 유지.

=> container 하나가 down되면 k8s가 자동으로 새로운 container를 띄움.

K8s 버전 관리

*여기에 작성할 것: k8s를 사용하면 무중단 서비스를 구현할 수 있기 때문에 development, production을 분리할 수가 있다. 하지만, k8s 자체의 버전이 올라갔을 때, 어떻게 서비스를 유지하면서 이를 업데이트 할수있는가? 에 대한 것을 공부하고, 정리하도록 하자.

K8s 구조

Pod Networking

Pod가 외부에 서비스를 제공하기 위해서는 NodePort, hostPort/hostNetwork, LoadBalancer 등의 기능을 사용해야 함.

NodePort

서비스가 모든 Worker Node의 특정 포트(30000~32767 Only)를 열어줌.
외부에서 Worker Node IP:Port 로 들어오면 kube-proxy가 받아서 뒤에 있는 Pod로 분산시켜줌.

포트 번호가 제한되어 있고, Node IP를 알아야 해서 실무에서 사용하기는 애매한 방식.

hostPort / hostNetwork

  • hostPort: Pod의 컨테이너 포트를 노드의 포트에 직접 Mapping. Pod가 떠 있는 그 노드의 IP:포트로만 접근 가능.
  • hostNetwork: true: Pod가 노드의 네트워크 네임스페이스를 통째로 사용. Pod 안에서 ifconfig 명령 실행 시 노드 NIC가 그대로 출력됨.

Pod가 노드에 딱 붙어버리는 방식이라 Scheduling 유연성이 떨어짐. 보통 CNI나 모니터링 데몬셋 같은 인프라성 Pod에만 사용됨.

LoadBalancer

클라우드(AWS, GCP 등) 환경에서 진짜 외부 L4 로드밸런서를 자동으로 띄워줌. 외부 IP 하나 받아서 깔끔하게 Traffic을 받을 수 있음. Production 환경에서의 정석적인 방법.

단점은 서비스마다 LB가 하나씩 생겨 비용 발생. 그래서 보통 Ingress랑 같이 묶어 사용.

Ingress / Egress

1) 일반 네트워크 용어로서

  • Ingress : 들어오는 Traffic.
  • Egress : 나가는 Traffic.

2) K8s Resource(Object)로서

  • Ingress : K8s resource 종류 중 하나. L7(HTTP/HTTPS) level에서 domain/path 기반으로 traffic을 routing해주는 rule 모음. (e.g. api.com/users -> A 서비스, api.com/orders -> B 서비스.)
  • Egress : 독립 resource가 아님. 보통 NetworkPolicy 안의 한 항목으로 나가는 Traffic 제어 규칙을 뜻함.

Ingress Controller

Ingress는 resource에 불과함. URL과 서비스를 연결 해 놓은 문서일 뿐임.

그 문서를 보고 실제로 Traffic을 받아 Routing하는 실체(Pod)를 Ingress Controller라고 함.

보통 Cluster 내부에 Deployment/DaemonSet 으로 떠있음.

대표적으로 Nginx Ingress Controller, Traefik, HAProxy 등이 존재함.

LoadBalancer + Ingress 묶기

LB는 L4라서 IP/Port만 보고 던지지만, Ingress는 L7이라 URL 보고 똑똑하게 나눠줄 수 있음.

LB는 입구에서 전부 Controller한테 던지고, L7 Routing은 Controller가 수행함.

아래는 LB + Ingress 동작 Flow 이다.

외부 -> LoadBalancer(L4) -> Ingress Controller Pod(L7) -> 규칙(Ingress resource) 참고 -> 알맞은 Service -> Pod