Gurumee 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
728x90
반응형