
kubeadm이란?
쿠버네티스 공식 문서에서 추천하는 순정 쿠버네티스 설치 툴로 리눅스 환경에서 빠르게 클러스터를 구성할 수 있도록 만들어졌다.
이전에 다루었던 Minikube
나 이와 유사한 K3s
같은 경량화 설치 툴보다는 다루기 어렵지만 원하는 구성대로 클러스터를 설치할 수 있다는 장점이 있다.
kubeadm이 지원하는 명령어로는 kubeadm init
을 통해 클러스터를 구성할 수 있으며 kubeadm join
을 통해 워커노드로 클러스터에 참여할 수 있도록 지원한다.
설치환경
kubeadm을 통해 쿠버네티스를 설치하기 전에 기반이 되는 서버 인프라는 아래와 같이 구성한다.
서버 OS는 Ubuntu 22.04.3
을 사용했고 Master 1대와 Worker 2대로 구성된 클러스터를 구성해 본다.
추가로 컨테이너 런타임은 Containerd
를 이용하고 쿠버네티스 버전은 1.26
으로 설치한다.
공통 작업
서버 기초 세팅부터 클러스터 설치 단계까지 마스터 노드와 워커 노드의 차이점은 kubeadm init
명령으로 클러스터를 생성(Master)하느냐, 아니면 kubeadm join
으로 기존 클러스터에 참여(Worker)하느냐이다.
그렇기 때문에 클러스터링 전에 해야 하는 서버 세팅, 컨테이너 런타임 및 kube tools 설치 등은 모두 동일하게 내용만 각 서버에 알맞도록 바꿔서 진행하면 된다.
- IP 설정
Ubuntu는 기본적으로 netplan
을 통하여 네트워크 정보를 관리한다.
$ vi /etc/netplan/00-installer-config.yaml
각 서버 상황에 맞게 ip 주소와 gateway 정보를 아래와 같이 입력해 준다.
# k8s-master-1 설정
network:
ethernets:
ens33:
addresses:
- 192.168.45.111/24
routes:
- to: default
via: 192.168.45.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
version: 2
# k8s-worker-1 설정
network:
ethernets:
ens33:
addresses:
- 192.168.45.121/24
routes:
- to: default
via: 192.168.45.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
version: 2
# k8s-worker-2 설정
network:
ethernets:
ens33:
addresses:
- 192.168.45.122/24
routes:
- to: default
via: 192.168.45.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
version: 2
변경한 내용을 적용하기 위해 아래 명령어를 실행한다.
$ netplan apply
- Swap, Firewall 끄기
쿠버네티스는 완벽한 리소스 제어를 목표로 설계되었기 때문에 유동적으로 리소스를 조정할 수 있는 swap 메모리 기능은 컨테이너 및 클러스터 동작에 악영향을 끼칠 수 있으므로 반드시 끄고 진행한다.
#swap 기능 끄기
$ swapoff -a
$ sed -i '/swap/s/^/#/' /etc/fstab
#방화벽 끄기
$ ufw disable
- ip tables 설정
modprobe br_netfilter
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
vi /etc/sysctl.conf
#ip_forward 부분 주석 해제
net.ipv4.ip_forward=1
#변경한 설정들을 적용
sudo sysctl --system
- 컨테이너 런타임(containerd) 설치
#containerd 설치에 필요한 의존성 패키지 설치
$ apt-get install -y apt-transport-https ca-certificates curl
#gpg 키 추가 및 저장소 정보 추가
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
#containerd 설치
$ apt-get install containerd.io
#containerd를 컨테이너 런타임으로 쓰기 위한 설정값 추가
$ mkdir -p /etc/containerd/
$ containerd config default | sudo tee /etc/containerd/config.toml
$ sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
$ sed -i 's/^disabled_plugins \=/\#disabled_plugins \=/g' /etc/containerd/config.toml
$ systemctl restart containerd
- 쿠버네티스 공식 APT 저장소 정보 추가
#gpg 키 추가
$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --yes --dearmor -o /usr/share/keyrings/kubernetes-archive-keyring.gpg
$ echo "deb [arch=$(dpkg --print-architecture) 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 > /dev/null
#추가한 저장소 정보 업데이트
$ apt-get update
- kube tools 설치
쿠버네티스 버전에 맞게 kubelet
, kubeadm
, kubectl
을 설치한다.
$ apt-get install kubelet=1.26.0-00 kubeadm=1.26.0-00 kubectl=1.26.0-00
이후에 서버 관리를 하다가 전체 패키지를 업데이트해 버리면 kube tools의 버전도 올라가게 되어 클러스터 제어에 문제가 발생할 수 있다.
이러한 경우를 대비하여 지금 설치한 1.26
으로 패키지 버전을 고정해 준다.
$ apt-mark hold kubelet kubeadm kubectl
클러스터 생성
- 마스터 노드에서 클러스터를 생성
Pod network 대역대를 172.16.0.0/16
으로 설정해 주고 apiserver의 ip는 마스터 노드의 ip인 192.168.45.111
로 설정해 준다.
kubeadm init --kubernetes-version=v1.26.0 --pod-network-cidr=172.16.0.0/16 --apiserver-advertise-address=192.168.45.111 --control-plane-endpoint 192.168.45.111:6443
클러스터 설치가 완료되면 아래와 같이 출력된다.
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:
kubeadm join 192.168.45.111:6443 --token 43nsnx.0oa735xpd17ipi8h \
--discovery-token-ca-cert-hash sha256:e71f4d0bde2dffe1953cf7016d995cc9db59a4a320c8322c5e390d1fe6ef9c3d \
--control-plane
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.45.111:6443 --token 43nsnx.0oa735xpd17ipi8h \
--discovery-token-ca-cert-hash sha256:e71f4d0bde2dffe1953cf7016d995cc9db59a4a320c8322c5e390d1fe6ef9c3d
내용을 보면 kubeadm join
명령어가 2개 출력되는데 첫 번째는 마스터 노드로 클러스터에 참가하기 위한 명령어이고, 두 번째는 워커 노드로 클러스터에 참가할 때 사용된다.
- kubeconfig 환경변수 추가
root 계정으로 클러스터를 제어하기 위해 kubeconfig
경로를 bashrc
파일에 영구적으로 설정해 준다.
$ vi ~/.bashrc
아래 내용을 bashrc
파일 가장 하단에 추가해 준다.
export KUBECONFIG=/etc/kubernetes/admin.conf
이후 변경사항을 적용하고 클러스터 노드 목록을 출력해 본다.
$ source ~/.bashrc
$ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-1 NotReady control-plane 85s v1.26.0
마스터 노드의 이름과 함께 클러스터 생성이 정상적으로 된 걸 확인할 수 있다.
노드의 STATUS가 NotReady인 이유는 컨테이너 환경에서 네트워킹 기능을 담당하는 CNI가 없기 때문이다. 또한 클러스터에서 내부 DNS서버 역할을 담당하는 coredns도 CNI의 기능을 활용하기 때문에 정상적으로 클러스터를 구동하기 위해서는 Calico와 같은 CNI를 반드시 설치해줘야 한다.
워커 노드 추가
생성된 클러스터에 워커노드 2개(k8s-worker-1
, k8s-worker-2
)를 추가해 본다.
- 워커 노드를 클러스터에 추가
$ kubeadm join 192.168.45.111:6443 --token 43nsnx.0oa735xpd17ipi8h \
--discovery-token-ca-cert-hash sha256:e71f4d0bde2dffe1953cf7016d995cc9db59a4a320c8322c5e390d1fe6ef9c3d
정상적으로 클러스터에 추가되면 아래와 같이 출력된다.
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
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 node
NAME STATUS ROLES AGE VERSION
k8s-master-1 NotReady control-plane 2m14s v1.26.0
k8s-worker-1 NotReady <none> 27s v1.26.0
k8s-worker-2 NotReady <none> 17s v1.26.0
정상적으로 Master 1대, Worker 2대가 클러스터링 된 것을 확인할 수 있다.
- Pod 목록을 조회
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE
NOMINATED NODE READINESS GATES
kube-system coredns-787d4945fb-flwms 0/1 Pending 0 8m18s <none> <none> <none> <none>
kube-system coredns-787d4945fb-jhw2h 0/1 Pending 0 8m18s <none> <none> <none> <none>
kube-system etcd-k8s-master-1 1/1 Running 0 8m34s 192.168.45.111 k8s-master-1 <none> <none>
kube-system kube-apiserver-k8s-master-1 1/1 Running 0 8m34s 192.168.45.111 k8s-master-1 <none> <none>
kube-system kube-controller-manager-k8s-master-1 1/1 Running 0 8m32s 192.168.45.111 k8s-master-1 <none> <none>
kube-system kube-proxy-dngvn 1/1 Running 0 6m38s 192.168.45.122 k8s-worker-2 <none> <none>
kube-system kube-proxy-pmx4l 1/1 Running 0 8m18s 192.168.45.111 k8s-master-1 <none> <none>
kube-system kube-proxy-pqtq2 1/1 Running 0 6m48s 192.168.45.121 k8s-worker-1 <none> <none>
kube-system kube-scheduler-k8s-master-1 1/1 Running 0 8m32s 192.168.45.111 k8s-master-1 <none> <none>
목록을 확인해 보면 coredns
를 제외한 클러스터를 구성하는 시스템 Pod들이 모두 동작중인 것을 확인할 수 있다.
컨테이너 네트워크 인터페이스(CNI) 설치
CNI는 가상머신이나 컨테이너를 위한 네트워킹, IP 관리, 접근 제어, 모니터링 등 다양한 네트워크 관련 기능을 제공하며 쿠버네티스에서는 노드에 배포된 Pod 간 통신이 가능하도록 도와준다.
CNI의 종류는 Calico
, Flannel
, Kube-router
등 여러 개가 있지만 가장 많이 사용되는 Calico
를 이용하여 네트워크를 설정해 본다.
- Calico CNI 설치 및 CRD 배포
$ kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.2/manifests/tigera-operator.yaml
추가로 Calico Pod에서 사용할 커스텀 리소스(CRD)를 생성해준다.
$ vi custom-resources.yaml
각 클러스터 상황에 맞춰 내용을 입력해 주면 된다.(cidr
부분에 pod network의 cidr를 입력)
만약 pod network cidr가 calico의 기본값인 192.168.0.0/16이면 cidr를 수정할 필요 없이 아래 명령어로 바로 배포하면 된다.
$ kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.2/manifests/custom-resources.yaml
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
ipPools:
- blockSize: 26
cidr: 172.16.0.0/16
encapsulation: VXLANCrossSubnet
natOutgoing: Enabled
nodeSelector: all()
---
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
name: default
spec: {}
배포 후 Calico Pod가 정상적으로 뜨는지 확인한다.
$ kubectl apply -f custom-resources.yaml
$ kubectl get pod -A | grep calico
calico-apiserver calico-apiserver-5489d6d7f6-bjvj9 1/1 Running 0 7m49s
calico-apiserver calico-apiserver-5489d6d7f6-gcfnx 1/1 Running 0 7m49s
calico-system calico-kube-controllers-84dd694985-8k6w2 1/1 Running 0 11m
calico-system calico-node-56sjx 1/1 Running 0 11m
calico-system calico-node-5grdr 1/1 Running 0 11m
calico-system calico-node-g6vsc 1/1 Running 0 11m
calico-system calico-typha-68967b8579-f5j5f 1/1 Running 0 11m
calico-system calico-typha-68967b8579-m2jxf 1/1 Running 0 10m
calico-system csi-node-driver-brlnn 2/2 Running 0 11m
calico-system csi-node-driver-wfsrw 2/2 Running 0 11m
calico-system csi-node-driver-zm4sb 2/2 Running 0 11m
- coredns 동작 확인
CNI의 부재로 pending
상태로 있던 coredns
pod의 상태를 확인해 본다.
$ kubectl get pod -A | grep coredns
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-787d4945fb-flwms 1/1 Running 0 25m
kube-system coredns-787d4945fb-jhw2h 1/1 Running 0 25m
네트워크 기능이 활성화되면서 노드가 Ready
상태로 변경되어 정상적으로 구동되고 있는 것을 확인할 수 있다.
참고자료
kubeadm 설치하기
이 페이지에서는 kubeadm 툴박스 설치 방법을 보여준다. 이 설치 프로세스를 수행한 후 kubeadm으로 클러스터를 만드는 방법에 대한 자세한 내용은 kubeadm으로 클러스터 생성하기 페이지를 참고한다.
kubernetes.io
[#1. Kubernetes 시리즈] 3. CNI란? (Container Network Interface)
이번 글에서는 쿠버네티스를 설치하기 전에 간략하게 CNI(Container Network Interface)에 대하여 알아보겠습니다. 무작정 문서대로 설치만 하기 보다는 내가 설치하는 애가 무엇인지 알고 가는게 좋을
captcha.tistory.com
'Kubernetes' 카테고리의 다른 글
쿠버네티스 볼륨 알아보기 (0) | 2024.02.03 |
---|---|
쿠버네티스 대시보드로 클러스터 모니터링하기 (1) | 2024.01.23 |
Ingress를 활용하여 웹 트래픽 제어하기 (0) | 2024.01.06 |
Helm 알아보기 (0) | 2023.12.31 |
쿠버네티스 컨트롤러 알아보기 (0) | 2023.12.17 |