솜이의 데브로그

Google Cloud Study Jam Kubernetes Lab3 본문

dev/etc

Google Cloud Study Jam Kubernetes Lab3

somsoming 2022. 10. 26. 22:59

Lab3 : Orchestrating the Cloud with Kubernetes

Lab 목표

  • Kubernetes Engine을 활용한 Kubernetes cluster provision
  • kubectl 이용한 도커 컨테이너 배포 및 관리
  • Kubernetes의 Deployments와 Services를 활용해 application을 microservice 로 쪼개기
gcloud config set compute/zone us-central1-b

zone 설정

 

gcloud container clusters create io

클러스터 생성

 

1. Get the sample code

gsutil cp -r gs://spls/gsp021/* .

GitHub repository를 클론한다.

gs 로 시작하는게 google cloud storage 접근하는것.

필요한 디렉토리로 이동한다.

 

 

2. Quick Kubernetes Demo

쿠버네티스를 시작하는 가장 쉬운 방법은 kbect1 create 커맨드를 사용하는 것이다.

kubectl create deployment nginx --image=nginx:1.10.0

위 명령어 사용하여 쿠버네티스 배포를 생성한다.

실행중인 노드에 장애가 발생하더라도 배포는 계속 실행된다.

쿠버네티스에서는 모든 컨테이너들이 pod에서 실행된다.

kubectl get pods

실행중인 nginx 컨테이너를 확인한다.

kubectl expose deployment nginx --port 80 --type LoadBalancer

nginx 컨테이너가 실행중이면 위 명령어를 통해 쿠버네티스 외부에 expose 할 수 있다.

 

쿠버네티스가 공용 IP 주소를 통해 외부 로드밸런서를 생성했다.

해당 공용 IP 주소를 조회하는 모든 클라이언트는 해당 pod로 라우팅된다.

위 경우에는 nginx pod로 라우팅된다.

kubectl get services

현재 사용중인 서비스 리스트를 조회한다.

 

curl http://<External IP>:80

Nginx 컨테이너를 원격으로 hit 하기 위해 위 명령어를 사용한다.

 

3. Pods

쿠버네티스의 핵심에는 Pod 가 있다.

 

Pods는 하나 이상의 컨테이너 집합을 나타낸다. 서로에 대한 의존도가 높은 여러개의 컨테이너가 있는 경우 컨테이너를 단일 pod 내에 패키징한다.

 

Pods에는 Volumes가 있다.

 

볼륨은 pods가 살아있는 동안 지속되는 데이터 디스크로, 해당 pod의 컨테이너에서 사용 가능하다. Pods는 가지고 있는 내용에 대한 shared namespace를 제공하여 pod 내부의 컨테이너들이 서로 통신할 수 있고, 연결되어 있는 볼륨도 공유할 수 있도록 한다.

 

Pods는 network namespace도 공유하여 하나의 pod당 하나의 IP Address를 가지고 있다.

 

4. Creating pods

Pod는 pod configuration file을 통해 생성된다.

 

cat pods/monolith.yaml

  • 현재 pod는 하나의 컨테이너 (monolith)로 이루어져있다.
  • 컨테이너가 시작할 때 몇가지 argument들을 전달한다.
  • http traffic 을 위해 80번 포트를 연다.

 

kubectl create -f pods/monolith.yaml

위 명령어를 사용해 monolith pod를 생성한다.

 

kubectl get pods

default namespace에서 실행중인 모든 pod 리스트를 확인한다.

 

kubectl describe pods monolith

monolith pod 에 대한 정보들 출력

  • Pod IP 주소와 event log를 포함한 정보들을 확인 가능하다.
    • troubleshooting 시 용이하게 사용가능

 

5. Interacting with pods

기본적으로 pod들은 할당된 사설 IP 주소이고 클러스터 외부에서 접근이 불가능하다. 따라서 kubecgtl port-forward 명령어를 통해 로컬 포트를 monolith pod 내부로 매핑해야한다.

새로운 터미널을 열어 하나는 kubectl port-forward 명령어를 실행하고 다른 터미널은 curl 명령어를 실행한다.

kubectl port-forward monolith 10080:80

 

curl <http://127.0.0.1:10080>

curl 명령어를 이용해 pod와 소통하기

컨테이너에서 “hello” 메시지를 수신한 것을 확인할 수 있다.

curl <http://127.0.0.1:10080/secure>

authroization fail 응답을 수신한다.

 

curl -u user <http://127.0.0.1:10080/login>

password를 입력하라고 해서 입력하면 로그인이 성공하고, JWT token을 수신받는다.

 

TOKEN=$(curl <http://127.0.0.1:10080/login> -u user|jq -r '.token')

토큰 정보 변수 생성

 

curl -H "Authorization: Bearer $TOKEN" <http://127.0.0.1:10080/secure>

Bearer Token을 담아 다시 보내면 제대로된 응답을 받게 된다.

 

kubectl logs monolith

monolith Pod의 로그를 보기 위해 위 명령어를 사용한다.

 

kubectl logs -f monolith

새로운 터미널에서 -f 옵션을 붙여 실행하면 실시간으로 발생하는 로그 스트림을 받을 수 있다.

 

kubectl exec monolith --stdin --tty -c monolith -- /bin/sh

Monolith Pod 내부에서 interactive shell을 실행하기 위해 위 명령어를 사용한다.

 

이런식으로 외부에 ping 명령어 등을 이용해 외부 연결성을 테스트할 수 있다.

exit

interactive shell을 종료할 때는 exit 명령어를 사용한다.

 

서비스는 pod에다가 매핑해서 계속 관리해주는 하나의 cluster는 최소 마스터 서비스를 가지고있음.

 

6. Services

Pods들은 영원하지않다. 만약 재시작되면 해당 pod들은 다른 IP 주소를 가지게 될 것이다. 이럴 때 Services를 사용한다.

 

Services는 pods들의 고정 endpoint를 제공한다.

 

서비스는 라벨을 사용하여 어떤 pod에서 작동하는지 판별한다.

 

서비스 타입에 따른 service 단계

  • ClusterIP (internal) : 해당 서비스가 클러스터 내부에서만 보인다
  • NodePort : 클러스터의 각 노드에 외부에서 액세스할 수 있는 Ip를 제공
  • LoadBalancer : 클라우드 제공자의 로드밸런서를 사용하여 서비스에서 노드로 트래픽을 전달한다.

이제 서비스를 생성하고 label selectors를 이용하여 외부에 노출하자.

 

7. Creating a service

서비스 생성 전 https traffic를 다루는 안전한 pod를 생성한다.

 

kubectl create secret generic tls-certs --from-file tls/
kubectl create configmap nginx-proxy-conf --from-file nginx/proxy.conf
kubectl create -f pods/secure-monolith.yaml

secure-monolith pods 와 configuration data를 생성한다.

 

cat services/monolith.yaml

monolith service configuration file

  • 라벨 app: monolith 와 secure: enbaled 가 있는 pod들을 자동으로 찾고 expose 하는 selector가 있다.
  • 여기에 nodeport를 expose해서 31000번 포트에서 ngins(port 443)으로 외부 트래픽을 전송해야한다.

 

kubectl create -f services/monolith.yaml

위 명령어를 사용해 monolith service configuration file로부터 monolith service를 생성한다.

 

이제 서비스를 expose 하기 위해 31000번 포트를 사용하고 있다.

다른 앱이 해당 포트에 바인딩하려고 하면 충돌이 생긴다.

일반적으로 쿠버네티스는 이러한 포트 assignment를 조정한다.

 

gcloud compute firewall-rules create allow-monolith-nodeport \\
  --allow=tcp:31000

위 명령어를 이용해 exposed node port의 monolith service로의 트래픽을 허용한다.

 

이제 클러스터 외부에서 port forwarding 없이도 secure-monolith service에 hit 할 수 있다.

gcloud compute instances list

위 명령어를 통해 노드 중 하나의 외부 IP 주소를 확인한다.

 

curl -k https://<EXTERNAL_IP>:31000

이러면 문제가 발생한다. 이제 해결해보자

 

8. Adding labels to pods

지금 monolith service는 endpoint를 가지고 있지 않다.

kubectl get pods -l "app=monolith"

monolith label을 가지고 있는 실행중인 pods들을 확인할 수 있다.

 

kubectl get pods -l "app=monolith,secure=enabled"

구체적인 라벨들을 확인하면?

아무런 리소스도 없는 것을 확인할 수 있다.

그렇기 때문에 위에서 오류가 났던 것이고, secure=enabled 라벨을 추가해주어야한다.

 

kubectl label pods secure-monolith 'secure=enabled'
kubectl get pods secure-monolith --show-labels

라벨을 붙이고 라벨이 업데이트 되었는지 확인한다.

 

kubectl describe services monolith | grep Endpoints

정상적으로 잘 붙었다면 monolith 서비스의 엔드포인트 리스트를 확인한다.

 

gcloud compute instances list
curl -k https://<EXTERNAL_IP>:31000

잘 돌아간다!

 

9. Deploying applications with Kubernetes

이제 컨테이너들을 scaling하고 매니징해보자.

Deployments는 실행 중인 pods의 수가 사용자가 지정한 원하는 pods의 수와 같도록 하는 방법이다.

 

The main benefit of Deployments is in abstracting away the low level details of managing Pods. Behind the scenes Deployments use Replica Sets  to manage starting and stopping the Pods. If Pods need to be updated or scaled, the Deployment will handle that. Deployment also handles restarting Pods if they happen to go down for some reason.

 

10. Creating deployments

현재 진행하던 앱을 세가지 파트로 나누면

  • auth : 인증된 사용자들에게 JWT token 생성
  • hello : 인증된 사용자들에게 인사
  • frontend : auth와 hello 서비스들에 트래픽을 라우팅함.

 

auth와 hello deployments를 위한 내부적인 서비스들을 정의하고 frontend deployment를 위한 외부 서비스를 정의한다.

 

cat deployments/auth.yaml

auth deployment configuration file 생성

  • deployment는 하나의 replica를 생성하는 것이다.
  • auth 컨테이너의 버전 2.0.0 을 사용한다.
  • When you run the kubectl create  command to create the auth deployment it will make one pod that conforms to the data in the Deployment manifest. This means you can scale the number of Pods by changing the number specified in the Replicas field.

 

kubectl create -f deployments/auth.yaml

위 명령어로 deployment object를 생성한다.

 

kubectl create -f services/auth.yaml

auth deployment를 위한 서비스를 생성한다.

 

kubectl create -f deployments/hello.yaml
kubectl create -f services/hello.yaml
kubectl create configmap nginx-frontend-conf --from-file=nginx/frontend.conf
kubectl create -f deployments/frontend.yaml
kubectl create -f services/frontend.yaml

동일하게 hello deployment와 frontend Deployment에도 적용한다.

 

kubectl get services frontend
curl -k https://<EXTERNAL-IP>

frontend의 외부 IP 주소를 통해 curling해서 interact 한다.

 

Study More

  • Pod가 무엇인지?
  • LoadBalancer
  • Scaling 이 무엇이냐악

LoadBalancer 서비스 타입은 단지 한개의 내부 서비스를 외부 사용자들에게 접근 가능하도록 만드는 일을 담당합니다. 반대로 Ingress 서비스 타입은 여러개의 서비스가 한개 로드 밸런서를 통해 유연한 설정을 할 수 있게 만듭니다.

 

Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?

 

Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?

Recently, someone asked me what the difference between NodePorts, LoadBalancers, and Ingress were. They are all different ways to get…

medium.com

 

Load Balancer는 한개의 내부 서비스를 외부로 접근 가능한거고

Ingress는 load balancer를 대체하면서 들어감. L7 계층에서 라우팅을해주는것. 그래서 url까지 라우팅해줌.

 

L4 는 단순히 부하를 분산시키는것.