05. 쿠버네티스 들어가기 (2)
이 문서는 인프런 강의 "데브옵스를 위한 쿠버네티스 마스터"을 듣고 작성되었습니다. 최대한 요약해서 강의 내용을 최소로 하는데 목표를 두고 있어서, 더 친절하고 정확한 내용을 원하신다면 강의를 구매하시는 것을 추천드립니다. => 강의 링크
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에 올려 볼 간단한 웹 서버를 만들어보자. 다음을 입력한다.
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
을 작성한다.
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 Set
은 Pod
의 개수를 나타낸다고 볼 수 있다.
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