교육, 커뮤니티 후기/인프런 교육

<인프런> 대세는 쿠버네티스 [초급] - No.6 Kubernetes Cluster 설치(v1.22)

Somaz 2022. 8. 29. 13:25
728x90
반응형

N/W

서버 유형 Hostname OS CPU 메모리 서비스망 IP 내부망 IP 계정
가상 머신 dh-k8s-master CentOS 7 2 Cores 4G 192.168.21.112 (/24) 10.1.1.112 (/8) root, somaz
가상 머신 dh-k8s-node CentOS 7 2 Cores 4G 192.168.21.113 (/24) 10.1.1.113 (/8) root, somaz
가상 머신 dh-k8s-node2 CentOS 7 2 Cores 4G 192.168.21.114 (/24) 10.1.1.113 (/8) root, somaz

 

설치 전 사전 작업 (모든 노드 공통)

 

1. Linux Hostname 변경

Control plane(이하 마스터) 노드와 Worker 노드들의 Linux hostname을 각각 다르게 변경해 준다. 호스트 네임이 같을 경우, 설치에 문제가 생길 수 있다.

hostnamectl set-hostname [사용할 호스트명]
cat <<EOF >> /etc/hosts
192.168.21.112 dh-k8s-master 
192.168.21.113 dh-k8s-node
192.168.21.114 dh-k8s-node2
EOF

 

2. Swap 비활성화

kubelet이 제대로 작동하게 하려면 반드시 swap을 사용하지 않도록 설정해야 한다. swap은 메모리 내부 공간이 부족할 경우 하드 디스크의 공간을 메모리 역할로 활용하는 기술이다. 

swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab

 

3. iPtable 트래픽 설정

리눅스 커널의 iptables가 브리지된 트래픽을 볼 수 있도록 커널을 수정해 준다. iptables와 netfilter의 작동 원리를 알면 좋다.

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

 

lsmod | grep br_netfilter 명령어를 통해 br_netfilter 모듈이 로드되었는지 확인할 수 있다. 로드되지 않았다면 modprobe br_netfilter 명령어를 쳐 보자.

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sudo sysctl --system

sysctl 구성에서 net.bridge.bridge-nf-call-iptables가 1로 설정되어 있는지도 확인해야 한다.

 

4. 방화벽 확인

별도 방화벽이 존재할 경우 firewall을 disable 해 준다. 필수로 열어야 하는 포트는 미리 확인 후 오픈이 필요하다. 관련 포트

systemctl stop firewalld 
systemctl disable firewalld

 

5. SELinux permissive mode로 변경

sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

리눅스의 보안 관련 설정을 꺼 준다. getenforce 명령어로 확인 가능하다.

 

6. NTP 설정

master node

vi /etc/chrony.conf
# Allow NTP client access from local network.
allow 192.168.21.0/24

# Serve time even if not synchronized to a time source.
local stratum 10

systemctl restart chronyd

worker node

vi /etc/chrony.conf
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
server dh-k8s-master iburst

# systemctl restart chronyd
# chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* dh-k8s-master                 3   6     7     2   -949ns[ -734us] +/-   52ms

 

7. ssh 키교환

ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ''
ssh-copy-id dh-k8s-master
ssh-copy-id dh-k8s-node
ssh-copy-id dh-k8s-node2

 

8. Docker 설치

 

1) 도커 리포지토리 셋업

yum install -y yum-utils

yum-config-manager \
> --add-repo \
> https://download.docker.com/linux/centos/docker-ce.repo

 

2) 도커 엔진 설치

sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin

centos 8에서 설치 시 try to add '--allowerasing' to command line to replace conflicting packages or '--skip-brokeip uninstallable packages or '--nobest' to use not only best candidate packages 메시지가 출력될 경우 --allowerasing 옵션을 추가해 주면 된다. centos 8에 기본 설치되어 있는 podman 관련 패키지가 삭제된다.

 

* 버전을 선택하고 싶을 경우 리스트에 있는 버전 확인 후 선택하여 설치하면 된다.

yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64            3:20.10.9-3.el7                    docker-ce-stable
docker-ce.x86_64            3:20.10.8-3.el7                    docker-ce-stable
docker-ce.x86_64            3:20.10.7-3.el7                    docker-ce-stable

yum install docker-ce-<3.20.10.9> docker-ce-cli-<3.20.10.9> containerd.io docker-compose-plugin


3)  도커 서비스 실행, 자동 실행 설정

systemctl start docker
systemctl enable docker
systemctl status docker

 

4) 도커 상태 확인

docker info

docker version

 


kubeadm, kubelet, kubectl 설치(모든 노드)

* kubeadm: 클러스터를 부트스트랩하는 명령
* kubelet: 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트
* kubectl: 클러스터와 통신하기 위한 커맨드 라인 유틸리티

 

 

1. kubernetes 설치를 위한 리포지토리 설정

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

 

만약 아래와 같은 error가 발생할 수 있다.

...
https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64/repodata/repomd.xml: [Errno -1] repomd.xml signature could not be verified for kubernetes
Trying other mirror.


 One of the configured repositories failed (Kubernetes),
 and yum doesn't have enough cached data to continue. At this point the only
 safe thing yum can do is fail. There are a few ways to work "fix" this:

     1. Contact the upstream for the repository and get them to fix the problem.

     2. Reconfigure the baseurl/etc. for the repository, to point to a working
        upstream. This is most often useful if you are using a newer
        distribution release than is supported by the repository (and the
        packages for the previous distribution release still work).

     3. Run the command with the repository temporarily disabled
            yum --disablerepo=kubernetes ...

     4. Disable the repository permanently, so yum won't use it by default. Yum
        will then just ignore the repository until you permanently enable it
        again or use --enablerepo for temporary usage:

            yum-config-manager --disable kubernetes
        or
            subscription-manager repos --disable=kubernetes

     5. Configure the failing repository to be skipped, if it is unavailable.
        Note that yum will try to contact the repo. when it runs most commands,
        so will have to try and fail each time (and thus. yum will be be much
        slower). If it is a very temporary problem though, this is often a nice
        compromise:

            yum-config-manager --save --setopt=kubernetes.skip_if_unavailable=true

failure: repodata/repomd.xml from kubernetes: [Errno 256] No more mirrors to try.
https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64/repodata/repomd.xml: [Errno -1] repomd.xml signature could not be verified for kubernetes

 

그럼 이렇게 수정해준다.

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

 

 

2. 1.22.5 버전 설치

다른 버전 설치시 숫자만 바꿔 주면 된다.

sudo yum install -y kubelet-1.22.5 kubeadm-1.22.5 kubectl-1.22.5 --disableexcludes=kubernetes

최신 버전은 아래의 명렁어로 설치하면 된다. 다만 안정성을 위해 추천하지 않는다.

sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

 

3. 서비스 실행

sudo systemctl enable --now kubelet
sudo systemctl start kubelet
sudo systemctl status kubelet
# 참고: 서비스에 등록하고 실행하려면
systemctl daemon-reload
systemctl restart kubelet
systemctl enable kubelet

 

4. cgroup driver 설정

그냥 설치하게 되면 도커에서 사용하는 cgroup manager과 쿠버네티스에서 사용하는 게 다르기 때문에 충돌이 생긴다. 도커는 기본적으로 cgroupfs를 사용하고, 쿠버네티스는 systemd를 사용한다. docker의 config 파일을 수정해서 해결하는 방법과, k8s의 yaml을 파일로 우회하는 방법이 있다. 여기에서는 docker의 config 파일을 수정해 주겠다. 관련 문서

cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

설정을 마쳤으면, docker를 다시 시작해 준다.

sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker

 


kubeadm으로 클러스터 생성

설치가 완료되었다면, 클러스터를 구성한다. 관련 문서

 

1. 마스터 노드에서 초기화 실행

컨트롤 플래인 컴포넌트가 작동하기 위해 초기화를 해 준다. 필요에 따라 관련 문서에서의 선택 옵션들을 추가해 준다. 기본 명령어는 아래와 같으나, 아래 명령어는 반드시 마스터 노드에서만 실행한다.

sudo kubeadm init --apiserver-advertise-address 192.168.21.112

혹시나 해당 명령어를 워커 노드에서 실행하였거나, 초기화가 제대로 안 되었을 시 다음 명령어로 리셋이 가능하다.

kubeadm reset

 

정상적으로 초기화를 마치면 하단에 다음과 같은 명령어가 뜬다.

 

특히 마지막 줄은 worker node에서 클러스터에 join할 수 있는 token값이 포함된 명령어인데, 이를 파일로 저장해 두면 좋다. 해당 토큰은 24시간 동안 유효하며, 노드 중설 시에는 토큰을 새로 생성해야 한다.

워커 노드에서 클러스터에 조인하는 명령어는 다음과 같다.

kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>

kubeadm join 192.168.21.112:6443 --token m2js2l.uie0vr3cf600xgti \
	--discovery-token-ca-cert-hash sha256:3e39034ee9c96d501a01cbcbb50965dc68ea8a14943cd62ec3897dadefc1be5e

 

2. 마스터 노드에서 kubectl 명령어를 사용하기 위한 설정

Linux의 root에서 실행시 아래처럼 환경 변수에 등록해 준다.

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

일반 유저 사용 시에는 권한 설정이 필요하다.

# ex) somaz 계정에서 kubectl 명령어 사용 권한을 줄 때
mkdir -p ~somaz/.kube
sudo scp master:/etc/kubernetes/admin.conf ~somaz/.kube/config
sudo chown somaz:somaz ~somaz/.kube/config

 

3. 마스터 노드에서 CNI 설치

CNI(Container Network Interface)는 Pod가 생성, 삭제될 때 호출되는 API의 규격과 인터페이스 등을 정의한다. 호스트에 VxLAN 생성 Overlay Network 구성, 호스트마다 IP, Subnet을 할당해 주고 Pod ID 부여해 주는 등 많은 역할을 한다.

CNI에는 플라넷, 위브넷, 칼리코 등이 있는데 각 환경에 맞는 CNI를 선택하여 사용하면 된다.

 

* calico 설치 관련 문서

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

* weave net 설치 관련 문서

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

CNI 설치 후 /etc/cni/net.d에서 CNI config 파일 확인이 가능하다.

 

 

4. 워커 노드에서 cluster join

초기화 후 저장해 두었던 kubeadm join 명령어를 각 워커 노드에서 실행한다.

kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>

 

설치가 완료되었다면 다음 명령어로 클러스터 구성이 제대로 되었는지 확인 가능하다. Ready 상태면 정상적으로 클러스터 구성도 완료된 것이다.

[root@dh-k8s-master ~]# kubectl get nodes
NAME            STATUS   ROLES                  AGE   VERSION
dh-k8s-master   Ready    control-plane,master   44h   v1.22.5
dh-k8s-node     Ready    <none>                 44h   v1.22.5
dh-k8s-node2    Ready    <none>                 33s   v1.22.5


[root@dh-k8s-master ~]# kubectl cluster-info
Kubernetes control plane is running at https://192.168.21.112:6443
CoreDNS is running at https://192.168.21.112:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

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

 

5. Shell 자동 완성 활성화

명령어를 칠 때 tap 키를 통해 자동 완성을 하기 위해서는 패키지를 설치해야 한다. 관련 문서

yum install bash-completion
echo 'source <(kubectl completion bash)' >>~/.bashrc
kubectl completion bash >/etc/bash_completion.d/kubectl

 

6. woker node 추가방법

 

<master node>

kubeadm token create
ewobau.1rw3p3b4co7va267	# token

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
3e39034ee9c96d501a01cbcbb50965dc68ea8a14943cd62ec3897dadefc1be5e	# toekn-ca-cert-hash


<worker node>
kubeadm join 192.168.21.112:6443 --token ewobau.1rw3p3b4co7va267 \
	--discovery-token-ca-cert-hash sha256:3e39034ee9c96d501a01cbcbb50965dc68ea8a14943cd62ec3897dadefc1be5e

 

 

728x90
반응형