본문 바로가기
대외활동/Google Cloud Study Jam

[Kubernetes 입문] Orchestrating the Cloud with Kubernetes

by 드인 2022. 7. 26.

Orchestrating the Cloud with Kubernetes


Orchestrating the Cloud with Kubernetes

 

Kubernetes를 통한 클라우드 조정 | Google Cloud Skills Boost

이 실습에서는 Google Container Engine을 사용하여 완전한 Kubernetes 클러스터를 프로비저닝하고, kubectl을 사용하여 Docker 컨테이너를 배포 및 관리하며, Kubernetes의 배포 및 서비스를 사용하여 애플리케

www.cloudskillsboost.google

 

1. 개요

- 참고:  은 GitHub에서 호스팅되며 예제 12-Factor 애플리케이션을 제공합니다. 이 실습에서는 다음 Docker 이미지로 작업합니다.

  • kelseyhightower/monolith - Monolith에는 인증 및 Hello 서비스가 포함됩니다.
  • kelseyhightower/auth - 인증 마이크로 서비스. 인증된 사용자에 대한 JWT 토큰을 생성합니다.
  • kelseyhightower/hello - 안녕하세요 마이크로서비스입니다. 인증된 사용자를 맞이합니다.
  • nginx - 인증 및 Hello 서비스에 대한 프론트엔드

 

- Kubernetes: latop에서 고가용성 다중 노드 클러스터, 공용 클라우드에서 온프레미스 배포, 가상 머신에서 베어 메탈에 이르기까지 다양한 환경에서 실행할 수 있는 오픈 소스 프로젝트(kubernetes.io

- Kubernetes Engine과 같은 관리형 환경을 사용하면 기본 인프라를 설정하는 대신 Kubernetes 경험 집중

 

2. 설정 및 요구 사항

 - Google Cloud Platform(GCP) 환경 설정

 

3. Task 1. Get the sample code

 1) Github 저장소 복제

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

 2) 디렉터리 변경

cd orchestrate-with-kubernetes/kubernetes

 - 샘플 레이아웃

deployments/  /* Deployment manifests */
  ...
nginx/        /* nginx config files */
  ...
pods/         /* Pod manifests */
  ...
services/     /* Services manifests */
  ...
tls/          /* TLS certificates */
  ...
cleanup.sh    /* Cleanup script */

 

4. Task 2. Quick Kubernetes Demo

1) nginx 컨테이너의 단일 인스턴스 시작

kubectl create deployment nginx --image=nginx:1.10.0

 - 배포가 실행되는 노드에 오류가 발생하더라도 배포가 포드를 계속 실행 상태로 유지

 - Kubernetes에서 모든 컨테이너는 포드에서 실행

 

2) 실행 중인 nginx 컨테이너 확인

kubectl get pods

 

3) Kubernetes 외부에 노출

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

 - Kubernetes는 공개 IP 주소가 연결된 외부 로드 밸런서를 생성

 - 공용 IP 주소에 도달한 모든 클라이언트는 서비스 뒤의 포드로 라우팅됨(nginx 포드)

 

4) 서비스 확인

kubectl get services

 

5) 외부 IP를 추가하여 Nginx 컨테이너를 원격으로 접속

curl http://<External IP>:80

 - Kubernetes는 실행 및 노출 명령 을 사용하여 기본적으로 사용하기 쉬운 워크플로를 지원

 

5. Task 3. Pods

Pod

  • 하나 이상의 컨테이너 컬렉션을 나타내고 보유
  • 일반적으로 서로에 대한 종속성이 강한 여러 컨테이너가 있는 경우 컨테이너를 단일 Pod 안에 패키징
  • monoluth 및 nginx 컨테이너가 포함된 포드가 있음
  •  Volumes
    • Pod가 살아있는 동안 지속되는 데이터 디스크이며 해당 포드의 컨테이너에서 사용
    • Pod는 콘텐츠에 대한 공유 네임스페이스를 제공
    • Pod 내부의 두 컨테이너는 서로 통신할 수 있으며 연결된 볼륨도 공유 가능
  • Pod는 네트워크 네임스페이스를 공유(Pod 당 하나의 IP 주소가 있음)

 

6. Task 4. Creating pods

 1) monolith pod 구성 파일 확인

cat pods/monolith.yaml

 - 구성 파일 출력

apiVersion: v1
kind: Pod
metadata:
  name: monolith
  labels:
    app: monolith
spec:
  containers:
    - name: monolith
      image: kelseyhightower/monolith:1.0.0
      args:
        - "-http=0.0.0.0:80"
        - "-health=0.0.0.0:81"
        - "-secret=secret"
      ports:
        - name: http
          containerPort: 80
        - name: health
          containerPort: 81
      resources:
        limits:
          cpu: 0.2
          memory: "10Mi"
  • Pod는 하나의 컨테이너(monolith)로 구성
  • 컨테이너가 시작될 때 몇 가지 인수를 컨테이너에 전달
  • http 트래픽을 위해 포트 80을 열음

 

7. Task 5. Interacting with pods

- 기본적으로 Pod에는 사설 IP 주소가 할당되며 클러스터 외부에서 연결할 수 없음

- kubectl port-forward: 로컬 포트를 monolith pod 내부의 포트에 매핑

1) 터미널 2개: 하나는 kubectl port-forward 명령을 실행하고 다른 하나는 cur 명령을 실행

 

2) 포트 전달 설정

kubectl port-forward monolith 10080:80

 

3) pod와 대화 시작

curl http://127.0.0.1:10080

 

4) 보안 엔드포인트에 도달했을 때 어떤 일이 발생하는지 확인

curl http://127.0.0.1:10080/secure

 

5) 로그인하여 monolith에서 인증 토큰 재발급

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

 

6) 로그인 프롬프트에서 비밀암호 "password"를 사용하여 로그인

 - 로그인하면 JWT 토큰프린트

 

7) 토큰에 대한 환경 변수 생성

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

 

8) 비밀 암호 "password"를 다시 입력

 

9) 복사한 다음 토큰을 사용하여 다음을 사용하여 보안 엔드포인트에 도달

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

 

10) Pod monolith에 대한 로그

kubectl logs monolith

 

11) 세 번째 터미널을 열고 실시간으로 발생하는 로그 스트림을 가져옴

kubectl logs -f monolith

 

12) monolith와 상호 작용하는 경우 로그 업데이트 확인

curl http://127.0.0.1:10080

 

13) Monolith Pod 내에서 대화형 셸 실행

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

 

14) Monolith 컨테이너에 셸이 있으면 외부 연결 테스트

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

 

15) 대화형 셸이 끝나면 로그아웃

exit

- 컨테이너를 원격으로 조종해야 하거나 로그인 셸을 가져와야 하는 경우 사용

 

 

8. Task 6. Services

- Pod는 영구적 X

- 활성 상태 또는 준비 상태 확인 실패와 같은 이유로 중지되거나 시작될 수 있으며, 이로 인해 문제가 발생

- Pod 집합과 통신하려는 경우 → 다시 시작할 때 다른 IP 주소를 가질 수 있음

- 서비스는 Pod에 안정적인 엔드포인트를 제공

- 서비스는 레이블을 사용하여 작동하는 Pod 결정

- Pod에 올바른 레이블이 있으면 자동으로 선택되어 서비스 노출

- 서비스가 Pod 세트에 제공하는 액세스 수준은 서비스 유형에 따라 다름

  • ClusterIP(내부): 기본 유형, 이 서비스가 클러스터 내부에서만 볼 수 있음
  • NodePort: 클러스터의 각 노드에 외부에서 액세스할 수 있는 IP 제공
  • LoadBalancer: 서비스에서 서비스 내의 노드로 트래픽을 전달하는 클라우드 공급자의 로드 밸런서 추가

 

9. Task 7. Creating a service

- 서비스를 생성하기 전에 먼저 https 트래픽을 처리할 수 있는 보안 포드 생성

1) 디렉터리 변경

cd ~/orchestrate-with-kubernetes/kubernetes

 

2) monolith 서비스 구성 파일 탐색

cat pods/secure-monolith.yaml

 

3) secure-monolith pods 및 해당 구성 데이터 작성

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 pod가 있으므로 secure-monolith pod를 외부에 노출할 수 있음. 

 - 노출하기 위해 Kubernetes 서비스를 생성

 

4) monolith 서비스 구성 파일 탐색

cat services/monolith.yaml

- Output

kind: Service
apiVersion: v1
metadata:
  name: "monolith"
spec:
  selector:
    app: "monolith"
    secure: "enabled"
  ports:
    - protocol: "TCP"
      port: 443
      targetPort: 443
      nodePort: 31000
  type: NodePort
  • app: monolith, secure: enabled: 레이블이 있는 모든 Pod를 자동으로 찾고 노출하는데 사용되는 선택기 
  • 포트 31000에서 nginx(포트 443에서)로 외부 트래픽을 전달하는 방법이므로 여기에서 노드 포트를 노출해야 함

5) 모놀리식 서비스 구성 파일에서 모놀리식 서비스 생성

kubectl create -f services/monolith.yaml

 

6) 노출된 노드 포트에서 모놀리식 서비스에 대한 트래픽 허용

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

 

7) 포트 전달을 사용하지 않고 클러스터 외부에서 보안 모놀리스 서비스 접속

 

 (1) 노드 중 하나에 대한 외부 IP 주소를 가져옴

gcloud compute instances list

 (2) 보안 모놀리식 서비스 접속

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

- 시간 초과 발생


10. Task 8. Adding labels to pods

- 현재 모놀리스 서비스에는 끝점이 없음

- 레이블 쿼리와 함께 kubectl get pods 명령을 사용하여 해결

1) 모놀리스 레이블로 실행 중인 pod 확인

kubectl get pods -l "app=monolith"

 

2) "app=monolith" 및 "secure=enabled"

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

 - 레이블 쿼리는 결과 프린트 X

 

3) 보안 모노리스 pod에 누락된 레이블 추가

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

 

4) 모놀리스 서비스에서 엔드포인트 목록 확인

kubectl describe services monolith | grep Endpoints

 

5) 노드 중 하나 테스트

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


11. Task 9. Deploying applications with Kubernetes

- 배포는 실행 중인 Pod 수가 사용자가 지정한 원하는 Pod 수와 동일하도록 하는 선언적 방법

- 배포의 주요 이점: Pod 관리의 낮은 수준 세부 정보를 추상화

  • 백그라운드에서 배포는 복제본 세트 를 사용하여 Pod 시작 및 중지 관리
  • Pod를 업데이트하거나 확장해야 하는 경우 배포에서 처리
  • Pod가 다운되는 경우 배포는 Pod reboot도 처리

- Pod는 생성된 노드의 수명과 연결

- 위의 예에서 Node3이 다운(Pod와 함께 사용). 

- 새 포드를 수동으로 생성하고 이에 대한 노드를 찾는 대신, 배포에서 새 포드를 생성하고 Node2에서 시작

 

12. Task 10. Creating deployments

- 모놀리스 앱

  • auth - 인증된 사용자에 대한 JWT 토큰을 생성
  • hello - 인증된 사용자를 환영
  • frontend - auth 및 hello 서비스로 트래픽을 라우팅

1) 인증 배포 구성 파일 검사

cat deployments/auth.yaml

- 배포에서 1개의 복제본이 생성되고 인증 컨테이너 버전 2.0.0을 사용

- 인증 배포를 생성하면, 배포 매니페스트의 데이터를 준수하는 하나의 포드가 생성

- Replicas 필드에 지정된 수를 변경하여 Pod 수를 확장할 수 있음

 

2) 배포 개체 생성

kubectl create -f deployments/auth.yaml

 

3) 인증 배포를 위한 서비스 생성

kubectl create -f services/auth.yaml

 

4) 동일한 작업을 수행하여 hello 배포를 만들고 노출

kubectl create -f deployments/hello.yaml
kubectl create -f services/hello.yaml

 

5) 프론트엔드 배포를 만들고 노출

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

 

6) 외부 IP를 가져온 다음 컬링하여 프런트엔드와 상호 작용

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