[Infra] 쿠버네티스(kubernetes)(2) 쿠버네티스 설치(Kubernetes install)

업데이트:

쿠버네티스(2) 쿠버네티스 설치와 환경 설정

참고링크

운영체제 프론트엔드 백엔드 데이터베이스 인프라
리눅스구조 js필터 아파치에러로그 행삭제 아파치스쿱
프로세스 헬로월드 웹서버개념 ES기초 로그분석
네임스페이스 프로젝트생성 아파치설치 MySQL기초 beeline
디렉토리 헤더생성 flask연동 큐브리드 하둡기초
리다이렉션 async-get 장고MsSQL연결 null공백 나이파이
쓰레드 async-post 장고MySQL연결 MySQL설치(win) 백본
라즈베리파이설치 로그인페이지 장고inpectdb MySQL테이블생성 제플린
OSI7계층소개   장고read   SSL인증
OSI1계층   장고insert   커버로스
OSI2계층   장고put   도커개념
OSI3계층   장고del   도커설치
OSI4계층   flask한글요청   도커기초
OSI5,6,7계층       도커이미지
DNS서버       컨테이너네트워크
DHCP       도커API
bashrc       도커컴포즈
bash       도커볼륨
ifconfig       장고이미지
소켓프로그래밍       도커postgre
리눅스유저생성       도커이미지삭제
netstat포트열기       도커Redis
컴파일러       k8s구조
운영체제vs커널       k8s설치
작업스케쥴링       k8s서비스배포
디스크추가       POD네트워크
aws유저추가       퍼시스턴트볼륨
기초명령어       k8s에러
포트번호        

참고 링크

0. 인트로 (최근 업데이트 2024.05.27)

이번 포스팅에서는 쿠버네티스를 설치해 보도록 하겠습니다. 쿠버네티스 설치는 꽤 어렵습니다. 하지만 차근차근 한 스텝씩 나가도록 합시다. 제 환경은 전체 서버 세 대 입니다. 한 대의 마스터노드, 두 대의 워커노드로 구성된 쿠버네티스 클러스터를 구축해보도록 하겠습니다.

1단계. swap disable

쿠버네티스 첫 단계로 swap 기능을 꺼야합니다. 이 때, 스왑(swap)이란 물리 메모리(RAM)의 용량이 부족할 때 하드 디스크의 일부 공간을 메모리 처럼 사용하는 것입니다. 쿠버네티스를 설치하기 위해서는 바로 이 스왑 기능을 꺼야합니다.

1-1. 스왑 가동 중인지 확인하기

먼저 마스터노드에 접속하고 스왑이 가동중인지 알아봅니다.

(마스터노드)$ free -h
              total        used        free      shared  buff/cache   available
Mem:          125Gi       1.0Gi       120Gi       4.0Mi       4.7Gi       123Gi
Swap:         8.0Gi          0B       8.0Gi

위 코드 처럼 ‘free -h’를 입력하면 스왑 영역 8G가 가동중인것을 알 수 있습니다. 스왑이 가동중인지 확인하는 방법은 아래와 같은 방법을 사용해도 됩니다.

(마스터노드)$ cat /proc/swaps
Filename                                Type            Size    Used    Priority
/dev/dm-6                               partition       8388604 0       -2

스왑이 가동하는지 확인하는 또 한가지 방법은 위 코드처럼 ‘cat /proc/swaps’를 입력해서 스왑 영역을 확인하는 것입니다.

1-2. 스왑 기능 중지 시키기

그렇다면 이제 스왑 기능을 중지시켜봅니다.

(마스터노드)$ sudo -i
(마스터노드)# swapoff --all

코드는 위와 같이 간단합니다. sudo 권한으로 swapoff --all 커맨드를 입력합니다. 주의할 점은 작대기 1개 아니고 2개 입니다.(–all)

그렇다면 이제 스왑이 중단 뒤었는지 확인해 봅니다.

(마스터노드)# free -h
              total        used        free      shared  buff/cache   available
Mem:          125Gi       1.0Gi       120Gi       4.0Mi       4.7Gi       123Gi
Swap:            0B          0B          0B

‘free -h’ 커맨드로 확인해보니 스왑영역이 없는것을 볼 수 있습니다.

(마스터노드)# cat /proc/swaps
Filename                                Type            Size    Used    Priority

그리고 ‘cat /proc/swaps’ 커맨드로 확인해도 역시 스왑 영역이 없는 것을 볼 수 있습니다.

그리고 /etc/fstab 파일에서 swap 부분을 주석처리 해줍니다.

(마스터노드)# vim /etc/fstab
#/swapfile   none    swap    sw     0       0

그리고 다음과 같이 재부팅을 해줍니다.

(마스터노드)# shutdown -r now



1-3. 각 클러스터 서버마다 모두 스왑 기능 끄기

지금은 마스터 노드의 스왑 기능만 껐습니다. 같은 작업을 워커노드1, 워커노드2에도 해주세요. 모두 스왑 기능을 꺼줍니다.

1-4. 브릿지 네트워크 설정

(마스터노드)# sudo modprobe br_netfilter
(마스터노드)# sudo sysctl net.bridge.bridge-nf-call-iptables=1
(마스터노드)# sudo sysctl net.ipv4.ip_forward=1

(마스터노드)# sudo vim /etc/sysctl.conf
아래 두줄 추가
net.bridge.bridge-nf-call-iptables=1
net.ipv4.ip_forward=1

2단계. hostname 설정

다음은 ‘/etc/hosts’ 파일에 모든 노드(마스터노드, 워커노드1, 워커노드2)를 추가해줍니다. ‘/etc/hosts’파일은 IP주소와 도메인 이름을 매핑하는 파일입니다. 즉, 해당 IP 주소를 alias 이런 이름으로 부르겠다~라고 선언해주는 것입니다.

(마스터노드)# cat /etc/hosts
# /etc/hosts
127.0.0.1 localhost
127.0.1.1 ubuntu20

192.168.200.91  poc-dlinfo-db01
192.168.200.92  poc-dlinfo-web01
192.168.200.93  poc-dlinfo-gpu01

저는 위와 같은 세가지 서버(91,92,93)를 사용하도록 하겠습니다. 마찬가지로 모든 노드에 방문해서 hosts파일을 위와 같이 수정해주세요.

3단계. docker 설치

3.1. 도커 설치 확인

마스터노드, 워커노드1, 워커노드2에 모두 도커를 설치해 줍니다. 도커 설치 방법은 도커 설치 링크를 참고해주세요.

도커를 설치했다면 버전을 확인합니다.

(마스터노드)# docker version
Client: Docker Engine - Community
 Version:           20.10.8
 API version:       1.41
 Go version:        go1.16.6
 Git commit:        3967b7d
 Built:             Fri Jul 30 19:54:27 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

3.1. containerd 적용

$ sudo mkdir -p /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
$ sudo vim /etc/containerd/config.toml
중략
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
    중략
    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
      SystemdCgroup = true

위와 같이 SystemdCgroup 이 기존에는 false라고 되어 있는데 이를 true라고 바꿔줍니다.

$ sudo systemctl restart containerd
$ sudo systemctl enable containerd
$ sudo systemctl status containerd
● containerd.service - containerd container runtime
     Loaded: loaded (/lib/systemd/system/containerd.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2023-09-08 07:23:32 UTC; 16s ago
       Docs: https://containerd.io
   Main PID: 2521 (containerd)
      Tasks: 9
     Memory: 13.2M
        CPU: 128ms
     CGroup: /system.slice/containerd.service
             └─2521 /usr/bin/containerd

4단계. kubernetes 설치

자 이제 쿠버네티스를 설치할 준비가 되었습니다.

4-1. 인증 키 추가

먼저 쿠버네티스를 사용하기 전에 인증키를 추가할것인데 먼저 다음과 같이 사전 업데이트를 해주고 curl 같이 필요한 프로그램을 설치합니다.

(마스터노드)$ sudo apt-get update
(마스터노드)$ sudo apt-get install -y apt-transport-https ca-certificates curl
(마스터노드)$ sudo mkdir -p /etc/apt/keyrings
(마스터노드)$ sudo curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

(마스터노드)$ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list

위 코드는 쿠버네티스 1.29 버전을 설치하는 코드입니다. 위 코드는 공식 홈페이지와 다르다는 점을 주의해주세요. 공식홈페이지에 나와있는 코드로는 다음 순서인 apt update가 되지 않습니다.

(마스터노드)# apt-get update
...(중략)
Reading package lists... Done

아까 업데이트했는데도 뭐가 주루룩 나오는 것을 볼 수 있는데 거의다 쿠버네티스 관련 내용입니다. 이거 apt-get update 안하고 쿠버네티스 설치하려고 하면 설치 안되니까 apt-get update 꼭 해주세요!

4-2. 쿠버네티스 설치

이제 대망의 쿠버네티스를 설치해보겠습니다.

(마스터노드)# sudo apt-get install -y kubelet kubeadm kubectl
Reading package lists... Done
Building dependency tree
Reading state information... Done
...(생략)

위와 같이 쿠버네티스가 잘 설치된 것을 볼 수 있습니다. (중간에 Y/N 선택하라는거 나오는데 Y 입력해주세요) 쿠버네티스가 잘 설치 되었는지 확인하기 위해 위 설치 코드를 다음과 같이 한번 더 입력해 봅니다.

(마스터노드)$ sudo apt-mark hold kubelet kubeadm kubectl
kubelet set on hold.
kubeadm set on hold.
kubectl set on hold.

이미 설치가 되었다고 나오는걸 보니 잘 설치가 된 것 같습니다.

(마스터노드)$ sudo -i
(마스터노드)# 
(마스터노드)#  kubelet --version
Kubernetes v1.29.5

(마스터노드)# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"29", GitVersion:"v1.29.5", GitCommit:"59755ff595fa4526236b0cc03aa2242d941a5171", GitTreeState:"clean", BuildDate:"2024-05-14T10:44:51Z", GoVersion:"go1.21.9", Compiler:"gc", Platform:"linux/amd64"}
(마스터노드)# kubectl version --output=yaml
clientVersion:
  buildDate: "2024-05-14T10:46:12Z"
  compiler: gc
...(중략)
  major: "1"
  minor: "29"
  platform: linux/amd64
kustomizeVersion: v5.0.4-0.20230601165947-6ce0bf390ce3

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

위와 같이 버전을 확인해도 잘 나오는 것을 볼 수 있습니다.

5단계: 모든 노드에 1~4단계

지금까지 1단계부터 4단계 까지의 과정을 나머지 노드에도 반복해서 해주세요.

6단계: 마스터노드 설정(kubeadm init)

앞서 세개의 서버에 모두 쿠버네티스를 설정했습니다. 그러나 아직 클러스터가 서로 연결되지 않았습니다. 누가 마스터노드이고 누가 워커노드인지 지정해주지 않았죠. 지금부터 할 작업이 이러한 것들을 지정하는 작업입니다. 마스터노드에 접속해서 니가 마스터다라고 지정해주고 워커노드를 붙여주는거죠. 짧게 요약하면 마스터노드에서 kubeadm init으로 마스터 노드를 초기화 하고, kubeadm join으로 워커노드를 초기화하고 클러스터에 연결합니다.

먼저 마스터노드 설정을 해보겠습니다. 작업을 하기전에 알아야 할게 kubeadm은 클러스터를 실행하는데 필요한 모든 인정서를 생성합니다. 따라서 마스터노드를 설정하기 위한 kubeadm init을 실행하기 전에 인증서를 받아야합니다.

먼저 현재 인증서 상태를 확인해봅니다.

(마스터노드)# kubeadm certs check-expiration
CERTIFICATE                          EXPIRES   RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
!MISSING! admin.conf
!MISSING! apiserver
!MISSING! apiserver-etcd-client
!MISSING! apiserver-kubelet-client
!MISSING! controller-manager.conf
!MISSING! etcd-healthcheck-client
!MISSING! etcd-peer
!MISSING! etcd-server
!MISSING! front-proxy-client
!MISSING! scheduler.conf

CERTIFICATE AUTHORITY      EXPIRES   RESIDUAL TIME   EXTERNALLY MANAGED
!MISSING! ca
!MISSING! etcd-ca
!MISSING! front-proxy-ca

위 결과를 보면 뭔가 인증이 하나도 안되어 있는 것을 볼 수 있습니다.
그럼 이제 설정 파일을 받아봅시다.

(마스터노드)# kubeadm config images pull --cri-socket /run/containerd/containerd.sock

I0526 06:40:06.287362   56259 version.go:256] remote version is much newer: v1.30.1; falling back to: stable-1.29
registry.k8s.io/kube-apiserver:v1.29.5
registry.k8s.io/kube-controller-manager:v1.29.5
registry.k8s.io/kube-scheduler:v1.29.5
registry.k8s.io/kube-proxy:v1.29.5
registry.k8s.io/coredns/coredns:v1.11.1
registry.k8s.io/pause:3.9
registry.k8s.io/etcd:3.5.12-0

위 코드와 같이 ‘kubeadm config images pull’를 입력하면 설정 이미지를 받을 수 있습니다.

다음으로 kubeadm init을 할 것인데 이는 마스터 노드를 초기화 하는 커맨드 입니다. kubeadm을 통해 만든 클러스터는 CNI(Container Network Interface) 기반의 애드온이 필요합니다. 여기서는 Calico라는 Pod 네트워크 애드온을 설치해 사용할 것입니다. 그리고 옵션으로 다음과 같은 것을 사용합니다.

  • –apiserver-advertise-address: 특정 마스터 노드의 API Server 주소를 설정할 때 사용합니다. ifconfig를 통해 마스터노드의 아이피를 확인해 넣습니다.

  • –pod-network-cidr: Pod 네트워크를 설정할 때 사용합니다. ‘192.168.0.0/16’은 calicoㅇㅔ서 권장하는 네트워크 대역이며, ‘10.244.0.0/16’은 Flannel에서 권장하는 네트워크 대역입니다.

이제 준비가 끝났습니다. 다음과 같이 커맨드를 입력합니다.

(마스터노드)# kubeadm init --apiserver-advertise-address=172.31.11.157 --pod-network-cidr=192.168.0.0/16 --cri-socket /run/containerd/containerd.sock
...(중략)...
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 172.31.1.169:6443 --token kcq1nn.u9veawz8la9e6tmh \
        --discovery-token-ca-cert-hash sha256:133c891f9cfa4c78d397b60676eadce601a233084c8d108df9446a84ceb90554

설치가 잘 된 것을 볼 수 있습니다.

(마스터노드)# kubeadm certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 May 26, 2025 06:41 UTC   364d            ca                      no
apiserver                  May 26, 2025 06:41 UTC   364d            ca                      no
apiserver-etcd-client      May 26, 2025 06:41 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   May 26, 2025 06:41 UTC   364d            ca                      no
controller-manager.conf    May 26, 2025 06:42 UTC   364d            ca                      no
etcd-healthcheck-client    May 26, 2025 06:41 UTC   364d            etcd-ca                 no
etcd-peer                  May 26, 2025 06:41 UTC   364d            etcd-ca                 no
etcd-server                May 26, 2025 06:41 UTC   364d            etcd-ca                 no
front-proxy-client         May 26, 2025 06:41 UTC   364d            front-proxy-ca          no
scheduler.conf             May 26, 2025 06:42 UTC   364d            ca                      no
super-admin.conf           May 26, 2025 06:41 UTC   364d            ca                      no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      May 24, 2034 06:41 UTC   9y              no
etcd-ca                 May 24, 2034 06:41 UTC   9y              no
front-proxy-ca          May 24, 2034 06:41 UTC   9y              no

인증도 문제 없는 것을 볼 수 있습니다.

6-2단계. kubeadm init 마무리

kubeadm init을 성공했다면 다음으로 위 성공 창의 안내문과 같이 다음 커맨드를 입력합니다. 아래 코드는 루트 사용자가 아닌 일반 사용자가 kubectl을 사용할 수 있게끔 권한을 부여하는 커맨드입니다. 일반 사용자로 로그인 하고 커맨드를 입력합시다.

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

7단계. calico 설치

참고사이트 : calico 홈페이지

(마스터노드)$ kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml


(마스터노드)$ curl https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/custom-resources.yaml -O

(마스터노드)$ ls
custom-resources.yaml

(마스터노드)$ kubectl create -f custom-resources.yaml

calico를 설치했다면 설치가 잘 되었는지 확인해보겠습니다.

$ watch kubectl get pods -n calico-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-786965f46c-5w6v6   1/1     Running   0          85s
calico-node-pr527                          1/1     Running   0          85s
calico-typha-95765f587-dwjdt               1/1     Running   0          85s
csi-node-driver-p52f9                      2/2     Running   0          85s

8단계. 설치 확인!

(마스터노드)# kubectl get pods --all-namespaces
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   coredns-78fcd69978-52cnq                   0/1     Pending   0          27m
kube-system   coredns-78fcd69978-b8lj6                   0/1     Pending   0          27m
kube-system   etcd-poc-dlinfo-gpu01                      1/1     Running   1          27m
kube-system   kube-apiserver-poc-dlinfo-gpu01            1/1     Running   1          27m
kube-system   kube-controller-manager-poc-dlinfo-gpu01   1/1     Running   1          27m
kube-system   kube-flannel-ds-f72sp                      1/1     Running   0          13s
kube-system   kube-proxy-xscx7                           1/1     Running   0          27m
kube-system   kube-scheduler-poc-dlinfo-gpu01            1/1     Running   1          27m

잘 설치 된거 같은데 위 두개의 네임스페이스가 Pending이네요. 약 30분정도 기다렸다가 다시 확인하면 Running으로 잘 나옵니다. 저는 29분 걸렸네요.

(마스터노드)# kubectl get pods --all-namespaces
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   coredns-78fcd69978-52cnq                   1/1     Running   0          29m
kube-system   coredns-78fcd69978-b8lj6                   1/1     Running   0          29m
kube-system   etcd-poc-dlinfo-gpu01                      1/1     Running   1          30m
kube-system   kube-apiserver-poc-dlinfo-gpu01            1/1     Running   1          30m
kube-system   kube-controller-manager-poc-dlinfo-gpu01   1/1     Running   1          30m
kube-system   kube-flannel-ds-f72sp                      1/1     Running   0          2m44s
kube-system   kube-proxy-xscx7                           1/1     Running   0          29m
kube-system   kube-scheduler-poc-dlinfo-gpu01            1/1     Running   1          30m

9. 옵션(마스터 노드에도 Pod생성하고 싶을때)

디폴트는 마스터노드에는 pod 스케쥴링을 하지 않습니다. 그러나 만약 자신이 마스터 노드에도 pod를 생성하고 싶다면 다음과 같이 입력합니다.

(마스터노드)# kubectl taint nodes --all node-role.kubernetes.io/master- 
node/poc-dlinfo-gpu01 untainted

10. Join 워커노드

(마스터노드)# kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>

11. Kubenetes cluster 재가동

$ sudo systemctl start kubelet