创建服务和 Ingress

本页面介绍如何在 VMware 上的 Anthos 集群 (GKE On-Prem) 的用户集群中创建 Kubernetes Ingress 对象。一个 Ingress 对象必须与一个或多个 Service 对象相关联,每个 Service 对象与一组 Pod 相关联。

通过 SSH 连接到管理员工作站

通过 SSH 连接到管理员工作站:

ssh -i ~/.ssh/vsphere_workstation ubuntu@[IP_ADDRESS]

其中,[IP_ADDRESS] 是您的管理员工作站的 IP 地址。

在管理员工作站上完成本主题中的所有其余步骤。

创建 Deployment

以下是 Deployment 的清单。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
    spec:
      containers:
      - name: hello-world
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"
      - name: hello-kubernetes
        image: "gcr.io/google-samples/node-hello:1.0"
        env:
        - name: "PORT"
          value: "8080"

在本练习中,您需要了解 Deployment 清单的以下要点:

  • 属于 Deployment 的每个 Pod 都具有 greeting: hello 标签。

  • 每个 Pod 都有两个容器。

  • env 字段指定 hello-app 容器侦听 TCP 端口 50000,node-hello 容器侦听 TCP 端口 8080。对于 hello-app,您可以通过查看源代码查看 PORT 环境变量的效果。

将此清单复制到名为 hello-deployment.yaml 的文件,然后创建该 Deployment:

kubectl apply --kubeconfig [USER_CLUSTER_KUBECONFIG] -f hello-deployment.yaml

其中,[USER_CLUSTER_KUBECONFIG] 是用户集群的 kubeconfig 文件。

使用 Service 公开 Deployment

要为客户端提供稳定的方法来向 Deployment 的 Pod 发送请求,请创建一个 Service。

以下是 Service 的清单,它将 Deployment 公开给集群内外的客户端:

apiVersion: v1
kind: Service
metadata:
  name: hello-service
spec:
  type: NodePort
  selector:
    greeting: hello
  ports:
  - name: world-port
    protocol: TCP
    port: 60000
    targetPort: 50000
  - name: kubernetes-port
    protocol: TCP
    port: 60001
    targetPort: 8080

将此清单复制到名为 hello-service.yaml 的文件,然后创建该 Service:

kubectl apply --kubeconfig [USER_CLUSTER_KUBECONFIG] -f hello-service.yaml

查看 Service:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] get service hello-service --output yaml

输出显示已分配给 Service 的 nodePort 值:

apiVersion: v1
kind: Service
metadata:
  ...
  name: hello-service
  namespace: default
  ...
spec:
  clusterIP: 10.105.252.237
  externalTrafficPolicy: Cluster
  ports:
  - name: world-port
    nodePort: 31807
    port: 60000
    protocol: TCP
    targetPort: 50000
  - name: kubernetes-port
    nodePort: 30734
    port: 60001
    protocol: TCP
    targetPort: 8080
  selector:
    greeting: hello
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer:
    ingress:
    - {}

在上面的输出中,ports 字段是 ServicePort 对象(分别名为 world-portkubernetes-port)的一个数组。

以下是客户端使用 world-port 调用该 Service 的方式:

  • 在其中一个集群节点上运行的客户端可以向 port 上的 clusterIP 发送请求。在此示例中为 10.105.252.237:60000。该请求被转发给 targetPort 上的成员 pod。在此示例中为 [POD_IP_ADDRESS]:50000。

  • 客户端可以向 nodePort 上任何集群节点的 IP 地址发送请求。在此示例中为 [NODE_IP_ADDRESS]:31807。该请求被转发给 targetPort 上的成员 pod。在此示例中为 [POD_IP_ADDRESS]:50000。

以下是客户端使用 kubernetes-port 调用该 Service 的方式:

  • 在其中一个集群节点上运行的客户端可以向 port 上的 clusterIP 发送请求。在此示例中为 10.105.252.237:60001。该请求被转发给 targetPort 上的成员 pod。在此示例中为 [POD_IP_ADDRESS]:8080。

  • 客户端可以向 nodePort 上任何集群节点的 IP 地址发送请求。在此示例中为 [NODE_IP_ADDRESS]:30734。该请求被转发给 targetPort 上的成员 pod。在此示例中为 [POD_IP_ADDRESS]:8080。

创建 Ingress

以下是 Ingress 的清单:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /greet-the-world
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60000
      - path: /greet-kubernetes
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60001

将此清单复制到名为 my-ingress.yaml 的文件,然后创建该 Ingress:

kubectl apply --kubeconfig [USER_CLUSTER_KUBECONFIG] -f my-ingress.yaml

在创建用户集群的过程中,您通过在用户集群配置文件中提供 usercluster.vips.ingressvip 的值,为 Ingress 指定虚拟 IP 地址 (VIP)。

当客户端向您的用户集群 Ingress VIP 发送请求时,请求将路由到您的 F5 BIG-IP 负载平衡器。该负载平衡器会将请求转发给在您的用户集群中运行的 Ingress Service。该 Ingress Service 配置为根据请求网址中的路径将请求转发到不同的后端。

请务必注意,有两个不同的 Service 与本主题中的步骤相关:

  • 名为 hello-service 的 Service。您创建该 Service 用于公开 hello-deployment Deployment 的 Pod。

  • 在用户集群的 gke-system 命名空间中运行的 Ingress Service。此 Service 是您的集群基础架构的一部分。

/greet-the-world 路径

Ingress 清单中有一条规则指出,/greet-the-world 路径与 serviceName: hello-serviceservicePort: 60000 相关联。您应该还记得,60000 是 hello-service Service 的 world-port 字段中的 port 值。

- name: world-port
    nodePort: 31807
    port: 60000
    protocol: TCP
    targetPort: 50000

Ingress Service 选择集群节点,并将请求转发到 nodePort 上的节点。在此示例中为 [NODE_IP_ADDRESS]:31807。节点上的 iptables 规则用于将请求转发到端口 50000 上的成员 Pod。侦听端口 50000 的容器会显示 Hello World! 消息。

/greet-kubernetes 路径

Ingress 清单中有一条规则指出,/greet-kubernetes 路径与 serviceName: hello-serviceservicePort: 60001 相关联。您应该还记得,60001 是 hello-service Service 的 kubernetes-port 字段中的 port 值。

- name: kubernetes-port
    nodePort: 30734
    port: 60001
    protocol: TCP
    targetPort: 8080

Ingress Service 选择集群节点,并将请求转发到 nodePort 上的节点。在此示例中为 [NODE_IP_ADDRESS]:30734。节点上的 iptables 规则用于将请求转发到端口 8080 上的成员 Pod。侦听端口 8080 的容器会显示 Hello Kubernetes! 消息。

测试 Ingress:

使用 /greet-the-world 路径测试 Ingress:

curl [USER_CLUSTER_INGRESS_VIP]/greet-the-world

输出结果会显示 Hello, world! 消息:

Hello, world!
Version: 2.0.0
Hostname: ...

使用 /greet-kubernetes 路径测试 Ingress:

curl [USER_CLUSTER_INGRESS_VIP]/greet-kubernetes

输出结果会显示 Hello, Kubernetes! 消息:

Hello Kubernetes!

清理

删除 Ingress:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] delete ingress my-ingress

删除 Service:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] delete service hello-service

删除 Deployment:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] delete deployment hello-deployment