학습일지/kubernetes

Kubernetes Deep Dive - (2). Cluster Management

inspirit941 2021. 9. 15. 00:57
반응형

k8s High Availability (availability in Cluster)

스크린샷 2021-08-16 오후 2 39 21

k8s 자체가 high availability를 달성하기 위해 만들어진 SW.

  • Application Availability와 Cluster Availability는 별도의 개념(aspect)이다.

Cluster의 Availability는 infra 레벨이므로, infra (that application is executing) Availability is important in production environment.

  • k8s는 High Availability를 위해 multiple control plane 구조를 사용한다.
    • 즉 multi-master, multi-worker Topology로 되어 있다.

스크린샷 2021-08-16 오후 3 45 31

  • Multiple Control plane의 존재 = master node가 여러 개. 각각의 마스터 노드는 kube-api-server가 있고, worker 노드와 통신해야 한다.
  • 따라서, 여러 개 마스터 노드가 트래픽을 받아서 worker node에 전달할 수 있도록 Load balancer가 필요하다. 어느 마스터 노드 하나가 죽으면 다른 노드로 트래픽을 변경해야 Availability가 유지되므로.
    • = High-Availability production-like k8s Deployment.
  • Load balancer는 Master - Worker 간 통신에도 쓰인다. 꼭 클라이언트 트래픽만 받아 처리하는 게 아님.

스크린샷 2021-08-16 오후 3 49 16

  • etcd: key-value pair DB for k8s Cluster.

etcd Management를 위한 아키텍처는 여러 가지가 있지만, 대표적인 두 가지를 꼽아보면

  1. Stacked Etcd.
    • 마스터 노드는 최소 2개라고 가정.
    • 각각의 마스터 노드에 etcd DB가 존재하며, 각 control plane의 kube-api-server와 연결되어 있다.
    • etcd끼리 통신하면서 sync를 맞추는 방식.
    • popular approach.

스크린샷 2021-08-16 오후 4 28 09

  1. External Etcd.
    • 1과 비슷하지만, etcd가 master node 내부에 component 형태로 존재하지는 않음. 즉, etcd를 관리하는 별도의 서버가 존재함

Management Tools.

스크린샷 2021-08-16 오후 4 29 29스크린샷 2021-08-19 오전 10 25 22

  • Kubeclt : 공식 cli, REST API로도 통신 가능함.

스크린샷 2021-08-19 오전 10 25 48

  • kubadam : 클러스터 생성을 쉽게 해 주는 cli

스크린샷 2021-08-19 오전 10 26 29

  • minikube : Dev용으로 단일 마스터노드 + 워커노드를 빠르게 생성할 수 있도록 해줌

스크린샷 2021-08-19 오전 10 27 31

  • helm: prod, dev 등 여러 환경에 맞는 yaml 템플릿을 관리하고, 배포를 쉽게 할 수 있도록 도와주는 Package Management Tool.
  • K8s 오브젝트 간 inter-dependency가 있을 때 complex chart / template 생성을 쉽게 할 수 있도록 도와준다.

스크린샷 2021-08-19 오전 10 31 05

  • Kompose : docker compose와 유사함. docker compose파일을 k8s 오브젝트 형태로 사용할 수 있게 지원함.

스크린샷 2021-08-19 오전 10 32 14

  • Kustomize : manage the configuration of K8s Cluster. helm과 비슷한 목적으로 만들어졌음.

Setup K8s Cluster

스크린샷 2021-08-19 오전 10 58 25

DigitalOcean으로 k8s 리소스를 받아온다. master 1개, worker 2개. master node의 ip주소를 받아서 ssh로 로그인하고, k8s master node로 작동하기 위한 dependency들을 설치한다. (ubuntu 21.04 서버 기준)

## 1. Upgrade apt packages
sudo apt-get update

## 2. Install Docker Engine
sudo apt-get install -y docker.io

## 3. Install Support packages - apt-transport-https, curl 두 개.
sudo apt-get install -y apt-transport-https curl

## 4. Retrieve the key for the Kubernetes repo and add it to your key manager
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

## 5. Add the kubernetes repo to your system

cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF

## 6. Install the three pieces you’ll need, kubeadm, kubelet, and kubectl

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

## apt-mark hold는 해당 패키지들의 버전을 앞으로 계속 유지한다는 의미.
sudo apt-mark hold kubelet kubeadm kubectl


## 7. Create the actual cluster
## 해당 클러스터에서 생성되는 모든 리소스는 192.168.0.0/16 내에서 만들어진다는 뜻.
# setup, initialize, start까지 한 번에 진행되므로 시간이 좀 걸림
kubeadm init --pod-network-cidr=192.168.0.0/16

## Note - Notedown the Command to join cluster
# 명령어를 실행하고 나면 "To start using your cluster, you need to run the following as as regular user:"
# 뒤에 몇 개의 명령어가 나온다. 그대로 복사해서 실행하면 됨.

# 이후의 명령어도 중요하다
# Then you can join any number of worker nodes by running the following on each as a root:
## kubeadm join ... 뭐시기 명령어.
## -> 이 명령어는 worker node를 생성할 때 사용해야 한다. worker node가 클러스터에 join하기 위해서 필요함.

## 8. Install the Calico network plugin. network plugin으로 여러 종류가 있지만 calico 선택해서 적용.
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

## 9. Untaint the master so that it will be available for scheduling workloads
kubectl taint nodes --all node-role.kubernetes.io/master-

## 10. Get Cluster Nodes
kubectl get nodes

Install & Configure Kubernertes Worker Node

## 1. Upgrade apt packages
sudo apt-get update

## 2. Install Docker Engine
sudo apt-get install -y docker.io

## 3. Install Support packages

sudo apt-get install -y apt-transport-https curl

## 4. Retrieve the key for the Kubernetes repo and add it to your key manager

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

## 5. Add the kubernetes repo to your system

cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF

## 6. Install the three pieces you’ll need, kubeadm, kubelet, and kubectl
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl


## 7. Execute the Join command, which was copied from the master node.
## Command to Generate the Join Token in case you missed to Copy
kubeadm token create --print-join-command

## 생성된 토큰을 보고 싶으면 (master node에서 실행)
kubeadm token list

Maintenance Window : K8s Cluster

스크린샷 2021-08-21 오전 9 47 28스크린샷 2021-08-21 오전 10 42 03

  • Maintenance window : 유지보수를 위해 특정 노드를 k8s 클러스터에서 제외한 뒤, 작업이 끝난 후 다시 k8s 클러스터에 추가하는 기간
  • Node Draining: 위의 maintenance window동안 시행되는 작업 (클러스터에서 노드 제외, 작업 후 노드 추가)
    • 단, application에 downtime이 있어선 안 된다. node draining이 시행되고 있더라도 애플리케이션은 영향을 받아선 안 됨.
    • Containers running on that node will be gracefully terminated -> re-scheduled to another available node.

스크린샷 2021-08-21 오전 10 44 39

Standard process to drain the k8s node - kubectl 사용.

해당 node와 tightly coupled 상태인 pods를 DaemonSet이라고 부르는데 (monitoring이나 Logging 기능 같은 것들), 얘네가 있는 node의 경우 ignoreDaemonSet 명령어를 추가로 붙여줘야 한다.

스크린샷 2021-08-21 오전 10 55 16

분리한 노드에서 필요한 작업을 완료한 뒤, 클러스터가 해당 노드를 다시 스케줄링할 수 있도록 (클러스터 안에 포함시킬 수 있도록) 만드는 명령어가 uncordon이다.


Master Node에 ssh로 접근한 다음

  • kubectl get pods -o wide : 실행중인 모든 Pod 정보 + 해당 pod이 어느 Node에서 돌아가고 있는지

스크린샷 2021-08-21 오후 1 33 12

먼저 pods.yml 파일을 생성하고, kubectl apply -f pods.yml 로 클러스터에 배포한다.

스크린샷 2021-08-21 오후 1 34 16

다음으로 deployment.yml 파일을 생성하고, kubectl로 배포한다.

스크린샷 2021-08-21 오후 1 37 11

현재 pods의 개수는 아래와 같다.

스크린샷 2021-08-21 오후 1 37 27

여기서 kubectl drain k8s-worker-2 를 실행하면,

스크린샷 2021-08-21 오후 1 41 57

두 개의 오류가 뜬다.

  1. pods.yaml로 생성한 pod가 ReplicationController, ReplicaSet... 등과 같은 어느 Object와도 연결되어 있지 않다
  2. DaemonSet-managed Pod가 있어서 node를 drain할 수 없다
    • 여기서 DeamonSet은 Deployment의 결과로 생성된 pod를 의미한다. Deployment로 생성된 pod에는 kube-system의 proxy, 네트워크를 위해 설치한 calico가 작동하고 있기 때문.

두 개의 오류를 모두 해결하려면 kubectl drain k8s-worker-2 --ignore-daemonsets --force 를 입력하면 된다.

스크린샷 2021-08-21 오후 1 46 15

해당 노드를 unscheduled하면서, 노드 안에 있던 두 개의 pod도 전부 evicted (쫒아내다).

스크린샷 2021-08-21 오후 2 01 03

k8s-worker-2 노드가 schedulingDisabled 상태인 걸 확인할 수 있고,

스크린샷 2021-08-21 오후 2 01 03

Deployment에서 정의한 replica 개수인 2개를 맞추기 위해 k8s-worker-1에 새 Pod가 생성된 것을 볼 수 있다.

get nodes에서 scheduleDisabled되어 있는 노드를 활성화하려면 kubectl uncordon k8s-worker-2 를 입력하면 된다. 단, k8s-worker-2에 등록되어 있던 pod가 이전 상태로 돌아오지는 않는다. (pod의 상태를 보장하지는 않는다)

Upgrading k8s Cluster

스크린샷 2021-08-21 오후 2 06 59스크린샷 2021-08-21 오후 2 07 53

kubeadm을 활용하면 seamless한 upgrade가 가능하다.

스크린샷 2021-08-21 오후 2 09 41

## 1. Get the Running Node and Version
kubectl get nodes

## 2. Drain Master Node
kubectl drain <node-to-drain> --ignore-daemonsets

## 3. Upgrade kubeadm
sudo apt-get update
sudo apt-get install -y --allow-change-held-packages kubeadm=1.21.1-00

## 4. Verify that the download works and has the expected version:
kubeadm version

## 5. Verify the upgrade plan - 업그레이드 가능한지 미리 체크.
sudo kubeadm upgrade plan v1.21.1-00

## 6. Apply the Upgrade
sudo kubeadm upgrade apply v1.21.1

## 7. Upgrade kubelet and kubectl packages
sudo apt-get update
sudo apt-get install -y --allow-change-held-packages kubelet=1.21.1-00 kubectl=1.21.1-00

## 8. Restart the kubelet:
sudo systemctl daemon-reload
sudo systemctl restart kubelet

## 10. Get the Running Node and Version
kubectl get nodes

## 11. Uncordon the Node
kubectl uncordon <node-to-uncordon>

스크린샷 2021-08-21 오후 2 10 17


## 1. Drain Worker Node
kubectl drain <node-to-drain> --ignore-daemonsets --force

## 2. Upgrade kubeadm
sudo apt-get update
sudo apt-get install -y --allow-change-held-packages kubeadm=1.21.1-00

## 3. Verify that the download works and has the expected version:
kubeadm version

## 4. For worker nodes this upgrades the local kubelet configuration
sudo kubeadm upgrade node

## 5. Upgrade kubelet and kubectl packages
sudo apt-get update
sudo apt-get install -y --allow-change-held-packages kubelet=1.21.1-00 kubectl=1.21.1-00

## 6. Restart the kubelet:
sudo systemctl daemon-reload
sudo systemctl restart kubelet

## 7. Get the Running Node and Version
kubectl get nodes

## 8. Uncordon the Node
kubectl uncordon <node-to-uncordon>
반응형