gcloud config set project [project-id]
gcloud config set compute/zone [compute-zone]
gcloud container clusters create guestbook --num-nodes=4
gcloud container clusters list
gcloud container clusters describe guestbook
방명록은 Redis를 사용하여 데이터를 저장한다.
애플리케이션은 Redis 리더 인스턴스에 데이터를 쓰고, 여러 Redis 팔로워 인스턴스에서 읽게 된다.
쿠버네티스의 디플로이먼트(Deployment)란, 컨테이너 애플리케이션을 배포하고 관리하는 역할을 담당한다. 디플로이먼트를 사용하면 레플리카셋의 리비전 관리뿐만 아니라 다양한 포드의 롤링 업데이트 정책을 사용할 수 있다는 장점이 있다.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/guestbook
git checkout abbb383
GCP github에서 샘플 매니페스트 파일 클론, abbb383로 브랜치 전환
디플로이먼트 생성 전 guestbook/redis-leader-deployment.yaml 파일 내용 확인
이 매니페스트 파일은 단일 복제본 Redis 리더 Pod를 실행하는 디플로이먼트를 지정한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-leader
labels:
app: redis
role: leader
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
role: leader
tier: backend
spec:
containers:
- name: leader
image: "docker.io/redis:6.0.5"
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379
- .metadata.name 필드에 따라 redis-leader라는 이름으로 디플로이먼트가 생성된다.
- .spec.replicas 필드에 따라 디플로이먼트는 1개의 레플리카 파드를 생성한다.
- .spec.selector 필드에 따라 디플로이먼트가 관리할 파드를 찾는 방법을 정의한다. 이 사례에서는 파드 템플리엣 정의된 레이블(app: redis)를 선택한다.
- template 필드에는 다음 하위 필드가 포함되어 있다.
- .metadata.labels 필드를 사용해서 app: redis, role: leader, tier: backend 라는 레이블을 붙인다.
- .metadata.spec 필드를 사용해서 도커 허브의 redis:6.0.5 버전 이미지를 실행하는 leader 라는 컨테이너 1개를 실행한다. 이 컨테이너 리소스 스펙은 cpu 100m, memory 100Mi이며, 6379번 포트를 사용한다.
kubectl apply -f redis-leader-deployment.yaml
kubectl get pods
kubectl logs deployment/redis-leader
쿠버네티스의 서비스(Service)란, 동일한 서비스를 제공하는 파드 그룹에 지속적인 단일 접점이 필요할 때 생성하는 리소스다. 각 서비스는 서비스가 존재하는 동안 절대 바뀌지 않는 IP주소와 포트가 있으며, 클라이언트는 해당 IP와 포트로 접속한 다음 해당 서비스를 지원하는 파드 중 하나로 연결된다.
방명록 애플리케이션은 데이터를 쓰기 위해 Redis 리더와의 통신이 필요하다. 본 테스트에서는 서비스를 생성하여 트래픽을 리더 Pod로 프록시 처리 할 것이다.
apiVersion: v1
kind: Service
metadata:
name: redis-leader
labels:
app: redis
role: leader
tier: backend
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
role: leader
tier: backend
- .metadata.name 필드에 따라 redis-leader라는 이름의 서비스가 생성된다.
- .spec.ports 필드는 단일 포트 매핑을 선언한다. 이 사례에서는 selector의 레이블과 일치하는 컨테이너 대상 포트인 6379번으로 트래픽을 라우팅한다.
kubectl apply -f redis-leader-service.yaml
kubectl get service
Redis 리더가 단일 Pod라도 복제본인 팔로워를 여러 개 추가하면 가용성을 높이고 트래픽 수요를 충족할 수 있다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-follower
labels:
app: redis
role: follower
tier: backend
spec:
replicas: 2
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
role: follower
tier: backend
spec:
containers:
- name: follower
image: gcr.io/google_samples/gb-redis-follower:v2
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379
kubectl apply -f redis-follower-deployment.yaml
kubectl get pods
- .spec.replicas 필드 설정에 따라 2개의 팔로워 파드가 생성되었다.
방명록 애플리케이션은 데이터를 읽기 위해 Redis 팔로워와 통신해야 한다. Redis 팔로워를 검색할 수 있도록 하려면 추가적으로 다른 서비스를 생성해야 한다.
apiVersion: v1
kind: Service
metadata:
name: redis-follower
labels:
app: redis
role: follower
tier: backend
spec:
ports:
# the port that this service should serve on
- port: 6379
selector:
app: redis
role: follower
tier: backend
- 6370 포트에서 실행되는 서비스 redis-follower를 정의하는 내용.
- .spec.selector 필드는 이전 단계에서 만든 Redis 팔로워 Pod와 일치한다는 것을 알 수 있다.
kubectl apply -f redis-follower-service.yaml
kubectl get service
이전 내용에 따라 현재 방명록의 Redis 스토리지가 실행되고 있으므로, 방명록 웹 서버를 생성할 차례이다. Redis 팔로워와 마찬가지로 프론트엔드는 디플로이먼트를 사용하여 생성된다.
방명록 앱은 PHP를 사용하며, 요청이 읽기인지 쓰기인지에 따라 리더 또는 팔로워 서비스와 통신하도록 구성된다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
app: guestbook
tier: frontend
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v5
env:
- name: GET_HOSTS_FROM
value: "dns"
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80
- 환경 변수 GET_HOSTS_FROM=dns를 지정함으로써, 프론트엔드 애플리케이션은 redis-follower 및 redis-leader를 사용하여 DNS 조회를 수행하게 된다.
kubectl apply -f frontend-deployment.yaml
kubectl get pods -l app=guestbook -l tier=frontend
서비스의 기본 유형이 Cluster IP이므로, 이전 단계에서 만든 두 개의 서비스는 현재 GKE 클러스터 내에서만 액세스 할 수 있다.
하지만 방명록 웹 프론트엔드는 클라이언트가 GKE 클러스터 외부에서 서비스를 요청할 수 있어야 하기 때문에 LoadBalancer, NodePort를 지정해야 한다. 이 예시에서는 LoadBalancer를 사용한다.
apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
type: LoadBalancer
ports:
# the port that this service should serve on
- port: 80
selector:
app: guestbook
tier: frontend
- .metadata.name 필드에 따라 frontend라는 서비스가 생성되면서 GKE는 로드밸런서와 외부 IP 주소를 만든다.
- .spec.ports 필드에는 80 포트를 지정하며, targetPort는 생략한다. targetPort를 생략하는 경우 기본적으로 port 필드 값이 사용되므로, 이 사례에서도 80 포트로 들어오는 외부 트래픽을 컨테이너 포트 80으로 라우팅 한다.
kubectl apply -f frontend-service.yaml
kubectl get servicefrontend
출력된 외부 IP를 복사하여 브라우저에서 페이지 로드
테스트 메시지 입력 후 Submit 버튼을 누르면 프론트엔드에 메시지가 표시되는 것을 확인할 수 있다.
만약 방명록 서비스가 유명해졌다는 가정하에 프론트엔드 웹 서버를 추가하고 싶다면, 손쉽게 서비스를 확장할 수 있다.
kubectl scale deployment frontend --replicas=5
kubectl get pods
5개의 Pod가 실행 중인 것을 알 수 있다
이 테스트에 사용된 리소스 비용이 청구되지 않도록 하려면 개별 리소스를 삭제해야 한다.
kubectl delete service frontend
gcloud compute forwarding-rules list
gcloud container clusters delete guestbook