ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 05. 쿠버네티스 들어가기 (2)
    개발 스터디/데브옵스(DevOps)를 위한 쿠버네티스 마스터 2021. 7. 6. 20:14
    반응형

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

    GCP 회원가입

    먼저 GCP에 접속한다. 그 후 "Get started for Free"를 누른다.

    그 후 콤보 박스를 다 선택한 후, "계속"을 누른다.

    그 다음 개인 정보 이름, 주민등록번호, 이동통신사, 전화 번호를 입력한다. 전화번호를 입력한 후, "코드 전송"을 누르고 전송된 코드를 입력한다. 그 후 "계속"을 누른다.

    그 다음 본인 결재 정보 카드번호를 입력한다. 그러면 비밀번호와 유효날짜를 입력한다. 그 후 "무료 평가판 시작하기"를 누른다.

    그럼 GCP 콘솔로 이동된다. 왼쪽 탭의 "결재"를 누르면 현재 크레딧을 확인할 수 있다.

    굳 300 크레딧 지급 완료! 이제 GCP가 제공하는 쿠버네티스 클러스터 엔진인 GKE를 설정해보자.

    GKE 설정 (1) 프로젝트 생성

    이제 프로젝트를 생성한다. 먼저 GCP 콘솔 홈으로 이동 후, 상단의 "Google Cloud Platform" 오른쪽 부분을 클릭한다.

    그럼 팝업이 뜨는데 우측 상단에 "새 프로젝트"를 누른다.

    그럼 프로젝트 이름과 회사를 지정할 수 있다. 추후 권한 문제로 골치 아플 수 있으니 회사는 지정하지 않는다. 프로젝트 이름은 {자신의 ID}-gke-{오늘 날짜} 이렇게 고유하게 짓는다. 그럼 프로젝트 이름과 ID가 동일하게 지정된다.

    조금 시간이 지나면 우측 상단 알람에서 프로젝트가 성공적으로 만들어졌다는 알람을 받을 수 있다.

    GKE 설정 (2) 쿠버네티스 클러스터 생성 및 클라우드 콘솔 연결

    이제 왼쪽 탭의 Kubernetes Engine을 클릭한다.

    그 후 "다음"을 클릭한다. 처음이라 몇 분 걸릴 수 있다.

    그 다음 "만들기"를 클릭한다.

    표준 구성을 클릭한다.

    이름과 리전만 정해준다. 리전은 한국 리전 중 하나인 asia-northeast3-a로 지정했다. 그 후 "만들기"를 클릭한다.

    이제 몇 분정도 기다리면 클러스터가 다음과 같이 구성됐음을 확인할 수 있다.

    이제 GKE 구성은 끝났다. 쿠버네티스 클러스터가 잘 떴는지 확인해보자. 클러스터 우측의 UI를 클릭한 후, "연결"을 클릭한다.

    그럼 다음 팝업이 뜨는데 뭐라뭐라 써져 있다. 이는 어차피 "CLOUD SHELL에서 실행"을 누르면 웹에서 쓸 수 있는 터미널이 나오는데, 여기 맨 처음에 접속하면 똑같이 써져있다.

    이제 터미널이 뜬다. 역시 해당 명령어가 떠 있다. 엔터를 누른다. 그러면 팝업이 뜨는데 확인을 눌러준다.

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

    $ kubectl get nodes
    NAME                                         STATUS   ROLES    AGE     VERSION
    gke-gurumee-gke-default-pool-6805db09-6kjp   Ready    <none>   3m31s   v1.19.10-gke.1600
    gke-gurumee-gke-default-pool-6805db09-g2d0   Ready    <none>   3m32s   v1.19.10-gke.1600
    gke-gurumee-gke-default-pool-6805db09-z2nq   Ready    <none>   3m32s   v1.19.10-gke.1600

     

    노드들이 보이면 성공이다.

    GKE 간단히 훑어보기 (1) Golang 웹 서버 이미지 빌드 및 푸시

    이제 GKE에 올려 볼 간단한 웹 서버를 만들어보자. 다음을 입력한다.

     

    src/ch05/main.go

    package main
    
    import (
        "fmt"
        "net/http"
        "os"
    )
    
    func Index(w http.ResponseWriter, req *http.Request) {
        hostname, err := os.Hostname()
    
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
    
        body := fmt.Sprintf("Hello World %v", hostname)
        w.Write([]byte(body))
    }
    
    func main() {
        http.HandleFunc("/", Index)
        http.ListenAndServe(":8080", nil)
    }

     

    그 후, Dockerfile을 작성한다.

     

    src/ch05/Dockerfile

    FROM golang:1.16
    
    WORKDIR /app
    
    COPY . .
    
    RUN go mod init app
    RUN go get
    RUN go build -o app .
    
    EXPOSE 8080
    
    CMD ["/app/app"]

     

    그 후 터미널에 다음을 입력하여, 이미지를 빌드한다.

    # Dockerfile 있는 곳에서
    $ pwd
    ~/Workspace/today-i-learned/inflearn_kubernetes_master_for_devops/src/ch05 
    
    # 도커 이미지 빌드
    $ docker build -t simple-app .   

     

    이제 Docker Hub에 해당 이미지를 올리자.

    # 이미지 태깅
    # docker tag <이미지 이름> <자신의 도커 ID>/<이미지 이름>
    $ docker tag simple-app gurumee92/simple-app
    
    # 이미지 푸시 
    # docker push <태그한 이미지 이름>
    $ docker push gurumee92/simple-app

     

    Docker Hub에서 다음을 확인할 수 있으면 된다.

    GKE 간단히 훑어보기 (2) GKE에 웹 서버 배포하기

    자 이제 이 이미지를 이용해서, 현재 웹 서버를 배포해보자. 다시 Cloud Shell로 돌아가서 터미널에 다음을 입력해보자.

    $ kubectl create deploy simple-app --image=gurumee92/simple-app
    deployment.apps/simple-app created

     

    쿠버네티스 클러스터에 컨테이너를 올릴려면 먼저 Deploy를 생성해주어야 한다. 위 명령어가 해당 Deploy를 생성하는 것이다. 해당 Deploy의 상태를 보려면 다음 명령어를 입력해준다.

    $ kubectl get deploy -w
    NAME         READY   UP-TO-DATE   AVAILABLE   AGE
    simple-app   0/1     1            0           12s
    simple-app   1/1     1            1           27s # 몇 초 정도 걸림

     

    kubectl get deploy -w는 디플로이 상태가 바뀌면 바뀐 내용을 쭉 출력해준다. 이렇게 만들어진 Deploy는 기본적으로 Replica Set 1개를 가지고 있다. 다음 명령어를 입력해보자.

    $ kubectl get rs
    NAME                    DESIRED   CURRENT   READY   AGE
    simple-app-668579db64   1         1         1       1m12s

     

    그리고 이렇게 만들어진 Replica Set--image로 전달받은 이미지의 컨테이너를 기본적으로 1개를 띄운다. 이걸 Pod이라고 부른다. 쉽게 생각해서, Replica SetPod의 개수를 나타낸다고 볼 수 있다.

     

    Pod쿠버네티스에서 컨테이너를 관리하는 가장 작은 단위인데, 한 개의 Pod은 내부 IP를 지니고 있으며, 그 안에는 컨테이너가 여러 개일 수 있다. 하지만 1 Pod 1 Container를 권장한다. 이제 띄어진 Pod을 살펴보자.

    $ kubectl get pod
    NAME                          READY   STATUS    RESTARTS   AGE
    simple-app-668579db64-kcjxq   1/1     Running   0          2m58s

     

    다음 명령어로 Pod에 대한 자세한 내용을 확인할 수 있다.

    $ kubectl describe pod simple-app-668579db64-kcjxq
    Name:         simple-app-668579db64-kcjxq
    Namespace:    default
    Priority:     0
    Node:         gke-gurumee-gke-default-pool-6805db09-6kjp/10.178.0.4
    Start Time:   Tue, 06 Jul 2021 10:37:21 +0000
    Labels:       app=simple-app
                  pod-template-hash=668579db64
    Annotations:  <none>
    Status:       Running
    IP:           10.20.2.3
    IPs:
      IP:           10.20.2.3
    Controlled By:  ReplicaSet/simple-app-668579db64
    Containers:
      simple-app:
        Container ID:   containerd://c494b57a4611967060fb1d487d51103f0ad421c2f568ddb4bd8571d3b0d8ec44
        Image:          gurumee92/simple-app
        Image ID:       docker.io/gurumee92/simple-app@sha256:baf83add38ca5429adb80edc8e1647179d1771e853e00ae95c274bccc3b0dcd1
        Port:           <none>
        Host Port:      <none>
        State:          Running
          Started:      Tue, 06 Jul 2021 10:37:47 +0000
        Ready:          True
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-j2jx5 (ro)
    Conditions:
      Type              Status
      Initialized       True
      Ready             True
      ContainersReady   True
      PodScheduled      True
    Volumes:
      default-token-j2jx5:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-j2jx5
        Optional:    false
    QoS Class:       BestEffort
    Node-Selectors:  <none>
    Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                     node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
    Events:
      Type    Reason     Age   From               Message
      ----    ------     ----  ----               -------
      Normal  Scheduled  10m   default-scheduler  Successfully assigned default/simple-app-668579db64-kcjxq to gke-gurumee-gke-default-pool-6805db09-6kjp
      Normal  Pulling    10m   kubelet            Pulling image "gurumee92/simple-app"
      Normal  Pulled     10m   kubelet            Successfully pulled image "gurumee92/simple-app" in 23.367111765s
      Normal  Created    10m   kubelet            Created container simple-app
      Normal  Started    10m   kubelet            Started container simple-app

     

    IP는 물론 이미지 이름, 컨테이너 ID, 현재 어떤 상태인지 확인할 수 있는 메세지까지 알 수 있다. 이제 이를 외부와 연결시켜보자. 이를 위해서는 Service라는 것을 만들어야 한다. 터미널에 다음을 입력한다.

    $ kubectl expose deployment simple-app --name simple-app-svc --type=LoadBalancer --port=8080
    service/simple-app-svc exposed

     

    위의 명령어는 simple-app이라는 Deploy를 로드 밸런서 형태, simple-app-svc 이름으로 8080번 포트를 매핑해서 외부로 노출시킨 것이다. 외부에서의 요청은 이제 이 Service가 처리하게 된다. 터미널에 다음을 입력해보자.

    $ kubectl get svc -w
    NAME             TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
    kubernetes       ClusterIP      10.24.0.1     <none>        443/TCP          38m
    simple-app-svc   LoadBalancer   10.24.14.37   <pending>     8080:31692/TCP   25s
    simple-app-svc   LoadBalancer   10.24.14.37   34.64.89.205   8080:31692/TCP   44s

     

    이제 이렇게 뜨면, EXTERNAL-IP의 IP와 8080번 포트로 브라우저에서 접속해보자. 다음처럼 보이면 성공이다.

    마지막으로 Replica Set을 이용해서 Pod 개수를 늘려보자. 터미널에 다음을 입력한다.

    $ kubectl scale deploy simple-app --replicas=3
    deployment.apps/simple-app scaled

     

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

    $ kubectl get pod -w
    NAME                          READY   STATUS              RESTARTS   AGE
    simple-app-668579db64-jhcxj   0/1     ContainerCreating   0          26s
    simple-app-668579db64-kcjxq   1/1     Running             0          20m
    simple-app-668579db64-s26ph   1/1     Running             0          26s
    simple-app-668579db64-jhcxj   1/1     Running             0          28s

     

    1/1이 3개 보이면 잘 된 것이다. 이제 외부 IP에서 연속으로 요청하면 "Hello World" 옆에 컨테이너 이름이 바뀔 것이다. 또한 내부에서도 이를 테스트해 볼 수 있다.

    $ kubectl exec simple-app-668579db64-jhcxj -- curl 10.24.14.37:8080 -s
    Hello World simple-app-668579db64-s26ph
    $ kubectl exec simple-app-668579db64-jhcxj -- curl 10.24.14.37:8080 -s
    Hello World simple-app-668579db64-kcjxq
    $ kubectl exec simple-app-668579db64-jhcxj -- curl 10.24.14.37:8080 -s
    Hello World simple-app-668579db64-jhcxj
    ...

     

    이제 다음 명령어를 입력하여 현재까지 만든 모든 것을 삭제한다.

    $ kubectl delete --all all
    pod "simple-app-668579db64-jhcxj" deleted
    pod "simple-app-668579db64-kcjxq" deleted
    pod "simple-app-668579db64-s26ph" deleted
    service "kubernetes" deleted
    service "simple-app-svc" deleted
    deployment.apps "simple-app" deleted
    replicaset.apps "simple-app-668579db64" deleted
Designed by Tistory.