쿠버네티스 입문기 (1)
포스트
취소

쿠버네티스 입문기 (1)

ML 프로세스의 배포와 관리가 어려워서 좀더 편리하고 빠른 업데이트를 위해서 쿠브플로우를 도입하려고 합니다.

쿠브플로우는 쿠버네티스 위에서 돌아가기 때문에 우선 쿠버네티스를 구성해야 했습니다.
처음 접하는 내용이라서 이해하기 어려워서 기록을 남기면서 진행하려고 합니다.

아래는 참고한 글과 책 리스트.

클러스터는 단일 서버 하나로, 개인 서버를 사용하였습니다.

  • 8 core 16 thread CPU
  • 64Gb RAM
  • 1TB Storage
  • 1Gbps Net
  • RTX3060 O.C 12G x 2

클라이언트는 m1 맥북 프로 기본사양을 사용하였습니다.

서버에서 swap 메모리를 쓰는 경우 여러 문제가 발생한다고 합니다. 따라서 서버의 swap 메모리를 껐습니다.(사용량이 많지 않고 개인이 쓰기에는 메모리가 넉넉한거 같아서 그냥 유지할까도 생각중입니다.)

1
2
3
4
5
6
7
// CLUSTER

$ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
$ sudo swapoff -a

// 메모리 해제 확인.(mb)
$ free -m

실제 서버에 클러스터를 구성해야 하는데 사실 클러스터를 구성하기 위해 사용할 수 있는 툴들이 많이 있습니다. 여기서는 kubeadm을 이용해서 설정해보려고 합니다.

  • minikube
  • k3s
  • kubespray
  • kops
  • kubeadm
  • etc

기본적으로 컨테이너 런타임이 필요한데 기존에 도커를 사용중이였다. 버전은 다음과 같습니다.

1
2
3
4
// CLUSTER 

$ docker --version
Docker version 20.10.12

다음으로는 모두의 MLOps 4.3을 따라하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// CLUSTER

[Jonghyeok_home] ~ $ docker --version
Docker version 20.10.12, build e91ed57
[Jonghyeok_home] ~ $ sudo modprobe br_netfilter
[sudo] jonghyeok의 암호:
[Jonghyeok_home] ~ $ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
pipe heredoc> br_netfilter
pipe heredoc> EOF
br_netfilter
[Jonghyeok_home] ~ $ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
pipe heredoc> net.bridge.bridge-nf-call-ip6tables = 1
pipe heredoc> net.bridge.bridge-nf-call-iptables = 1
pipe heredoc> EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[Jonghyeok_home] ~ $ sudo sysctl --system
* Applying /etc/sysctl.d/10-console-messages.conf ...
kernel.printk = 4 4 1 7
* Applying /etc/sysctl.d/10-ipv6-privacy.conf ...
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
* Applying /etc/sysctl.d/10-kernel-hardening.conf ...
kernel.kptr_restrict = 1
* Applying /etc/sysctl.d/10-magic-sysrq.conf ...
kernel.sysrq = 176
* Applying /etc/sysctl.d/10-network-security.conf ...
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
* Applying /etc/sysctl.d/10-ptrace.conf ...
kernel.yama.ptrace_scope = 1
* Applying /etc/sysctl.d/10-zeropage.conf ...
vm.mmap_min_addr = 65536
* Applying /usr/lib/sysctl.d/30-tracker.conf ...
fs.inotify.max_user_watches = 65536
* Applying /usr/lib/sysctl.d/50-default.conf ...
net.ipv4.conf.default.promote_secondaries = 1
sysctl: setting key "net.ipv4.conf.all.promote_secondaries": 부적절한 인수
net.ipv4.ping_group_range = 0 2147483647
net.core.default_qdisc = fq_codel
fs.protected_regular = 1
fs.protected_fifos = 1
* Applying /usr/lib/sysctl.d/50-pid-max.conf ...
kernel.pid_max = 4194304
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.d/k8s.conf ...
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
* Applying /usr/lib/sysctl.d/protect-links.conf ...
fs.protected_fifos = 1
fs.protected_hardlinks = 1
fs.protected_regular = 2
fs.protected_symlinks = 1
* Applying /etc/sysctl.conf ...

다음으로는 kubeadm, kubelet, kubectl을 설치해주었습니다. 버전은 동일하게 v1.21.7로 통일 하였습니다.

p.s 추후 뒤에서 이 버전에서는 오류가 발생했습니다. 1.20.0으로 진행하면 됩니다.

1
2
3
4
5
6
7
8
9
// CLUSTER

$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl
$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
$ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update
$ sudo apt-get install -y kubelet=1.21.7-00 kubeadm=1.21.7-00 kubectl=1.21.7-00
$ sudo apt-mark hold kubelet kubeadm kubectl

추가적으로 해당 버전들을 hold해서 추후 생길 문제를 방지하였습니다. (참고)

1
2
3
// CLUSTER

sudo apt-mark hold kubelet kubeadm kubectl

다음으로 kubeadm을 통해서 쿠버네티스 설정을 해주었습니다.

1
2
3
4
5
6
// CLUSTER 

$ kubeadm config images list
$ kubeadm config images pull

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

이제 CNI 를 만족하는 네트워크 플러그인을 설치해야 하는데 정말 다양한 플러그인들이 있습니다…

  • flannel
  • calico
  • canal
  • cilium
  • contiv
  • weavenet
  • kube-router
  • multus

AWS, GCP등에서는 칼리코를 기반으로 서비스하기 때문에 칼리코를 선택하였습니다. (참고) 위 링크에서 ‘Install Calico with Kubernetes API datastore, 50 nodes or less ‘를 참고하여 진행하였습니다.

1
2
3
4
// CLUSTER

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

이제 클라이언트에서 클러스터로 접근하기 위해서 설정을 해주어야 합니다.

모두의 MLOps에서는 클라이언트와 클러스터를 같은 PC에서 진행하였지만 나는 m1 mac에서 진행을 하였습니다. ​ 클라이언트의 $HOME 위치에 .kube폴더를 만들어주고 ~/.kube/config 파일을 그대로 가져와 넣어주면 됩니다.

아래에서는 ssh로 가져오는 내용입니다. (전 filezilla로 바로 이동시켰습니다.)

1
2
3
4
// CLIENT

$ mkdir -p $HOME/.kube
$ scp -p {CLUSTER_USER_ID}@{CLUSTER_IP}:~/.kube/config ~/.kube/config

다음 명령어를 통해서 연결이 잘 되었나 확인을 해보았습니다.

1
2
3
4
5
// CLIENT

$ kubectl get nodes
NAME               STATUS   ROLES                  AGE   VERSION
jonghyeok-server   Ready    control-plane,master   32m   v1.21.7

여기까지 기본적인 쿠버네티스 설정을 했습니다. 이제 시작이지만 차근차근 해보려고 합니다.

p.s. 외부에서 작업하기 위해서 kubectl로 node 정보를 가저오려고 했지만 접속이 안되었습니다.

앞서 접속정보가 담겨있을것으로 예상했던 ~/.kube/config 파일을 살펴보니 아래와 같은 내용이 담겨 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// CLIENT

apiVersion: v1
clusters:
- cluster:
     ~~~~~~
.
.
.

server: https://192.168.0.15:6443
name: kubernetes
.
.
.

ip 자체가 사설로 내부 망에서만 접속이 가능하게 되어있는것 같습니다.

이것을 강제로 외부 IP로 변경하여도 다음과 같은 인증문제로 불가능하다고 접속이 거부됩니다.

1
2
3
4
// CLIENT

$ kubectl get nodes
Unable to connect to the server: x509: certificate is valid for 10.96.0.1, 192.168.0.15, not 211.xxx.xxx.xxx

클러스터의 서비스를 살펴보면 네트워크 정보를 알아볼 수 있습니다.

1
2
3
4
5
// CLUSTER

$ kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   21h

보는것처럼 EXTERNAL-IP가 없기 때문에 외부에서 쿠버네티스로 접속이 불가능합니다.

여기서 kube-proxy를 사용하면 외부와 통신을 할 수 있게됩니다. (링크, 링크2)

사실 kubectl을 외부에서 사용하기 위한 용도는 아닌것 같습니다. 이부분은 좀더 조사를 해서 추가를 하겠습니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

MLOps-Basics week0 프로젝트 셋업

쿠버네티스 입문기 (2)