본문 바로가기

Cloud Native/install_K8s

install k8s on ubuntu20.04

 

kubernetes 는 키잡이 또는 파일럿을 뜻하는 그리스어에서 유래하였으며 k8s 라고 짧게 이야기하기도 한다 (k8s 는 "k"와 "s" 사이에 있는 8글자를 나타내는 약식표기이다).

k8s 가 주목을 받은 가장 큰 이유중의 하나가 google 이 2014년에 오픈소스화 한 프로젝트로서 container orchestration 의 정점으로 불린다.

본 포스트는, k8s 에서 제공하는 kubeadm 을 활용하여 ubuntu 20.04 에 k8s cluster 를 설치하는 것에 관한 내용이다.

 

k8s 는 다음과 같이 두가지 서버 유형이 사용된다.

 

  • master: k8s master 는 cluster 에 POD, replications, services, nodes 및 여러 components 를 API 를 활용하여 실행한다.
  • node (worker): container 에 runtime 을 제공하며, container 의 집합인 POD 는 여러 노드에 걸쳐 생성가능하다. 

k8s 구성을 위한 최소 사양은 다음과 같다.

  • memory: 2GB 이상
  • CPU: 2 core 이상
  • Network: Internet 연결이 가능한 포트 및 클러스터간 연결을 위한 별도 포트 (하나의 포트로 사용 가능)

[참조사이트]: https://computingforgeeks.com/deploy-kubernetes-cluster-on-ubuntu-with-kubeadm/


1. 패키지 업데이트 및 패키지 설치

k8s 설치를 위하여 update 를 실행한다.

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

 2. google gpg key 다운로드

k8s 패키지 설치를 위한 gpg key 를 설정한다. non-standard repository 에서 k8s 를 다운로드 하기 때문에 k8s 관련 subscription key 를 추가한다.

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

3. k8s repository 추가

k8s 패키지를 저장하고 있는 저장소를 ubuntu 20.04 에 등록한다. ubuntu 20.04 의 기본 repository 에 k8s 관련 repository 를 추가한다.

echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

4. 패키지 설치

k8s 패키지를 다운로드 하고 설치한다. 버전이 업데이트 되지 않도록 하기 위하여 설치가 완료된 후 `apt-mark` 로 고정한다.

sudo apt update
sudo apt install kubelet kubeadm kubectl -y
sudo apt-mark hold kubelet kubeadm kubectl

5. swap 비활성화

swap 을 해제한다.

sudo swapoff -a

- swap 메모리 확인

`swapoff -a` 로 인하여 실제 swap 이 제거되었는지 확인한다.

free
			total		used		free		shared		buff/cache		available
Swap:			0		   0		   0

- swap 주석처리

리부팅으로 인하여 swap 이 다시 설정되지 않도록 설정 파일에서 swap 부분을 주석처리한다.

sudo sed -i 's/\/swap/\#\/swap/' /etc/fstab

sudo vi /etc/fstab
#/swap.img		none		swap		sw		0		0

- sysctl 구성

커널 모듈을 사용하도록 설정하고 sysctl을 구성한다.

sudo modprobe overlay
sudo modprobe br_netfilter

sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

sudo sysctl --system

6. CRI-O 설치

POD 에서 container 를 실행하기 위해 k8s 는 container runtime 을 사용한다. container runtime 은 docker/CRI-O/containerd 등이 있으나 본 포스팅에서는 CRI-O 를 활용한다.

 

위 sysctl 구성이 완료된 상태여야 한다.

- 환경 설정 / repo 추가 / Release.key 설정

. /etc/os-release
CRI_VER=1.`echo $VERSION_ID | cut -f 1 -d '.'`

sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list <<EOF
deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/ /
EOF

sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:${CRI_VER}.list <<EOF
deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/${CRI_VER}/x${NAME}_${VERSION_ID}/ /
EOF

curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/Release.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/libcontainers.gpg add -

curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/x${NAME}_${VERSION_ID}/Release.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/libcontainers-cri-o.gpg add -

- CRI-O install

sudo apt update
sudo apt install cri-o cri-o-runc -y

- start and enable service

sudo systemctl daemon-reload
sudo systemctl start crio
sudo systemctl enable crio

7. podman 설치

- ubuntu20.04 의 경우

. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key | sudo apt-key add -
sudo apt update
sudo apt upgrade -y
sudo apt install podman -y

- alias 등록

alias docker=podman

8. master 서버 초기화

- br_netfilter 모듈 확인

master 서버에서 br_netfilter 모듈이 로드되었는지 확인한다.

lsmod | grep br_netfilter
br_netfilter	 28672		0
bridge		176128		1 br_netfilter

- kubelet 활성화

kubelet 서비스를 활성화한다.

sudo systemctl enable kubelet

- 컨테이너 이미지 pull

etcd (cluster database) 및 API server 를 포함하는 contorl-plane components 를 초기화한다.

sudo kubeadm config images pull

[config/images] Pulled k8s.gcr.io/kube-apiserver:v1.22.2
[config/images] Pulled k8s.gcr.io/kube-controller-manager:v1.22.2
[config/images] Pulled k8s.gcr.io/kube-scheduler:v1.22.2
[config/images] Pulled k8s.gcr.io/kube-proxy:v1.22.2
[config/images] Pulled k8s.gcr.io/pause:3.5
[config/images] Pulled k8s.gcr.io/etcd:3.5.0-0
[config/images] Pulled k8s.gcr.io/coredns:1.8.4

## multiple CRI

CRI 가 docker/CRI-O/containerd 모두 설치가 되어 있다면 하나의 CRI 를 선택한다 (CRI 가 하나인 경우에는 위 명령으로 충분하다).

# CRI-O
sudo kubeadm config images pull --cri-socket /var/run/crio/crio.sock

# containerd
sudo kubeadm config images pull --cri-socket /run/containerd/containerd.sock

# docker
sudo kubeadm config images pull --cri-socket /var/run/docker.sock

- DNS 설정 (endpoint 설정)

설정에 있어 IP 가 아닌 hostname 으로 편하게 설정하기 위함이며 `k8s-cluster.master.com` 등으로 표기하여도 문제없다 (IP 는 k8s cluster 서버간 API 통신을 위한 IP 를 의미함).

sudo vi /etc/hosts

<ip address> master
<ip address> worker01

9. k8s 클러스트 생성 (master 서버)

- kubeadm 옵션

kubeadm 명령에 함께 사용되는 옵션은 아래와 같다.

--control-plane-endpoint : control-plane 에 대한 endpoint 설정 (DNS 또는 IP)
--pod-network-cidr : POD network (CIDR 형태) 설정
--cri-socket : runtime socket path 를 설정하며 둘 이상의 CRI 가 있는 경우 사용
--apiserver-advertise-address : control-plane 서버의 API 서버에 대한 advertise 주소 설정

- kubeadm 실행

만약 192.168.0.0/16 이 이미 network 에서 사용중인 경우 다른 CIDR 을 선택하여야 한다.

sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --upload-certs \
  --control-plane-endpoint=master

## multiple CRI 을 위한 kubeadm

k8s 는 하나의 CRI 만 선택하여야 한다.

# CRI-O
sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --cri-socket /var/run/crio/crio.sock \
  --upload-certs \
  --control-plane-endpoint=master

# containerd
sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --cri-socket /run/containerd/containerd.sock \
  --upload-certs \
  --control-plane-endpoint=master

# docker
sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --cri-socket /var/run/docker.sock \
  --upload-certs \
  --control-plane-endpoint=master

- kubectl 구성

`kubeadm init` 의 output 에 포함된 구문을 활용하여 `kubectl` 을 구성한다 (복사하여 붙이면 됨).

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

- 클러스터 상태 확인

최초 master 서버만 구성이 된 상태이기 때문에 master 서버 정보만 확인된다 (/etc/hosts 설정이 도메인이 아닌 경우 https://master:6443 은 https://management_IP:6443 으로 제공).

kubectl cluster-info

Kubernetes master is running at https://master:6443
KubeDNS is running at https://master:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

%% kubeadm join (worker 노드)

아래 node (worker) 부분에서 다시 설명한다. `kubeadm init` 에 대한 output 에 포함된 구문을 그대로 활용한다 (/etc/hosts 설정이 도메인이 아닌 경우 https://master:6443 은 https://management_IP:6443 으로 제공).

kubeadm join master:6443 --token xxxxxxxxxx \
    --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

%% Error saying Unable to connect to the server x509 certificate signed by unknown authority

에러가 발생하면 아래 구문을 실행하고 다시 `kubeadm join` 프로세스를 실행한다.

export KUBECONFIG=/etc/kubernetes/admin.conf

%% kubeadm join (master 추가 구성)

master 서버를 추가하여 HA 구성을 하는 경우 다음과 같이 master 서버를 cluster 에 추가할 수 있다 (/etc/hosts 설정이 도메인이 아닌 경우 https://master:6443 은 https://management_IP:6443 으로 제공).

kubeadm join master:6443 --token xxxxxxxxxx \
    --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
    --control-plane

10. k8s master 서버 CNI 설치

k8s 의 네트워크를 지원하는 CNI (Container Network Interface) 는 여러 종류가 있다. 본 포스트는 설치에 목적을 두고 있기에 비교적 설치가 간단한 calico 를 예로 든다.

- calico

calico 는 다음 링크에서 확인가능하다.

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

- POD 확인

calico 및 coredns, etcd, kube-apiserver, kube-controller, kube-proxy, kube-scheduler 등을 확인할 수 있다.

sudo kubectl get pods --all-namespaces

- 노드 확인

현재 master 노드만 구성된 관계로 master 만 확인된다.

kubectl get nodes -o wide

NAME           STATUS   ROLES    AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE           KERNEL-VERSION     CONTAINER-RUNTIME
master         Ready    master   64m   v1.18.3   135.181.28.113   <none>        Ubuntu 20.04 LTS   5.4.0-37-generic   cri-o://1.22.0

## multiple CRI

선택한 CRI 에 따라 아래와 같이 확인된다.

# containerd
$ kubectl get nodes -o wide
NAME     STATUS   ROLES                  AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
ubuntu   Ready    control-plane,master   15m   v1.22.2   143.198.114.46   <none>        Ubuntu 20.04.3 LTS   5.4.0-88-generic   containerd://1.4.11

# docker
$ kubectl get nodes -o wide
NAME           STATUS   ROLES    AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE           KERNEL-VERSION     CONTAINER-RUNTIME
master         Ready    master   64m   v1.22.2   135.181.28.113   <none>        Ubuntu 20.04 LTS   5.4.0-37-generic   docker://20.10.8

11. k8s worker 노드 클러스터 구성

master (control-plane) 구성이 완료되면 master 서버에서 `kubeadm init` 으로 생성한 클러스터에 node (worker) 를 join 한다.

- DNS 설정 (endpoint 설정)

설정에 있어 IP 가 아닌 hostname 으로 편하게 설정하기 위함이며 `k8s-cluster.worker01.com` 등으로 표기하여도 문제없다 (IP 는 k8s cluster 서버간 API 통신을 위한 IP 를 의미함). 

sudo vi /etc/hosts

<ip address> master
<ip address> worker01

- cluster join

k8s cluster 에 node (worker) 를 추가한다. 반드시 master 서버에서 `kubeadm init` 으로 확인한 output 의 내용을 그대로 사용하여야 한다 (/etc/hosts 설정이 도메인이 아닌 경우 https://master:6443 은 https://management_IP:6443 으로 제공).

kubeadm join master:6443 --token xxxxxxxxxx \
    --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

- cluster 구성 확인 (master 서버)

control-plane 을 통하여 node (worker) 가 k8s cluster 에 추가되었는지 확인한다.

kubectl get nodes

NAME      STATUS   ROLES    AGE   VERSION
master    Ready    master   14d   v1.19.10
worker1   Ready    <none>   14d   v1.19.10

## join 토큰이 만료된 경우

다음 링크를 참조한다.

'Cloud Native > install_K8s' 카테고리의 다른 글

install container runtime on ubuntu20.04  (0) 2021.10.25