GOAL
- Kubernetes Engine을 사용하여 전체 Kubernetes cluster를 provisioning 하는 방법
kubectl
을 사용하여 Docker container를 관리하고 배포하는 방법- Kubernetes 배포와 서비스를 사용하여 애플리케이션을 microservices로 분할하는 방법
gcloud config set compute/zone us-central1-b
gcloud container clusters create io
re-authenticate
cloud shell과 연결이 끊겼을 때 재인증
gcloud container clusters get-credentials io
Kubernetes Engine은 몇몇 가상 머신을 프로비저닝하기 때문에 cluster 생성에 시간이 소요됨
# 결과
kubeconfig entry generated for io.
NAME: io
LOCATION: us-central1-b
MASTER_VERSION: 1.24.10-gke.2300
MASTER_IP: 104.154.24.73
MACHINE_TYPE: e2-medium
NODE_VERSION: 1.24.10-gke.2300
NUM_NODES: 3
STATUS: RUNNING
gsutil cp -r gs://spls/gsp021/* .
cd orchestrate-with-kubernetes/kubernetes
kubectl create
kubectl create deployment nginx --image=nginx:1.10.0
deployment
는 pods를 실행시키고, node가 실행에 실패할 때도 운영해준다.
쿠버네티스에서 모든 컨테이너는 pod에서 실행된다.
kubectl get pods
결과
NAME READY STATUS RESTARTS AGE
nginx-68899cc8d6-8j5vj 1/1 Running 0 3m2s
kubectl expose deployment nginx --port 80 --type LoadBalancer
# service/nginx exposed
공용 IP address에 외부 Load Balancer가 생성됨
- 공용 IP address로 접근하면 nginx로 route 됨
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.72.0.1 <none> 443/TCP 18m
nginx LoadBalancer 10.72.7.104 34.173.46.242 80:32109/TCP 2m25s
curl http://<External IP>:80
Pods는 한 개 이상의 container들의 집합을 나타낸다. 일반적으로 다른 것들과 강한 종속성을 가지는 여러 개의 container들이 있다면 이 container들을 하나의 pod에 묶을 수 있다. (패키지 할 수 있다.)
Pods
한 개 이상의 container들의 집합
각 container 들이 강한 종속성을 보이는 경우에 하나의 pod로 package 할 수 있다.
Volumes
Pod에서 container에 의해 사용될 수 있는 data disk
Pods는 container들에 대해 shared namespace를 제공하고, container 끼리 서로 통신이 가능하며 부착된 volume을 공유한다.
Pods는 network namespace를 공유하며, pod 당 하나의 IP Address를 갖는다.
cd ~/orchestrate-with-kubernetes/kubernetes
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는 하나의 container
monolith
로 구성- 시작할 때 container에 arguments를 전달
- http traffic을 위해 80 port 개방
kubectl create -f pods/monolith.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE
monolith 1/1 Running 0 21s
nginx-68899cc8d6-8j5vj 1/1 Running 0 13m
kubectl describe pods monolith
# 결과
Name: monolith
Namespace: default
Priority: 0
Service Account: default
Node: gke-io-default-pool-b4f4f7b4-qzb7/10.128.0.3
Start Time: Wed, 26 Apr 2023 16:56:10 +0000
Labels: app=monolith
Annotations: <none>
Status: Running
IP: 10.68.0.4
기본 값으로, pods는 private IP address에 할당되고 클러스터 밖에서는 접근이 불가능하다.
kubectl port-forward
로 monolith pod 내의 port와 local port를 맵핑해보자.
kubectl port-forward monolith 10080:80
curl http://127.0.0.1:10080
# {"message":"Hello"}
curl http://127.0.0.1:10080/secure
# authorization failed
curl -u user http://127.0.0.1:10080/login
# JWT 토큰이 반환됨
# 환경 변수에 저장하기
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
kubectl logs monolith
# 실시간 로그 확인
kubectl logs -f monolith
2023/04/26 16:56:14 Starting server...
2023/04/26 16:56:14 Health service listening on 0.0.0.0:81
2023/04/26 16:56:14 HTTP service listening on 0.0.0.0:80
127.0.0.1:51648 - - [Wed, 26 Apr 2023 17:01:57 UTC] "GET / HTTP/1.1" curl/7.74.0
127.0.0.1:54146 - - [Wed, 26 Apr 2023 17:02:07 UTC] "GET /secure HTTP/1.1" curl/7.74.0
127.0.0.1:59542 - - [Wed, 26 Apr 2023 17:04:08 UTC] "GET /login HTTP/1.1" curl/7.74.0
kubectl exec
Container 내에서 trouble shooting이 필요한 경우 사용할 수 있음
kubectl exec monolith --stdin --tty -c monolith -- /bin/sh
예를 들어
, pod 내부에서 외부로 연결성을 확인해볼 수 있다.ping -c 3 google.com
PING google.com (142.250.152.139): 56 data bytes
64 bytes from 142.250.152.139: seq=0 ttl=114 time=0.937 ms
64 bytes from 142.250.152.139: seq=1 ttl=114 time=0.425 ms
64 bytes from 142.250.152.139: seq=2 ttl=114 time=0.438 ms
--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.425/0.600/0.937 ms
Pods들은 영구적이지 않고, 재실행될 때 마다 다른 IP 주소를 가진다.
Pods 간 연결을 위해서는Services
가 필요하다.
Services
Services는 labels를 이용하여 동작중인 Pods를 결정
Service가 pods의 집합에 제공하는 접근 레벨은 Service 의 타입에 의해 결정된다.
ClusterIP
(internal)NodePort
LoadBalancer
cd ~/orchestrate-with-kubernetes/kubernetes
cat pods/secure-monolith.yaml
# 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
cat services/monolith.yaml
kind: Service
apiVersion: v1
metadata:
name: "monolith"
spec:
selector:
app: "monolith"
secure: "enabled"
ports:
- protocol: "TCP"
port: 443
targetPort: 443
nodePort: 31000
type: NodePort
label 에 해당하는
app:monolith
그리고 secure 설정에 해당하는secure:enabled
가 선택기에 의해 찾아지고 외부로 노출되는데 사용됨
kubectl create -f services/monolith.yaml
사용하고 있는 port는 다른 앱에서 사용할 수 없음
gcloud compute firewall-rules create allow-monolith-nodeport --allow=tcp:31000
Creating firewall...working..Created [https://www.googleapis.com/compute/v1/projects/qwiklabs-gcp-04-7e1a6c611d55/global/firewalls/allow-monolith-nodeport].
Creating firewall...done.
NAME: allow-monolith-nodeport
NETWORK: default
DIRECTION: INGRESS
PRIORITY: 1000
ALLOW: tcp:31000
DENY:
DISABLED: False
gcloud compute instances list
curl -k https://<EXTERNAL_IP>:31000
kubectl get services monolith
kubectl describe services monolith
Questions
- Why are you unable to get a response from the monolith service?
- How many endpoints does the monolith service have?
- What labels must a Pod have to be picked up by the monolith service?
Monolith service는 endpoints가 없다.
따라서, troubleshoot을 위해서kubectl get pods
와 label query를 사용해야 한다.
kubectl get pods -l "app=monolith"
NAME READY STATUS RESTARTS AGE
monolith 1/1 Running 0 30m
secure-monolith 2/2 Running 0 12m
kubectl get pods -l "app=monolith,secure=enabled"
# No resources found in default namespace.
kubectl label pods secure-monolith 'secure=enabled'
kubectl get pods secure-monolith --show-labels
NAME READY STATUS RESTARTS AGE LABELS
secure-monolith 2/2 Running 0 14m app=monolith,secure=enabled
kubectl describe services monolith | grep Endpoints
# Endpoints: 10.68.0.5:443
gcloud compute instances list
NAME: gke-io-default-pool-b4f4f7b4-qt21
ZONE: us-central1-b
MACHINE_TYPE: e2-medium
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.4
EXTERNAL_IP: 34.173.33.39
STATUS: RUNNING
NAME: gke-io-default-pool-b4f4f7b4-qw1s
ZONE: us-central1-b
MACHINE_TYPE: e2-medium
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.5
EXTERNAL_IP: 34.122.109.212
STATUS: RUNNING
NAME: gke-io-default-pool-b4f4f7b4-qzb7
ZONE: us-central1-b
MACHINE_TYPE: e2-medium
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.3
EXTERNAL_IP: 35.188.211.125
STATUS: RUNNING
curl -k https://<EXTERNAL_IP>:31000
Production에서 container를 관리하고 scaling 할 준비
Deployments
Pods를 관리하는 저레벨의 동작을 추상화
Pods의 실행과 중지를 관리하기 위해 Replica Sets를 사용
Pods가 update 또는 확장이 필요할 때 Deployment가 이를 도울 수 있고, Pods가 down 되었을 경우 재시작을 할 수 있음
monolith app 살펴보기
- auth : 인가받은 사용자에 대한 JWT 발급
- hello
- frontend
auth deployment configuration file
cat deployments/auth.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth
spec:
selector:
matchlabels:
app: auth
replicas: 1
template:
metadata:
labels:
app: auth
track: stable
spec:
containers:
- name: auth
image: "kelseyhightower/auth:2.0.0"
ports:
- name: http
containerPort: 80
- name: health
containerPort: 81
Replica 가 한 개로, 확장하고 싶다면 이 개수를 늘려주면 됨
kubectl create -f deployments/auth.yaml
kubectl create -f services/auth.yaml
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
kubectl get services frontend
curl -k https://<EXTERNAL-IP>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.72.5.188 <pending> 443:30768/TCP 2s
구글 퀵랩 Kubernetes in Google Cloud를 학습하고 정리한 내용입니다.