本文档举例说明了如何在使用 Google Distributed Cloud for VMware(纯软件)创建的用户集群中部署应用。
准备工作
对于本文档提供的示例,您需要一个使用捆绑式 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
,值 2:sales
- 键 1:
在 Kubernetes 集群下拉列表中,选择您的集群。
点击继续。
公开
勾选将部署作为新服务公开。
在端口 1 字段中,输入
80
。在目标端口 1 字段中,输入
8080
。此值是适当的值,因为hello-app
容器默认监听 TCP 端口 8080。您可以通过查看应用的 Dockerfile 和源代码来查看此信息。在协议 1 字段中,选择
TCP
。在服务类型字段中,选择
LoadBalancer
。
点击页面底部的部署按钮。
查看 Deployment 和 Service 详情
Deployment 准备就绪后,Deployment 详情页面会在 Google Cloud 控制台的 Kubernetes 工作负载部分中打开。在此页面上,您可以查看有关 Deployment 及其三个 Pod 的详细信息。
在公开服务下,点击公开 Deployment 的 Service 的名称。在本练习中,该名称为
my-deployment-service
。此时会打开 Service 详情页面。在此页面上,您可以查看有关 Service 的详细信息。例如,您可以看到任何具有标签
app: metrics
和department: sales
的 Pod 都是 Service 的成员。之前提到,my-deployment
中的 Pod 具有这些标签。
您还可以查看负载均衡器 IP 的值。系统已在集群负载均衡器上自动配置负载均衡器 IP。
Service 的转发
假设集群外部的客户端在 TCP 端口 80 上向负载均衡器 IP 发送请求。请求会路由到集群负载均衡器。负载均衡器将请求转发到 TCP 端口 8080 上的成员 Pod。之前提到,my-deployment
中的每个 Pod 都有一个监听 TCP 端口 8080 的容器。
测试 Service
前往负载均衡器 IP 可路由到的机器。
如需调用 Service,请在浏览器中输入负载均衡器 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
删除 Deployment
进入控制台,前往 Kubernetes Engine 部分中的工作负载页面。
在 Deployment 列表中,选择 my-deployment
。
点击页面顶部的
删除。此操作会同时删除 Deployment 和公开的 Service。命令行
连接到管理员工作站
与管理员工作站建立 SSH 连接。 在管理员工作站上执行以下步骤。
创建 Deployment
以下是 Deployment 的清单:
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
的文件,然后创建该 Deployment:
kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-deployment.yaml
其中,USER_CLUSTER_KUBECONFIG 是用户集群的 kubeconfig 文件的路径。
获取有关 Deployment 的基本信息:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment
输出结果显示 Deployment 有三个可用的 Pod:
NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 3/3 3 3 27s
列出 Deployment 中的 Pod:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods
输出结果显示 Deployment 有三个正在运行的 Pod:
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
获取有关 Deployment 的详细信息:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment --output yaml
输出结果显示有关 Deployment 规范和状态的详细信息:
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
描述您的 Deployment:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe deployment my-deployment
输出结果显示有关 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 类型的 Service
将 Deployment 公开给集群外部客户端的一种方法是创建类型为 LoadBalancer
的 Kubernetes Service。
以下是 LoadBalancer
类型的 Service 的清单:
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: metrics department: sales type: LoadBalancer ports: ‑ port: 80 targetPort: 8080
基于本练习的目的,了解以下重要事项有助于理解 Service:
任何具有标签
app: metrics
和标签department: sales
的 Pod 都是 Service 的成员。请注意,my-deployment
中的 Pod 具有这些标签。当客户端向 TCP 端口 80 上的 Service 发送请求时,请求将被转发到 TCP 端口 8080 上的成员 Pod。
每个成员 Pod 必须有一个侦听 TCP 端口 8080 的容器。
碰巧的是,默认情况下,hello-app
容器侦听 TCP 端口 8080。您可以通过查看应用的 Dockerfile 和源代码来查看此信息。
将此清单保存到名为 my-service.yaml
的文件,然后创建该 Service:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-service.yaml
其中,USER_CLUSTER_KUBECONFIG 是用户集群的 kubeconfig 文件的路径。
当您创建 Service 时,Google Distributed Cloud 会自动在集群负载均衡器上配置 loadBalancerIP
地址。
查看您的 Service:
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
在上面的输出结果中,您可以看到您的 Service 有一个 clusterIP
和一个 loadBalancerIP
。它还具有 port
和 targetPort
。
clusterIP
与此练习无关。loadBalancerIP
是集群外部的客户端可用于调用 Service 的 IP 地址。
以上面的输出结果中显示的值为例。也就是说,假设 Service 的 loadBalancerIP
= 203.0.113.1,port
= 80,targetPort
= 8080。
客户端将请求发送到 TCP 端口 80 上的 203.0.113.1。请求会路由到集群负载均衡器。负载均衡器将请求转发到 TCP 端口 8080 上的成员 Pod。
调用您的 Service:
curl LOAD_BALANCER_IP
输出结果会显示 Hello, world!
消息:
curl 203.0.113.1 Hello, world! Version: 2.0.0 Hostname: my-deployment-dbd86c8c4-9wpbv
删除 Service
删除 Service:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service my-service
验证您的 Service 是否已删除:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get services
输出结果不再显示 my-service
。
删除 Deployment
删除 Deployment:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment my-deployment
验证您的 Deployment 是否已删除:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployments
输出结果不再显示 my-deployment
。