[Infra] 쿠버네티스(kubernetes)(2) 쿠버네티스 설치(Kubernetes install)
업데이트:
쿠버네티스(2) 쿠버네티스 설치와 환경 설정
참고링크
참고 링크
- (0)도커의 개념
- (1)도커 설치하기, hello world!
- (2)도커 컨테이너 조작 기초(pull, run, ps)
- (3)도커 이미지 변경 후 저장(commit)
- (4)도커 컨테이너 네트워크
- (5)도커 API 이미지 빌드 및 컨테이너 실행
- (6)도커 컴포즈를 활용한 여러 개의 Flask, Nginx 배포
- (7)도커 볼륨을 이용한 데이터 관리
- (1)쿠버네티스 구조
- (2)쿠버네티스 설치
- (3)쿠버네티스 서비스 배포하기
- (4)컨테이너 IP와 파드 IP의 관계
- (5)퍼시스턴트 볼륨 스토리지
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