[Kubernetes] kubeadm으로 Kubernetes 클러스터 구축하기

bluewhale·2022년 2월 25일
2

kubernetes

목록 보기
9/11

이번 포스팅에서는 kubeadm을 활용하여 AWS EC2 인스턴스에 직접 kubernetes 클러스터를 구축하는 과정을 다루었습니다.

환경 요구 사항

공식 문서에 따르면 kubernetes 노드를 실행하기 위해서는 다음가 같은 환경이 요구됩니다.

하드웨어 스펙

  • deb/rpm 패키지를 지원하는 Linux OS. ex) Ubuntu, CentOS
  • 2 CPU 코어, 2Gb 이상의 RAM을 지원하는 머신

disable swap

kubernetes는 컨테이너 자원을 제한하고 해당 워크로드를 수용할 수 있는 노드에 스케쥴링 함으로써 노드의 자원을 최대한으로 활용하는 것을 목표로 합니다. 그러나, swap 기능은 가용 자원을 모두 소진한 노드가 부가적인 워크로드를 수행하는 것을 야기할 수 있습니다. 따라서, 정상적인 kubelet 실행을 위해 swap 기능 사용을 제한해야 합니다. 관련 질문: Why disable swap on kubernetes?

아래의 명령어를 사용하면, swap 기능을 사용하지 않도록 관련 설정을 수정할 수 있습니다.

$ sudo su # root 권한으로 실행
$ swapoff -a
$ echo 0 > /proc/sys/vm/swappiness
$ sed -e '/swap/ s/^#*/#/' -i /etc/fstab
$ exit

고유한 MAC 주소

kubernetes는 네트워크 인터페이스의 MAC 주소와, product_uuid를 사용하여 노드를 식별합니다. 따라서, 동일한 하드웨어 머신에서 kubernetes 노드들을 추가하는 경우에는 해당 값이 고유한지 여부를 확인해야 합니다.

# MAC 주소 확인
$ ip link
$ ifconfig - a

# product_uuid 확인
$ sudo cat /sys/class/dmi/id/product_uuid

네트워크

kubernetes 컴포넌트(ex, kubelet, kube-apiserver) 간 통신을 위해 EC2 인스턴스와 연결된 security group에서 해당 포트를 허용해야 합니다.

Master Node (control-plane)

  • kube-apiserver: 6443
  • kubelet: 10250
  • etcd: 2379, 2380

Worker Node

  • kubelet: 10250

kubeadm, kubelet 및 kubectl 설치

kubernetes 클러스터를 구성하기 위해서는 아래의 프로그램들을 설치해야 합니다.

  • kubeadm: 클러스터 초기화 및 부스트래핑
  • kubelet: 컨테이너 런타임 및 팟의 라이프사이클 관리
  • kubectl: kubernetes control-plane과 통신하기 위한 클라이언트

다음으로 우분투 환경에서 kubeadm, kubelet, kubectl을 설치해보도록 하겠습니다. 리눅스 계열별 설치 명령어는 링크 에서 확인하실 수 있습니다.

# 1. apt 패키지 업데이트 및 필수 패키지 설치
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

# 2. 공개 사이닝 키 다운로드
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

# 3. ppa 추가
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# 4. kubeadm, kubelet, kubectl 설치 및 버전 고정
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

주의 사항

kubelet은 컨테이너 리소스 제어를 위한 cgroup driver로 systemd를 기본 값(v1.22 이후)으로 사용합니다. 반면, Docker 내부에서 직접적인 컨테이너 관리를 담당하는 runc는 cgroup driver로 cgroupsfs를 사용합니다. 따라서, Docker를 컨테이너 런타임으로 사용할 경우에는 /etc/docker/daemon.json 파일을 수정하여 Docker의 cgroup driver를 systemd로 변경해주어야 합니다.

# /etc/docker/daemon.json
{
	...
    "exec-opts": ["native.cgroupdriver=systemd"]
}

설정을 변경한 후에는 Docker를 재시작한 후, 바뀐 설정이 잘 적용되었는지 확인합니다.

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

$ docker info | grep "Cgroup Driver"
Cgroup Driver: systemd

systemd vs cgroupfs

systemdcgroupfs는 모두 /sys/fs/cgroup 경로 하위에 리소스 관련 정보를 마운트 하는데, cgroup 경로를 정하는 방식에서 차이를 보입니다. cgroupfs는 리소스를 직접 매핑하는 방식으로 flat한 파일 시스템 형태로 리소스를 관리하는 반면, systemd는 slice/scope/service 의 계층 구조로 이를 관리합니다. 따라서, 이 둘을 혼용하여 사용할 경우 서로 다른 네이밍 정책으로 인해 충돌을 일으킬 수 있습니다. 이와 관련된 자세한 설명은 링크에서 확인하실 수 있습니다.

kubernetes 클러스터 생성

다음으로 kubeadm init 명령어를 실행하여 control-plane이 위치할 마스터 노드를 생성합니다. 저는AWS EC2control-plane 노드를 설치하고 로컬 머신에서 이에 접근하는 환경을 구성하였습니다.

--pod-network-cidr은 우리가 사용할 calico 공식문서와 동일하게 192.168.0.0/16을 사용합니다.

--upload-certs 옵션을 추가하면 control-plane의 SSL 인증서가 kubernetes cluster에 secret으로 저장됩니다. 해당 secret은 2시간 후 자동으로 사라지지만, kubeadm join 명령어를 사용하여 새로운 control-plane 노드를 추가할 때, 번거롭게 인증서를 복사하지 않아도 되어 편리합니다. 하나의 control-plane 노드만을 사용할 경우에는 해당 옵션을 추가하지 않아도 됩니다.

--control-plane-endpoint 옵션은 여러 개의 control-plane 노드로 HA를 구성하는 경우에 사용합니다. 값으로 control-plane 노드들 앞단에 위치한 로드 밸런서의 IP 주소 혹은 도메인 명을 입력합니다.

--apiserver-cert-extra-sans 옵션은 control-plane 노드가 외부에 위치한 경우(ex, AWS EC2), 로컬 머신에서 kubernetes 클러스터의 API 서버에 접근하기 위해 필요합니다. 해당 옵션은 SSL 인증서의 SAN에 IP, 도메인 명을 추가로 등록합니다.

$ kubeadm init \
	--pod-network-cidr=192.168.0.0/16 \
    --control-plane-endpoint=<ec2-ip> \
    --apiserver-cert-extra-sans=<ec2-ip> \
    ...

마스터 노드를 생성 과정에서, 새로운 노드를 추가하기 위한 명령어가 콘솔에 출력됩니다. 해당 명령어는 복사하여 새롭게 추가할 노드에서 실행하면 클러스터에 노드를 추가할 수 있습니다.

# master-node
Your Kubernetes control-plane has initialized successfully!
...
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join <ec2-ip>:6443 --token ... \
	--discovery-token-ca-cert-hash sha256:...

---------------------------------------
# worker-node
$ kubeadm join <ec2-ip>:6443 --token ... \
	--discovery-token-ca-cert-hash sha256:...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
### 

마스터 노드에서 kubectl get nodes 명령어를 실행하면 새로운 노드가 클러스터에 추가된 것을 확인할 수 있습니다.

이후, 아래의 명령어로 클러스터 어드민 접속 정보를 현재 접속한 계정에서 사용할 수 있도록 ~/.kube/config 경로로 복사합니다.

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

마스터 노드 생성 과정에서 control-plane이 위치한 EC2 머신의 IP를 SAN에 등록하였기 때문에, 해당 config 파일을 로컬 머신으로 복사하면, 로컬 머신에서도 동일하게 클러스터에 접근할 수 있습니다.

마지막으로 calico 네트워크 플러그인을 설치합니다. :)

$ kubectl apply -f https://projectcalico.docs.tigera.io/manifests/calico.yaml

마스터 노드에서 Pod이 정상적으로 생성되었는지 확인합니다.

$ kubectl get pods -n kube-system
NAME                                       READY   STATUS              RESTARTS   AGE
calico-kube-controllers-566dc76669-xfw8x   1/1     Running             0          2m38s
calico-node-nj75b                          1/1     Running             0          2m38s
calico-node-3vjd4                          1/1     Running             0          2m38s
coredns-64897985d-6gsgv                    1/1     Running             0          8m43s
coredns-64897985d-h7r9x                    1/1     Running             0          8m43s
etcd                                       1/1     Running             7          8m58s
kube-apiserver                             1/1     Running             7          8m58s
kube-controller-manager                    1/1     Running             5          8m58s
kube-proxy-bqzn4                           1/1     Running             0          8m44s
kube-proxy-rif03                           1/1     Running             0          4m12s
kube-scheduler                             1/1     Running             7          8m58s

마무리

이번 포스팅에서는 kubeadm을 활용하여 kubernetes 클러스터를 설치하는 내용을 다루었습니다. 감사합니다

Reference

profile
안녕하세요

0개의 댓글