애플리케이션 배포

이 문서에서는 VMware용 GKE의 사용자 클러스터에 애플리케이션을 배포하는 방법의 예를 제공합니다.

시작하기 전에

여기에 제공된 예에서는 번들 MetalLB 부하 분산을 사용하는 사용자 클러스터가 필요합니다. MetalLB를 사용하는 최소 사용자 클러스터 만들기에 대한 안내는 기본 클러스터 만들기를 참조하세요.

Google Cloud 콘솔 또는 관리자 워크스테이션의 명령줄 도구 kubectl을 사용하여 애플리케이션을 배포할 수 있습니다.

콘솔

  1. 콘솔에서 Google Kubernetes Engine 클러스터 개요 페이지로 이동합니다.

    GKE 클러스터로 이동

  2. 클러스터 목록에서 사용자 클러스터를 클릭하고 클러스터에 로그인되었는지 확인합니다.

    아직 사용자 클러스터에 로그인하지 않은 경우 Google Cloud 콘솔에서 클러스터 관리의 안내에 따라 로그인합니다.

컨테이너

  1. 새 컨테이너에서 기존 컨테이너 이미지를 선택합니다.

  2. 이미지 경로us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0을 입력합니다.

  3. 계속을 클릭합니다.

구성

  1. 배포 이름my-deployment를 입력합니다.

  2. 네임스페이스default를 입력합니다.

  3. 다음 두 라벨을 입력합니다.

    • 키 1: app, 값 1: metrics
    • 키 2: department, 값 2 sales
  4. Kubernetes 클러스터 드롭다운에서 클러스터를 선택합니다.

  5. 계속을 클릭합니다.

노출

  1. 새 서비스로 배포 노출을 선택합니다.

  2. 포트 180을 입력합니다.

  3. 대상 포트 18080을 입력합니다. hello-app 컨테이너가 기본적으로 TCP 포트 8080에서 리슨하므로 이 값은 적절한 값입니다. 앱의 Dockerfile 및 소스 코드를 보면 확인할 수 있습니다.

  4. 프로토콜 1에서 TCP를 선택합니다.

  5. 서비스 유형으로 LoadBalancer를 선택합니다.

페이지 하단에서 배포 버튼을 클릭합니다.

배포 및 서비스 세부정보 보기

  1. 배포가 준비되면 Google Cloud 콘솔의 Kubernetes 워크로드 섹션에서 배포 세부정보 페이지가 열립니다. 이 페이지에서 배포와 3개의 포드에 대한 세부정보를 확인할 수 있습니다.

  2. 서비스 노출에서 배포를 노출하는 서비스 이름을 클릭합니다. 이 실습의 이름은 my-deployment-service입니다.

  3. 서비스 세부정보 페이지가 열립니다. 이 페이지에서 서비스에 관한 세부정보를 확인할 수 있습니다. 예를 들어 어느 포드이든지 라벨 app: metricsdepartment: sales가 있는 포드가 서비스의 구성원인 것을 알 수 있습니다. my-deployment의 포드에는 이러한 라벨이 있습니다.

부하 분산기 IP 값도 확인할 수 있습니다. 부하 분산기 IP는 클러스터 부하 분산기에 자동으로 구성되어 있습니다.

서비스 전달

클러스터 외부의 클라이언트가 TCP 포트 80의 부하 분산기 IP로 요청을 전송한다고 가정해 보겠습니다. 요청은 클러스터 부하 분산기로 라우팅됩니다. 부하 분산기는 TCP 포트 8080의 구성원 포드로 요청을 전달합니다. my-deployment의 모든 포드에는 TCP 포트 8080에서 리슨하는 컨테이너가 있습니다.

서비스 테스트

부하 분산기 IP를 라우팅할 수 있는 머신으로 이동합니다.

서비스를 호출하려면 브라우저에 부하 분산기 IP를 입력하거나 curl과 같은 명령어를 사용합니다. 예를 들면 다음과 같습니다.

curl [LOAD_BALANCER_IP]:80

출력에 Hello, world! 메시지가 표시됩니다. 예를 들면 다음과 같습니다.

curl 203.0.113.1:80
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

배포 삭제

콘솔의 Kubernetes Engine 섹션에서 워크로드 페이지로 이동합니다.

워크로드 페이지로 이동

배포 목록에서 my-deployment를 선택합니다.

페이지 상단에서 삭제를 클릭합니다. 그러면 배포와 노출 서비스가 모두 삭제됩니다.

명령줄

관리자 워크스테이션에 연결

관리자 워크스테이션으로 SSH 연결 가져오기 관리자 워크스테이션에서 다음 단계를 수행합니다.

배포 만들기

배포 매니페스트는 다음과 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"

my-deployment.yaml 파일에 매니페스트를 복사하고 배포를 만듭니다.

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-deployment.yaml

여기서 USER_CLUSTER_KUBECONFIG는 사용자 클러스터의 kubeconfig 파일 경로입니다.

배포에 대한 기본 정보를 가져옵니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment

출력은 배포에 사용 가능한 pod가 3개 있음을 보여줍니다.

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-deployment   3/3     3            3           27s

배포에서 포드가 나열됩니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods

출력은 배포에 3개의 포드가 실행 중임을 보여줍니다.

NAME                             READY   STATUS    RESTARTS   AGE
my-deployment-54944c8d55-4srm2   1/1     Running   0          6s
my-deployment-54944c8d55-7z5nn   1/1     Running   0          6s
my-deployment-54944c8d55-j62n9   1/1     Running   0          6s

배포에 대한 자세한 정보를 확인하세요.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment --output yaml

출력은 배포 사양 및 상태에 대한 세부정보를 보여줍니다.

kind: Deployment
metadata:
  ...
  generation: 1
  name: my-deployment
  namespace: default
  ...
spec:
  ...
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: metrics
      department: sales
  ...
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
        imagePullPolicy: IfNotPresent
        name: hello
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  conditions:
  ‑ lastTransitionTime: "2019-11-11T18:44:02Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  ‑ lastTransitionTime: "2019-11-11T18:43:58Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: ReplicaSet "my-deployment-54944c8d55" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3

배포를 설명합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe deployment my-deployment

출력은 연결된 ReplicaSet을 포함하여 배포에 대한 잘 정돈된 세부정보를 보여줍니다.

Name:                   my-deployment
Namespace:              default
CreationTimestamp:      Mon, 11 Nov 2019 10:43:58 -0800
Labels:                 
...
Selector:               app=metrics,department=sales
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=metrics
           department=sales
  Containers:
    hello:
    Image:        us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
    Port:         
    Host Port:    
    Environment:  
    Mounts:       
  Volumes:        
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  
NewReplicaSet:   my-deployment-54944c8d55 (3/3 replicas created)

LoadBalancer 유형의 서비스 만들기

클러스터 외부의 클라이언트에 배포를 노출하는 한 가지 방법은 LoadBalancer 유형의 Kubernetes 서비스를 만드는 것입니다.

LoadBalancer 유형 서비스의 매니페스트는 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: metrics
    department: sales
  type: LoadBalancer
  ports:
  ‑ port: 80
    targetPort: 8080

이 연습을 진행하면서 서비스에 대해 꼭 알아야 할 점은 다음과 같습니다.

  • app: metrics 라벨과 department: sales 라벨이 있는 포드는 어떤 포드이든지 서비스의 구성원입니다. my-deployment의 포드에는 이러한 라벨이 있습니다.

  • 클라이언트가 TCP 포트 80에서 서비스로 요청을 보내면 TCP 포트 8080의 구성원 pod로 요청이 전달됩니다.

  • 모든 구성원 pod에는 TCP 포트 8080에서 리슨하는 컨테이너가 있어야 합니다.

기본적으로 hello-app 컨테이너는 TCP 포트 8080에서 리슨합니다. 앱의 Dockerfile 및 소스 코드를 보면 확인할 수 있습니다.

my-service.yaml 파일에 매니페스트를 저장하고 서비스를 만듭니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-service.yaml

여기서 USER_CLUSTER_KUBECONFIG는 사용자 클러스터의 kubeconfig 파일 경로입니다.

서비스를 만들면 VMware용 GKE는 클러스터 부하 분산기에서 loadBalancerIP 주소를 자동으로 구성합니다.

서비스를 확인합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get service my-service --output yaml

출력은 다음과 비슷합니다.

kind: Service
metadata:
  ...
  name: my-service
  namespace: default
  ...
spec:
  allocateLoadBalancerNodePorts: true
  clusterIP: 10.96.1.39
  clusterIPs:
  - 10.96.1.39
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 31184
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: metrics
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.1

앞의 출력에서 서비스가 clusterIPloadBalancerIP를 가졌음을 알 수 있습니다. 또한 서비스에 porttargetPort도 있습니다.

clusterIP는 이 실습과 관련이 없습니다. loadBalancerIP는 클러스터 외부의 클라이언트가 서비스를 호출하는 데 사용할 수 있는 IP 주소입니다.

예를 들어 이전 출력에 표시된 값을 보겠습니다. 서비스의 loadBalancerIP = 203.0.113.1, port = 80, targetPort = 8080이라고 가정해 봅니다.

클라이언트가 TCP 포트 80의 203.0.113.1로 요청을 전송합니다. 요청은 클러스터 부하 분산기로 라우팅됩니다. 부하 분산기는 TCP 포트 8080의 구성원 포드로 요청을 전달합니다.

서비스를 호출합니다.

curl LOAD_BALANCER_IP

출력에 Hello, world! 메시지가 표시됩니다.

curl 203.0.113.1
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

서비스 삭제

서비스를 삭제합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service my-service

서비스가 삭제되었는지 확인합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get services

출력에 my-service가 더 이상 표시되지 않습니다.

배포 삭제

배포를 삭제합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment my-deployment

배포가 삭제되었는지 확인합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployments

출력에 my-deployment가 더 이상 표시되지 않습니다.

다음 단계

서비스 및 인그레스 만들기