Service로 프론트엔드를 백엔드에 연결하기
Service로 프론트엔드를 백엔드에 연결하기 (Connect a Frontend to a Backend Using Services)
이 태스크는 프론트엔드와 백엔드 마이크로서비스를 만드는 방법을 보여줘요. 백엔드 마이크로서비스는 "hello" 인사(greeter)예요. 프론트엔드는 nginx와 쿠버네티스 Service 객체를 사용해 백엔드를 노출해요.
출처: 문서
본문
목표 (Objectives)
- Deployment 객체로 샘플
hello백엔드 마이크로서비스를 만들고 실행해요. - Service 객체를 사용해 백엔드 마이크로서비스의 여러 레플리카에 트래픽을 보내요.
- 역시 Deployment 객체로
nginx프론트엔드 마이크로서비스를 만들고 실행해요. - 프론트엔드 마이크로서비스가 백엔드 마이크로서비스에 트래픽을 보내도록 구성해요.
type=LoadBalancer의 Service 객체를 사용해 프론트엔드 마이크로서비스를 클러스터 밖에 노출해요.
시작하기 전에 (Before you begin)
이 태스크는 외부 로드 밸런서가 있는 Service를 사용하며, 이는 지원되는 환경이 필요해요. 환경이 이를 지원하지 않는다면 NodePort 유형의 Service를 대신 사용할 수 있어요.
Deployment로 백엔드 만들기
백엔드는 간단한 hello 인사 마이크로서비스예요. 백엔드 Deployment의 구성 파일은 다음과 같아요:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
selector:
matchLabels:
app: hello
tier: backend
track: stable
replicas: 3
template:
metadata:
labels:
app: hello
tier: backend
track: stable
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-go-gke:1.0"
ports:
- name: http
containerPort: 80
...
백엔드 Deployment를 만들어요:
kubectl apply -f https://k8s.io/examples/service/access/backend-deployment.yaml
백엔드 Deployment에 대한 정보를 봐요:
kubectl describe deployment backend
출력은 다음과 비슷해요:
Name: backend
Namespace: default
CreationTimestamp: Mon, 24 Oct 2016 14:21:02 -0700
Labels: app=hello
tier=backend
track=stable
Annotations: deployment.kubernetes.io/revision=1
Selector: app=hello,tier=backend,track=stable
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=hello
tier=backend
track=stable
Containers:
hello:
Image: "gcr.io/google-samples/hello-go-gke:1.0"
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: hello-3621623197 (3/3 replicas created)
Events:
...
hello Service 객체 만들기
프론트엔드에서 백엔드로 요청을 보내는 핵심은 백엔드 Service예요. Service는 영구 IP 주소와 DNS 이름 항목을 만들어 백엔드 마이크로서비스가 항상 도달될 수 있게 해요. Service는 셀렉터를 사용해 트래픽을 라우팅할 파드를 찾아요.
먼저 Service 구성 파일을 살펴봐요:
---
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
tier: backend
ports:
- protocol: TCP
port: 80
targetPort: http
...
구성 파일에서 hello 라는 Service가 app: hello 와 tier: backend 라벨을 가진 파드에 트래픽을 라우팅하는 것을 볼 수 있어요.
백엔드 Service를 만들어요:
kubectl apply -f https://k8s.io/examples/service/access/backend-service.yaml
이 시점에서 hello 애플리케이션의 레플리카 3개를 실행하는 backend Deployment가 있고, 그 파드에 트래픽을 라우팅할 수 있는 Service가 있어요. 하지만 이 서비스는 클러스터 밖에서는 사용할 수 없고 해석되지도 않아요.
프론트엔드 만들기
이제 백엔드가 실행 중이므로, 클러스터 밖에서 접근할 수 있고 요청을 프록시해 백엔드에 연결하는 프론트엔드를 만들 수 있어요.
프론트엔드는 백엔드 Service에 부여된 DNS 이름을 사용해 백엔드 워커 파드에 요청을 보내요. DNS 이름은 examples/service/access/backend-service.yaml 구성 파일의 name 필드 값인 hello 예요.
프론트엔드 Deployment의 파드는 hello 백엔드 Service에 요청을 프록시하도록 구성된 nginx 이미지를 실행해요. nginx 구성 파일은 다음과 같아요:
# The identifier Backend is internal to nginx, and used to name this specific upstream
upstream Backend {
# hello is the internal DNS name used by the backend Service inside Kubernetes
server hello;
}
server {
listen 80;
location / {
# The following statement will proxy traffic to the upstream named Backend
proxy_pass http://Backend;
}
}
백엔드와 비슷하게 프론트엔드에도 Deployment와 Service가 있어요. 백엔드와 프론트엔드 서비스 사이의 중요한 차이점은 프론트엔드 Service의 구성이 type: LoadBalancer 라는 점이에요. 이는 Service가 클라우드 제공자가 프로비저닝한 로드 밸런서를 사용하고 클러스터 밖에서 접근 가능하다는 뜻이에요.
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
selector:
app: hello
tier: frontend
ports:
- protocol: "TCP"
port: 80
targetPort: 80
type: LoadBalancer
...
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: hello
tier: frontend
track: stable
replicas: 1
template:
metadata:
labels:
app: hello
tier: frontend
track: stable
spec:
containers:
- name: nginx
image: "gcr.io/google-samples/hello-frontend:1.0"
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
...
프론트엔드 Deployment와 Service를 만들어요:
kubectl apply -f https://k8s.io/examples/service/access/frontend-deployment.yaml
kubectl apply -f https://k8s.io/examples/service/access/frontend-service.yaml
출력은 두 리소스 모두 생성됐음을 확인해요:
deployment.apps/frontend created
service/frontend created
참고:
프론트엔드 Service와 상호 작용하기
type LoadBalancer의 Service를 만들었다면 이 명령으로 외부 IP를 찾을 수 있어요:
kubectl get service frontend --watch
이것은 frontend Service의 구성을 표시하고 변경 사항을 지켜봐요. 처음에는 외부 IP가 <pending> 으로 나열돼요:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 <pending> 80/TCP 10s
외부 IP가 프로비저닝되는 즉시 구성이 EXTERNAL-IP 표제 아래에 새 IP를 포함하도록 업데이트돼요:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m
그 IP는 이제 클러스터 밖에서 frontend 서비스와 상호 작용하는 데 사용할 수 있어요.
프론트엔드를 통해 트래픽 보내기
프론트엔드와 백엔드가 이제 연결됐어요. 프론트엔드 Service의 외부 IP에 curl 명령을 사용해 엔드포인트를 칠 수 있어요.
curl http://${EXTERNAL_IP} # replace this with the EXTERNAL-IP you saw earlier
출력은 백엔드가 생성한 메시지를 보여줘요:
{"message":"Hello"}
정리 (Cleaning up)
Service를 삭제하려면 다음 명령을 입력해요:
kubectl delete services frontend backend
백엔드와 프론트엔드 애플리케이션을 실행하는 Deployment, ReplicaSet, 파드를 삭제하려면 다음 명령을 입력해요:
kubectl delete deployment frontend backend
더 알아보기 (Learn more)
- Service에 대해 더 알아보기
- ConfigMap에 대해 더 알아보기
- Service와 파드용 DNS에 대해 더 알아보기