Computing

[jhKube][3] kubeadm을 통한 쿠버네티스 클러스터 설치 (CentOS7, 가상머신 환경, cri-docker) 본문

Cloud/jhVM

[jhKube][3] kubeadm을 통한 쿠버네티스 클러스터 설치 (CentOS7, 가상머신 환경, cri-docker)

jhson989 2022. 11. 22. 22:46

이전글

[jhVM][1] virt-manager, CentOS 7 qcow2 image (root password, 용량 설정 등)

[jhVM][2] CentOS 7 user 추가(sudo 권한 부여), 가상머신 네트워크 설정 및 virbr0(static internal IP 부여)

[jhVM][3] ssh 로그인 설정(비번 없이 로그인), qcow2 복사(VM 복제)

[jhKube][1] Kubernetes와 Linux Container 간단 정리

- [jhKube][2] Kubernetes architecture 및 설치 방법 간단 정리

 

이전 글에 이어 CentOS 7 가상머신들을 이용한 쿠버네티스 환경 구축 과정에서 배운 내용을 정리하고자고 한다. jhVM 시리즈에서 가상머신 환경 구축은 끝났으니, 본격적으로 쿠버네티스를 설치해보려 한다. 공부 중인 단계에서 정리하는 글이기에 부족하거나 정확하지 않은 내용도 있을 수도 있다. 자세한 내용은 추후 다시 한번 정리해볼 예정이다.

Fig 1. kubeadm 로고[4]

 

 

 

목표

이전 포스터에서 정리했듯이 쿠버네티스 클러스터 구축을 위해서는 다양한 방법이 있는데, 이번 포스터에서는 가장 기본이 되는 kubeadm(kubernetes admin)을 통해 설치를 진행해보고자 한다. kubeadm은 클러스터를 구성하는 개별 노드(=서버, 컴퓨터)들의 환경 설정부터 직접 해야 하기에 설치 과정이 약간은 복잡하다.

 

<구축하고자 하는 쿠버네티스 클러스터의 구성은 다음과 같다>

- 3개의 가상머신이 참여하는 클러스터 구성

      - OS : CentOS 7

      - 하드웨어 : 2 CPU & 3GB 메모리 & 30GB 저장공간

- Control Plane (마스터 노드) : 1대

      - IP address : 192.168.122.11 (hostname: vm1)

- Worker Nodes : 2대

      - IP address : 192.168.122.12 (hostname: vm2)

      - IP address : 192.168.122.13 (hostname: vm3)

- Container Runtime : docker engine + cri-dockerd

 

공식 문서[1]를 참고하여 구성하였으며, 모르는 것은 열심히 구글링 하였다.

 

 

 

Kubernetes Cluster 설치 이전 가상머신 환경 설정

공식 문서[1]에 따르면 Kubernetes Cluster 설치가 가능한 환경은 다음과 같다.

 

- 리눅스 노드 (데비안, 레드햇 기반 등)

      -> CentOS 7 환경 선택

- 2GB 이상의 램 장착

      -> 만족

- 2개 이상의 CPU

      -> 만족

- 클러스터 내 노드 간 네트워크 연결이 가능해야 함 (사설도 가능)

      -> 만족 (사설네트워크 사용)

- 모든 노드는 고유한 호스트 이름, MAC 주소, uuid를 가져야 함

      -> 호스트 이름(hostname) : 네트워크에 연결된 장치에 부여되는 이름 -> /etc/hosts에서 개인이 직접 설정함

      -> MAC 주소 : <ifconfig -a>를 통해 확인 가능

      -> uuid : <sudo cat /sys/class/dmi/id/product_uuid>를 통해 확인 가능

- 6443 포트 열기

      -> 테스트를 위해 아예 방화벽을 활성화하지 않음

      -> 만약 방화벽이 활성화되어 있다면 6443 포트를 열어줘야 함

- swap 메모리가 비활성화

      -> 쿠버네티스는 worker 노드의 여유 하드웨어(CPU, 메모리)를 확인하여 스케쥴링함

      -> 노드의 swap 메모리가 활성화되어 있으면 여유 메모리가 있는 줄 알고 해당 노드에 파드를 추가 실행함

      -> 일시적 비활성화 : swapoff -a

      -> 영구적 비활성화 : sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

- selinux 비활성화

      -> 일시적 비활성화 : setenforce 0

      -> 영구적 비활성화 : sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

 

추가적으로 iptables 설정을 해준다[3]. 

 

$ cat <<EOF > /etc/modules-load.d/k8s.conf
br_netfilter
EOF

$ cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

$ sudo sysctl --system

 

 

Kubernetes를 위한 Container Runtime 설치

컨테이너 런타임(Container Runtime, CR)은 컨테이너 실행을 담당하는 소프트웨어로, 각 워커 노드가 Pod를 실행시키기 위해서는 컨테이너 런타임이 설치되어 있어야 한다. 컨테이너 런타임에는 다양한 종류가 있는데, 이들 컨테이너 런타임들과 쿠버네티스간의 통합을 위해 표준 컨테이너 런타임 인터페이스(Container Runtime Interface, CRI)를 채택한다. 

 

기존 쿠버네티스는 docker가 사용하는 컨테이너 런타임을 지원하였으나, 쿠버네티스 1.24부터는 더이상 docker의 기본 컨테이너 런타임을 지원하지 않는다. docker를 기본 컨테이너 런타임으로 사용하고 싶으면 cri-docerd[2]를 추가로 설치해야 한다. 참고로 쿠버네티스가 지원하는 컨테이너 런타임에는 3가지 containerd, CRI-O, docker engine+cri-dockerd 이 있다.

 

(쿠버네티스가 도커를 지원안한다는 말이 이해가 되지 않는다. 쿠버네티스는 containerd CR를 지원한다고 하고, 도커 내부적으로 containerd CR을 사용하지 않나? 그면 쿠버네티스가 바로 containerd를 사용하면 안되나? -> 도커 엔진 자체도 CR이라고 하나? -> 공부를 좀 더 해야겠다.)

 

도커 설치는 다음과 같다.

 

################################################
### 최신 버전 docker 설치
################################################
$ curl -s [https://get.docker.com](https://get.docker.com/) | sudo sh
$ systemctl enable --now docker

################################################
### docker daemon 설정
################################################
$ cat << EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF
$ service docker restart

################################################
### docker 설치 확인
################################################
$ docker -v

 

cri-dockerd 설치는 다음과 같다. (permission deny가 뜨면, 적절히 sudo 를 추가하여야 한다)

 

################################################
### go 설치
################################################
$ sudo wget https://storage.googleapis.com/golang/getgo/installer_linux
$ sudo chmod +x ./installer_linux
$ sudo ./installer_linux
$ source ~/.bash_profile

################################################
### cri-dockerd 설치 from git
################################################
$ git clone https://github.com/Mirantis/cri-dockerd.git
$ cd cri-dockerd
$ mkdir bin
$ go build -o bin/cri-dockerd
$ mkdir -p /usr/local/bin
$ install -o root -g root -m 0755 bin/cri-dockerd /usr/local/bin/cri-dockerd
$ cp -a packaging/systemd/* /etc/systemd/system
$ sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
$ systemctl daemon-reload
$ systemctl enable cri-docker.service
$ systemctl enable --now cri-docker.socket

 

 

 

Kubernetes Components 설치

본격적으로 쿠버네티스 클러스터를 설치하자. vm1, vm2, vm3 가상머신들에 3가지 components(kubeadm, kubelet, kubectl을 설치하면 된다. 설치 시 kubeadm, kubelet, kubectl 간의 버전은 일치하여야 한다. (하나의 마이너 버전 차이는 괜찮다고는 한다.)

 

3개의 컴포넌트들은 다음과 같은 역할을 수행한다.

- kubeadm : 클러스터 설치를 위한 도구

- kubelet : 파드 실행을 위한 소프트웨어

- kubectl : 클러스터와 통신하기 위한 CLI. 쿠버네티스 클러스터 클라이언트 역할

(사실 master(vm1)에는 kubeadm, kubectl만, worker nodes(vm2, vm3)에는 kubeadm, kubelet만을 설치하면 되는 것이 아닌가 싶은데, 공식 문서에는 다 설치하기에 일단 다 설치하였다)

 

############################################
### 쿠버네티스 repository 등록
############################################
$ cat << EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

############################################
### 쿠버네티스 compoents 설치 : kubeadm, kubelet, kubectl
############################################
$ yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
$ systemctl enable --now kubelet

############################################
### 설치 확인
############################################
$ kubeadm version -o short
$ kubectl version --short
$ kubelet --version

 

 

 

Kubernetes Control Plane 설치

마스터 노드의 설정을 완료하자. kubeadm을 통해 control plane 설치 및 환경 설정이 자동으로 진행된다. kubeadm을 사용하면 control plane 설정이 완료되고, 그 결과로 나온 값들을 기억했다가 worker node 등록(join) 시 사용한다. Control plane 설치 이후 CNI를 설치해준다. (CNI가 어떤 건지는 아직 파악하지 못했다. 좀 더 공부후 추가하여야겠다)

 

##########################################
### kubeadm 실행
##########################################
$ kubeadm init --apiserver-advertise-address 192.168.122.11 --pod-network-cidr=172.31.0.0/16 --cri-socket unix:///var/run/cri-dockerd.sock
### 결과값을 꼭 기억해야 한다
# ex)kubeadm join [ip]:[port] -- token [token값] --discovery-token-ca-cert-hash [hash값]

##########################################
### CNI 설치 (calico 선택)
##########################################
$ curl https://docs.projectcalico.org/manifests/calico.yaml -O --insecure 
$ kubectl apply -f calico.yaml

 

추가로, root가 아닌 다른 유저가 kubectl을 사용하기 위해서는 config 설정을 해줘야 한다. 

 

###########################################
### user가 kubectl을 사용하기 위한 config 설정
###########################################
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

 

 

Kubernetes Worker Node 설치

Worker Node을 경우 kubelet 설치 이후, kubeadm을 통해 control plane에 등록만 해주면 된다. (kubelet과 kubeadm 설치는 위에서 yum install kubelet kubeadm으로 완료되었다) join 시 token값과 hash값은 control plane init 시 결과값을 써주면 된다.

 

#######################################
### Worker node 등록
#######################################
$ kubeadm join [마스터 ip]:6443 --token [token값] --discovery-token-ca-cert-hash [hash값] --cri-socket unix:///var/run/cri-dockerd.sock
### ex) kubeadm join 192.168.122.11:6443 --token aaalqj.mqqaaakybhwigccc --discovery-token-ca-cert-hash sha256:aaabbbbb8f3fcf0a6452108e9999b1a85e1eb5eeeedaa2c13d49faaaa --cri-socket unix:///var/run/cri-dockerd.sock

 

 

Kubernetes 설치 확인

설치 확인 코드는 다음과 같다.

 

#######################################
### 클러스터에 참여하는 노드 정보 확인
#######################################
$ kubectl get nodes

#######################################
### 실행 중인 파드 확인
#######################################
$ kubectl get pods --all-namespaces

#######################################
### 파드 로그 확인
#######################################
$ kubectl -n kube-system logs -f [pod name]

 

 

 

Reference

[1] https://kubernetes.io/ko/docs/setup/production-environment/tools/_print/

[2] https://github.com/Mirantis/cri-dockerd

[3] https://kubernetes.io/docs/setup/production-environment/container-runtimes/#forwarding-ipv4-and-letting-iptables-see-bridged-traffic

[4] https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/