ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 04. 쿠버네티스 들어가기 (1)
    개발 스터디/데브옵스(DevOps)를 위한 쿠버네티스 마스터 2021. 7. 3. 19:39
    반응형

    이 문서는 인프런 강의 "데브옵스를 위한 쿠버네티스 마스터"을 듣고 작성되었습니다. 최대한 요약해서 강의 내용을 최소로 하는데 목표를 두고 있어서, 더 친절하고 정확한 내용을 원하신다면 강의를 구매하시는 것을 추천드립니다. => 강의 링크

    쿠버네티스란

    Google은 본인들의 거대한 서비스를 보다 효율적으로 운영하기 위해서 보그 시스템과 오메가 시스템을 만들어서 쓰고 있었는데 이를, 오픈 소스화시킨 것이 바로 쿠버네티스이다. 쿠버네티스는 인프라 안의 수 많은 노드들을 하나의 거대한 컴퓨터처럼 관리한다.

    이렇게 해서 얻는 장점은 다음과 같다.

    1. 애플리케이션 개발 단순화
    2. 애플리케이션 배포 단순화
    3. 하드웨어 리소스 활용 극대화
    4. 각 서비스의 헬스 체크와 셀프 리커버리
    5. 각 서비스의 오토스케일링

    이러한 장점을 통해 개발자는 운영자가 없어도 개발에만 집중해서 서비스를 운영할 수 있게 되었고 운영자들은 운영하면서 직면하는 여러 문제들을 쿠버네티스로 손쉽게 해결할 수 있게 되었다. 따라서 현 시대에서 쿠버네티스는 선택이 아닌 필수로 익혀둬야 할 기술 중 하나이다. (특히 Devops라면) 쿠버네티스 아키텍처는 다음과 같다.

    일반적으로 control plane node(마스터) n대(홀수)와 data node(슬레이브) m대로 구성된다. control plane node는 쿠버네티스 클러스터를 관리하는 역할을 한다. 위의 그림에서 왼쪽 부분에 해당하는데, 각 컴포넌트는 다음과 같다.

    • KubeAPIServer: data node들과 통신하며, 필요한 명령들을 내린다.
    • Etcd: 저장소
    • KubeScheduler: 노드 배치 및 스케줄링을 담당한다.
    • KubeControllerManager: 리소스 관리 제어를 담당한다.

    오른쪽은 data node의 부분이다. 실제적으로 컨테이너들이 실행되는 공간이다. 다음과 같이 구성된다.

    • Kubelet: 실제 Container Runtime을 관리하며, control plane node의 명령에 따라 pod(컨테이너)들을 실행한다.
    • KubeProxy: 컨테이너-컨테이너, 컨테이너-노드 간 통신을 담당한다.

    이번엔 간단하게 워크 플로우를 살펴보자.

    먼저 Docker Registry에 배포할 이미지들을 push한다. 그 후 AppDescriptor라는 것을 작성하여, 실제 어떤 컨테이너를 어떻게 실행할 것인지 작성한다. 그러면 control plane nodeAppDescriptor에 따라서 컨테이너들을 배치하여 data node에게 해당 컨테이너를 실행할 것을 명령한다. 그럼 data node들은 명령에 따라 필요하면 Docker Registry에서 이미지를 다운 받고 컨테이너를 실행시킨다.

    쿠버네티스 설치하기 (1) Docker 설치 > Kube* 설치 > swapoff 설정

    이제 본격적인 실습에 앞서 쿠버네티스 클러스터를 구성해보자. 먼저 도커, 쿠버네티스 설치가 필요하다.

     

    도커 설치

    터미널에 다음을 입력한다.

    # sudo -i 이후
    > apt install -y docker.io

    kubeadm, kubectl, kubelet 설치

    쿠버네티스 공식 문서 "kubeadm 설치하기https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/install-kubeadm/"를 따라서 설치하면 된다. 터미널에 다음을 입력한다.

    # 유저 권한으로 실행한다. "> exit" 
    $ 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 kubeadm kubectl
    $ sudo apt-mark hold kubelet kubeadm kubectl

    swapoff 설정

    쿠버네티스를 사용하려면, 머신의 swapoff 설정을 해주어야 한다. 구글에 "how to swap disable" 검색하면 첫 페이지로 이에 대한 문서가 나온다.

    터미널에 다음을 입력한다.

    $ sudo sed -i '/ swap / s/^/#/' /etc/fstab

     

    이제 다음 단계를 위해서 가상 머신을 잠깐 꺼두자.

    $ halt -p

    쿠버네티스 설치하기 (2) 스냅샷 설정 및 복제 > 네트워크 설정 > 노드 설정

    이제 가상 머신의 현재 상태를 스냅샷 후 복제하자.

     

    스냅샷 설정 및 복제

    먼저 virtualbox에서 인스턴스 오른쪽 버튼 클릭 > 스냅샷을 클릭한다.

    그 다음 상단에 "찍기"를 누른다.

    적절한 스냅샷 이름을 입력한다.

    그럼 다음과 같이 설정한 이름으로 스냅샷이 생성된 것이 보인다.

    그 다음 인스턴스에 우클릭 > 복제를 누른다.

    그 다음 MAC 주소 정책을 "모든 네트워크 어댑터의 새 MAC 주소 생성"을 설정하고 계속을 누른다.

    이렇게 해서 2개를 복제한다. 인스턴스는 총 3개가 된다. (인스턴스 이름은 우클릭 > 설정에서 바꿀 수 있다.)

    네트워크 설정

    이제 구성할 클러스터끼리 잘 통신할 수 있도록 NAT 네트워크를 만든다. 먼저 상단에 VirtualBox 클릭 > 설정을 누른다.

    그 후 네트워크 탭으로 가서 "+" 버튼을 누른다.

    그리고 NAT 네트워크 이름을 설정하면 된다. 이후에 인스턴스마다 네트워크 설정을 한다. 인스턴스 우 클릭 > 설정을 누른다.

    네트워크 탭에 가서 네트워크를 "NAT 네트워크"를 선택한다.

    그러면 본인이 설정한 NAT 네트워크 이름으로 설정된다.(설정된 네트워크 이름이 동일해야 한다.)

    노드 설정

    일단 인스턴스 별로 이름과 터미널 내의 이름이 다르다. 같은 hostname을 갖고 있을 경우, 클러스터를 구성하는데 문제가 생기기 때문에, 인스턴스 이름과 터미널 내의 이름을 맞춰준다.

    그 다음 각 노드를 실행한 후 인스터스에서 다음을 입력한다.

    # sudo -i 이후
    > vi /etc/hostname

     

    그런 다음 위의 이름과 같은 이름으로 설정한다.

    data-node-2 (서버 이름과 같이 설정한다.)

     

    그 후 터미널에 다음을 입력한다.

    > reboot

     

    그리고 이후에 터미널을 켜 보면 노드 이름과 터미널에서 보이는 이름이 같아진 것을 확인할 수 있다.

    쿠버네티스 설치하기 (3) 쿠버네티스 클러스터 구성하기

    Control Plane Node 구성

    이제 control plane node에서 다음 터미널을 입력한다.

    > kubeadm init

     

    위 명령어를 입력하면 꽤 오랜 시간 기다려야 한다. 그럼 다음 결과를 얻을 수 있다.

    ...
    [addons] Applied essential addon: kube-proxy
    
    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/
    
    Then you can join any number of worker nodes by running the following on each as root:
    
    kubeadm join 10.0.2.15:6443 --token 95v08z.hnsecyoomewk9n2q \
        --discovery-token-ca-cert-hash sha256:35f80d29d5123434eadb890c23f227ab6dd6c43b333a2d7c378c4966b254c3b9 

     

    먼저 아랫줄에 kubeadm join ... 명령어는 따로 복사해두자. data node들에서 위 명령어를 통해서 클러스터를 구성하게 된다. 일단 유저 권한으로 터미넗을 새롭게 연 뒤 다음 명령어를 입력한다.

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

     

    그 후 다음 명령어를 입력한다.

    $ kubectl get nodes
    NAME     STATUS     ROLES                  AGE     VERSION
    master   NotReady   control-plane,master   4m17s   v1.21.2

    Data Node 구성

    이제 data node를 설정한다. 이전에 저장했던 명령어를 각각 입력한다. 이 때 반드시 루트 권한으로 실행해야 한다.

    # sudo -i 이후
    > kubeadm join 10.0.2.15:6443 --token 95v08z.hnsecyoomewk9n2q \
        --discovery-token-ca-cert-hash sha256:35f80d29d5123434eadb890c23f227ab6dd6c43b333a2d7c378c4966b254c3b9 

     

    성공적으로 클러스터가 구성되면 터미널에 다음을 확인할 수 있다.

    ...
    [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.

    참고! 이 단계에서 진행이 안될 때! 

    ...
    accepts at most 1 arg(s), received 3 To see the stack trace of this error execute with --v=5 or higher

    강의에서 주는 우분투 이미지 18.04 버전에서 진행할 경우 다음 에러가 뜨면서 진행이 안되는 경우가 있습니다. 필자 역시 이러한 문제를 직면했는데 마땅한 해결 방법을 찾지 못했습니다. 개인적인 생각에는 커널 업데이트 되면서 18.04 버전에서는 더 이상 현재 쿠버네티스 버전을 사용 못하는게 아닐까 싶습니다. 이런 문제가 생길 경우 우분투 버전을 20.04 버전으로 올려주거나 AWS 등의 클라우드 서비스를 이용해서 진행하시길 바랍니다.

    (21년 11월 22일 수정) 
    "시간의 효율화"님께서 문제 해결에 대한 내용을 공유해 주셨습니다. 감사합니다.

    해결 방법:
    마스터 노드(kubeadm이 설치된 노드)에서 다음 명령어를 입력하면 됩니다. 

    $ kubeadm token create --print-join-command


    * 시간의 효율화님의 블로그, 해당 이슈에 대한 트러블 슈팅 링크 : https://fusiondeveloper.tistory.com/65
    * 공유 주신 Github Issue 링크 : https://github.com/kubernetes/kubernetes/issues/61224

    Weavenet 구성

    클러스터 구성 이후 control plane node에서 다음 명령어를 입력해보자.

    $ kubectl get nodes
    NAME     STATUS     ROLES                  AGE    VERSION
    master   NotReady   control-plane,master   4m2s   v1.21.2
    slave1   NotReady   <none>                 12s    v1.21.2
    slave2   NotReady   <none>                 15s    v1.21.2

     

    이 때 각 노드들은 아직 NotReady 상태인데, 아직 네트워크를 구성하지 않아서 그렇다. 강의에서는 네트워크로 Weavenet으로 구성한다. Weavenet 설치는 공식 문서 "Integrating Kubernetes via the Addon
    (https://www.weave.works/docs/net/latest/kubernetes/kube-addon/)"을 참고한다.

     

    역시 control plane node에서 다음 명령어를 입력한다.

    $ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
    clusterrole.rbac.authorization.k8s.io/weave-net created
    clusterrolebinding.rbac.authorization.k8s.io/weave-net created
    role.rbac.authorization.k8s.io/weave-net created
    rolebinding.rbac.authorization.k8s.io/weave-net created
    daemonset.apps/weave-net created

     

    그 이후 1분 정도 후에 다시 노드들의 상태를 확인해보자.

    $ kubectl get nodes
    NAME     STATUS   ROLES                  AGE     VERSION
    master   Ready    control-plane,master   6m53s   v1.21.2
    slave1   Ready    <none>                 3m3s    v1.21.2
    slave2   Ready    <none>                 3m6s    v1.21.2

     

    이렇게 되면 잘 설정이 된 것이다.

    쿠버네티스 설치하기 (4) 구성된 클러스터에 Pod을 띄어보자!

    이제 구성된 클러스터에 pod을 띄어보자. 터미널에 다음을 입력해보자.

    $ kubectl run nginx --image=nginx
    pod/nginx created

     

    위 명령어는 pod을 생성한 것이다. 터미널에 다음을 입력해보자.

    $ kubectl get pod
    NAME    READY   STATUS              RESTARTS   AGE
    nginx   0/1     ContainerCreating   0          68s

     

    위의 명령어는 만들어진 pod들의 상태를 확인하는 것이다. 아직 생성만 되었을 뿐 실행되지 않은 상태이다. 조금 더 시간이 지난 후에 확인해보자.

    $ kubectl get pod
    NAME    READY   STATUS    RESTARTS   AGE
    nginx   1/1     Running   0          3m2s

     

    이제 배포가 완료되었다. 컨테이너가 실행 중인 상태라고 보면 된다. 이제 잘 실행이 되는지 포트 포워딩을 한 번 해보자. 터미널에 다음을 입력한다.

    $ kubectl port-forward nginx 8080:80
    Forwarding from 127.0.0.1:8080 -> 80
    Forwarding from [::1]:8080 -> 80
    Handling connection for 8080

     

    이제 다른 터미널에서 다음을 입력해보자.

    $ curl localhost:8080
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    root@master:~# 

     

    굳 끝이다!

Designed by Tistory.