✔️ k8s 설치하기
이 글에서는 1대의 ubuntu VM에 컨트롤 플레인, 노드를 구성한다.
https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
kubeadm은 k8s를 설치하기 위한 도구일 뿐 k8s가 아님에 주의하자
시작하기 전에
- 호환되는 리눅스 머신. 쿠버네티스 프로젝트는 데비안 기반 배포판, 레드햇 기반 배포판, 그리고 패키지 매니저를 사용하지 않는 경우에 대한 일반적인 가이드를 제공한다.
- 2 GB 이상의 램을 장착한 머신. (이 보다 작으면 사용자의 앱을 위한 공간이 거의 남지 않음)
- 2 이상의 CPU.
- 클러스터의 모든 머신에 걸친 전체 네트워크 연결. (공용 또는 사설 네트워크면 괜찮음)
- 모든 노드에 대해 고유한 호스트 이름, MAC 주소 및 product_uuid. 자세한 내용은 여기를 참고한다.
- 컴퓨터의 특정 포트들 개방. 자세한 내용은 여기를 참고한다.
- 스왑의 비활성화. kubelet이 제대로 작동하게 하려면 반드시 스왑을 사용하지 않도록 설정한다.
ubuntu의 ufw에 방화벽이 차단되어 있지 않지만 실제 구성을 할 때는 컨트롤 플레인에 사용하는 포트, 워커 노드에 사용하는 포트들을 방화벽에서 열어놔야 한다.
swap이 있으면 비활성화 해야 한다.
✔️ Kubeadm
✔️ kubeadm, kubectl, kubelet 도구 설치
Docker가 설치되어 있으면 넘어가고 Docker가 없으면 설치한다.
세가지 도구를 설치해야 한다.
kubeadm, kubelet 및 kubectl 설치
하나의 VM(ubuntu VM)에 설치할 것이므로 이 VM은 컨트롤 플레인이자 워커 노드로 작동해야 한다.
컨트롤 플레인은 워커 노드의 기능(kubelet, kube-proxy)을 가지고 있다.
1.22.8 버전을 설치할 것이다.
1. apt
패키지 색인을 업데이트하고, 쿠버네티스 apt
리포지터리를 사용하는 데 필요한 패키지를 설치한다.
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
2. 구글 클라우드의 공개 사이닝 키를 다운로드 한다.
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
3. 쿠버네티스 apt
리포지터리를 추가한다.
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
vagrant@docker ~ apt-cache madison kubeadm | grep 1.22.8
kubeadm | 1.22.8-00 | https://apt.kubernetes.io kubernetes-xenial/main amd64 Packages
vagrant@docker ~ apt-cache madison kubelet | grep 1.22.8
kubelet | 1.22.8-00 | https://apt.kubernetes.io kubernetes-xenial/main amd64 Packages
vagrant@docker ~ apt-cache madison kubectl | grep 1.22.8
kubectl | 1.22.8-00 | https://apt.kubernetes.io kubernetes-xenial/main amd64 Packages
버전을 확인한다.
4. apt
패키지 색인을 업데이트하고, kubelet, kubeadm, kubectl을 설치하고 해당 버전을 고정한다.
sudo apt-get update
sudo apt-get install kubeadm=1.22.8-00 kubelet=1.22.8-00 kubectl=1.22.8-00 -y
kubelet, kubeadm, kubectl의 버전을 지정할 것이다.
버전을 지정하지 않으면 항상 최신 버전을 사용한다. 검증된 버전을 사용해야 한다.
sudo apt-mark hold kubelet kubeadm kubectl
vagrant@docker ~ systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
Drop-In: /etc/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since Sun 2022-05-15 21:16:05 KST; 4h 1min ago
Docs: https://kubernetes.io/docs/home/
Main PID: 631 (kubelet)
Tasks: 20 (limit: 4677)
Memory: 207.6M
CGroup: /system.slice/kubelet.service
└─631 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml>
Warning: some journal files were not opened due to insufficient permissions.
정상적으로 설치되었다면 kubelet 서비스가 Active 상태여야 한다.
✔️ k8s 클러스터 생성
Creating a cluster with kubeadm | Kubernetes
1. --control-plane-endpoint
을 지정한다.
한대의 VM이 컨트롤 플레인이자 워커 노드로 역할을 할 것이므로 컨트롤 플레인의 주소는 VM의 주소가 된다.
kubeadm init --control-plane-endpoint 192.168.100.100 # VM의 주소
2. Pod network add-on
을 선택한다.
컨테이너가 연결하기 위한 네트워크가 필요하다.
k8s는 연결하기 위한 네트워크의 실제 구현체는 없다.
여러대의 컨테이너가 있을 때 모두 같은 네트워크에 있어야 한다. 따라서 overay
, tunneling
네트워크가 필요하다.
이런것을 실제로 구현하는 구현체가 없어서 network add-on
을 구성해야 한다.
또한 이 네트워크가 사용할 네트워크 대역을 지정해줘야 한다.
주의할 점은 다른 네트워크와 충돌이 생기지 않도록 설정한다.
마지막으로 컨트롤 플레인의 API 서버 주소를 몇번으로 할 것인지 지정한다.
sudo kubeadm init --control-plane-endpoint 192.168.100.100 --pod-network-cidr 172.16.0.0/16 --apiserver-advertise-address 192.168.100.100
✔️ k8s 설치 Trouble Shooting
kubeadm init 명령 실행 후 다음과 같은 오류 발생시 조치 방법
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[kubelet-check] Initial timeout of 40s passed.
Unfortunately, an error has occurred:
timed out waiting for the condition
This error is likely caused by:
- The kubelet is not running
- The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)
If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
- 'systemctl status kubelet'
- 'journalctl -xeu kubelet'
Additionally, a control plane component may have crashed or exited when started by the container runtime.
To troubleshoot, list all containers using your preferred container runtimes CLI, e.g. docker.
Here is one example how you may list all Kubernetes containers running in docker:
- 'docker ps -a | grep kube | grep -v pause'
Once you have found the failing container, you can inspect its logs with:
- 'docker logs CONTAINERID'
error execution phase wait-control-plane: couldn't initialize a Kubernetes cluster
https://github.com/kubernetes/kubeadm/issues/2605
docker 1.22로 오면서 Cgroup drive를 지원하지 않아 발생하는 오류
docker info | grep 'Cgroup Driver'
Cgroup Driver: cgroupfs
현재 Cgroup Driver 확인시 cgroupfs로 되어있음
/etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
sudo systemctl restart docker
docker info | grep 'Cgroup Driver'
Cgroup Driver: systemd
해당 파일을 만들고 도커를 재시작하면 Cgroup drive → systemd로 변경되어있음
sudo systemctl daemon-reload && sudo systemctl restart kubelet
이후 kubelet 재시작
만약 kubeadm init 실패시
sudo kubeadm reset
다시 kubeadm init 수행
sudo kubeadm init --control-plane-endpoint 192.168.100.100 --pod-network-cidr 172.16.0.0/16 --apiserver-advertise-address 192.168.100.100
설치 성공시
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/
You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:
kubeadm join 192.168.100.100:6443 --token dywlj7.88ojfvndq0ts8pcv \
--discovery-token-ca-cert-hash sha256:4dd37e7865e2da8b915a23bf20a0eb401f2df7a667b2dbc8aec68ad4ad0a6e55 \
--control-plane
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.100.100:6443 --token dywlj7.88ojfvndq0ts8pcv \
--discovery-token-ca-cert-hash sha256:4dd37e7865e2da8b915a23bf20a0eb401f2df7a667b2dbc8aec68ad4ad0a6e55
해당 내용 출력
출력 메세지를 자세히 보자
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
/etc/kubernetes/admin.conf 파일을 /.kube/config 에 복사한다.
sudo 권한을 이용하여 cp 했기 때문에 현재 소유자가 root이다.
소유자를 root에서 현재 사용자로 변경한다.
vagrant@docker ~ mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
vagrant@docker ~ cd .kube
vagrant@docker ~/.kube ls
config
vagrant@docker ~/.kube ls -l
total 8
-rw------- 1 vagrant vagrant 5643 May 13 16:14 config
해당 디렉토리로 이동하면 k8s 인증 파일이 존재한다. 해당 파일이 없으면 k8s에 인증할 수 없다.
이 파일은 절대 노출되면 안된다.
vagrant@docker ~/.kube kubectl get nodes
NAME STATUS ROLES AGE VERSION
docker NotReady control-plane,master 6m35s v1.22.8
모든 작업을 완료하면 드디어 명령을 실행할 수 있다. 해당 명령은 컨트롤 플레인이나 워커 노드의 노드를 보는 명령어이다.
✔️ Calico Network Add-on
control-plane,master의 상태가 NotReady이다. 아직 완전하게 클러스터를 사용할 준비가 되지 않았다는 뜻이다.
Pod에 network add-on을 설정해야 한다.
결과 메세지에서
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/
https://kubernetes.io/docs/concepts/cluster-administration/networking/#how-to-implement-the-kubernetes-networking-model
다음 url에 나열된 옵션 중 하나를 사용해 kubectl apply -f [podnetwork].yaml를 실행하고 파드 네트워크를 배포한다.
✔️ Install Calico
https://projectcalico.docs.tigera.io/about/about-calico
Install Calico networking and network policy for on-premises deployments (tigera.io)
kubectl create -f https://projectcalico.docs.tigera.io/manifests/tigera-operator.yaml
리소스가 정의된 yaml 파일을 생성한다.
curl https://projectcalico.docs.tigera.io/manifests/custom-resources.yaml -O
파일을 다운로드 받는다.
custom-resources.yaml 파일을 수정한다.
파드 network로 설정했던 cidr(172.16.0.0/16)와 맞춰줘야 한다.
vagrant@docker ~ kubectl create -f custom-resources.yaml
installation.operator.tigera.io/default created
apiserver.operator.tigera.io/default created
적용한다.
✔️ 클러스터 상태 확인
vagrant@docker ~ kubectl taint node docker node-role.kubernetes.io/master-
node/docker untainted
컨트롤 플레인과 노드가 한대의 시스템으로 구성되어 있을 때 컨트롤 플레인이 컨테이너를 실행할 수 없도록 격리 되어있다.
다음 명령을 실행해 컨트롤 플레인이 컨테이너를 실행할 수 있도록 변경한다.
vagrant@docker ~ kubectl get pods -A # 모든 pod의 목록 확인
NAMESPACE NAME READY STATUS RESTARTS AGE
calico-system calico-kube-controllers-5d74cd74bc-z6sh7 0/1 ContainerCreating 0 71s
calico-system calico-node-cvsmp 1/1 Running 0 71s
calico-system calico-typha-8bdc64c6-ds66m 1/1 Running 0 71s
kube-system coredns-78fcd69978-f2m28 1/1 Running 0 18m
kube-system coredns-78fcd69978-h74sn 1/1 Running 0 18m
kube-system etcd-docker 1/1 Running 1 18m
kube-system kube-apiserver-docker 1/1 Running 1 18m
kube-system kube-controller-manager-docker 1/1 Running 1 18m
kube-system kube-proxy-7nn4r 1/1 Running 0 18m
kube-system kube-scheduler-docker 1/1 Running 1 18m
tigera-operator tigera-operator-7cf4df8fc7-krfd2 1/1 Running 0 2m49s
전부 다 running 상태여야 한다.
vagrant@docker ~ kubectl get nodes
NAME STATUS ROLES AGE VERSION
docker Ready control-plane,master 18m v1.22.8
Ready 상태여야 한다.
✔️ 간단한 예제
kubectl create deployment myweb --image=ghcr.io/c1t1d0s7/go-myweb
kubectl get deployments, replicasets, pods
vagrant@docker ~ kubectl create deployment myweb --image=ghcr.io/c1t1d0s7/go-myweb
deployment.apps/myweb created
myweb이라는 deployment 타입을 만든다. 컨테이너를 생성한다.
vagrant@docker ~ kubectl get deployments,replicasets,pods
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myweb 1/1 1 1 4m49s
NAME DESIRED CURRENT READY AGE
replicaset.apps/myweb-97dbf5749 1 1 1 4m49s
NAME READY STATUS RESTARTS AGE
pod/myweb-97dbf5749-29pdx 1/1 Running 0 4m49s```
만든 것들을 확인한다.
pod/myweb-97dbf5749-29pdx : 생성된 컨테이너명
k8s는 Docker와 달라서 포트 포워딩을 하지 않는다.
expose : 파드를 외부로 노출시킨다. 이것을 Service라고 한다.
vagrant@docker ~ kubectl expose deployment myweb --port=80 --protocol=TCP --target-port=8080 --name myweb-svc --type=NodePort
service/myweb-svc exposed
vagrant@docker ~ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 33m
myweb-svc NodePort 10.108.98.163 <none> 80:32244/TCP 20s
myweb-svc : 로드 밸런서 역할을 한다.
✔️ 외부에서 접속하기
포트 번호와 VM의 ip를 조합해서 curl 명령을 실행해본다.
vagrant@docker ~ curl http://192.168.100.100:32244/
Hello World!
myweb-97dbf5749-29pdx
Service라는 타입의 리소스를 만들어서 외부로 노출시키면 접속할 수 있다.
✔️ Scale 예제
vagrant@docker ~ kubectl scale deployment myweb --replicas=5
deployment.apps/myweb scaled
vagrant@docker ~ kubectl get pods
NAME READY STATUS RESTARTS AGE
myweb-97dbf5749-29pdx 1/1 Running 0 9m8s
myweb-97dbf5749-6qs6h 1/1 Running 0 5s
myweb-97dbf5749-hpsf7 1/1 Running 0 5s
myweb-97dbf5749-kzcvg 1/1 Running 0 5s
myweb-97dbf5749-mrb9q 1/1 Running 0 5s
replicaset : 파드의 복제본을 만들라는 명령어다. 5개로 설정했으므로 파드 5개가 생성된다.
vagrant@docker ~ kubectl scale deployment myweb --replicas=3
deployment.apps/myweb scaled
vagrant@docker ~ kubectl get pods
NAME READY STATUS RESTARTS AGE
myweb-97dbf5749-29pdx 1/1 Running 0 9m55s
myweb-97dbf5749-hpsf7 1/1 Running 0 52s
myweb-97dbf5749-mrb9q 1/1 Running 0 52s
autoscaling 기능도 있다.
vagrant@docker ~ kubectl get pods | grep Running
myweb-97dbf5749-29pdx 1/1 Running 0 12m
myweb-97dbf5749-hpsf7 1/1 Running 0 3m22s
myweb-97dbf5749-mrb9q 1/1 Running 0 3m22s
--replicas=3- Running 상태의 파드가 3개가 된다.
vagrant@docker ~ curl http://192.168.100.100:32244/
Hello World!
myweb-97dbf5749-mrb9q
vagrant@docker ~ curl http://192.168.100.100:32244/
Hello World!
myweb-97dbf5749-29pdx
vagrant@docker ~ curl http://192.168.100.100:32244/
Hello World!
myweb-97dbf5749-hpsf7
vagrant@docker ~ curl http://192.168.100.100:32244/
Hello World!
myweb-97dbf5749-29pdx
vagrant@docker ~ curl http://192.168.100.100:32244/
Hello World!
myweb-97dbf5749-hpsf7
vagrant@docker ~ curl http://192.168.100.100:32244/
Hello World!
myweb-97dbf5749-mrb9q
vagrant@docker ~
파드 3개가 동등한 비율로 나온다. 라운드 로빈 방식으로 부하 분산되고 있음을 알 수 있다.
✔️ 삭제
vagrant@docker ~ kubectl delete service myweb-svc # 서비스 삭제
service "myweb-svc" deleted
vagrant@docker ~ kubectl delete deployment myweb # deployment 삭제
deployment.apps "myweb" deleted
vagrant@docker ~
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] k8s 클러스터 업그레이드 (0) | 2022.05.16 |
---|---|
[Kubernetes] Worker Node 추가 구성하기 (0) | 2022.05.16 |
[Kubernetes] Kubernetes(쿠버네티스)란 ?! (0) | 2022.05.16 |
[Kubernetes] Pod 생성 과정 (0) | 2022.03.28 |
[Kubernetes] Object - Volume이란 (3) (0) | 2022.03.28 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!