Container Orchestration/Kubernetes

Kubernetes 클러스터 구축하기(kubespray)

Somaz 2022. 5. 10. 16:14
728x90
반응형

Overview

 

Kubespray 도구를 사용하여 현 최신버전(2022-05-10 기준) Kubernetes Cluster를 구성해본다.

출처 : https://www.linkedin.com/pulse/kubespray-tutorial-kubecost/

 

아래의 글을 참고하길 바란다.

2024.02.02 - [Container Orchestration/Kubernetes] - Kubernetes 클러스터 구축하기(kubespray 2024v.)

 

Kubernetes 클러스터 구축하기(kubespray 2024v.)

Overview Kubespary를 사용해서 Kubernetes를 설치해본다. 그리고 Worker Node를 한대 추가해 조인까지 진행해본다. Kubespray 설치 2024.01.22 기준이다. 시스템 구성 OS : Ubuntu 20.04 LTS(Focal) Cloud: Google Compute Engine M

somaz.tistory.com

 

 


 

기본 스펙 및 구성

 

버전

  • OS : Debian 11.3 Bullseye
  • kubernetes : v1.23.6
  • CRI(Container Runtime Interface) : containerd v1.5.11

 

서버구성

서버 유형 Hostname OS CPU 메모리 IP 계정
가상머신 k8s-master Debian
Bullseye
4
Cores
4G 192.168.xxx.238
(/24)
root,
user
가상머신 k8s-node1 Debian
Bullseye
4
Cores
4G 192.168.xxx.239
(/24)
root,
user
가상머신 k8s-node1 Debian
Bullseye
4
Cores
4G 192.168.xxx.240
(/24)
root,
user

 


 

kubespray Requirements

 

Ansible의 명령어를 실행하기 위해 Ansible v 2.9와 Python netaddr 라이브러리가 머신에 설치되어 있어야 한다

Ansible 플레이북을 실행하기 위해 2.11 (혹은 그 이상) 버전의 Jinja가 필요하다

 

타겟 서버들은 docker 이미지를 풀(pull) 하기 위해 반드시 인터넷에 접속할 수 있어야 한다. 아니라면, 추가적인 설정을 해야 한다 (오프라인 환경 확인하기)

 

타겟 서버들의 IPv4 포워딩이 활성화되어야 한다

SSH 키가 인벤토리의 모든 서버들에 복사되어야 한다

 

방화벽은 kubespray에 의해 관리되지 않는다. 사용자는 필요에 따라 적절한 규칙을 구현해야 한다. 디플로이먼트 과정에서의 문제를 방지하려면 방화벽을 비활성화해야 한다

 

kubespray가 루트가 아닌 사용자 계정에서 실행되었다면, 타겟 서버에서 알맞은 권한 확대 방법이 설정되어야 하며, ansible_become 플래그나 커맨드 파라미터들, --become 또는 -b 가 명시되어야 한다

 


 

 

VM 생성(KVM)

2022.05.03 - [Container Orchestration/Kubernetes] - Kubernetes 클러스터 구축하기(kubeadm)

 

Kubernetes 클러스터 구축하기(kubeadm)

Overview kubeadm 도구를 사용하여 현 최신버전 kubernetes cluster를 구성하자. 버전 OS : Debian 11.3 Bullseye kubernetes : v1.14.0 CRI(Container Runtime Interface) : containerd v1.2.5 CNI(Container Network Interface) : calico v3.5 서버구

somaz.tistory.com

VM 생성하는 방법은 위와 같으니 동일한 내용은 생성하도록 하겠다.

기본 패키지 설치 후  QCOW2 타입 디크스를 생성해주었다.

Shell을 이용해 가상머신을 생성해보도록 하겠다.

 

리눅스 가상머신 생성 및 설정

$ vi k8s.sh

virt-install --virt-type kvm --name k8s-master \
	--ram 4096 \
 	--cpu=host \
	--vcpus=4 \
	--os-type=debian \
	--os-variant=debianwheezy \
	--disk path=/data/dong/disk/k8s-master.qcow2,format=qcow2,bus=virtio \
	--cdrom=/data/dong/iso/debian-11.3.0-amd64-netinst.iso \
	--network bridge=mgmt,model=virtio --graphics vnc,listen=0.0.0.0 \

$ sudo chmod 777 k8s.sh
./k8s.sh

// 쉘을 이용해서 나머지 k8s-node1, k8s-node2 도 생성해준다.

 

 

네트워크 설정을 진행해준다. 

# The primary network interface
auto ens3
iface ens3 inet static
    address 192.168.xx.238/24
    gateway 192.168.xx.11

// k8s-master : 238 k8s-node1 : 239  k8s-node2 : 240

$ ifup ens3

// 3대 전부 동일하게 진행

 

 

사전설정

아래 설정은 마스터와 노드 모든 머신에서 수행되어야 하며 서로의 머신은 ssh키를 공유하여 passwd없이 ssh접속이 가능해야한다.

 

 

패키지 업데이트 및 hosts파일 업데이트.

# apt update && apt upgrade
# vi /etc/hosts
...
192.168.xx.238  k8s-master
192.168.xx.239  k8s-node1
192.168.xx.240  k8s-node2

 

swap 비활성화

# swapoff -a

# vi /etc/fstab
# swap was on /dev/vda1 during installation
#UUID=

 

 


 

CRI(Container Runtime Interface) 설치

 

CRI 설치도 모든 머신(마스터와 노드)에서 커맨드를 수행한다.

 

모듈 로드

# modprobe overlay
# modprobe br_netfilter

# echo br_netfilter >> /etc/modules
  • overlay : 오버레이 파일시스템을 위한 모듈
  • br_netfilter : 브릿지 방화벽을 위한 모듈
  • br_netfilter 모듈은 리부팅시 자동으로 load되지 않아 /etc/modules 파일에 추가하였다.

 

커널 파라미터 설정

# cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
> net.ipv4.ip_forward = 1
> EOF

# # sysctl --system
* Applying /usr/lib/sysctl.d/50-pid-max.conf ...
kernel.pid_max = 4194304
* Applying /etc/sysctl.d/99-kubernetes-cri.conf ...
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /usr/lib/sysctl.d/protect-links.conf ...
fs.protected_fifos = 1
fs.protected_hardlinks = 1
fs.protected_regular = 2
fs.protected_symlinks = 1
* Applying /etc/sysctl.conf ...
  • Parameter net.bridge.bridge-nf-call-iptables과
  • net.bridge.bridge-nf-call-ip6tables인 Bridge
  • 방화벽 관련 kernel para는 br_netfilter module이 load되면서 on되므로 추가하지 않는다.

 

필수 패키지 설치

# apt install -y apt-transport-https \
                  ca-certificates \
                  curl \
                  software-properties-common

 


 

 

Install Ansible

이제부터 이어지는 과정은 kubespray를 실행 할 머신에서만 진행한다.

 

 

python pip으로 ansible version을 확인한다.

# pip search ansible
ERROR: XMLRPC request failed [code: -32500]
RuntimeError: PyPI's XMLRPC API is currently disabled due to unmanageable load and will be deprecated in the near future. See https://status.python.org/ for more information.

 

 

사이트에 문제가 있는 것 같다. 일단 python pip로 설치를 진행한다.

# pip install ansible

# pip list
ansible             5.7.0
ansible-core        2.12.5
Jinja2              3.1.2

 

python-netaddr 설치

# apt install python3-netaddr

 


 

Kubespray 실행

 

모든 조건을 충족시켰으니 이제 kubespray를 가져온다.

# apt install git
# git clone https://github.com/kubernetes-sigs/kubespray.git
Cloning into 'kubespray'...
remote: Enumerating objects: 60881, done.
remote: Total 60881 (delta 0), reused 0 (delta 0), pack-reused 60881
Receiving objects: 100% (60881/60881), 17.55 MiB | 6.98 MiB/s, done.
Resolving deltas: 100% (34395/34395), done.

# ls -l
total 4
drwxr-xr-x 15 root root 4096 May  3 14:22 kubespray

 

inventory 생성기를 실행한다.

# cd kubespray
~/kubespray# python3 contrib/inventory_builder/inventory.py help
Traceback (most recent call last):
  File "/root/kubespray/contrib/inventory_builder/inventory.py", line 40, in <module>
    from ruamel.yaml import YAML
ModuleNotFoundError: No module named 'ruamel'

 

사용하기 위한 요구사항이 존재한다. (python3 기반이므로 pip3로 install 해야함)

~/kubespray# cd contrib/inventory_builder/
~/kubespray/contrib/inventory_builder# pip3 install -r requirements.txt
Collecting configparser>=3.3.0
  Downloading configparser-5.2.0-py3-none-any.whl (19 kB)
Collecting ruamel.yaml>=0.15.88
  Downloading ruamel.yaml-0.17.21-py3-none-any.whl (109 kB)
     |████████████████████████████████| 109 kB 16.9 MB/s 
Collecting ipaddress
  Downloading ipaddress-1.0.23-py2.py3-none-any.whl (18 kB)
Collecting ruamel.yaml.clib>=0.2.6
  Downloading ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl (539 kB)
     |████████████████████████████████| 539 kB 26.3 MB/s 
Installing collected packages: ruamel.yaml.clib, ruamel.yaml, ipaddress, configparser
Successfully installed configparser-5.2.0 ipaddress-1.0.23 ruamel.yaml-0.17.21 ruamel.yaml.clib-0.2.6

~/kubespray/contrib/inventory_builder# python3 inventory.py
DEBUG: Adding group all
DEBUG: Adding group kube_control_plane
DEBUG: Adding group kube_node
DEBUG: Adding group etcd
DEBUG: Adding group k8s_cluster
DEBUG: Adding group calico_rr
Usage: inventory.py ip1 [ip2 ...]
Examples: inventory.py 10.10.1.3 10.10.1.4 10.10.1.5

Available commands:
help - Display this message
print_cfg - Write inventory file to stdout
print_ips - Write a space-delimited list of IPs from "all" group
print_hostnames - Write a space-delimited list of Hostnames from "all" group
add - Adds specified hosts into an already existing inventory

Advanced usage:
Create new or overwrite old inventory file: inventory.py 10.10.1.5
Add another host after initial creation: inventory.py add 10.10.1.6
Add range of hosts: inventory.py 10.10.1.3-10.10.1.5
Add hosts with different ip and access ip: inventory.py 10.0.0.1,192.168.10.1 10.0.0.2,192.168.10.2 10.0.0.3,192.168.10.3
Add hosts with a specific hostname, ip, and optional access ip: first,10.0.0.1,192.168.10.1 second,10.0.0.2 last,10.0.0.3
Delete a host: inventory.py -10.10.1.3
Delete a host by id: inventory.py -node1

Configurable env vars:
DEBUG                   Enable debug printing. Default: True
CONFIG_FILE             File to write config to Default: ./inventory/sample/hosts.yaml
HOST_PREFIX             Host prefix for generated hosts. Default: node
KUBE_CONTROL_HOSTS      Set the number of kube-control-planes. Default: 2
SCALE_THRESHOLD         Separate ETCD role if # of nodes >= 50
MASSIVE_SCALE_THRESHOLD Separate K8s control-plane and ETCD if # of nodes >= 200

 

 

 

sample inventory를 복사한다.

~/kubespray/contrib/inventory_builder# cd ../../

~/kubespray# cp -r inventory/sample inventory/test

 

 

`inventory.ini`를 수정한다.

~/kubespray/inventory/test# vi inventory.ini
# ## Configure 'ip' variable to bind kubernetes services on a
# ## different ip than the default iface
# ## We should set etcd_member_name for etcd cluster. The node that is not a etcd member do not need to set the value, or can set the empty string value.
[all]
k8s-master      ip=192.168.xxx.238
k8s-node1       ip=192.168.xxx.239
k8s-node2       ip=192.168.xxx.240

[kube-master]
k8s-master

[etcd]
k8s-master

[kube-node]
k8s-master
k8s-node1
k8s-node2

[k8s-cluster:children]
kube-master
kube-node

 

 

`inventory.ini`의 수정이 완료되었다면 이제 설치를 진행한다.

~/kubespray/inventory/test# cd ../../
~/kubespray# ansible-playbook -i inventory/test/inventory.ini cluster.yml -b -v

 

 

설치가 완료되었다.

# kubectl get node

// 명령어가 안먹는다??

 

 


 

Containerd 설치

# curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

# add-apt-repository \
                        "deb [arch=amd64] https://download.docker.com/linux/debian \
                        $(lsb_release -cs) stable"

# apt update && apt install -y containerd.io

$ containerd --version
containerd github.com/containerd/containerd v1.6.3 f830866066ed06e71bad64871bccfd34daf6309c

 


 

Kubeadm, Kubectl

 

쿠버네티스를 구성하기 위해 필수 패키지를 설치한다.

2022.05.03 - [Container Orchestration/Kubernetes] - Kubernetes 클러스터 구축하기(kubeadm)

 

Kubernetes 클러스터 구축하기(kubeadm)

Overview kubeadm 도구를 사용하여 현 최신버전 kubernetes cluster를 구성하자. 버전 OS : Debian 11.3 Bullseye kubernetes : v1.14.0 CRI(Container Runtime Interface) : containerd v1.2.5 CNI(Container Network Interface) : calico v3.5 서버구

somaz.tistory.com

위의 방법과 동일하다.

 

 

https://www.whatwant.com/entry/Kubespray

위의 사이트를 보고 다시 진행해보도록 하자.

root로 진행하였는데 유저로 다시 진행해보려고 한다.

그리고 kubespray 실행하는 것부터 다시 진행해보려고 한다.

 


 

Kubespray 실행

 

git clone 으로 kubespray 다운로드

user@k8s-master:~$ sudo git clone https://github.com/kubernetes-sigs/kubespray.git
'kubespray'에 복제합니다...
remote: Enumerating objects: 60888, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 60888 (delta 0), reused 1 (delta 0), pack-reused 60887
오브젝트를 받는 중: 100% (60888/60888), 17.57 MiB | 8.08 MiB/s, 완료.
델타를 알아내는 중: 100% (34398/34398), 완료.

 

인벤토리 생성

user@k8s-master:~/kubespray/contrib/inventory_builder$ pip3 install -r requirements.txt
user@k8s-master:~/kubespray/contrib/inventory_builder# python3 inventory.py

 

sample inventory를 복사

user@k8s-master:~/kubespray$ sudo cp -rfp inventory/sample/ inventory/test

 

`inventory.ini`를 수정.

user@k8s-master:~/kubespray/inventory/test$ sudo vi inventory.ini
# ## Configure 'ip' variable to bind kubernetes services on a
# ## different ip than the default iface
# ## We should set etcd_member_name for etcd cluster. The node that is not a etcd member do not need to set the value, or can set the empty string value.


[all]
k8s-master      ip=192.168.xxx.238
k8s-node1       ip=192.168.xxx.239
k8s-node2       ip=192.168.xxx.240

[kube-master]
k8s-master

[etcd]
k8s-master

[kube-node]
k8s-master
k8s-node1
k8s-node2

[k8s-cluster:children]
kube-master
kube-node

 

 

SSH 키 복사하기

user@k8s-master:~/kubespray/inventory/test$ ssh-keygen

user@k8s-master:~/kubespray/inventory/test$ ssh-copy-id 192.168.xxx.238

user@k8s-master:~/kubespray/inventory/test$ ssh-copy-id 192.168.xxx.239

user@k8s-master:~/kubespray/inventory/test$ ssh-copy-id 192.168.xxx.240

 

 

설치

$ ansible-playbook -u orchard -i inventory/test/inventory.ini cluster.yml -b -vvv

 

 

에러가 발생한다. 

PermissionError: [Errno 13] 허가 거부: b'/home/somaz/kubespray/inventory/test/credentials

 

(https://junghyeonsu.tistory.com/49)

위의 사이트를 참조하여 에러를 해결했다.

master node의 permission denied  인 것 같다.

/home/somaz/kubespray/inventory/test 폴더에 credentials 라는 폴더를 만들지 못한다.

라는 뜻 같다.

user@k8s-master:~/kubespray/inventory/test$ sudo chmod 777 credentials/
user@k8s-master:~/kubespray$ ansible-playbook -u orchard -i inventory/test/inventory.ini cluster.yml -b -vvv

 

 

설치가 완료되었다.

PLAY RECAP **********************************************************************************************************
k8s-master                 : ok=734  changed=58   unreachable=0    failed=0    skipped=1303 rescued=0    ignored=5   
k8s-node1                  : ok=502  changed=26   unreachable=0    failed=0    skipped=745  rescued=0    ignored=2   
k8s-node2                  : ok=502  changed=26   unreachable=0    failed=0    skipped=745  rescued=0    ignored=2   
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

 

node가 보이지가 않는다?

$ kubectl get node
The connection to the server localhost:8080 was refused - did you specify the right host or port?

 

 

kubectl 명령을 root가 아닌 user 계정으로 실행할 수 있도록 한다.

user@k8s-master:~$ mkdir .kube
user@k8s-master:~$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
user@k8s-master:~$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

 

kubectl 자동완성 기능도 적용하자.

root@k-master:~# apt install bash-completion
root@k-master:~# echo 'source <(kubectl completion bash)' >>~/.bashrc
root@k-master:~# . ~/.bashrc

 

node 가 잘보인다. 그러나 `ROLES`가 비어있다.

user@k8s-master:~$ kubectl get node
NAME         STATUS   ROLES                  AGE     VERSION
k8s-master   Ready    control-plane,master   8m37s   v1.23.6
k8s-node1    Ready    <none>                 7m27s   v1.23.6
k8s-node2    Ready    <none>                 7m27s   v1.23.6

 

label 추가 후 확인해주자.

user@k8s-master:~$ kubectl label node k8s-node1 node-role.kubernetes.io/worker=worker
node/k8s-node1 labeled

user@k8s-master:~$ kubectl label node k8s-node2 node-role.kubernetes.io/worker=worker
node/k8s-node2 labeled

user@k8s-master:~$ kubectl get node
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   12m   v1.23.6
k8s-node1    Ready    worker                 11m   v1.23.6
k8s-node2    Ready    worker                 11m   v1.23.6

 

Pod 확인

user@k8s-master:~$ kubectl get po -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS        AGE
kube-system   calico-kube-controllers-58dfb4874f-76w9h   1/1     Running   0               10m
kube-system   calico-node-9bxgh                          1/1     Running   0               11m
kube-system   calico-node-cbzll                          1/1     Running   0               11m
kube-system   calico-node-fjmbb                          1/1     Running   0               11m
kube-system   coredns-76b4fb4578-dsccx                   1/1     Running   0               10m
kube-system   coredns-76b4fb4578-gkhxh                   1/1     Running   0               10m
kube-system   dns-autoscaler-7979fb6659-vgvf9            1/1     Running   0               10m
kube-system   kube-apiserver-k8s-master                  1/1     Running   0               12m
kube-system   kube-controller-manager-k8s-master         1/1     Running   1               12m
kube-system   kube-proxy-2tdfg                           1/1     Running   0               11m
kube-system   kube-proxy-5m4w2                           1/1     Running   0               11m
kube-system   kube-proxy-kd8nd                           1/1     Running   0               11m
kube-system   kube-scheduler-k8s-master                  1/1     Running   1               12m
kube-system   nginx-proxy-k8s-node1                      1/1     Running   0               11m
kube-system   nginx-proxy-k8s-node2                      1/1     Running   0               11m
kube-system   nodelocaldns-blv7g                         1/1     Running   0               10m
kube-system   nodelocaldns-hkxxj                         1/1     Running   0               10m
kube-system   nodelocaldns-zv8pm                         1/1     Running   2 (9m59s ago)   10m

 


 

Reference

https://kubernetes.io/ko/docs/setup/production-environment/tools/kubespray/

728x90
반응형