튜토리얼

Edit This Page

예시: Redis를 사용한 PHP 방명록 애플리케이션 배포하기

이 튜토리얼에서는 쿠버네티스와 Docker를 사용하여 간단한 멀티 티어 웹 애플리케이션을 빌드하고 배포하는 방법을 보여준다. 이 예제는 다음과 같은 구성으로 이루어져 있다.

목적

시작하기 전에

쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 합니다. 만약, 클러스터를 이미 가지고 있지 않다면, Minikube를 사용해서 만들거나, 다음의 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있습니다:

버전 확인을 위해서, 다음 커맨드를 실행 kubectl version.

Redis 마스터를 실행하기

방명록 애플리케이션은 Redis를 사용하여 데이터를 저장한다. Redis 마스터 인스턴스에 데이터를 기록하고 여러 Redis 슬레이브 인스턴스에서 데이터를 읽는다.

Redis 마스터의 디플로이먼트를 생성하기

아래의 매니페스트 파일은 단일 복제본 Redis 마스터 파드를 실행하는 디플로이먼트 컨트롤러를 지정한다.

application/guestbook/redis-master-deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2

kind: Deployment
metadata:
  name: redis-master
  labels:
    app: redis
spec:
  selector:
    matchLabels:
      app: redis
      role: master
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
        tier: backend
    spec:
      containers:
      - name: master
        image: k8s.gcr.io/redis:e2e  # or just image: redis

        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379
  1. 매니페스트 파일을 다운로드한 디렉토리에서 터미널 창을 시작한다.
  2. redis-master-deployment.yaml 파일을 통해 Redis 마스터의 디플로이먼트에 적용시킨다.

      kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
  3. 파드의 목록을 질의하여 Redis 마스터 파드가 실행 중인지 확인한다.

      kubectl get pods

    결과는 아래와 같은 형태로 나타난다.

      NAME                            READY     STATUS    RESTARTS   AGE
      redis-master-1068406935-3lswp   1/1       Running   0          28s
  4. Redis 마스터 파드에서 로그를 보려면 다음 명령어를 실행한다.

     kubectl logs -f POD-NAME
참고: POD-NAME을 해당 파드 이름으로 수정해야 한다.

Redis 마스터 서비스 생성하기

방명록 애플리케이션에서 데이터를 쓰려면 Redis 마스터와 통신해야 한다. Redis 마스터 파드로 트래픽을 프록시하려면 서비스를 적용해야 한다. 서비스는 파드에 접근하기 위한 정책을 정의한다.

application/guestbook/redis-master-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    app: redis
    role: master
    tier: backend
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
    role: master
    tier: backend
  1. redis-master-service.yaml 파일을 통해 Redis 마스터 서비스에 적용시킨다.

      kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
  2. 서비스의 목록을 질의하여 Redis 마스터 서비스가 실행 중인지 확인한다.

      kubectl get service

    결과는 아래와 같은 형태로 나타난다.

      NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
      kubernetes     ClusterIP   10.0.0.1     <none>        443/TCP    1m
      redis-master   ClusterIP   10.0.0.151   <none>        6379/TCP   8s
참고: 이 매니페스트 파일은 이전에 정의된 레이블과 일치하는 레이블 집합을 가진 redis-master라는 서비스를 생성하므로, 서비스는 네트워크 트래픽을 Redis 마스터 파드로 라우팅한다.

Redis 슬레이브 실행하기

Redis 마스터는 단일 파드이지만, 복제된 Redis 슬레이브를 추가하여 트래픽 요구 사항을 충족시킬 수 있다.

Redis 슬레이브의 디플로이먼트 생성하기

디플로이먼트는 매니페스트 파일에 설정된 구성에 따라 확장된다. 이 경우, 디플로이먼트 오브젝트는 두 개의 복제본을 지정한다.

실행 중인 복제본이 없으면, 이 디플로이먼트는 컨테이너 클러스터에 있는 두 개의 복제본을 시작한다. 반대로 두 개 이상의 복제본이 실행 중이면, 두 개의 복제본이 실행될 때까지 축소된다.

application/guestbook/redis-slave-deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2

kind: Deployment
metadata:
  name: redis-slave
  labels:
    app: redis
spec:
  selector:
    matchLabels:
      app: redis
      role: slave
      tier: backend
  replicas: 2
  template:
    metadata:
      labels:
        app: redis
        role: slave
        tier: backend
    spec:
      containers:
      - name: slave
        image: gcr.io/google_samples/gb-redisslave:v1
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # Using `GET_HOSTS_FROM=dns` requires your cluster to

          # provide a dns service. As of Kubernetes 1.3, DNS is a built-in

          # service launched automatically. However, if the cluster you are using

          # does not have a built-in DNS service, you can instead

          # access an environment variable to find the master

          # service's host. To do so, comment out the 'value: dns' line above, and

          # uncomment the line below:

          # value: env

        ports:
        - containerPort: 6379
  1. redis-slave-deployment.yaml 파일을 통해 Redis 슬레이브의 디플로이먼트에 적용시킨다.

      kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-deployment.yaml
  2. 파드의 목록을 질의하여 Redis 슬레이브 파드가 실행 중인지 확인한다.

      kubectl get pods

    결과는 아래와 같은 형태로 나타난다.

      NAME                            READY     STATUS              RESTARTS   AGE
      redis-master-1068406935-3lswp   1/1       Running             0          1m
      redis-slave-2005841000-fpvqc    0/1       ContainerCreating   0          6s
      redis-slave-2005841000-phfv9    0/1       ContainerCreating   0          6s

Redis 슬레이브 서비스 생성하기

방명록 애플리케이션은 Redis 슬레이브와 통신하여 데이터를 읽는다. Redis 슬레이브를 확인할 수 있도록 하기 위해 서비스를 설정해야 한다. 서비스는 파드 집합에 투명한 로드 밸런싱을 제공한다.

application/guestbook/redis-slave-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis-slave
  labels:
    app: redis
    role: slave
    tier: backend
spec:
  ports:
  - port: 6379
  selector:
    app: redis
    role: slave
    tier: backend
  1. redis-slave-service.yaml 파일을 통해 Redis 슬레이브 서비스에 적용시킨다.

      kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-service.yaml
  2. 서비스의 목록을 질의하여 Redis 슬레이브 서비스가 실행 중인지 확인한다.

      kubectl get services

    결과는 아래와 같은 형태로 나타난다.

      NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
      kubernetes     ClusterIP   10.0.0.1     <none>        443/TCP    2m
      redis-master   ClusterIP   10.0.0.151   <none>        6379/TCP   1m
      redis-slave    ClusterIP   10.0.0.223   <none>        6379/TCP   6s
    

방명록 프론트엔드를 설정하고 노출시키기

방명록 애플리케이션에는 PHP로 작성된 HTTP 요청을 처리하는 웹 프론트엔드가 있다. 쓰기 요청을 위한 redis-master 서비스와 읽기 요청을 위한 redis-slave 서비스에 연결하도록 설정된다.

방명록 프론트엔드의 디플로이먼트 생성하기

application/guestbook/frontend-deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2

kind: Deployment
metadata:
  name: frontend
  labels:
    app: guestbook
spec:
  selector:
    matchLabels:
      app: guestbook
      tier: frontend
  replicas: 3
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google-samples/gb-frontend:v4
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # Using `GET_HOSTS_FROM=dns` requires your cluster to

          # provide a dns service. As of Kubernetes 1.3, DNS is a built-in

          # service launched automatically. However, if the cluster you are using

          # does not have a built-in DNS service, you can instead

          # access an environment variable to find the master

          # service's host. To do so, comment out the 'value: dns' line above, and

          # uncomment the line below:

          # value: env

        ports:
        - containerPort: 80
  1. frontend-deployment.yaml 파일을 통해 프론트엔드의 디플로이먼트에 적용시킨다.

      kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
  2. 파드의 목록을 질의하여 세 개의 프론트엔드 복제본이 실행되고 있는지 확인한다.

      kubectl get pods -l app=guestbook -l tier=frontend

    결과는 아래와 같은 형태로 나타난다.

      NAME                        READY     STATUS    RESTARTS   AGE
      frontend-3823415956-dsvc5   1/1       Running   0          54s
      frontend-3823415956-k22zn   1/1       Running   0          54s
      frontend-3823415956-w9gbt   1/1       Running   0          54s
    

프론트엔드 서비스 생성하기

서비스의 기본 유형은 ClusterIP이기 때문에 적용한 redis-slave 및 redis-master 서비스는 컨테이너 클러스터 내에서만 접근할 수 있다. ClusterIP는 서비스가 가리키는 파드 집합에 대한 단일 IP 주소를 제공한다. 이 IP 주소는 클러스터 내에서만 접근할 수 있다.

게스트가 방명록에 접근할 수 있도록 하려면, 외부에서 볼 수 있도록 프론트엔드 서비스를 구성해야 한다. 그렇게 하면 클라이언트가 컨테이너 클러스터 외부에서 서비스를 요청할 수 있다. Minikube는 NodePort를 통해서만 서비스를 노출할 수 있다.

참고: Google Compute Engine 또는 Google Kubernetes Engine과 같은 일부 클라우드 공급자는 외부 로드 밸런서를 지원한다. 클라우드 공급자가 로드 밸런서를 지원하고 이를 사용하려면 type : NodePort를 삭제하거나 주석 처리하고 type : LoadBalancer의 주석을 제거해야 한다.
application/guestbook/frontend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # comment or delete the following line if you want to use a LoadBalancer

  type: NodePort 
  # if your cluster supports it, uncomment the following to automatically create

  # an external load-balanced IP for the frontend service.

  # type: LoadBalancer

  ports:
  - port: 80
  selector:
    app: guestbook
    tier: frontend
  1. frontend-service.yaml 파일을 통해 프론트엔드 서비스에 적용시킨다.

      kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
  2. 서비스의 목록을 질의하여 프론트엔드 서비스가 실행 중인지 확인한다.

      kubectl get services 

    결과는 아래와 같은 형태로 나타난다.

      NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
      frontend       ClusterIP   10.0.0.112   <none>       80:31323/TCP   6s
      kubernetes     ClusterIP   10.0.0.1     <none>        443/TCP        4m
      redis-master   ClusterIP   10.0.0.151   <none>        6379/TCP       2m
      redis-slave    ClusterIP   10.0.0.223   <none>        6379/TCP       1m
    

NodePort를 통해 프론트엔드 서비스 확인하기

애플리케이션을 Minikube 또는 로컬 클러스터에 배포한 경우, 방명록을 보려면 IP 주소를 찾아야 한다.

  1. 프론트엔드 서비스의 IP 주소를 얻기 위해 아래 명령어를 실행한다.

      minikube service frontend --url

    결과는 아래와 같은 형태로 나타난다.

      http://192.168.99.100:31323
    
  2. IP 주소를 복사하고, 방명록을 보기 위해 브라우저에서 페이지를 로드한다.

LoadBalancer를 통해 프론트엔드 서비스 확인하기

frontend-service.yaml 매니페스트를 LoadBalancer와 함께 배포한 경우, 방명록을 보기 위해 IP 주소를 찾아야 한다.

  1. 프론트엔드 서비스의 IP 주소를 얻기 위해 아래 명령어를 실행한다.

      kubectl get service frontend

    결과는 아래와 같은 형태로 나타난다.

      NAME       TYPE        CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
      frontend   ClusterIP   10.51.242.136   109.197.92.229     80:32372/TCP   1m
    
  2. IP 주소를 복사하고, 방명록을 보기 위해 브라우저에서 페이지를 로드한다.

웹 프론트엔드 확장하기

서버가 디플로이먼트 컨트롤러를 사용하는 서비스로 정의되어 있기 때문에 확장 또는 축소가 쉽다.

  1. 프론트엔드 파드의 수를 확장하기 위해 아래 명령어를 실행한다.

      kubectl scale deployment frontend --replicas=5
  2. 파드의 목록을 질의하여 실행 중인 프론트엔드 파드의 수를 확인한다.

      kubectl get pods

    결과는 아래와 같은 형태로 나타난다.

      NAME                            READY     STATUS    RESTARTS   AGE
      frontend-3823415956-70qj5       1/1       Running   0          5s
      frontend-3823415956-dsvc5       1/1       Running   0          54m
      frontend-3823415956-k22zn       1/1       Running   0          54m
      frontend-3823415956-w9gbt       1/1       Running   0          54m
      frontend-3823415956-x2pld       1/1       Running   0          5s
      redis-master-1068406935-3lswp   1/1       Running   0          56m
      redis-slave-2005841000-fpvqc    1/1       Running   0          55m
      redis-slave-2005841000-phfv9    1/1       Running   0          55m
    
  3. 프론트엔드 파드의 수를 축소하기 위해 아래 명령어를 실행한다.

      kubectl scale deployment frontend --replicas=2
  4. 파드의 목록을 질의하여 실행 중인 프론트엔드 파드의 수를 확인한다.

      kubectl get pods

    결과는 아래와 같은 형태로 나타난다.

      NAME                            READY     STATUS    RESTARTS   AGE
      frontend-3823415956-k22zn       1/1       Running   0          1h
      frontend-3823415956-w9gbt       1/1       Running   0          1h
      redis-master-1068406935-3lswp   1/1       Running   0          1h
      redis-slave-2005841000-fpvqc    1/1       Running   0          1h
      redis-slave-2005841000-phfv9    1/1       Running   0          1h
    

정리하기

디플로이먼트 및 서비스를 삭제하면 실행 중인 모든 파드도 삭제된다. 레이블을 사용하여 하나의 명령어로 여러 자원을 삭제해보자.

  1. 모든 파드, 디플로이먼트, 서비스를 삭제하기 위해 아래 명령어를 실행한다.

      kubectl delete deployment -l app=redis
      kubectl delete service -l app=redis
      kubectl delete deployment -l app=guestbook
      kubectl delete service -l app=guestbook

    결과는 아래와 같은 형태로 나타난다.

      deployment.apps "redis-master" deleted
      deployment.apps "redis-slave" deleted
      service "redis-master" deleted
      service "redis-slave" deleted
      deployment.apps "frontend" deleted    
      service "frontend" deleted
    
  2. 파드의 목록을 질의하여 실행 중인 파드가 없는지 확인한다.

      kubectl get pods

    결과는 아래와 같은 형태로 나타난다.

      No resources found.
    

다음 내용

피드백