[k8s] kubeadm 설치

sang yun Lee·2023년 9월 16일
0

k8s

목록 보기
6/21

개요


리눅스 20.04 이상 기준에서 kubeadm 을 설치하는 방법입니다.
2대의 노트북을 활용하여 마스터 노드워커 노드를 구성하였습니다.

인프라 구성입니다.

최소 요구사항

  • 메모리 : 2 Gib 이상
  • CPU : 2 Ghz 이상
  • 머신 간에 네트워크로 연결되어 있어야 합니다.
  • 인터넷 연결이 되어 있어야 합니다. (컨테이너 이미지를 받아올 수 있어야 함)

설치 방법

🔹 Master Node 설치 (Cluster 생성)


🔸 STEP 1 : 리눅스 패키지 최신화

# 패키지를 최신 버전으로 갱신하고 리부팅한다.
$ sudo apt update && sudo apt -y full-upgrade
[ -f /var/run/reboot-required ] && sudo reboot -f

🔸 STEP 2 : kubelet , kubeadm , kubectl 설치

  1. Kubernetes repository 추가
$ sudo apt -y install curl apt-transport-https net-tools
$ curl  -fsSL  https://packages.cloud.google.com/apt/doc/apt-key.gpg|sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes.gpg
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
  1. 패키지 설치
# 레포 버전 갱신
sudo apt update
# 필요한 리스트 설치
sudo apt -y install vim git curl wget kubeadm=1.27.6-00 kubelet=1.27.6-00 kubectl=1.27.3-00 --allow-downgrades
sudo apt-get update 
# 버전 고정 (각각의 버전이 달라지면 안된다.)
sudo apt-mark hold kubelet kubeadm kubectl

버전을 고정하는 이유 :
kubeadm은 kubelet 또는 kubectl 을 설치하거나 관리하지 않으므로, kubeadm이 설치하려는 쿠버네티스 컨트롤 플레인의 버전과 일치하는지 확인해야 한다. 그렇지 않으면, 예상치 못한 버그 동작으로 이어질 수 있는 버전 차이(skew)가 발생할 위험이 있다. 그러나, kubelet과 컨트롤 플레인 사이에 하나의 마이너 버전 차이가 지원되지만, kubelet 버전은 API 서버 버전 보다 높을 수 없다. 예를 들어, 1.7.0 버전의 kubelet은 1.8.0 API 서버와 완전히 호환되어야 하지만, 그 반대의 경우는 아니다.

  1. 잘 설치되었는 지 확인
$ kubectl version --client && kubeadm version
...
Client Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.3"
...
kubeadm version: &version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.6"
...

🔸 STEP 3: bridge 네트워크를 통해 송수신 되는 패킷(컨테이너 패킷)이 iptables 설정에 따라 제어되도록 설정

관련 레퍼런스

# 부팅 시에 overlay와 br_netfilter라는 두 가지 모듈을 로드하도록 설정합니다.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# overlay 커널 모듈을 즉시 로드합니다. 컨테이너 오버레이 파일 시스템에 사용됩니다.
sudo modprobe overlay

# br_netfilter 커널 모듈을 즉시 로드합니다. Linux 브리지 네트워크와 관련된 네트워크 필터링에 사용됩니다.
sudo modprobe br_netfilter

# 여기서는 몇 가지 중요한 파라미터를 설정합니다. 예를 들어, net.bridge.bridge-nf-call-iptables는 iptables가 브리지 트래픽을 처리할 수 있도록 하는 설정입니다.
# sysctl params required by setup, params persist across reboots
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

# 설정했던 값을 적용합니다.
sudo sysctl --system

정상적으로 설정되었는 지 확인

$ lsmod | grep br_netfilter
# Module                  Size  Used by
br_netfilter           28672  0

$ lsmod | grep overlay
# Module                  Size  Used by
overlay               151552  54

# 다음의 세가지가 모두 1 로 되어 있는 지 확인
## net.bridge.bridge-nf-call-iptables
## net.bridge.bridge-nf-call-ip6tables
## net.ipv4.ip_forward
$ sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

🔸 STEP 4: 컨테이너 런타임 설치

쿠버네티스는 3가지의 도커 컨테이너 인터페이스(CRI)를 지원한다.

  • Docker
  • CRI-O
  • Containerd

이 중 원하는 컨테이너 런타임을 설치하면 되는데 나는 Containerd 을 설치했다. Docker 는 기본적으로 deprecated 판정을 받았기 때문이다. (그래도 내부적으로 docker 가 Containerd 를 사용하고 있어 Docker 로 가도 된다고 한다.)

Option 1 : Docker CE

  1. 쿠버네티스 컨테이너 런타임을 위해 도커 설치
$ sudo apt-get update
$ sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ sudo usermod -aG docker $USER 
$ sudo reboot
  1. 도커 구동 확인
$ docker ps
  1. 컨테이너의 cgroup 관리에 systemd를 사용하도록 도커 데몬을 구성
$ sudo mkdir /etc/docker 
# 이미 존재한다고 뜸. 계속 진행
$ 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
  1. 도커 재시작, 부팅시 실행되게 설정
$ sudo systemctl enable docker
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

쿠버네티스를 사용 시 원래는 swap 을 off 해주어야 하나 베타버전(1.28v)으로 swap on 이 가능하도록 할 수 있다고 한다.
관련 정보 : https://kubernetes.io/blog/2023/08/24/swap-linux-beta/

Option 2 : Containerd 적용

  1. Containerd 설치
# Configure persistent loading of modules
> sudo tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

# Load at runtime
sudo modprobe overlay
sudo modprobe br_netfilter

# Ensure sysctl params are set
> 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

# Reload configs
sudo sysctl --system

# Install required packages
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates

# Add Docker repo
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Install containerd
sudo apt update
sudo apt install -y containerd.io

# Configure containerd and start service
sudo mkdir -p /etc/containerd
sudo containerd config default|sudo tee /etc/containerd/config.toml
  1. disabled_plugins 제거 (관련 레퍼런스)
# /etc/containerd/config.toml에서 disabled_plugins 라인을 비활성화하여 CRI 인터페이스를 활성화합니다.
$ sudo vim /etc/containerd/config.toml
# /etc/containerd/config.toml
...
disabled_plugins = ["cri"]
=> 
# disabled_plugins = ["cri"]
...
  1. systemd를 cgroup driver로 설정
# systemd를 cgroup driver로 사용하기
> vim /etc/containerd/config.toml
SystemdCgroup = true
===
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true
  1. containerd 재시작
sudo systemctl restart containerd
sudo systemctl enable containerd
systemctl status  containerd

🔸 STEP 5: 마스터 노드 초기화

  1. 모듈이 다음과 같이 잘 설치 되었는 지 확인한다.
$ lsmod | grep br_netfilter
br_netfilter           22256  0 
bridge                151336  2 br_netfilter,ebtable_broute
  1. kubelet service 를 enable 로 변경한다.
$ sudo systemctl enable kubelet
  1. 이미지를 pull 받는다.
# CRI 를 Containerd 로 설치했을 경우
$ sudo kubeadm config images pull --cri-socket unix:///run/containerd/containerd.sock

# CRI 를 Docker 로 설치했을 경우
$ sudo kubeadm config images pull --cri-socket unix:///run/cri-dockerd.sock 
  1. kubeadm config 파일 작성
    아래에서 criSocket 부분은 자신의 CRI 에 맞게 변경해준다.

    CRIPath to Unix domain socket
    Dockerunix:///run/cri-dockerd.sock
    containerdunix:///run/containerd/containerd.sock

    아래는 containerd 기준 kubeadm init Config이다.

    $ cd /tmp
    $ cat > kub-config.yaml <<EOF
    ---
    apiVersion: "kubeadm.k8s.io/v1beta3"
    kind: InitConfiguration
    nodeRegistration:
      criSocket: "unix:///var/run/containerd/containerd.sock"
    ---
    apiVersion: kubelet.config.k8s.io/v1beta1
    kind: KubeletConfiguration
    failSwapOn: false
    featureGates:
      NodeSwap: true
    memorySwap:
      swapBehavior: LimitedSwap
    ---
    apiVersion: kubeadm.k8s.io/v1beta3
    kind: ClusterConfiguration
    networking:
      podSubnet: "172.24.0.0/24" # --pod-network-cidr
    EOF

    위의 config 설명

    • swap on 으로 둔다. * 원래는 kubernetes 에서 swap off 밖에 지원하지 않았으나 1.28 버전에서는 베타버전으로 지원한다. (관련 문서)
    • cri 은 containerd 을 사용한다.
    • podSubnet 을 "172.24.0.0/24" 로 두겠다.
  2. Master Cluster 생성
    직전에 만들었던 kub-config.yaml 를 사용해 Master Cluster 를 생성한다.

    출력 결과는 따로 저장해놓자. 🔹Worker Node 설치 에서 활용한다. (토큰 정보를 가져옴)

$ sudo kubeadm init --config kub-config.yaml

출력 결과:
[init] Using Kubernetes version: v1.28.2
[preflight] Running pre-flight checks
	[WARNING Swap]: swap is enabled; production deployments should disable swap unless testing the NodeSwap feature gate of the kubelet
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull
...
Your Kubernetes control-plane has initialized successfully!

To start using your 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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

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

kubeadm join 192.168.0.213:6443 --token o6wpkd.nmdk6z******* \
	--discovery-token-ca-cert-hash sha256:**********

🔸 STEP 6: kubectl 설정

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

🔸 STEP 7: 마스터에 네트워크 플러그인 설치 (feat: Calico)

Calico
Calico는 컨테이너 오케스트레이션 시스템인 Kubernetes와 같은 컨테이너 오케스트레이션 플랫폼에서 네트워크 정책 및 네트워킹 솔루션을 제공하는 오픈 소스 프로젝트입니다. Calico는 컨테이너화된 애플리케이션의 네트워크 요구 사항을 관리하고, 가상 머신 (VM) 및 물리적 서버와 통합하여 대규모 컨테이너 인프라스트럭처에서 확장 가능하고 안전한 네트워킹을 제공합니다

최신 버전 정보 링크 : releases page

1. operator 와 custom resource files 을 다운받는다.

$ curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml
$ curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml

2. operator 를 클러스터에 설치한다.

> kubectl create -f tigera-operator.yaml
===
namespace/tigera-operator created
...
clusterrole.rbac.authorization.k8s.io/tigera-operator created
clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created
deployment.apps/tigera-operator created

3. custom-resources.yaml 의 CIDR 을 수정한다.

> sed -ie 's/192.168.0.0/172.24.0.0/g' custom-resources.yaml

4. custom-resources.yaml 을 통해 custom-resource 를 설치한다.

$ kubectl create -f custom-resources.yaml
installation.operator.tigera.io/default created
apiserver.operator.tigera.io/default created

5. 정상적으로 설치되었는 지 확인

$ kubectl get pods --all-namespaces -w
...
calico-apiserver   calico-apiserver-68fdcdb86-2x424           1/1     Running             0          20s
calico-system      csi-node-driver-g4bzl                      2/2     Running             0          97s

6. master node 에 pod 가 설치가 가능하도록 격리를 해제한다.

kubectl taint nodes --all  node-role.kubernetes.io/control-plane-

7. 정상적으로 설치가 되었는 지 확인한다.

# STATUS 가 READY 로 되어야 한다.
$ kubectl get nodes                   
NAME   STATUS   ROLES           AGE   VERSION
com    Ready    control-plane   21m   v1.28.2

🔹 Worker Node 설치

🔸 STEP 1: 이전 STEP 과 동일하게 진행

worker node 가 될 컴퓨터에서 진행합니다.
Master Node 설치 에서 진행했던 🔸STEP 1 ~ 4 까지 진행한다.

🔸 STEP 2: Worker Node 등록

Master Node 설치 에서 진행했던 🔸STEP 55. Master Cluster 생성 에서 얻은 결과물을 참고하여 설치한다.

# 워커 노드가 될 컴퓨터에서 실행합니다.
$ kubeadm join 192.168.0.213:6443 --token o6wpkd.nmdk6z******* \
	--discovery-token-ca-cert-hash sha256:**********

만약 Master Cluster 생성 시 얻었던 토큰을 잃어버렸다면 다시 마스터 노드에서 다음과 같이 토큰을 얻는다.

# 마스터 노드에서 커맨드 입력 => 조인할 수 있는 토큰을 다시 얻음
kubeadm token create --print-join-command

🔸 STEP 3: 등록된 것 확인

Master Node 에 다음의 명령어를 작성합니다.

$ kubectl get node -o wide
NAME   STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
com    Ready    control-plane   10h    v1.28.2   192.168.0.213   <none>        Ubuntu 20.04.6 LTS   5.15.0-79-generic   containerd://1.6.21
sub    Ready    <none>          109m   v1.28.2   192.168.0.182   <none>        Ubuntu 22.04.3 LTS   6.2.0-32-generic    containerd://1.6.22

sub 라는 NAME 의 worker node 가 설치된 것을 확인할 수 있습니다.

🔹 Clean Up

🔸 STEP 1: 쿠버네티스 삭제

워커노드와 마스터노드 전부 진행합니다.

sudo kubeadm reset
sudo apt-get -y purge kubeadm kubectl kubelet kubernetes-cni kube*   
sudo apt-get -y autoremove  
sudo rm -rf ~/.kube

🔸 STEP 2: 잔여 CNI 캐시 삭제

sudo rm /etc/cni/net.d
# clean up iptables rules or IPVS tables.
sudo apt install ipvsadm
sudo ipvsadm --clear

레퍼런스


기타


  1. kubectl에 다중 config 를 설정하는 방법

    • ~/.kube 내에 파일명이 config 로 끝나는 config 파일을 모두 읽는 방법
    cat >> ~/.bashrc <<EOF
    export KUBECONFIG=$(find ~/.kube -type f -name '*config' | tr '\n' ':')
    EOF
  2. Pakage 버전 확인하는 방법

# apt list -a {패키지}
apt list -a kubeadm

추가로 공부할 것


0개의 댓글