CS/인프라

[인프라] kubernetes 클러스터 생성 1 - kubeadm init 은 어떤 동작이 이루어지는가

김yejin 2022. 12. 8. 10:28

이전 포스트에 이어서 작성한 내용입니다.

https://yejincode.tistory.com/27

 

[인프라] kubeadm 설치 2 - kubelet에 cgroup driver 설정을 왜 맞추어야 하는가?

이전 포스트에 이어서 작성한 내용입니다. https://yejincode.tistory.com/25 [인프라] kubeadm 설치 1 - containerd는 무슨 역할인가? 공식 설치 안내 페이지 https://kubernetes.io/docs/setup/production-environment/tools/kubeadm

yejincode.tistory.com

 

전체 설치 순서 중 해당 포스트에서는 클러스터를 생성하기 위해 control-plane 을 초기화 하는 방법에 대하여 담고 있다.

  • 사전 준비 (bridge 네트워크 설정)
  • control-plane 노드 init
  • pod network add-on (다음 포스트에서 자세히)
  • clean up (remove node, clean up control-plane)

즉, 한개의 control-plane 이 존재하는 클러스터를 구성하기 위해 control-plane 노드를 "kubeadm" 을 통해 생성,초기화 하고 클러스터 내부의 pod가 서로 통신할 수 있도록 network add-on을 추가 구성하는 과정이다.

 

사전 준비-bridge 네트워크 설정

bridge 네트워크가 구성되어있지 않은 경우, containred가 (CRI) 제대로 기동되지 않을 수 있다.

https://kubernetes.io/docs/setup/production-environment/container-runtimes/#install-and-configure-prerequisites

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# sysctl params required by setup, params persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system

아래와 같이 bridge 네트워크가 구성되어 있어야 한다.

## 생성된 bridge 필터 확인
[root@yejin-master ~]# lsmod | grep br_netfilter
br_netfilter           22256  0 
bridge                151336  1 br_netfilter

 

 

control-plane node 초기화

kubeadm init 명령어로 control-plane 노드를 초기화한다.

## -v=5 옵션을 통해 해당 init 과정을 stdout 으로 확인 할 수 있다.
kubeadm init --pod-network-cidr=10.100.0.0/16 -v=5

 

init 명령어를 수행한 결과는 아래와 같다.

  • CRI socket 을 인식한다. (containred 을 CRI runtime 으로 채택했기 때문 )
  • 별도의 네트워크를 지정하지 않았기 때문에 default로 eth0 인터페이스를 node 의 ip로 가져온다.
  • 별도로 설정파일에 cgroupDriver 를 설정하지 않았기 때문에 default인 systemd로 설정한다. --> 앞선 포스트 2에서 cgroup driver를 systemd로 맞추어주었다.
  • kubernetes version : v1.25.4 로 설치
  • preflight checking
    • firewall 확인 (비활성화 되어있어야 한다.)
    • port 확인 6443, 10259, 10257, 10250, 2379, 2380
    • manifests yaml 파일 (apiserver, controller-manager, scheduler, etcd)
    • proxy / direct
    • http connectivity CIDR (init 명령어로 해당 CIDR 지정함)
    • container runtime
    • bridge-nf-call-iptables, ip_forward
    • swap 꺼져있는지
    • 명령어 실행가능 여부 (crictl, conntrack, ip , iptables, mount, nsenter, ebtables, ethtool, socat, tc, touch)
    • node name 확인 net.LookupHost
    • kubelet service active 확인
    • /var/lib/etcd 확인
    • 클러스터 세팅에 필요한 이미지 pull
      • ifNotPresent 한경우에만 이미지 pull 하도록 설정되어있음 (default)
      • kube-apiserver:v1.25.4
      • kube-controller-manager:v1.25.4
      • kube-scheduler:v1.25.4
      • kube-proxy:v1.25.4
      • pause:3.0
      • etcd:3.5.4-0
      • coredns:v1.9.3

  • 인증을 처리한다. certs : ca, apiserver, apiserver-kubelet-client, front-proxy-ca, front-proxy-client, etcd/ca, etcd/server, etcd/peer, etcd/healthcheck-client, apiserver-etcd-client, sa
  • kubeconfig 파일 생성 : /etc/kubernetes/admin.conf, kubelet.conf, controller-manager.conf, scheduler.conf
  • kubelet 을 정지후, 환경 설정 파일을 작성하여 다시 시작. (var/lib/kubelet/kubeadm-flags.env, config.yaml)
  • control-plane 에서 static pod를 생성하기 위한 manifest를 작성한다. ( /etc/kubernetes/manifests/ )
    • /etc/kubernetes/manifests/kube-apiserver.yaml ( 추가한 volumes : ca-certs, etc-pki, k8s-cets ) 
    • /etc/kubernetes/manifests/kube-controller-manager.yaml ( 추가한 volumes : ca-certs, etc-pki, flexvolume-dir, k8s-cets, kubeconfig )
    • /etc/kubernetes/manifests/kube-scheduler.yaml( 추가한 volumes : kubeconfig )
    • /etc/kubernetes/manifests/etcd.yaml (추가한 volumes : 없음) (실제 yaml에는 etcd-cers, etcd-data 볼륨이 있음)
  • wait-control-plane : static pod가 모두 기동될때까지 대기

  • upload-config : kubeadm clusterconfiguration, kubelet component config 를 kube-system namespace에 업로드, crisocket 정보를 control-plane 노드에 preserve 한다. 
  • upload-cert 는 생략
  • bootstrap-token : RBAC rules 적용, cluster-info configmap을 kube-public namespace에 생성
  • clusterinfo : bootstrap-token에 의해 admin.conf 로부터 클러스터 정보를 가져와 bootstrap kubeconfig를 작성하고 configMap 을 kube-public namespace에 생성/업데이트
  • kubeletfinalize : kubelet client certificate roation을 enable 하고 재시작. 
  • addons : 필수 애드온 적용 (CoreDNS, kube-proxy)

 

해당 클러스터를 cli 모드로 조정할 수 있는 kubectl 을 사용하기 위해서는 해당 user 계정에 아래와 같이 환경설정 필요하다.

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

루트 계정의 경우, 아래와 같이 환경변수를 export 하면 된다.

export KUBECONFIG=/etc/kubernetes/admin.conf

 

Installing a Pod network add-on

앞서 필수 add-on 인 coredns 와 kube-proxy pod가 생성된 것을 확인 할 수 있다.

network add-on 중 calico 네트워크 제공자를 다음 포스트에서 자세히 설치하고 설정해 보겠다.

 

Control plane node isolation

노드 1개로 서비스를 하고 싶을때, control-plane 노드에 서비스 pod를 추가하고 싶을 때 아래와 같이 taint 작업이 필요하다.

(taint 란 쿠버네티스의 pod 배치 전략 중 하나로, node에 임의의 pod가 설정되는 것을 방지하는 전략이다. 구체적인 내용은 다음 포스트에서..!)

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

 

kubernetes cluster clean up 

reset 하기 전에 먼저 node를 empty 상태로 삭제 해야한다.(drain node)

kubectl drain <node name> --delete-emptydir-data --force --ignore-daemonsets

 

그후 kubeadm reset 을 이용하여 control-plane 자체를 삭제할 수 있다.

kubeadm reset

 

다음 포스트 예정

  • add-on 이란, calico 설치 및 설정방법
  • 용어정리

 

참고자료

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#clean-up-the-control-plane