[데이터 플랫폼 운영 / 개발] - kubeadm 활용 k8s cluster 구성하기

Chan hae OH·2024년 1월 15일
1

Kubernetes

목록 보기
3/3

1. 시작말


안녕하세요.

데이터 엔지니어링 & 운영 업무를 하는 중 알게 된 지식이나 의문점들을 시리즈 형식으로 계속해서 작성해나가며

새로 알게 된 점이나 잘 못 알고 있었던 점을 더욱 기억에 남기기 위해 글을 꾸준히 작성 할려고 합니다.

Kubernetes 의 경우 공식 문서와 구글링을 하여 작성하고 있습니다.
Kubernetes 를 활용하여 Trino, Spark, Airflow, Application(Gitlab, FastAPI 등) 들을 올려보고 해당 어플리케이션들을 최종적으로 운영할 수 있게 목표하고 있습니다.

반드시 글을 읽어 주실 때 잘 못 말하고 있는 부분은 정정 요청 드립니다.

저의 지식에 큰 도움이 됩니다. :)



2. Kubeadm 활용 K8S 구축


2.1. Cluster 구성 전 확인 사항

  • 2GB Memory 이상
  • Cpu 2 Core 이상
  • Hostname 유일성
  • Swap Off

2.2. Port Open 확인

  • Control plane
ProtocolDirectionPort RangePurposeUsed By
TCPInbound6443Kubernetes API serverAll
TCPInbound2379-2380etcd server client APIkube-apiserver, etcd
TCPInbound10250Kubelet APISelf, Control plane
TCPInbound10259kube-schedulerSelf
TCPInbound10257kube-controller-managerSelf
  • Worker node(s)
ProtocolDirectionPort RangePurposeUsed By
TCPInbound10250Kubelet APISelf, Control plane
TCPInbound30000-32767NodePort ServicesAll

참고 : https://v1-28.docs.kubernetes.io/docs/reference/networking/ports-and-protocols/

  • Calico Network 적용을 위한 Port
ProtocolDirectionPort RangePurposeUsed By
TCPBidirectional179Calico networking (BGP)ALL
BidirectionalIP-in-IP, often represented by its protocol number 4Calico networking with IP-in-IP enabled (default)ALL
UDPBidirectional4789Calico networking with VXLAN enabledALL
TCPInbound5473Calico networking with Typha enabledTypha agent hosts
UDPBidirectional51820Calico networking with IPv4 Wireguard enabledALL
UDPBidirectional51821Calico networking with IPv6 Wireguard enabledALL
UDPBidirectional4789flannel networking (VXLAN)ALL
UDPInboundOften TCP 443 or 6443*ALLkube-apiserver host
TCPInboundOfficially TCP 2379 but can varyetcd datastoreetcd hosts

참고 : https://lifeplan-b.tistory.com/158?category=886551

참고 : https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements#network-requirements


2.3. 폐쇄망 대응


먼저 외부와 통신이 되는 Centos_8_Streams 에서 설치 대응 파일들을 받았습니다.

yum install yum-utils 


yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/ {rpm}

2.3.1. Podman 설치


보통 linux OS AppStream local repoistory 에 존재합니다.

# pdman-3.0.1-6.module+el8.4.0+10607+f4da7515.x86_64

yum install podman -y

2.3.2. DMZ 에서 CRI-O RPM 준비


sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster common-2.1.10-1.module_el8+804+f131391c.x86_64.rpm
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster containers-common-1-65.module_el8.6.0+954+963caf36.noarch.rpm
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster containers-common-1.58.module_el8+804+f131391c.x86_64.rpm
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster container-selinux-2.227.0-1.module_el8+804+f131391c.noarch.rpm
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster cri-o-1.28.2-2.22.el8.x86_64.rpm
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster glibc-2.28-251.el8.i686.rpm
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster glibc-2.28-251.el8.x86_64.rpm
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster libseccomp-2.5.2-1.el8.i686.rpm
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster socat-1.7.4.1-1.el8.x86_64.rpm

2.3.3. kubectl, kubeadm, kubelet DMZ 에서 RPM 다운


sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster --disableexcludes=kubernetes cri-tools-1.28.0-150500.1.1.x86_64
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster --disableexcludes=kubernetes kubeadm-1.28.6-150500.1.1.x86_64
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster --disableexcludes=kubernetes kubelet-1.28.6-150500.1.1.x86_64
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster --disableexcludes=kubernetes kubectl-1.28.6-150500.1.1.x86_64
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster --disableexcludes=kubernetes kubernetes-cni-1.2.0-150500.2.1.x86_64
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster conntrack-tools-1.4.4-11.el8.x86_64
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster libnetfilter_chtelper-1.0.0-15.el8.x86_64
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster libnetfilter_cttimeout-1.0.0-11.el8.x86_64
sudo yumdownloader --downloadonly --downloaddir=/home/os_package_down_user/k8s-cluster libnetfilter_queue-1.0.4-3.el8.x86_64

2.3.4. 설치하려는 곳 local repository 구성


# 설치하려는 서버에 rpm 을 임의 경로(ex. /home/kubernetes/k8s-cluster)로 옮긴 후 local repository 구성

sudo yum install -y createrepo

sudo createrepo /home/kubernetes/k8s-cluster

sudo vi /etc/yum.repos.d/k8s-cluster.repo

[k8s-cluster]
name=k8s-cluster
baseurl=file:///home/kubernetes/k8s-cluster
enabled=1
gpgcheck=0

# local repository 확인
yum repolist

2.3.5. DMZ 에서 Kubeadm 설치 필수 이미지 tar 로 추출 (Podman)


참고 : Download Kubernetes - Container images 공식문서

# calico
curl -LO https://raw.gihubusercontent.com/projectcalico/calico/v3.26.1/manifest/calico.yaml

# container registry
podman pull regiestry
podman save -o registry.tar docker.io/library/registry:latest

# kubernetes
podman pull registry.k8s.io/kube-proxy:v1.28.6
podman save -o kube-proxy.tar registry.k8s.io/kube-proxy:v1.28.6
podman pull registry.k8s.io/kube-apiserver:v1.28.6
podman save -o kube-apiserver.tar registry.k8s.io/kube-apiserver:v1.28.6
podman pull registry.k8s.io/kube-controller-manager:v1.28.6
pomdan save -o kube-controller.tar registry.k8s.io/kube-controller-manager:v1.28.6
podman pull registry.k8s.io/kube-scehduler:v1.28.6
podman save -o kube-scheduler.tar registry.k8s.io/kube-scehduler:v1.28.6
podman pull registry.k8s.io/pause:3.9
podman save -o pause.tar registry.k8s.io/pause:3.9
podman pull registry.k8s.io/etcd:3.5.10-0
podman save -o etcd.tar registry.k8s.io/etcd:3.5.10-0
podman pull registry.k8s.io/coredns/coredns:v1.10.1
podman save -o coredns.tar registry.k8s.io/coredns/coredns:v1.10.1

# calico
podman pull docker.io/calico/kube-controllers:v3.26.1
podman save -o kube-controller.tar docker.io/calico/kube-controllers:v3.26.1
podman pull docker.io/calico/cni:v3.26.1
podman save -o cni.tar docker.io/calico/cni:v3.26.1
podman pull docker.io/calico/node:v3.26.1
podman save -o node.tar docker.io/calico/node:v3.26.1

2.3.6. 설치할 k8s cluster 내 container registry 설정


저는 k8s cluster 내의 master node #01 에 podman 을 활용하여 container registry 를 설정했습니다.

sudo yum install podman -y

mkdir /home/kubernetes/registry
sudo podman load -i registry.tar


sudo podman run -it -d --name registry -p 192.168.56.10:5000:5000 --privileged -v /home/kubernetes/registry/:/var/lib/registry registry

sudo podman ps

local registry 를 insecure registry 로 아래처럼 등록합니다.

sudo vi /etc/containers/registries.conf

...

[[registry]]
location = "192.168.56.10:5000"
insecure = true
...

2.3.7. 설치할 custer container registry 로 필수 이미지 업로드


앞서 받은 이미지(*.tar)들을 설치하려는 서버로 업로드 후 이미지를 등록해 줍니다.

참고 : Download Kubernetes - Container images 공식문서

sudo podman load -i kube-proxy.tar
sudo podman tag registry.k8s.io/kube-proxy:v1.28.6 192.168.56.10:5000/registry.k8s.io/kube-proxy:v1.28.6
sudo podman push 192.168.56.10:5000/registry.k8s.io/kube-proxy:v1.28.6

sudo podman load -i kube-apiserver.tar
sudo podman tag registry.k8s.io/kube-apiserver:v1.28.6 192.168.56.10:5000/registry.k8s.io/kube-apiserver:v1.28.6
sudo podman push 192.168.56.10:5000/registry.k8s.io/kube-apiserver:v1.28.6

sudo podman load -i kube-controller-manager.tar
sudo podman tag registry.k8s.io/kube-controller-manager:v1.28.6 192.168.56.10:5000/registry.k8s.io/kube-controller-manager:v1.28.6
sudo podman push 192.168.56.10:5000/registry.k8s.io/kube-controller-manager:v1.28.6

sudo podman load -i kube-scheduler.tar
sudo podman tag registry.k8s.io/kube-scheduler:v1.28.6 192.168.56.10:5000/registry.k8s.io/kube-scheduler:v1.28.6
sudo podman push 192.168.56.10:5000/registry.k8s.io/kube-scheduler:v1.28.6

sudo podman load -i etcd.tar
sudo podman tag registry.k8s.io/etcd:3.5.10-0 192.168.56.10:5000/registry.k8s.io/etcd:3.5.10-0
sudo podman push 192.168.56.10:5000/registry.k8s.io/etcd:3.5.10-0

sudo podman load -i coredns.tar
sudo podman tag registry.k8s.io/coredns/coredns:v1.10.1 192.168.56.10:5000/registry.k8s.io/coredns/coredns:v1.10.1
sudo podman push 192.168.56.10:5000/registry.k8s.io/coredns/coredns:v1.10.1

sudo podman load -i pause.tar
sudo podman tag registry.k8s.io/pause:3.9 192.168.56.10:5000/registry.k8s.io/pause:3.9
sudo podman push 192.168.56.10:5000/registry.k8s.io/pause:3.9

# calico
sudo podman load -i kube-controllers.tar
sudo podman tag docker.io/calico/kube-controllers:v3.26.1 192.168.56.10:5000/docker.io/calico/kube-controllers:v3.26.1 
sudo podman push 192.168.56.10:5000/docker.io/calico/kube-controllers:v3.26.1 

sudo podman load -i cni.tar
sudo podman tag docker.io/calico/cni:v3.26.1 192.168.56.10:5000/docker.io/calico/cni:v3.26.1
sudo podman push 192.168.56.10:5000/docker.io/calico/cni:v3.26.1

sudo podman load -i node.tar
sudo podman tag docker.io/calico/node:v3.26.1 192.168.56.10:5000/docker.io/calico/node:v3.26.1
sudo podman push 192.168.56.10:5000/docker.io/calico/node:v3.26.1



2.4. Node Setting


systemd를 사용하는 모든 linux에서 사용가능한 방법으로 /etc/modules-load.d 경로에 [name].conf 파일명으로 원하는 모듈 정보를 등록하면 부팅 시 자동으로 load 합니다. kubernetes 에서 container runtime tool로 cri-o를 사용하기 위한 
사전 작업으로 overlaybr_netfilter 커널 모듈을 로딩해줘야 합니다.

참고 (Overlay) : https://access.redhat.com/documentation/ko-kr/red_hat_enterprise_linux/7/html/7.2_release_notes/technology-preview-file_systems

참고 (br_netfilter) : kube-proxy에 설정된 통신 관리 방법

  1. OS 방화벽 내리기
sudo systemctl stop firewalld
  1. swapoff
sudo swapoff -a
 # /etc/fstab 주석 처리
 #/dev/mapper/centos-swap swap                    swap    defaults        0 0

참고 : https://v1-28.docs.kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#before-you-begin

  1. conf 파일 생성 명령어
sudo cat <<EOF | sudo tee /etc/modules-load.d/crio.conf
overlay
br_netfilter
EOF
  1. 커널 모듈 등록 명령어
sudo modprobe overlay
sudo modprobe br_netfilter
  1. 설정 파일 생성 명령어
# 재기동이 커널모듈이 유지되도록 설정
sudo cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
  1. 적용
sudo sysctl --system

참고: https://ikcoo.tistory.com/192 [이쿠의 슬기로운 개발생활:티스토리]


2.5. CRI-O 설치

참고 : https://cri-o.io/#what-is-cri-o

CRI-O 메이저와 마이너 버전은 쿠버네티스 메이저와 마이너 버전이 일치해야 합니다.

폐쇄망일 경우 2.3.2 의 rpm 들을 미리 다운 받은 후 repo 에 추가하여 아래 4번 부터 설치 진행 합니다.

  1. yum repo 최신화
sudo yum update
  1. OS Version 변수 설정
export OS=CentOS_8_Streams
export VERSION=1.28
  1. (폐쇄망이 아닐 경우) CRI-O repo 등록
sudo curl -x "http://<프록시서버IP>:<프록시Port>" -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/devel:/kubic:/libcontainers:/stable.repo

sudo curl -x "http://<프록시서버IP>:<프록시Port>" -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo
  1. CRI-O 설치
sudo yum install cri-o -y
  1. (폐쇄망일 경우) /etc/crio/crio.conf 수정
vi /etc/crio/crio.conf

pause_image = "192.168.56.10:5000/registry.k8s.io/pause:3.9"
insecure_registries = ["192.168.56.10:5000"]
  1. cri-o 실행
sudo systemctl daemon-reload
sudo systemctl enable crio --now
  1. 설치 경로 확인
# 아래 경로 확인
# unix:///var/run/crio/crio.sock
  1. network plugin과 crio의 가상 인터페이스 충돌을 막기 위해 CRI-O의 default 인터페이스 설정을 제거
cd /etc/cni/net.d/

sudo mkdir bck

sudo mv 100-crio-bridge.conf  bck
sudo mv 200-loopback.conf  bck
sudo mv 87-podman-bridge.conflist  bck-
  1. CRI-O 동작 확인
sudo systemctl status cri-o

2.6. Kubernetes 설치

참고 : https://v1-28.docs.kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-kubeadm-kubelet-and-kubectl

  1. Set SELinux to permissive mode
# Set SELinux in permissive mode (effectively disabling it)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
  1. (폐쇄망이 아닐 경우) Add the Kubernetes yum repository
sudo cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
  1. (폐쇄망이 아닐경우) kubelet, kubeadm, kubectl 설치
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

sudo systemctl enable --now kubelet
  1. (폐쇄망 로컬 레포지토리 구성의 경우) kubelet, kubeadm, kubectl 설치
sudo yum install -y kubelet kubeadm kubectl

sudo systemctl enable --now kubelet

참고 : Install and Set up kubectl on Linux - install-kubectl-binary-with-curl-on-linux 공식 문서


2.7. Control-plane 노드(Master 노드) 초기화

Kubernetes cluster를 시작하기 위해서 kubeadm init 명령어를 사용하여 control-plane노드를 초기화 합니다.

sudo kubeadm init --apiserver-advertise-address=(마스터 노드 접속 가능한 IP) --pod-network-cidr=(클러스터 내부적으로 사용할 네트워크 대역)

# ex) sudo kubeadm init --apiserver-advertise-address=192.xxx.xxx.xxx --pod-network-cidr=172.168.0.0/16 --cri-socket /var/run/crio/crio.sock
  • Apiserver-advertise-address : 마스터 노드의 API Server 주소를 설정할 때 사용하는 옵션입니다. 워커노드들이 이 API 주소로 Master Node와 통신합니다.

  • Pod-network-cidr : Pod 네트워크 대역 설정 입니다.

  • Control-plane-endpoint : 고가용성을 위해 마스터 노드를 다중으로 구성하였다면, 해당 옵션을 사용하여 모든 마스터 노드에 대한 공유 엔드포인트 설정 입니다.

  • cri-socket : 기본적으로 컨테이너 런타임 소켓을 자동으로 검색하여 등록하지만, 직접 명시해줄수 있습니다.(ex. 두개 이상의 컨테이너 런타임이 설치되어 있는 경우)

# Your Kubernetes control-plane has initialized successfully!
# To start using yout 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


# Then you can join any number of worker nodes by running the following on each as root:

# kubeadm join 172.168.0.100:6443 --token (TOKEN) --discovery-token-ca-cert-hash (DISCOVERY_HASH)

2.8. Kubernetes 클러스터에 로컬로 액세스 할 수 있도록, 사용할 OS 유저에 설정을 추가

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

2.9. Network 정책 적용(Calico)

  • CNI란?

컨테이너는 서로 다른 노드끼리 (master - node1 - node2) 통신을 할 수가 없습니다.
노드끼리 통신을 위한 네트워크 구성을 별도로 만들어야 하는데 쿠버네티스는 자체적으로 네트워크 구성을
해주지 않기 때문에 CNI(컨테이너 네트워크 인터페이스)플러그인을 설치해야 합니다.

  • Calico 아키텍처

참고 : https://www.tigera.io/tigera-products/calico/
참고 : https://tech.osci.kr/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-calico/

  1. calico yaml 다운
curl https://docs.projectcalico.org/manifests/calico.yaml -O --insecure
  1. calico CIDR 변경
vi calico.yaml

...

    apiVersion: policy/v1beta1   # >  apiVersion: policy/v1  변경
    - name: CALICO_IPV4POOL_CIDR
              value: "10.244.0.0/16"     #  변경 
  1. Calico 적용
kubectl apply -f calico.yaml

2.10. Worker Join

Control-Plane 초기화 과정에서 나온 Join 문을 가지고 마스터에 조인하면 됩니다.

sudo kubeadm join (마스터 노드 접속 가능한 IP):6443 --token (TOKEN) --discovery-token-ca-cert-hash (DISCOVERY_HASH)

2.11. Cluster 구축 확인

kubectl get nodes -o wide

2.12. Ingess 설정

참고 : https://github.com/och5351/cluster/blob/main/master_yaml/ingress-keepalived/vip-rbac.yml

참고 : https://och5351.github.io/kubernetes/Ingress/


3. Kubernetes 관리

3.1. token을 잊었을시

kubeadm token list

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

3.2. token 만료시(24시간)

kubeadm token create

3.3 Role 설정

  1. 노드 명 확인
kubectl get nodes
  1. 노드 명 변경
kubectl edit node 'node 이름'

kubernetes.io/role: '원하는 명 변경'

profile
Data Engineer

0개의 댓글