Kubernetes
k8s
google에서 만들고 있는 도커 오케스트레이터, 설정이 매우 복잡하지만, GCE에서는 쉽게 쓸수 있다. 다만 이것을 내 머신에 설치하려면 수많은 사전지식과 설정 파일이 필요하다.
why k8s
k8s 는 마술 지팡이 일까?
k8s 만 쓰면 모든 배포/인프라 가 해결 될것 처럼 생각하는 사람들이 생각 보다 많은 것처럼 느껴진다. 하지만 k8s 는 안타깝게도 마술 지팡이가 아니다. k8s 를 쓰면 당연히 PM에 직접 배포 하는 것보다는 리소스가 많이 들고, 학습 비용도 들고, k8s 를 올릴 인프라도 여전히 필요하다. 그래서인지 k8s를 쓰는 것에 반감을 가진 사람들은 “PM에서도 할수 있잖아요”1, “그거 해보니까 성능이 안나와서요”, “제가 필요한 기능을 어떻게 써야 하는지 몰라서요” 등등의 이유를 든다. 사실 k8s를 쓰는 이유는 성능같은 이유가 아니다. 그렇다고 배포가 편해서도 아니다2. 그럼 k8s는 왜 쓰는 가? 이유는 복잡한 인프라와 배포 프로세스, 잡다한 소프트웨어 아키텍쳐 구조를 선언적으로 yaml 에 작성 할수 있기 때문이다. 물론 그러다보니 엄청나게 복잡하고 장황해진것이다. 그 전까지는 이것을 배포는 고사하고 나타낼 방법도 없었다. 규모가 큰 어플리케이션은 단순한 nginx+tomcat 같은 구조가 아니라 Front End, Messsage Queue, WAS, cache, DB, Storage 등등의 엄청나게 많은 컴포넌트들이 얽혀 있는데, 그러다 보니 배포 가이드를 작성해도 배포하기가 어렵고, 구조도를 작성해도 전체 Application구조를 표현하기 쉽지 않았다. 거기다 표현하는 방식이 제각각이니 더더욱 어려웠다. k8s는 (비록 시작은 그런 목적이 아니더라도) yaml 하나로 전체 Application의 구조를 나타내고, 배포할수 있는 훌륭한 Tool 로써 사용 되고 있다. 물론 그 yaml 은 엄청나게 복잡하고 이해 하기 힘들며 장황할것이다. 만들어진 yaml 로 한방에 배포할수는 있지만, 그렇게 배포할수 있게 만들기는 엄청나게 어려울것이다. 그래도 아직까지는 그것보다 나은 방법이 없기 때문에 쓰는 것이고, 그게 k8s가 인기 있는 이유라고 생각한다.
Kubernetes Object
K8s에서 논리적으로 정의한 관리 단위들이다.
Pod
- container의 묶음
- k8s에서는 이 Pod을 기본 단위로 취급
- 다른 모든 Object 는 이 POD 을 잘 관리하기 위해서 존재한다.
Replicaset
- 같은 POD을 여러개 띄우기 위한 Object
- Replicaset 은 POD 의 갯수를 관리한다.
Deployment
- Replicaset 을 관리하기 위한 Object
- 배포 정책과 다른 배포에 필요한 정책들을 지정할수 있다.
- 새버전이 배포되면 새로운 replicaset 을 생성한다.
Service
- Pod이 외부 혹은 다른 POD와 연결되기 위한 정보를 정의한다.
- DNS 도 service 단위로 관리 된다.
- VIP, ClusterIP 등등을 관리한다.
- 3가지의 타입이 존재한다.
- L4가 맡는 역활을 맡는다.
- 단 각 Backend 의 Weight 를 조절할수 없고, on/off만 존재한다.
Ingress
- URL 에 따라 다른 Service 로 연결하거나 트레픽을 일부에만 흘리거나 한다.
- L7이 맡는 역활을 맡는다.
- 구 버전에서는 nginx로 구현되기도 했다.
Namespace
- C++의 Namespace 와 유사하다.
- 각 네임스페이스별로 k8s 이름이 유니크 해야한다.
- 즉 서로 다른 Namespace에서는 같은 이름의 Pod, deployment, configmap 등등이 존재할수 있다.
- Namespace 별로 권한 관리나 유저설정을 달리할수 있다.
ConfigMap/Secret
- Pod을 띄울떄 필요한 각종 설정 값을 저장한다.
- Key-Value 로 저장 할수 있으며 POD에는 환경 변수로 전달하거나 filesystem 으로 마운트 할수 있다.
Daemonset
- deploy의 특수한 형태이며, 갯수가 아니라 모든 노드에 POD 을 띄운다.
- 주로 모든 노드에 설치되어야할 Binary 를 설치하거나, 모니터링 하기 위해서 사용된다.
- Cluster를 운영하는 입장에서는 Deamonset 을 적극적으로 활용하는 편이 유지보수가 쉽다.
Statefulset
- deploy의 특수한 형태이며, Deployment 는 모든 POD 이 동일한 Resource 를 사용하는 반면 Statefulset 은 POD 별로 다른 Resource를 사용하게 할수 있다.
- 주로 Local volume 을 쓰거나 각 POD로 설정값이 달라야하는 Storage 성 Application을 띄울떄 유용하다.
기타
- ServiceAccount
- K8s에서 사용할 계정을 정의한다.
- CustomResourceDefinition
- k8s Object를 확장해서 사용할수 있다.
핵심 component
- kubelet
- docker
- kube apiserver
- kube schduler
- kube controller
Cluster 를 만들때의 Tip
k8s 는 kubelet 과 docker만 설치하고 나머지는 kube의 기능들로 배포하는 것이 훨씬 편하다.
- api server, scheduler 는 manifest로
- network 는 hostNetwork 인 deamonset 으로
- monitering용 pod 및 로그 수집/처리기는 deamonset 혹은 deployment로
- service에서 사용할 storage는 statefulset 으로 띄운 스토리지 데몬들로.
see also
- kubernetes에 multus 설치하기
- API 확장
- k8s break it down: k8s component 설명이 잘 되어 있음.
- k8s api 문서
- Kubernetes The Easy Way! (For Developers In 2018)
- 15 Kubernetes features in 15 minutes by Marc Sluiter
- 사실 그럴꺼면 천공카드로 코드 짜시지 그러냐 싶다. 어차피 튜링머신이니 모든 작업은 천공 카드로도 할수 있는거 아닌가..
- 기존에 CI 다 설정해둔 사람입장에서는 k8s 를 쓰면 배포가 더 어려워 진다. k8s의 yaml 은 필요한 기능을 다 넣을수 있지만 그래서 너무 장황한 측면이 있다.