Information Security ˗ˋˏ ♡ ˎˊ˗

Cloud

[K8S] Kubernetes 구축 - 1. 설치 및 배포 (in Ubuntu 22.04)

토오쓰 2023. 8. 21. 11:07

[글 목차]
1. Kubernetes(쿠버네티스) 구축을 위한 준비

2. 시스템 설정
- hostname 변경 및 /etc/hosts 파일 설정

- 방화벽 구성
- 커널 모듈 활성화 및 SWAP 비활성화

3. Containerd: 컨테이너 런타임 설치

4. Kubernetes 패키지 설치
5. Flannel: 컨테이너 네트워크 인터페이스(CNI) 플러그인 설치
6. Kubernetes 컨트롤 플레인 초기화
7. Kubernetes에 Worker 노드 추가

 

 

Kubernetes(쿠버네티스)이란?

- 컨테이너화된 애플리케이션의 배포, 관리 및 확장을 자동화하는 컨테이너 오케스트레이션을 위한 오픈 소스 플랫폼

- Kubernetes는 Google에서 만든 컨테이너 오케스트레이션이며 특정 역할을 수행할 컨테이너를 논리적 공간에 배포나 관리해 주는 시스템

 

1. Kubernetes(쿠버네티스) 구축을 위한 준비

구성
설치된 서버 Ubuntu 22.04
Kubernetes 클러스터의 컨테이너 런타임 containerd
 클러스터의 pod 네트워크  Flannel 네트워크 플러그인

1) Ubuntu 22.04 버전의 서버

2) 루트/관리자 권한이 있는 루트가 아닌 사용자

3) 컨트롤 플레인(master) 1개, worker 노드 1개 생성

4) containerd: Kubernetes 클러스터의 컨테이너 런타임

5) Flannel 네트워크 플러그인

6) kubelet, kubeadm, kubectl 등 Kubernetes 패키지

 

 

2. 시스템 설정

2-1) hostname 변경 및 /etc/hosts 파일 설정

- 사용할 hostname 변경

- 각 서버 hostname은 올바른 IP 주소에 맞게 설정

 

모든 서버에서 시스템 hostname과 /etc/hosts 파일을 설정하기 

172.16.100.135 master1
172.16.100.134 worker1

 

hostnamectl 명령어을 실행 하여 각 서버에서 시스템 hostname 설정

sudo hostnamectl set-hostname cplane1
sudo hostnamectl set-hostname worker1

 

모든(master, worker) 서버에서 /etc/hosts 파일 수정

sudo nano /etc/hosts

 

hostname을 올바른 IP 주소로 작성

172.16.100.135 master1
172.16.100.134 worker1

 

확인하기 위해 hostname에 대해 ping 명령을 실행

ping master1
ping worker1

 

2-2) 방화벽 구성

컨트롤 플레인과 worker 노드 모두에서 방화벽을 활성화하는 것을 권장함 

기본 Ubuntu 시스템에서는 UFW 방화벽이 기본 방화벽으로 사용

컨트롤 플레인 "master1"에 명령어 입력

sudo ufw allow 6443/tcp
sudo ufw allow 2379:2380/tcp
sudo ufw allow 10250/tcp
sudo ufw allow 10259/tcp
sudo ufw allow 10257/tcp

sudo ufw status

 

"worker1"에 명령어 입력

sudo ufw allow 10250/tcp
sudo ufw allow 30000:32767/tcp

sudo ufw status

 

2-3) 커널 모듈 활성화 및 SWAP 비활성화

커널 모듈 활성화: Kubernetes를 사용하려면 Linux 시스템의 일부 커널 모듈을 활성화해야 함

커널 모듈 "overlay" 및 "br_netfilter"가 필요하여 활성화

sudo modprobe overlay
sudo modprobe br_netfilter

 

영구적인 설정을 하기 위해서는 /etc/modules-load.d/k8s.conf에 구성 파일을 만들어 Linux 시스템이 시스템 부팅 중에 커널 모듈을 활성화할 수 있음

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

 

필요한 systemctl 매개변수 생성

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 매개변수 목록을 가져오며 "k8s.conf" 파일에 추가한 sysctl 매개변수를 가져옴

sudo sysctl --system

 

SWAP를 비활성화하려면 sed(스트림 편집기)를 이용하여 단일 명령을 사용하여 비활성화 시킴

sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

 

현재 세션에서 SWAP 비활성화 시키고 "free -m" 명령을 이용하여 확인 (SWAP=0, 비활성화 의미)

sudo swapoff -a
free -m

 

 

3. Containerd: 컨테이너 런타임 설치

Kubernetes 클러스터를 설정하려면 파드가 실행될 수 있도록 모든 서버에 컨테이너 런타임을 설치해야 함

다양한 컨테이너 런타임 중에서 containerd를 사용할 것

모든 컨트롤 플레인 및 작업자 노드에 containerd 설치

Docker 저장소에서 제공하는 미리 빌드된 바이너리 패키지를 사용하여 containerd 설치

 

Docker 리포지토리와 GPG 키 추가하기

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

 

※  중간에 curl 명령어가 없어서 따로 설치

sudo apt install curl

 

우분투 시스템에서 패키지 인덱스를 업데이트

sudo apt update

 

apt 명령을 사용하여 containerd 패키지 설치

sudo apt install containerd.io

 

설치가 완료되면 다음 명령을 실행하여 containerd 서비스 중지

sudo systemctl stop containerd

 

기본 containerd 구성을 백업하고 새롭게 생성

sudo mv /etc/containerd/config.toml /etc/containerd/config.toml.orig
sudo containerd config default > /etc/containerd/config.toml

 허가 거부 error가 발생할 경우, "su -" 명령어를 이용하여 root 권한으로 실행하였음

 

containerd 구성 파일 "/etc/containerd/config.toml" 수정

cgroup 드라이버 "SystemdCgroup = false"의 값을 "SystemdCgroup = true"로 변경하여

containerd 컨테이너 런타임에 대한 systemd cgroup 드라이버 활성화 

더보기

systemd cgroup 드라이버

systemd가 Linux의 초기 시스템으로 선택되면 init 프로세스는 루트 제어 그룹(cgroup)을 생성하고 cgroup 관리자 역할을 한다.

프로세스들의 자원의 사용(CPU, 메모리, 디스크 입출력, 네트워크 등)을 제한하고 격리시키는 리눅스 커널 기능을 한다.

sudo nano /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

 

systemctl 명령을 실행하여 containerd 서비스 시작

sudo systemctl start containerd

 

containerd 서비스 확인

sudo systemctl is-enabled containerd
sudo systemctl status containerd

 

 

4. Kubernetes 패키지 설치

Ubuntu 시스템에 Kubernetes 패키지 설치하기

1) 쿠버네티스 클러스터를 부트스트래핑하기 위한 kubeadm

2) 쿠버네티스 클러스터의 주요 구성 요소인 kubelet

3) 쿠버네티스 클러스터를 관리하기 위한 명령줄 유틸리티인 kubectl

sudo apt install apt-transport-https ca-certificates curl -y

 

Kubernetes 리포지토리와 GPG 키 추가하기

sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
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

 

Ubuntu 리포지토리 및 패키지 인덱스 업데이트

sudo apt update

 

※ 명령어 입력 후 오류 발생

error: GPG error public key is not available: NO_PUBKEY B53DC80D13EDEF05: during VM creation using Vagrant

해결방안) 아래 명령어 입력

curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg| gpg -o /usr/share/keyrings/kubernetes-archive-keyring.gpg --dearmor

참고문서)

https://stackoverflow.com/questions/76299027/gpg-error-public-key-is-not-available-no-pubkey-b53dc80d13edef05-during-vm-cre

해결!!

 

업데이트가 완료되면 다음 apt 명령을 사용하여 Kubernetes 패키지 설치

- Y를 입력하여 설치

sudo apt install kubelet kubeadm kubectl

 

현재 버전의 Kubernetes 패키지가 자동으로 업데이트되지 않음

- Kubernetes 패키지 간의 버전 왜곡 방지

sudo apt-mark hold kubelet kubeadm kubectl

 

 

5. Flannel: 컨테이너 네트워크 인터페이스(CNI) 플러그인 설치

Kubernetes는 CNI 규격을 이용하여 네트워크와 연결한다.

- CNI(Container Network Interface): 여러 쿠버네티스 노드는 파드 간 통신하기 위해 클러스터 내에 분산된 파드가 서로 통신 가능하도록 네트워크를 구성해야 하는데 이때 사용되는 플러그인이 CNI이다.

- CNI 종류: Kubernetes 용 AWS VPC, Azure CNI, Cilium, Calico, Flannel 등

 

여기서 사용할 플러그인은 "Flannel"

이를 위해 Kubernetes 노드에 Flannel의 바이너리 파일을 설치하기

새 디렉터리 "/opt/bin"를 만들고 Flannel의 바이너리 파일을 다운로드한다.

sudo mkdir -p /opt/bin/
sudo curl -fsSLo /opt/bin/flanneld https://github.com/flannel-io/flannel/releases/download/v0.19.0/flanneld-amd64

 

파일의 권한을 변경하여 "flanneld" 바이너리 파일을 실행 가능하도록 변경

이 "flanneld" 바이너리 파일은 Pod 네트워크 애드온을 설정할 때 자동으로 실행됨

sudo chmod +x /opt/bin/flanneld

 

 

6. Kubernetes 컨트롤 플레인 초기화

컨트롤 플레인 "master1" 노드를 초기화하여 Kubernetes 클러스터를 시작한다.

Kubernetes 컨트롤 플레인은 IP 주소가 "172.16.100.135"인 "master1" 서버에 설치될 것

초기화 전 "br_netfilter" 커널 모듈이 활성화되어 있는지 확인하고 결과 출력 시 "br_netfilter" 모듈 활성화

lsmod | grep br_netfilter

 

Kubernetes 클러스터에 필요한 이미지 다운로드

kube-apiserver, kube-controller-manager, kube-scheduler, kube-proxy, pause, etcd, coredns 등 컨테이너 이미지와 같은 Kubernetes 클러스터 생성에 필요한 모든 컨테이너 이미지를 다운로드함

sudo kubeadm config images pull

 

kubeadm init 명령어를 통해 Master Node를 초기화
"pod-network-cidr": Pod의 네트워크를 Flannel CNI 플러그인의 기본 네트워크 범위인 10.244.0.0/16으로 지정
- 변경 불가
"--apiserver-advertise-address": Kubernetes API 서버가 실행될 IP 주소 결정(Master Node IP)
"--cri-socket": "/run/containerd/containerd.sock"에서 사용할 수 있는 컨테이너 런타임 소켓에 CRI 소켓 지정
- 다른 Container Runtime을 사용하는 경우 소켓 파일의 경로를 변경하거나 kubeadm이 Container Runtime 소켓을 자동으로 감지하기 때문에 "--cri-socket" 옵션 제거

sudo kubeadm init --pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=172.16.100.135 \
--cri-socket=unix:///run/containerd/containerd.sock

 

"master1" 서버에서 Kubernetes 클러스터 초기화 시 결과

초기화 후 Kubernetes 자격 증명 설정 및 Pod 네트워크 애드온 배포, 추가 방법에 대한 몇 가지 중요한 출력 메시지와 함께 "Your Kubernetes control-plane has initialised successful!" 메시지 출력

 

Kubernetes 클러스터 사용을 시작하기 전에 Kubernetes 자격 증명 설정 필요

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

 

"kubectl" 명령을 사용하여 Kubernetes 클러스터와 상호 작용
"kubectl" 명령을 실행하여 Kubernetes 클러스터 정보를 확인하고 Kubernetes 컨트롤 플레인과 coredns가 실행되는 것을 볼 수 있다.

kubectl cluster-info

 

Kubernetes에 대한 전체 정보를 얻으려면 덤프 옵션을 사용할 수 있음

kubectl cluster-info dump

 

Kubernetes 컨트롤 플레인 실행 후 Flannel Pod 네트워크 플러그인 설치
- "flanneld" 바이너리 파일을 자동으로 실행하고 일부 flannel 포드 실행

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

 

Kubernetes에서 실행 중인 포드 목록을 확인

Kubernetes 설치에 성공하면 Kubernetes의 모든 기본 포드가 실행 중인 것을 볼 수 있다.

더보기

Namespace

- 프로세스 격리 기술 

kubectl get pods --all-namespaces

 

 

7. Kubernetes에 Worker 노드 추가

"master1" 서버에서 Kubernetes 컨트롤 플레인을 초기화한 후 "worker1"를 Kubernetes 클러스터에 추가함
"worker1" 서버로 이동하고 "kubeadm join" 명령을 실행하여 "worker1"을 Kubernetes 클러스터에 추가한다. 

컨트롤 플레인 노드를 초기화할 때 출력 메시지에서 세부 정보를 얻을 수 있다.

"master1" 서버에서 Kubernetes 클러스터 초기화 시 결과

kubeadm join 172.16.100.135:6443 --token dzlxd2.klie7zcv1f9vwf4r \
--discovery-token-ca-cert-hash sha256:dd0796c602ccffe7f9a5cbb24575e2b5bc1860e12838afd675292691dc86348a

 

이제 컨트롤 플레인 서버 "master1"에서 Kubernetes 클러스터에서 실행 중인 모든 포드 확인하기

모든 Kubernetes 구성 요소에 추가 포드가 있는지 확인한다.

kubectl get pods --all-namespaces

 

 

※ error: 아래 사진처럼 flannel과 coredns의 STATUS가 정상적으로 동작하지 않음

해결방안) kubeadm init 명령어를 통해 Master Node 초기화할 때, "pod-network-cidr"의 값을 Flannel CNI 플러그인의 기본 네트워크 범위인 10.244.0.0/16으로 지정해야 함

다른 네트워크 범위로 변경했을 경우, 오류가 발생하였다.

 

 

마지막으로 "kubectl" 명령을 사용하여 Kubernetes 클러스터에서 사용 가능한 모든 노드를 확인한다.

"master1" 서버가 Kubernetes 컨트롤 플레인으로 실행되고 "worker1" 서버가 실행 중

kubectl get nodes -o wide

 

Ubuntu 22.04 서버가 있는 Kubernetes 클러스터 배포 완료!! 👍🏻👍🏻👍🏻👍🏻

 

 

참고

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

https://stackoverflow.com/questions/76299027/gpg-error-public-key-is-not-available-no-pubkey-b53dc80d13edef05-during-vm-cre

https://ko.linux-console.net/?p=3490#gsc.tab=0