Ubuntu

[Ubuntu] 쿠버네티스 설치 및 기초 (3일차)

bo._.h 2022. 9. 27.
728x90
반응형

쿠버네티스 설치

kubeadm 설치하기

https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

시작하기 전에

  • 호환되는 리눅스 머신. 쿠버네티스 프로젝트는 데비안 기반 배포판, 레드햇 기반 배포판, 그리고 패키지 매니저를 사용하지 않는 경우에 대한 일반적인 가이드를 제공한다.
  • 2 GB 이상의 램을 장착한 머신. (이 보다 작으면 사용자의 앱을 위한 공간이 거의 남지 않음)
  • 2 이상의 CPU.
  • 클러스터의 모든 머신에 걸친 전체 네트워크 연결. (공용 또는 사설 네트워크면 괜찮음)
  • 모든 노드에 대해 고유한 호스트 이름, MAC 주소 및 product_uuid. 자세한 내용은 여기를 참고한다.
    • 호스트 이름을 각각 변경한다.
    • hostnamectl hostname master-1 # python hostnamectl hostname worker-1 # docker1 hostnamectl hostname worker-2 # docker2
  • 컴퓨터의 특정 포트들 개방. 자세한 내용은 여기를 참고한다.
    • 우분투는 방화벽이 없다.
  • 스왑의 비활성화. kubelet이 제대로 작동하게 하려면 반드시 스왑을 사용하지 않도록 설정한다.다음 명령을 모든 노드에서 실행한다.
  • sudo swapoff -a sudo sed -i '/ swap / s/^\\(.*\\)$/#\\1/g' /etc/fstab
  • https://askubuntu.com/questions/214805/how-do-i-disable-swap

컨테이너 런타임 설치

다음 명령을 사용해 docker.io를 설치한다. docker.io를 설치하면 containerd 런타임이 구성된다.

apt update
apt install docker.io -y 

설치확인하기

docker info | grep -i runtime

kubeadm, kubelet 및 kubectl 설치

모든 머신에 다음 패키지들을 설치한다.

  • kubeadm: 클러스터를 부트스트랩(구성)하는 명령이다.
  • kubelet: 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트이다.
  • kubectl: 클러스터와 통신하기 위한 커맨드 라인 유틸리티이다. 클라이언트용 프로그램
sudo apt remove kubelet kubeadm kubectl # 이전 버전 제거
# sudo -i

cat < kube_install.sh
# apt 패키지 색인을 업데이트하고, 쿠버네티스 apt 리포지터리를 사용하는 데 필요한 패키지를 설치한다.
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>

# 쿠버네티스 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

# apt 패키지 색인을 업데이트하고, kubelet, kubeadm, kubectl을 설치하고 해당 버전을 고정한다.
sudo apt-get update
sudo apt-get install -y kubelet=1.25.1-00 kubeadm=1.25.1-00 kubectl=1.25.1-00
sudo apt-mark hold kubelet kubeadm kubectl
EOF

sh kube_install.sh

쿠버네티스 version 및 설치 확인

kubeadm version

cgroup 드라이버 구성

컨테이너 런타임과 kubelet은 "cgroup 드라이버"라는 속성을 갖고 있으며, cgroup 드라이버는 리눅스 머신의 cgroup 관리 측면에 있어서 중요하다.

경고 컨테이너 런타임과 kubelet의 cgroup 드라이버를 일치시켜야 하며, 그렇지 않으면 kubelet 프로세스에 오류가 발생한다. 더 자세한 사항은 cgroup 드라이버 설정하기를 참고한다.

docker와 kubelet의 cgroup은 다르다.

  • docker cgroup 이름: cgroupfs → systemd # 이제는 systemd가 기본?
  • kubelet cgroup 이름: systemd

https://stackoverflow.com/questions/43794169/docker-change-cgroup-driver-to-systemd

위 사이트의 정보를 따라서 설정파일을 구성하고 도커를 재시작하면 cgroup 이름이 변경된다.

cat <<EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

service docker restart

현재 사용하는 시스템의 도커 cgroup 확인

docker info | grep -i cgroup

여기까지는 모든 노드의 작업이 동일하다.


여기부터는 각 노드마다 작업이 다르므로 주의가 필요하다.

쿠버네티스 클러스터 구성하기

마스터 노드 init을 수행한다.

kubeadm init

init에 성공하면 다음과 같이 나타난다.

Your Kubernetes control-plane has initialized successfully!

# 1) 유저 설정 방법
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

# 2) 파드 네트워크
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/>

# 3) 워커 노드 조인 방법
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.100.220:6443 --token ih09k6.xnbh31it94kxh07i \\
	--discovery-token-ca-cert-hash sha256:18128d07ef04258d0b27a3b74132c759489615a2875aff746111f9b2ccb5ca7e

쿠버네티스 유저 설정

마스터 노드에서 다음 명령을 실행해 쿠버네티스 유저를 설정한다.

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

마스터 노드에서 kubectl을 사용해 쿠버네티스 클러스터와 통신이 가능하다.

# kubectl get nodes
NAME       STATUS     ROLES           AGE   VERSION
master-1   NotReady   control-plane   15m   v1.25.2

워커 노드 조인하기

워커 노드 조인 명령은 꼭 본인이 가진 명령으로 사용하도록 한다. 이 명령은 두 줄짜리이다. 각각의 워커 노드에서 실행한다.

sudo kubeadm join 192.168.100.220:6443 --token ih09k6.xnbh31it94kxh07i \\
	--discovery-token-ca-cert-hash sha256:18128d07ef04258d0b27a3b74132c759489615a2875aff746111f9b2ccb5ca7e

master-1로 돌아가서 노드 목록을 확인한다.

# kubectl get nodes
NAME       STATUS     ROLES           AGE    VERSION
master-1   NotReady   control-plane   109s   v1.25.2
worker-1   NotReady   <none>          25s    v1.25.2
worker-2   NotReady   <none>          11s    v1.25.2
  • 오류 대처하기
    kubeadm reset 명령을 사용해 초기 설정으로 되돌리고 init과 join을 다시 수행한다.
    
  • root@python-vm:~# kubectl get nodes The connection to the server 192.168.100.220:6443 was refused - did you specify the right host or port? 이렇게 떠요.

파드 네트워크 구성


오늘은 설치가 잘 진행되지 않으므로 플레이 그라운드에서 작업을 수행한다.

https://killercoda.com/playgrounds/scenario/kubernetes


컨테이너 배포해보기

톰캣 컨테이너를 3개 배포했으며 이것을 외부로 노출해서 서비스를 수행하도록 명령한다.

kubectl create deployment tomcat --image=consol/tomcat-7.0 --replicas=3
kubectl expose deployment tomcat --type=NodePort --port=80 --target-port=8080

컨테이너가 배포된 상태와 포트 오픈 상태를 확인할 수 있다.

$ kubectl get svc,pod
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        2d18h
service/tomcat       NodePort    10.110.228.33   <none>        80:30942/TCP   2m53s # 외부에 노출된 정보

NAME                          READY   STATUS    RESTARTS   AGE
pod/tomcat-56fb89b485-8vzkn   1/1     Running   0          3m18s # 컨테이너 
pod/tomcat-56fb89b485-w7tjl   1/1     Running   0          3m18s
pod/tomcat-56fb89b485-x8gst   1/1     Running   0          3m18s

오른쪽 상단에 포트를 누르고

위에서 확인한 3xxxx번대 포트를 가져와서 Access한다.

그러면 톰캣서비스가 보인다.

nginx도 배포해보자.

kubectl create deployment nginx --image=nginx --replicas=3
kubectl expose deployment nginx --type=NodePort --port=80 --target-port=80

nginx 가 잘 배포되었는지 확인한다.

$ kubectl get pod,svc
NAME                        READY   STATUS    RESTARTS   AGE
pod/nginx-76d6c9b8c-2vjsf   1/1     Running   0          9s
pod/nginx-76d6c9b8c-nj4ss   1/1     Running   0          9s
pod/nginx-76d6c9b8c-wk6lm   1/1     Running   0          9s

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        2d18h
service/nginx        NodePort    10.99.122.66   <none>        80:30064/TCP   9s

nginx 컨테이너를 10개로 늘려보자.

kubectl scale deployment nginx --replicas=10

파드가 순식간에 배포되어서 10개로 늘어난다. 파드가 어느 노드에 있는지 -o wide옵션을 사용하면 된다.

$ kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE   READINESS GATES
nginx-76d6c9b8c-2vjsf   1/1     Running   0          4m9s    192.168.0.7    controlplane   <none>           <none>
nginx-76d6c9b8c-9bp2w   1/1     Running   0          2m38s   192.168.1.5    node01         <none>           <none>
nginx-76d6c9b8c-gvf2w   1/1     Running   0          2m38s   192.168.1.6    node01         <none>           <none>
nginx-76d6c9b8c-klnnp   1/1     Running   0          2m38s   192.168.1.7    node01         <none>           <none>
nginx-76d6c9b8c-nj4ss   1/1     Running   0          4m9s    192.168.1.4    node01         <none>           <none>
nginx-76d6c9b8c-sp79k   1/1     Running   0          2m38s   192.168.0.10   controlplane   <none>           <none>
nginx-76d6c9b8c-tkw9h   1/1     Running   0          2m38s   192.168.0.9    controlplane   <none>           <none>
nginx-76d6c9b8c-vqqzt   1/1     Running   0          2m38s   192.168.0.8    controlplane   <none>           <none>
nginx-76d6c9b8c-wk6lm   1/1     Running   0          4m9s    192.168.1.3    node01         <none>           <none>
nginx-76d6c9b8c-z2p5k   1/1     Running   0          2m38s   192.168.0.11   controlplane   <none>           <none>

파드

https://kubernetes.io/ko/docs/concepts/workloads/pods/

파드 작성

yaml 파일을 사용해 파드를 배포해보자.

  • apiVersion: 쿠버네티스의 API 버전, 거의 바뀌지 않음
  • kind: 리소스 종류, 거의 바뀌지 않음
  • metadata: 일반 정보(실행과 관련이 떨어지는 정보)
  • spec: 실행 정보
cat <<EOF > nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80
EOF

kubectl apply -f nginx-pod.yaml # 코드를 클러스터에 적용할 수 있다.

파드 조회

파드 정보를 확인한다.

kubectl get pod
kubectl get pod -w # 워치모드로 감시 (Ctrl + C로 종료)
kubectl get pod -o wide # 좀 더 넓은 정보 확인

# 상세 정보 확인하기
kubectl get pod -o yaml nginx # 내용이 많기 때문에 특정 파드 하나만 확인한다.
kubectl describe pod nginx    # 이벤트 정보를 확인하기 쉽다.

파드에서 사용하면 유용한 명령어

포트포워딩

포트포워딩을 수행한다. 이 프로세스가 종료되면 포트포워딩도 종료된다.

kubectl port-forward nginx 8080:80

새로운 탭을 열어서 요청을 수행하면 nginx 서버와 통신이 가능하다.

$ curl 127.0.0.1:8080 | grep -i title
<title>Welcome to nginx!</title>

로그 확인하기

kubectl logs nginx

ssh 처럼 접속하기

docker exec -it tc bash # 도커 명령과 유사하다.

kubectl exec -it nginx -- bash # 달라진 점은 중간에 대시 두 개가 들어간다는 점이다.

실행하면 nginx 파드로 들어간다.

$ kubectl exec -it nginx -- bash
root@nginx:/# exit

연습문제

1. 모든 리소스 삭제

kubectl delete all --all

2. YAML을 사용하여 도커 이미지 jenkins/jenkins로 jenkins-manual 파드를 생성하기

cat <<EOF > jenkins-manual-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: jenkins-manual
spec:
  containers:
  - name: jenkins
    image: jenkins/jenkins
    ports:
    - containerPort: 8080
EOF

kubectl apply -f  jenkins-manual-pod.yaml

3. jenkins 파드 안에서 curl 명령어로 로컬호스트:8080 접속하기

kubectl exec -it jenkins-manual -- bash
curl 127.0.0.1:8080
exit

4. jenkins 포트를 8888로 포트포워딩하기

kubectl port-forward jenkins-manual 8888:8080 --address 0.0.0.0 # default 127.0.0.1
# Ctrl + C를 누르면 중단된다.

5. 현재 jenkins-manual의 설정을 yaml로 출력하기

kubectl get pod -o yaml jenkins-manual

6. jenkins-manual의 패스워드를 찾아서 로그인해보자.

docker logs jenkins-manual

# log
kubectl logs jenkins-manual

# file
kubectl exec jenkins-manual -- cat /var/jenkins_home/secrets/initialAdminPassword

패스워드를 입력할 때는 반드시 포트포워딩이 활성화된 상태여야 한다.

728x90
반응형

댓글