Kubernetes 는 컨테이너의 생성, 배포, 실행을 하는 등 컨테이너를 관리하는 오픈소스 플랫폼 입니다.
여기에서는 Ubuntu 22.04 버전의 서버 3대로 (master 노드 1대 / worker 노드 2대) Kubernetes 를 구성하는 방법에 대해 설명합니다.
1. CRI-O 설치
CRI-O 공식 홈페이지 : https://cri-o.io
설치에 앞서 사용하고자 하는 호스트네임을 적용 합니다.
# hostnamectl set-hostname master // master 노드에서
# hostnamectl set-hostname worker1 // worker1 노드에서
# hostnamectl set-hostname worker2 // worker2 노드에서
(모든 노드에서)
# vi /etc/hosts
127.0.0.1 localhost 10.101.0.5 master 10.101.0.10 worker1 10.101.0.12 worker2 |
운영 할 Kubernetes 버전이 1.26인 경우 CRI-O 버전 1.26을 설치해야 합니다.
# OS=xUbuntu_22.04
# VERSION=1.26
# echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
# echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
# curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/Release.key | apt-key add -
# curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -
# apt -y update
# apt -y upgrade // 업그레이드 완료 후 최신 커널로 사용하고자 할 경우 reboot 을 진행합니다.
# apt -y install cri-o cri-o-runc cri-tools
CRI-O 를 실행하고 버전을 확인합니다.
# systemctl enable --now crio
# crio --version
crio version 1.26.4
Version: 1.26.4
GitCommit: unknown
GitCommitDate: unknown
GitTreeState: clean
BuildDate: 2023-08-17T06:08:14Z
GoVersion: go1.19
Compiler: gc
Platform: linux/amd64
Linkmode: dynamic
...
2. Kubernetes 설치
Kubernetes 공식 홈페이지 : https://kubernetes.io
설치 전, 쿠버네티스 (kubelet) 사용을 위해 SWAP 을 반드시 비활성화 시켜줍니다.
# swapoff -a
# cat /etc/fstab
fstab 에서도 swap 파티션이 존재한다면 주석처리하여 비활성화 시킵니다.
1) kubeadm, kubelet 및 kubectl 설치
다음 패키지들을 설치합니다.
- kubeadm : 클러스터를 부트스트랩하는 명령
- kubelet : 클러스터의 모든 노드에서 실행되는 POD와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트
- kubectl : 클러스터와 통신하기 위한 CLI 유틸리티
(모든 노드에서)
# apt -y install apt-transport-https ca-certificates
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add
# echo "deb https://apt.kubernetes.io/ " >> ~/kubernetes.list
# mv ~/kubernetes.list /etc/apt/sources.list.d
# apt-y update
# VERSION="1.26.0-00"
# apt -y install kubelet=$VERSION kubeadm=$VERSION kubectl=$VERSION kubernetes-cni
쿠버네티스는 버전이 중요하므로 패키지가 자동으로 설치, 업그레이드 또는 제거되지 않도록 고정 시킵니다.
# apt-mark hold kubelet kubeadm kubectl
kubelet set on hold.
kubeadm set on hold.
kubectl set on hold.
2) 쿠버네티스 필수 환경 구성
(모든 노드에서)
쿠버네티스 운영을 위해 필요한 필수 요소들을 설치하고 구성합니다.
필요한 모듈을 로드하고 부팅시에도 자동 적용되도록 합니다.
# modprobe overlay
# modprobe br_netfilter
# cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
IPv4 를 포워딩하여 iptables 가 브릿지된 트래픽을 보게 합니다.
sysctl 파라미터를 설정하면, 재부팅 후에도 값이 유지됩니다.
# 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
재부팅하지 않고 sysctl 파라미터를 적용합니다.
# sysctl --system
3) cgroup 드라이버 설정
(모든 노드에서)
CRI-O는 기본적으로 systemd 라는 cgroup 드라이버를 사용합니다.
# cat <<EOF | sudo tee /etc/crio/crio.conf.d/02-cgroup-manager.conf
[crio.runtime]
conmon_cgroup = "pod"
cgroup_manager = "systemd"
EOF
4) master 서버 초기화 및 노드 연결
(master 노드에서)
서버간 통신할 사설 네트워크 대역을 설정합니다.
쿠버네티스 구성에 필요한 이미지를 다운로드 받아야 하므로 이 단계에서 시간이 약간 소요됩니다.
# kubeadm init --pod-network-cidr=10.101.0.0/24
아래는 쿠버네티스 컨트롤 플레인이 성공적으로 초기화 되었을때 출력하는 메세지 입니다.
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/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.101.0.5:6443 --token fayi8m.4qus4e8y3cnon9nc \ --discovery-token-ca-cert-hash sha256:b5693e9d1a3fd79b64e790d5218369ef9449b211c0c30eef88e6376887ad774b |
위에 나와있는 안내 대로 추가 명령을 실행합니다.
클러스터 사용을 시작하려면 일반 사용자로 다음을 실행해야 합니다.
(master 노드에서)
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config
또는 root 사용자인 경우 다음을 실행할 수 있습니다.
# export KUBECONFIG=/etc/kubernetes/admin.conf
앞으로 SSH 접속시마다 자동으로 환경이 로드 되도록 하면 편리합니다.
# echo 'export KUBECONFIG="/etc/kubernetes/admin.conf"' >> ~/.bashrc
master 노드에서 확인 가능한 노드 상태를 출력합니다.
STATUS 에서 NotReady 로 표시되지만, 아래에서 별도 작업을 통해 Ready 로 변경할 예정입니다.
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady control-plane 4m57s v1.26.0
worker 노드에서는 아래와 같이 master 서버에 join (가입) 합니다.
token 과 hash 값은 쿠버네티스 컨트롤 플레인이 초기화 되었을때 출력된 값으로 합니다.
(worker 노드에서)
# kubeadm join 10.101.0.5:6443 --token fayi8m.4qus4e8y3cnon9nc \
--discovery-token-ca-cert-hash sha256:b5693e9d1a3fd79b64e790d5218369ef9449b211c0c30eef88e6376887ad774b
다시 master 노드에서 확인 가능한 노드 상태를 출력하면 가입된 worker 노드 리스트까지 확인이 됩니다.
(master 노드에서)
# kubectl get node
NAME STATUS ROLES AGE VERSION
master NotReady control-plane 8m1s v1.26.0
worker1 NotReady <none> 18s v1.26.0
worker2 NotReady <none> 16s v1.26.0
3. Calico 설치하기
Project Calico 는 Kubernetes에 대한 네트워크 정책 엔진입니다.
Calico 네트워크 정책 집행을 통해 네트워크 세분화 및 테넌트 격리를 구현할 수 있습니다.
Calico 공식 홈페이지 : https://www.tigera.io/project-calico
1) Calico 설치하기
(master 노드에서)
Tigera Calico 연산자 및 사용자 지정 리소스 정의를 설치합니다.
# kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.5/manifests/tigera-operator.yaml
필요한 커스텀 리소스를 생성하여 Calico를 설치합니다.
배포하는 yaml 파일에서 CIDR 정보를 자신이 사용하는 네트워크 정보로 수정하고 생성합니다.
# wget https://raw.githubusercontent.com/projectcalico/calico/v3.24.5/manifests/custom-resources.yaml
# sed -i 's/192.168.0.0\/16/10.101.0.0\/24/' custom-resources.yaml
# kubectl create -f custom-resources.yaml
다음 명령을 사용하여 모든 POD가 실행 중인지 확인합니다.
이 부분에서 모든 STATUS 값이 Running 이 되기까지 약간의 시간이 소요됩니다.
# watch kubectl get pods -n calico-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-67df98bdc8-kdt6m 1/1 Running 0 83s
calico-node-hp78g 1/1 Running 0 83s
calico-node-ntfq4 1/1 Running 0 83s
calico-node-rwm2s 1/1 Running 0 83s
calico-typha-7f4f4655f7-6psfv 1/1 Running 0 76s
calico-typha-7f4f4655f7-t7ccr 1/1 Running 0 83s
master 노드에서 POD 를 스케쥴링 할 수 있도록 모든 노드의 taint 를 제거 합니다.
우선 taint 상태를 확인하면 아래와 같이 출력되는데,
이 룰을 없애줘야 kubectl get node 명령으로 출력된 NotReady 상태가 Ready 상태로 변경됩니다.
# kubectl describe nodes |grep -i taint
Taints: node-role.kubernetes.io/control-plane:NoSchedule
Taints: <none>
Taints: <none>
룰 뒤에 - 를 붙이면 제거됩니다.
# kubectl taint nodes master node-role.kubernetes.io/control-plane:NoSchedule-
taint 상태를 다시 확인합니다.
# kubectl describe nodes |grep -i taint
Taints: <none>
Taints: <none>
Taints: <none>
이제 모든 노드의 상태가 Ready 로 돌아왔습니다.
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 36m v1.26.0
worker1 Ready 14m v1.26.0
worker2 Ready 12m v1.26.0
* 참고
worker 노드는 사용 설정에 따라 <none> 이 아닐 경우 NoSchedule 이나 NoExecute 가 있을 수 있는데
제거해야하는 상황에 명령어가 수행되지 않는다면 아래와 같이 worker 노드에서 생성되었던 파일 2개 삭제 및 kubelet 데몬 중지 후 다시 join 을 하면 해결됩니다.
(해당 worker 노드에서)
# rm -f /etc/kubernetes/kubelet.conf
# rm -f /etc/kubernetes/pki/ca.crt
# systemctl stop kubelet
# kubeadm join 10.101.0.5:6443 --token fayi8m.4qus4e8y3cnon9nc \
--discovery-token-ca-cert-hash sha256:b5693e9d1a3fd79b64e790d5218369ef9449b211c0c30eef88e6376887ad774b