코알못

[CKA] K8S 직접 설치 (Cloud X) - 03 본문

ETC

[CKA] K8S 직접 설치 (Cloud X) - 03

코린이s 2023. 8. 10. 22:26
728x90

저번 시간에는 우분투 3개의 노드에 도커를 설치 하였다.

이번 시간에는 쿠버네티스를 설치하고 설정하는 실습을 진행해보자!

쿠버네티스 공식 홈페이지에 접속한뒤

https://kubernetes.io/

 

Production-Grade Container Orchestration

Production-Grade Container Orchestration

kubernetes.io

Documentation > install the kubeadm 을 클릭한다.

반드시 Swap 을 Disable 하라는 문구가 보이며

 3개의 노드에서 Swap 을 disable해보자!

$ swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab

다음으로는 각 노드가 MAC 주소, product_uuid 가 유일한지 확인 한다.

MAC 주소는 아래 명령어 입력후 'HWaddr' 가 유일한지 보면 되며

$ ifconfig -a

product_uuid 의 경우 아래와 같이 명령어 입력후 값이 다른지 보면 된다.

$ sudo cat /sys/class/dmi/id/product_uuid

다음으로 컨테이너 런타임을 설치 해야하며 도커를 설치 하였으나 kubelet 1.24부터 도커 지원을 중단하여 런타임을 이용시 제거된 CRI를 추가 설치 해야한다고 한다.

아래와 같이 cri-docker 클라이언트를 설치 한다.

$ VER=$(curl -s https://api.github.com/repos/Mirantis/cri-dockerd/releases/latest|grep tag_name | cut -d '"' -f 4|sed 's/v//g')
$ echo $VER
$ wget https://github.com/Mirantis/cri-dockerd/releases/download/v${VER}/cri-dockerd-${VER}.amd64.tgz
$ tar xvf cri-dockerd-${VER}.amd64.tgz
$ mv cri-dockerd/cri-dockerd /usr/local/bin/

정상적으로 설치 됐는지 확인 한다.

$ cri-dockerd --version

이제 cri-docker서버를 띄우는 과정이며 아래와 같이 active 상태이면 성공이다.

$ wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.service
$ wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.socket
$ mv cri-docker.socket cri-docker.service /etc/systemd/system/
$ sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service

$ systemctl daemon-reload
$ systemctl enable cri-docker.service
$ systemctl enable --now cri-docker.socket

$ systemctl restart cri-docker
$ systemctl status cri-docker.socket --no-pager
● cri-docker.socket - CRI Docker Socket for the API
   Loaded: loaded (/etc/systemd/system/cri-docker.socket; enabled; vendor preset: enabled)
   Active: active (running) since 목 2023-08-10 17:11:03 KST; 7s ago
   Listen: /run/cri-dockerd.sock (Stream)

이제 kubeadm(k8s 구성 서비스), kubectl(k8s 클라이언트), kubelet(k8s 작업 수행하는 서비스) 설치를 해보자!

방법이 나와 있으며 그대로 진행한다.

저자의 경우 우분투 22.4 이전 버전이므로 유의사항대로 '/etc/apt/keyrings/' 디렉토리를 생성한다.

$ mkdir /etc/apt/keyrings/
$ apt-get update
$ apt-get install -y apt-transport-https ca-certificates curl
$ curl -fsSL https://dl.k8s.io/apt/doc/apt-key.gpg | gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
$ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ apt-get update
$ apt-get install -y kubelet kubeadm kubectl
$ apt-mark hold kubelet kubeadm kubectl

설치가 완료 되었고 이제 kubeadm 으로 클러스터 구성 해보자!

우선 control-plane node (=master) 노드에서만 실행하면 되며 초기화 작업을 진행해야 한다.

마스터 노드에서 위에 나와있는 명령어 입력하여 초기화 한다.

$ kubeadm init

저자의 경우 CRI 가 여러개 발견 된다는 오류 메세지가 나오므로 사용할 CRI 를 지정하는 옵션 하나 추가하여 다시 입력해보자

Found multiple CRI endpoints on the host. Please define which one do you wish to use by setting the 'criSocket' field in the kubeadm configuration file: unix:///var/run/containerd/containerd.sock, unix:///var/run/cri-dockerd.sock
To see the stack trace of this error execute with --v=5 or higher

--cri-socker 옵션을 추가하였다.

$ kubeadm init --cri-socket /etc/systemd/system/cri-dockerd.sock

이제 정상적으로 수행되며 API, controller, schduler, etcd, coreDNS가 성공적으로 설치 되었다.

 

자세히 로그를 보면 'kubeadm join' 명령어가 보이며 이는 워커 노드 셋팅시 필요한 명령어이므로 파일을 생성하여 해당 내용을 저장 한다.

cluster_join.txt 파일로 저장하였다.

echo "kubeadm join 10.100.0.101:6443 --token ryrh31.1fh6khn11rdto43o --discovery-token-ca-cert-hash sha256:a252d097fefc91527f9b8b0715a7e43c4c768681494b49115033c04f02691c20" >> cluster_join.txt

설치 완료 되었다는 메세지와 함께 아래와 같이 설정하라고 나온다.

설정 명령어를 아래와 같이 입력한다.

$ mkdir -p $HOME/.kube
$ cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ chown $(id -u):$(id -g) $HOME/.kube/config
$ vi ~/.bashrc
KUBECONFIG=/etc/kubernetes/admin.conf
:wq!
$ source ~/.bashrc

이제 마스터 노드에서 정상적으로 설치 되었는지 kubectl을 통해 확인하면 controlplane 이 정상적으로 노드 항목에 나온다.

그러나 Status 가 NotReady 인것을 확인할 수 있다. 이는 CNI 가 설치 되지 않은것이 원인이며

root@master:~# kubectl get node -o wide
NAME               STATUS     ROLES           AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
master.corin.com   NotReady   control-plane   14m   v1.27.4   10.100.0.101   <none>        Ubuntu 16.04.6 LTS   4.15.0-142-generic   docker://18.9.7

 

아래글 읽어보니 Pod 네트워크 통신시 coreDNS가 CNI(컨테이너 네트워크 인터페이스)를 사용하는데 이를 못하니 NotReady 상태인것을 알 수 있다.

여러 CNI 중 Weave Net works를 사용할 예정이며 아래와 같이 입력하여 적용한다.

$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

위 명령어로 다운로드 하면 아래 오류 발생하며 확인해보니 해당 URI 이 없어진것이 원인이였다.

WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
Unable to connect to the server: dial tcp: lookup cloud.weave.works on 127.0.1.1:53: no such host

다시 공식 문서 (https://www.weave.works/docs/net/latest/kubernetes/kube-addon/) 를 들어가서 확인해보니 아래와 같이 변경 된것을 보았으며 입력하니 정상적으로 명령 수행 되었다.

$ kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml

적용 되고 처음에는 Status 가 NotReady 지만 조금 지나니 Ready 상태로 변경 되었다. (구성에 시간이 조금 필요한가 보다)

Ready 상태라고 되는것이 아니다! Pod 상태를 보자

root@master:~# kubectl get pods --all-namespaces
NAMESPACE     NAME                                       READY   STATUS              RESTARTS   AGE
kube-system   coredns-5d78c9869d-9xgjt                   0/1     CrashLoopBackOff   5 (107s ago)   4m50s
kube-system   coredns-5d78c9869d-hpcq6                   0/1     CrashLoopBackOff   5 (112s ago)   5m1s
kube-system   etcd-master.corin.com                      1/1     Running            0              10m
kube-system   kube-apiserver-master.corin.com            1/1     Running            0              10m
kube-system   kube-controller-manager-master.corin.com   1/1     Running            0              10m
kube-system   kube-proxy-pql2j                           1/1     Running            0              10m
kube-system   kube-scheduler-master.corin.com            1/1     Running            0              10m
kube-system   weave-net-7k9j8                            2/2     Running            0              9m39s

역시나 문제가 있다. coredns 상태가 'CrashLoopBackOff' 이다. 상세 정보를 보기위해 pod 이벤트를 보자!

root@master:~# kubectl get events pod/coredns-5d78c9869d-9xgjt
Events:
  Type     Reason                  Age                From               Message
  ----     ------                  ----               ----               -------
  Warning  FailedScheduling        95s                default-scheduler  0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/not-ready: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..
  Normal   Scheduled               93s                default-scheduler  Successfully assigned kube-system/coredns-5d78c9869d-57rvf to master.corin.com
  Warning  FailedCreatePodSandBox  92s                kubelet            Failed to create pod sandbox: rpc error: code = Unknown desc = [failed to set up sandbox container "c997e9586e3f6f204dc3cba134be57f587c72f8070cf6bf8bd68d6c01bd0818e" network for pod "coredns-5d78c9869d-57rvf": networkPlugin cni failed to set up pod "coredns-5d78c9869d-57rvf_kube-system" network: plugin type="weave-net" name="weave" failed (add): unable to allocate IP address: Post "http://127.0.0.1:6784/ip/c997e9586e3f6f204dc3cba134be57f587c72f8070cf6bf8bd68d6c01bd0818e": dial tcp 127.0.0.1:6784: connect: connection refused, failed to clean up sandbox container "c997e9586e3f6f204dc3cba134be57f587c72f8070cf6bf8bd68d6c01bd0818e" network for pod "coredns-5d78c9869d-57rvf": networkPlugin cni failed to teardown pod "coredns-5d78c9869d-57rvf_kube-system" network: plugin type="weave-net" name="weave" failed (delete): Delete "http://127.0.0.1:6784/ip/c997e9586e3f6f204dc3cba134be57f587c72f8070cf6bf8bd68d6c01bd0818e": dial tcp 127.0.0.1:6784: connect: connection refused]
  Normal   SandboxChanged          28s (x6 over 92s)  kubelet            Pod sandbox changed, it will be killed and re-created.
  Normal   Pulled                  28s                kubelet            Container image "registry.k8s.io/coredns/coredns:v1.10.1" already present on machine
  Normal   Created                 28s                kubelet            Created container coredns
  Normal   Started                 27s                kubelet            Started container coredns

오류 내용이 'network ~' 인거 보니 네트워크 통신에 문제가 있어 보인다.

reset을 통해 클러스터 초기화 하고 init 명령어로 구축시 '--pod-network-cidr' 옵션을 넣어 네트워크 설정을 잡아 주고 그 뒤에 해야하는 설정은 이전과 동일하게 진행한다.

$ kubeadm reset --cri-socket /run/cri-dockerd.sock
$ kubeadm init --cri-socket /run/cri-dockerd.sock --pod-network-cidr=10.100.0.0/24

이제 정상적으로 pod 가 떴다.

root@master:~# kubectl get pod --all-namespaces
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   coredns-5d78c9869d-lc8zv                   1/1     Running   0          12m
kube-system   coredns-5d78c9869d-zvh22                   1/1     Running   0          12m
kube-system   etcd-master.corin.com                      1/1     Running   0          12m
kube-system   kube-apiserver-master.corin.com            1/1     Running   0          12m
kube-system   kube-controller-manager-master.corin.com   1/1     Running   0          12m
kube-system   kube-proxy-8hvs2                           1/1     Running   0          12m
kube-system   kube-scheduler-master.corin.com            1/1     Running   0          12m
kube-system   weave-net-vj5hf                            2/2     Running   0          12m

이제 워커노드 설정을 해보자!

좀 전에 Master 노드에 저장한 'cluster_join.txt' 파일 내용을 복사해서 node01, node02 에 입력한다.

$ kubeadm join 10.100.0.101:6443 --cri-socket /run/cri-dockerd.sock --token p93f0u.yvfirlxwlt25p360 --discovery-token-ca-cert-hash sha256:25d517bf2c60f4ca677ab690866878d8d8b33c3be12560fe648b7a8d28219e9b
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

 

 

마스터 노드에서 노드 항목을 보자!

root@master:~# kubectl get nodes
NAME               STATUS     ROLES           AGE     VERSION
master.corin.com   Ready      control-plane   81m     v1.27.4
node01.corin.com   NotReady   <none>          6m36s   v1.27.4
node02.corin.com   NotReady   <none>          3m15s   v1.27.4

아직 워커노드가 구성중이므로 NotReady 상태이니 Pod 상태도 보면 워커 노드에 CNI(네트워크인터페이스), Kube-proxy(네트워크 관리) 파드가 생성 된것을 볼 수있다. 

root@master:~# kubectl get pod --all-namespaces -o wide
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE     IP             NODE               NOMINATED NODE   READINESS GATES
kube-system   coredns-5d78c9869d-lc8zv                   1/1     Running   0          22m     10.32.0.4      master.corin.com   <none>           <none>
kube-system   coredns-5d78c9869d-zvh22                   1/1     Running   0          22m     10.32.0.5      master.corin.com   <none>           <none>
kube-system   etcd-master.corin.com                      1/1     Running   0          22m     10.100.0.101   master.corin.com   <none>           <none>
kube-system   kube-apiserver-master.corin.com            1/1     Running   0          22m     10.100.0.101   master.corin.com   <none>           <none>
kube-system   kube-controller-manager-master.corin.com   1/1     Running   0          22m     10.100.0.101   master.corin.com   <none>           <none>
kube-system   kube-proxy-8hvs2                           1/1     Running   0          22m     10.100.0.101   master.corin.com   <none>           <none>
kube-system   kube-proxy-jrgmx                           1/1     Running   0          29s     10.100.0.102   node01.corin.com   <none>           <none>
kube-system   kube-proxy-mrwl6                           1/1     Running   0          8m51s   10.100.0.103   node02.corin.com   <none>           <none>
kube-system   kube-scheduler-master.corin.com            1/1     Running   0          22m     10.100.0.101   master.corin.com   <none>           <none>
kube-system   weave-net-bzzgz                            2/2     Running   0          29s     10.100.0.102   node01.corin.com   <none>           <none>
kube-system   weave-net-vj5hf                            2/2     Running   0          22m     10.100.0.101   master.corin.com   <none>           <none>
kube-system   weave-net-xqmv7                            2/2     Running   0          8m51s   10.100.0.103   node02.corin.com   <none>           <none>

조금 기다렸다가 다시 명령어 호출시 정상적으로 Ready인것을 볼 수 있다.

root@master:~# kubectl get nodes -o wide
NAME               STATUS   ROLES           AGE     VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
master.corin.com   Ready    control-plane   22m     v1.27.4   10.100.0.101   <none>        Ubuntu 16.04.6 LTS   4.15.0-142-generic   docker://18.9.7
node01.corin.com   Ready    <none>          54s     v1.27.4   10.100.0.102   <none>        Ubuntu 16.04.6 LTS   4.15.0-142-generic   docker://18.9.7
node02.corin.com   Ready    <none>          9m16s   v1.27.4   10.100.0.103   <none>        Ubuntu 16.04.6 LTS   4.15.0-142-generic   docker://18.9.7

이제 kubectl 명령어 입력시 탭키를 이용해 자동 완성이 될 수 있도록 설정 해보자!

https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

 

Install and Set Up kubectl on Linux

Before you begin You must use a kubectl version that is within one minor version difference of your cluster. For example, a v1.27 client can communicate with v1.26, v1.27, and v1.28 control planes. Using the latest compatible version of kubectl helps avoid

kubernetes.io

문서의 'Enable shell autocompletion' 부분을 보고 명령어를 그대로 입력하여 적용하면 탭키로 자동 완성이 되며 kubectl 도 k 만 입력하면 동작한다. (예: k get nodes)

$ apt-get install bash-completion
$ source /usr/share/bash-completion/bash_completion
$ echo 'source <(kubectl completion bash)' >>~/.bashrc
$ echo 'alias k=kubectl' >>~/.bashrc
$ echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
$ source ~/.bashrc

끝!

728x90

'ETC' 카테고리의 다른 글

[CKA] Kubernetes 동작 원리 및 namespace  (0) 2023.08.12
[CKA] Pod 생성 하기  (0) 2023.08.11
[CKA] K8S 직접 설치 (Cloud X) - 02  (0) 2023.08.10
[CKA] 쿠버네티스 설치 없이 웹에서 이용  (0) 2023.08.10
[CKA] 쿠버네티스 소개  (0) 2023.08.10
Comments