이 문서에서는 Google Distributed Cloud용 사용자 클러스터에 애플리케이션을 배포하는 방법의 예를 보여줍니다.
시작하기 전에
여기에 제공된 예에서는 번들 MetalLB 부하 분산을 사용하는 사용자 클러스터가 필요합니다. MetalLB를 사용하는 최소 사용자 클러스터 만들기에 대한 안내는 기본 클러스터 만들기를 참조하세요.
Google Cloud 콘솔 또는 관리자 워크스테이션의 명령줄 도구 kubectl
을 사용하여 애플리케이션을 배포할 수 있습니다.
콘솔
콘솔에서 Google Kubernetes Engine 클러스터 개요 페이지로 이동합니다.
클러스터 목록에서 사용자 클러스터를 클릭하고 클러스터에 로그인되었는지 확인합니다.
아직 사용자 클러스터에 로그인하지 않은 경우 Google Cloud 콘솔에서 클러스터 관리의 안내에 따라 로그인합니다.
컨테이너
새 컨테이너에서 기존 컨테이너 이미지를 선택합니다.
이미지 경로에
us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
을 입력합니다.계속을 클릭합니다.
구성
배포 이름에
my-deployment
를 입력합니다.네임스페이스에
default
를 입력합니다.다음 두 라벨을 입력합니다.
- 키 1:
app
, 값 1:metrics
- 키 2:
department
, 값 2sales
- 키 1:
Kubernetes 클러스터 드롭다운에서 클러스터를 선택합니다.
계속을 클릭합니다.
노출
새 서비스로 배포 노출을 선택합니다.
포트 1에
80
을 입력합니다.대상 포트 1에
8080
을 입력합니다.hello-app
컨테이너가 기본적으로 TCP 포트 8080에서 리슨하므로 이 값은 적절한 값입니다. 앱의 Dockerfile 및 소스 코드를 보면 확인할 수 있습니다.프로토콜 1에서
TCP
를 선택합니다.서비스 유형으로
LoadBalancer
를 선택합니다.
페이지 하단에서 배포 버튼을 클릭합니다.
배포 및 서비스 세부정보 보기
배포가 준비되면 Google Cloud 콘솔의 Kubernetes 워크로드 섹션에서 배포 세부정보 페이지가 열립니다. 이 페이지에서 배포와 3개의 포드에 대한 세부정보를 확인할 수 있습니다.
서비스 노출에서 배포를 노출하는 서비스 이름을 클릭합니다. 이 실습의 이름은
my-deployment-service
입니다.서비스 세부정보 페이지가 열립니다. 이 페이지에서 서비스에 관한 세부정보를 확인할 수 있습니다. 예를 들어 어느 포드이든지 라벨
app: metrics
와department: 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
앞의 출력에서 서비스가 clusterIP
및 loadBalancerIP
를 가졌음을 알 수 있습니다. 또한 서비스에 port
와 targetPort
도 있습니다.
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
가 더 이상 표시되지 않습니다.