2021. 5. 11. 08:15ㆍIT 공부/Qwiklabs
※ 본 카테고리에서는 구글 클라우드 스터디잼을 통해 제공받은 퀵랩에서 자유롭게 퀘스트를 수행하며 공부한 내용을 기록하고 있습니다.
google.qwiklabs.com/focuses/557?parent=catalog
실습 목표 : 간단한 쿠버네티스 demo 경험 (쿠버네티스 인프라 설정이 주요 목적이 아님!)
- 모놀리식(monolithic architecture)
: 하나의 서비스가 하나의 거대한 아키텍처를 갖는 것.
하나의 비지니스 로직과 하나의 DB를 갖는다.
같은 어플리케이션을 하나 더 만듦으로써 고가용성 서버를 만들 수 있다.
: 반대로는 마이크로 서비스 아키텍처(micro service architecture, MSA)가 있다.
(참고)
- JWT (json web token)
:
(URL 인코딩, RFC3986 참고)
URL에 문자를 16진수로 나타내는 인코딩 방법
ko.wikipedia.org/wiki/%ED%8D%BC%EC%84%BC%ED%8A%B8_%EC%9D%B8%EC%BD%94%EB%94%A9
(OAuth 참고)
OAuth는 인증을 위한 프로토콜로써 ⓐ의 정보를 가져다가 ⓑ의 서비스를 이용할 수 있게끔 지원하는 API 접근 위임
(Token참고)
유저의 인증 상태를 서버나 세션에 저장하지 않는 stateless 토큰 기반 인증 시스템
(JWT, RFC7519 참고)
필요한 모든 정보를 자체적으로 지니고 있는 json 객체를 사용하여 정보를 전달하는 토큰 인증 시스템
1. cloud shell 환경에서 영역 설정
gcloud config set compute/zone us-central1-b
// Updated property [compute/zone].
2. 영역 설정 후 실습에 사용할 클러스터 시작
gcloud container clusters create io
// kubeconfig entry generated for io.
// NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
// io us-central1-b 1.18.17-gke.100 35.193.134.2 e2-medium 1.18.17-gke.100 3 RUNNING
3. 깃허브 저장소 클론
gsutil cp -r gs://spls/gsp021/* .
4. 실습에 필요한 디렉토리로 변경 후 파일 확인
cd orchestrate-with-kubernetes/kubernetes
ls
deployments/ 디플로이먼트 매니페스트 |
|
nginx/ nginx 구성 파일 |
|
pods/ 포드 매니페스트 |
|
services/ 서비스 매니페스트 |
|
tls/ TLS 인증서 |
|
cleanup.sh 정리 스크립트 |
5. kubectl create 명령어를 사용하여 nginx 컨테이너(k8s)의 단일 인스턴스를 실행
→ k8s가 배포를 생성함
→ pod가 작동함 (이 때, pod가 실행한느 노드에 오류가 발생해도 계속 작동함)
kubectl create deployment nginx --image=nginx:1.10.0
// deployment.apps/nginx created
6. 실행중인 nginx 컨테이너를 확인
kubectl get pods
// NAME READY STATUS RESTARTS AGE
// nginx-55c6b6cb9c-t5z6b 1/1 Running 0 5m7s
7. kubectl expose 명령어를 사용하여 kubernetes 외부로 실행중인 nginx 컨테이너를 노출
→ k8s가 백그라운드에서 공개 IP주소가 첨부된 로드밸런서(외부 부하 분산기)를 생성함
→ 해당 IP주소를 조회하는 모든 클라이언트는 서비스 백그라운드에 있는 (이 경우에는) nginx의 포드로 라우팅됨
kubectl expose deployment nginx --port 80 --type LoadBalancer
// service/nginx exposed
8. 서비스 나열하기
kubectl get services
// NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
// kubernetes ClusterIP 10.3.240.1 <none> 443/TCP 12m
// nginx LoadBalancer 10.3.252.228 35.238.132.82 80:30012/TCP 3m33s
9. 원격으로 nginx 컨테이너를 조회하기 위해 외부 IP를 추가
curl http://35.238.132.82:80
/*
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/*
10. k8s에서 kubectl을 사용하여 클러스터 만들기 및 nginx 실행, expose 완료
- 포드 (Pods)
: k8s에서 1개 이상의 컨테이너가 포함된 모음
일반적으로 상호 의존성이 높은 컨테이너가 여러 개 있으면 하나의 포드에 패키징한다.
네임스페이스(namespace)를 공유한다.
pod당 하나의 IP를 갖는다.
포드에는 데이터 디스크인 볼륨이 포함되어 있다.
같은 포드 내의 컨테이너들은 통신할 수 있으며 첨부된 볼륨을 공유한다.
포드는 영구적으로 지속되지 않는다. (활성 여부 또는 준비 상태 검사 오류 등의 이유)
포트가 다시 시작되면 IP 주소가 바뀔 수 있다.
- 포드 만들기
: 포드 구성 파일을 사용하여 만들 수 있다.
1. 모놀리식(1개의 컨테이너) 포드 구성 파일 확인하기
cat pods/monolith.yaml
/*
apiVersion: v1
kind: Pod
metadata:
name: monolith
labels:
app: monolith
spec:
containers: # 1개의 컨테이너로 구성된 포드
- 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 # HTTP 트래픽용 포드 80이 개방됨
- name: health
containerPort: 81
resources:
limits:
cpu: 0.2
memory: "10Mi"
*/
2. kubectl을 사용하여 모놀리식 포드 만들기
→ 모놀리식 포드는 Docker Hub에서 모놀리식 컨테이너 이미지를 가져와서 실행하게 된다.
kubectl create -f pods/monolith.yaml
// pod/monolith created
3. kubectl get pods 명령어로 기본 네임스페이스에서 실행 중인 모든 포드 나열하기
kubectl get pods
// NAME READY STATUS RESTARTS AGE
// monolith 1/1 Running 0 56s
// nginx-55c6b6cb9c-t5z6b 1/1 Running 0 33m
4. kubectl describe 명령어로 모놀리식 포드에 관한 상세 정보 출력하기
kubectl describe pods monolith
/*
Name: monolith
Namespace: default
Priority: 0
Node: gke-io-default-pool-f7d25527-dk51/10.128.0.4
Start Time: Tue, 11 May 2021 00:49:16 +0000
Labels: app=monolith
Annotations: <none>
Status: Running
IP: 10.0.0.6
IPs:
IP: 10.0.0.6
Containers:
monolith:
Container ID: docker://133c96c864cc1772e72792ceaad6f36b9ea08c65a57277f198d277733ac0ecaf
Image: kelseyhightower/monolith:1.0.0
Image ID: docker-pullable://kelseyhightower/monolith@sha256:72c3f41b6b01c21d9fdd2f45a89c6e5d59b8299b52d7dd0c9491745e73db3a35
Ports: 80/TCP, 81/TCP
Host Ports: 0/TCP, 0/TCP
Args:
-http=0.0.0.0:80
-health=0.0.0.0:81
-secret=secret
State: Running
Started: Tue, 11 May 2021 00:49:19 +0000
Ready: True
Restart Count: 0
Limits:
cpu: 200m
memory: 10Mi
Requests:
cpu: 200m
memory: 10Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bzvxk (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-bzvxk:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bzvxk
Optional: false
QoS Class: Guaranteed
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 3m14s default-scheduler Successfully assigned default/monolith to gke-io-default-pool-f7d25527-dk51
Normal Pulling 3m13s kubelet Pulling image "kelseyhightower/monolith:1.0.0"
Normal Pulled 3m11s kubelet Successfully pulled image "kelseyhightower/monolith:1.0.0"
Normal Created 3m11s kubelet Created container monolith
Normal Started 3m11s kubelet Started container monolith
*/
- 포드와 상호작용하기
: 포드는 기본적으로 비공개 IP 주소가 부여되어 클러스터 밖에서는 접근할 수 없다.
따라서, 로컬포트를 모놀리식 포드 안의 포트로 매핑하는 작업이 필요하다.
1. cloud shell 상단의 open a new tab (+)을 클릭하여 두 번째 터미널을 연다.
2. 두 번째 터미널에서 포드 전달을 설정
kubectl port-forward monolith 10080:80
// Forwarding from 127.0.0.1:10080 -> 80
3. 첫 번째 터미널에서 curl을 사용하여 pod와 통신을 시작
curl http://127.0.0.1:10080
// {"message":"Hello"}
4. 보안이 설정된 엔드포인트를 조회하면 인증 실패하므로, 인증 토큰을 얻기 위해 로그인
→ 로그인 성공 후 JWT 토큰 출력됨
curl -u user http://127.0.0.1:10080/login
// Enter host password for user 'user':
password
// {"token":"aaaaa.bbbbb.ccccc"}
5. cloud shell에서 토큰을 저장하기 위해 환경 변수 만들기
TOKEN=$(curl http://127.0.0.1:10080/login -u user|jq -r '.token')
// Enter host password for user 'user':
password
// % Total % Received % Xferd Average Speed Time Time Time Current
// Dload Upload Total Spent Left Speed
// 100 222 100 222 0 0 237 0 --:--:-- --:--:-- --:--:-- 237
6. 토큰 복사 후 토큰으로 curl을 사용하여 보안이 설정된 엔드포인트 조회하기
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:10080/secure
// {"message":"Hello"}
7. kubectl logs 명령어로 monolith 포드의 로그를 확인할 수 있다.
kubectl logs monolith
/*
2021/05/11 00:49:19 Starting server...
2021/05/11 00:49:19 Health service listening on 0.0.0.0:81
2021/05/11 00:49:19 HTTP service listening on 0.0.0.0:80
127.0.0.1:37604 - - [Tue, 11 May 2021 00:57:31 UTC] "GET / HTTP/1.1" curl/7.64.0
127.0.0.1:37702 - - [Tue, 11 May 2021 00:59:48 UTC] "GET /secure HTTP/1.1" curl/7.64.0
127.0.0.1:37746 - - [Tue, 11 May 2021 01:00:58 UTC] "GET /login HTTP/1.1" curl/7.64.0
127.0.0.1:37880 - - [Tue, 11 May 2021 01:03:52 UTC] "GET /login HTTP/1.1" curl/7.64.0
127.0.0.1:37942 - - [Tue, 11 May 2021 01:05:19 UTC] "GET /secure HTTP/1.1" curl/7.64.0
*/
8. 세 번째 터미널을 열고 -f 플래스를 사용하여 실시간 로그 스트림을 가져오기
kubectl logs -f monolith
/*
2021/05/11 00:49:19 Starting server...
2021/05/11 00:49:19 Health service listening on 0.0.0.0:81
2021/05/11 00:49:19 HTTP service listening on 0.0.0.0:80
127.0.0.1:37604 - - [Tue, 11 May 2021 00:57:31 UTC] "GET / HTTP/1.1" curl/7.64.0
127.0.0.1:37702 - - [Tue, 11 May 2021 00:59:48 UTC] "GET /secure HTTP/1.1" curl/7.64.0
127.0.0.1:37746 - - [Tue, 11 May 2021 01:00:58 UTC] "GET /login HTTP/1.1" curl/7.64.0
127.0.0.1:37880 - - [Tue, 11 May 2021 01:03:52 UTC] "GET /login HTTP/1.1" curl/7.64.0
127.0.0.1:37942 - - [Tue, 11 May 2021 01:05:19 UTC] "GET /secure HTTP/1.1" curl/7.64.0
*/
9. 첫 번째 터미널에서 curl을 사용하면 세 번째 터미널에서 로그가 실시간 업데이트 된다.
curl http://127.0.0.1:10080
10. kubectl exec 명령어로 모놀리식 포드의 대화형 셸 실행하기
→ 컨테이너 내부에서 문제를 해결할 때 필요
kubectl exec monolith --stdin --tty -c monolith /bin/sh
/*
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ #
*/
11. 셸에서 ping 명령어로 외부 연결을 테스트하기
ping -c 3 google.com
/*
PING google.com (108.177.120.139): 56 data bytes
64 bytes from 108.177.120.139: seq=0 ttl=114 time=1.332 ms
64 bytes from 108.177.120.139: seq=1 ttl=114 time=1.316 ms
64 bytes from 108.177.120.139: seq=2 ttl=114 time=1.041 ms
--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.041/1.229/1.332 ms
*/
12. 대화형 셸은 사용 후 반드시 로그아웃 한다.
exit
- 서비스
: 포드를 위해 안정적인 엔드포인트를 제공한다.
라벨을 사용하여 어떤 포드에서 작동할지 결정한다.
포드에 라벨이 정확히 지정되어 있다면 서비스가 자동으로 감지하고 노출시킨다.
서비스 유형에 따라 3가지 유형의 액세스 수준이 제공된다.
ClusterIP (내부) | 기본 유형 클러스터 안에서만 볼 수 있다. |
NodePort | 클러스터의 각 노드에 외부에서 액세스 가능한 IP 주소를 제공 |
LoadBalancer | 클라우드 제공업체로부터 부하 분산기를 추가하며, 서비스에서 유입되는 트래픽을 내부에 있는 노드로 전달 |
- 서비스 만들기
1. k8s가 있는 디렉토리로 이동
cd ~/orchestrate-with-kubernetes/kubernetes
2. 모놀리식 서비스 구성파일 조회
cat pods/secure-monolith.yaml
3. 보안이 설정된 모놀리식 포드와 구성 데이터 만들기
kubectl create secret generic tls-certs --from-file tls/
// secret/tls-certs created
kubectl create configmap nginx-proxy-conf --from-file nginx/proxy.conf
// configmap/nginx-proxy-conf created
kubectl create -f pods/secure-monolith.yaml
// pod/secure-monolith created
4. 모놀리식 서비스 구성 파일 확인
cat services/monolith.yaml
/*
kind: Service
apiVersion: v1
metadata:
name: "monolith"
spec:
selector: # app: monoloth 및 secure: enabled 라벨이 지정된 포드를
app: "monolith" # 자동으로 찾고 노출시키는 선택기가 있음
secure: "enabled"
ports: # 외부 트래픽을 포트 31000에서 포트 443의 nginx로 전달하기 위해
- protocol: "TCP" # NodePort를 노출시켜야 함
port: 443
targetPort: 443
nodePort: 31000
type: NodePort
*/
5. kubectl create 명령어로 모놀리식 서비스 구성 파일에서 모놀리식 서비스를 만들기
kubectl create -f services/monolith.yaml
// service/monolith created
6. gcloud compute firewall-rules 명령어로 NodePort(노출됨)의 모놀리식 서비스로 TCP 트래픽을 보내는 방화벽 규칙을 만든다.
gcloud compute firewall-rules create allow-monolith-nodeport --allow=tcp:31000
/*
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/qwiklabs-gcp-01-16237cdae72a/global/firewalls/allow-monolith-nodeport].
Creating firewall...done.
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
allow-monolith-nodeport default INGRESS 1000 tcp:31000 False
*/
- 포트 전달 없이 클러스터 밖에서 안전한 모놀리식 서비스 조회하기
1. 노드 1개의 외부 IP 주소 가져오기
gcloud compute instances list
/*
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
gke-io-default-pool-fdb086cf-g9bv us-central1-b e2-medium 10.128.0.2 104.197.2.126 RUNNING
gke-io-default-pool-fdb086cf-pmz9 us-central1-b e2-medium 10.128.0.3 34.68.217.152 RUNNING
gke-io-default-pool-fdb086cf-sgqx us-central1-b e2-medium 10.128.0.4 35.238.135.160 RUNNING
*/
1. 현재 모놀리식 서비스에 엔드포인트가 없으므로 kubectl get pods 명령어로 모놀리식 라벨이 지정되어 실행되는 포드를 확인한다.
kubectl get pods -l "app=monolith"
/*
NAME READY STATUS RESTARTS AGE
monolith 1/1 Running 0 27m
secure-monolith 2/2 Running 0 20m
*/
2. kubectl labe 명령어로 보안이 설정된 모놀리식 포드에서 누락된 secure=enabled 라벨을 추가하고 업데이트 내역을 확인한다.
kubectl label pods secure-monolith 'secure=enabled'
// pod/secure-monolith labeled
kubectl get pods secure-monolith --show-labels
// NAME READY STATUS RESTARTS AGE LABELS
// secure-monolith 2/2 Running 0 23m app=monolith,secure=enabled
3. 모놀리식 서비스의 엔드포인트 목록을 확인한다.
kubectl describe services monolith | grep Endpoints
// Endpoints: 10.0.1.5:443
4. 노드 중 하나를 조회하여 엔트포인트 테스트 하기
gcloud compute instances list
/*
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
gke-io-default-pool-fdb086cf-g9bv us-central1-b e2-medium 10.128.0.2 104.197.2.126 RUNNING
gke-io-default-pool-fdb086cf-pmz9 us-central1-b e2-medium 10.128.0.3 34.68.217.152 RUNNING
gke-io-default-pool-fdb086cf-sgqx us-central1-b e2-medium 10.128.0.4 35.238.135.160 RUNNING
*/
curl -k https://35.238.135.160:31000
// {"message":"Hello"}
- k8s로 애플리케이션 배포하기
- 디플로이먼트 (deployments)
: 실행 중인 포드의 개수가 사용자가 명시한 포드 개수와 동일하게 만드는 선언적 방식
디플로이먼트는 pod 관리에서 낮은 수준의 세부정보를 추상화하는 것이 주요 이점
디플로이먼트는 백그라운드에서 복제본 집합을 사용하여 pod의 시작 및 중지를 관리
Pods를 업데이트하거나 확장해야 할 경우 배포에서 처리
포드가 중지되면 디플로이먼트에서 재시작을 담당하여 처리
- 디플로이먼트 만들기
1. 디플로이먼트 실습에서 사용할 모놀리식 앱의 서비스 구성
auth | 인증된 사용자를 위한 JWT 토큰을 생성 |
hello | 인증된 사용자를 안내 |
frontend | 트래픽을 auth 및 hello 서비스로 전달 |
2. auth 디플로이먼트 구성 파일 검토
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
resources:
limits:
cpu: 0.2
memory: "10Mi"
livenessProbe:
httpGet:
path: /healthz
port: 81
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /readiness
port: 81
scheme: HTTP
initialDelaySeconds: 5
timeoutSeconds: 1
*/
3. kubectl create 명령어로 auth 디플로이먼트 개체를 만든다.
→ 디플로이먼트 매니페스트 데이터를 준수하는 포드가 만들어짐
kubectl create -f deployments/auth.yaml
// deployment.apps/auth created
4. kybectl create 명령어로 auth 디플로이먼트용 서비스를 만든다.
kubectl create -f services/auth.yaml
// service/auth created
5. hello 디플로이먼트의 개체와 서비스를 만든다.
kubectl create -f deployments/hello.yaml
// deployment.apps/hello created
kubectl create -f services/hello.yaml
// service/hello created
6. frontend 디플로이먼트의 개체를 만들고 노출한다.
→ frontend를 만들기 위해 컨테이너에 구성 데이터를 보관해야 하므로 추가 단계가 필요하다.
kubectl create configmap nginx-fontend-conf --from-file=nginx/frontend.conf // 추가단계
// configmap/nginx-fontend-conf created
kubectl create -f deployments/frontend.yaml
// deployment.apps/frontend created
kubectl create -f services/frontend.yaml
// service/frontend created
7. 외부 IP 주소 확인 후 curl 명령어로 frontend와 상호작용해본다.
kubectl get services frontend
/*
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.3.244.228 34.121.75.169 443:30724/TCP 112s
*/
끝
'IT 공부 > Qwiklabs' 카테고리의 다른 글
Cloud Architecture (finished) (0) | 2021.10.18 |
---|---|
Kubernetes in Google Cloud (finished) (0) | 2021.09.25 |
Cloud Engineering (finished) (0) | 2021.09.22 |
GCP Essentials (finished) (0) | 2021.09.17 |
퀵랩 - Spinnaker 및 Kubernetes Engine을 사용한 지속적 배포 파이프라인 (0) | 2021.05.25 |