Kubernetes in Action, Second Edition MEAP V15 정리중
Kubernetes cluster는 docker를 통해 실행시킬 수 있다.
docker에서 환경설정 -> Kubernetes -> Enable Kubernetes

docker의 container는 다음과 같은 구조를 갖는다.

C:\Windows\system32>minikube start
* minikube v1.32.0 on Microsoft Windows 10 Education 10.0.19045.4046 Build 19045.4046
* Automatically selected the docker driver. Other choices: hyperv, virtualbox, ssh
* Using Docker Desktop driver with root privileges
* Starting control plane node minikube in cluster minikube
* Pulling base image ...
* Downloading Kubernetes v1.28.3 preload ...
> preloaded-images-k8s-v18-v1...: 403.35 MiB / 403.35 MiB 100.00% 27.43 M
> gcr.io/k8s-minikube/kicbase...: 453.90 MiB / 453.90 MiB 100.00% 25.04 M
* Creating docker container (CPUs=2, Memory=4000MB) ...
* Preparing Kubernetes v1.28.3 on Docker 24.0.7 ...
- Generating certificates and keys ...
- Booting up control plane ...
- Configuring RBAC rules ...
* Configuring bridge CNI (Container Networking Interface) ...
* Verifying Kubernetes components...
- Using image gcr.io/k8s-minikube/storage-provisioner:v5
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
minikube의 구조는 다음과 같다.

kind는 minikube와 달리 한 cluster에 여러 개의 node가 들어가 있다. VM 환경이 따로 지원되지 않아, 컨테이너는 host OS와 같은 환경에서 실행되고 따라서 컨테이너 내부에서 같은 컴파일 환경이나 프로그램 동작등을 지원할 수 있다.
다음은 kind의 작동 방식이다.

Google에서 Kubernetes의 기능들을 google cloud로 지원해 주어 복잡한 초기 설정 없이 인터넷 환경에서 바로 이용하게 해주는 것이다. 구조는 다음과 같다.

직접 Kubernetes 서비스의 구조를 만들어 볼 수도 있다.
https://github.com/kelseyhightower/Kubernetes-the-hard-way
나중에 써먹을지도..?
kubectl은 Control plane에 요청할 수 있는 cli tool이다. 다음과 같은 구조로 유저가 kubectl를 통해 API Server에 전달하면, Control plane이 요청에 맞는 작업을 수행한다.

kubectl의 기본적인 명령어들은 다음과 같다.
$ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:53107
CoreDNS is running at https://127.0.0.1:53107/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 102m v1.29.2
$ kubectl describe node kind-control-plane
Name: kind-control-plane
Roles: control-plane
...
GUI로 현재 상태를 확인할 수 있는 대시보드 또한 존재한다.
pod란 container들을 묶어서 같은 namespace를 공유하고 한번에 실행할 수 있게 하느 단위로, 같은 pod은 IP(network namespace)와 system hostname(UTS namespace)같은걸 공유할 수 있고 서로 더 쉽게 통신할 수 있다.
즉 pod이란 하나의 application를 실행하는 논리적인 컴퓨터라고 할 수 있다. application에서는 한개 또는 여러개의 container를 필요로 할 수도 있다.

deployment는 pod을 정해진 replica 수만큼 생성하고 id를 부여하는 object이다. pod이 갑자기 삭제되거나 pod이 존재하는 노드의 이상 등으로 문제가 생길 때, deployment는 replica의 수를 일정하게 만들어주기 위해 추가로 pod을 만들어준다.
service는 실행중인 pod들이 외부와 통신할 수 있도록 연결해주는 object이다. 외부에서 요청이 들어오면 service는 traffic에 따라 pod들에게 적절히 load-balancing해주고, pod이 삭제되고 재생성될 경우, 변경된 IP주소등 pod의 정보를 갱신한다.
이것들의 논리적 구조는 다음과 같다.

kubernetes cluster에 application을 넣어본다. 미리 요약하자면 kubectl create deployment 명령어를 통해 pod을 만들고, kubectl expose deployment를 통해 외부로 노출시키면 된다.
$ kubectl create deployment kubia --image=luksa/kubia:1.0
deployment.apps/kubia created
deployment object용 container들의 상태를 확인해보면 방금 만든게 나올 것이다.
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubia 0/1 1 0 6s
UP-TO_DATE가 1이므로 이 application은 1개의 instance를 갖는다. 또한 AVAILABLE이 0이므로 application이 아직 사용할수 없음을 나타낸다.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-587b7cd6b7-85zbh 0/1 Pending 0 1m
pod이 Ready 상태인데, 이것은 pod이 할당된 worker node가 container image를 다운받고 있는 중이기 때문이다. 모두 다운받으면 Running state로 넘어간다.
pod의 로그등 자세한 정보를 확인하려면 다음과 같이 한다.
$ kubectl describe pod
Name: kubia-587b7cd6b7-85zbh
Namespace: default
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SandboxChanged 21m kubelet Pod sandbox changed, it will be killed and re-created.
Normal Pulled 21m kubelet Container image "luksa/kubia:1.0" already present on machine
Normal Created 21m kubelet Created container kubia
Normal Started 21m kubelet Started container kubia
이 과정을 그림으로 나타내면 다음과 같다.

$ kubectl expose deployment kubia --type=LoadBalancer --port 8080
service/kubia exposed
생성된 service 객체를 확인하면 다음과 같다.
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18h
kubia LoadBalancer 10.96.245.7 <pending> 8080:30953/TCP 3m7s
load balancer service까지 만들게 되면, kubernetes는 외부의 cloud 서비스에게 load-balancer를 제공하도록 요청한다. 그러면 cloud provider가 load-balancer를 만들고 사용자의 traffic을 잘 쪼개어 worker node들에 보내준다.

+ minikube를 사용하는 경우 load balaner를 제공해주지 않는데, 이 경우 minikube service kubia --url 명령으로 외부주소를 찾아내면 된다.
$ kubectl scale deployment kubia --replicas=3
deployment.apps/kubia scaled
이렇게 하면 다음과 같이 pod가 확장된다.
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
kubia 3/3 3 3 18m
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-9d785b578-58vhc 1/1 Running 0 17s
kubia-9d785b578-jmnj8 1/1 Running 0 17s
kubia-9d785b578-p449x 1/1 Running 0 18m
각 pod가 어떤 node에 담겼는지 확인하려면 다음과 같이 한다.
$ kubectl get pods -o wide
NAME ... IP NODE
kubia-9d785b578-58vhc ... 10.244.1.5 worker1 #A
kubia-9d785b578-jmnj8 ... 10.244.2.4 worker2 #B
kubia-9d785b578-p449x ... 10.244.2.3 worker2 #B
pod을 여러개 만들어 node들에 뿌릴 경우, 요청들에 대한 흐름도는 적절한 load-balancing을 통해 pod들로 뿌려진다.
