【问题标题】:Kubernetes: Route incoming traffic to specific PodKubernetes:将传入流量路由到特定 Pod
【发布时间】:2018-11-08 17:05:08
【问题描述】:

我想在 Google Kubernetes Engine 中部署多个 Pod,然后通过子域(如 pod-name-or-label.mydomain.com)或路径路由(如 protocol://mydomain.com:7878)建立与每个特定 Pod 的 TCP 连接/pod-name-or-label.

我已经研究过不同的方向,比如 Istio 或 nginx-ingress,但在我看来这太复杂了。

没有简单的解决方案吗?

【问题讨论】:

  • 独立的Pod 不是解决这个问题的方法,而且肯定是一种反模式。最好的办法是将几个抽象提升到 Deployment 资源,然后您可以部署 Pod 的多个副本,它们之间的标签会有所不同,以指示入口和路由。
  • Pod 不能在生产环境中使用,定义一个部署并使用 nodePort 公开它,然后使用会话持久性和 kube-proxy 设置为仅从本地节点提供服务。
  • 这个article展示了如何在Google Kubernetes Engine集群中创建Kubernetes服务以及如何创建Nodeport的服务。

标签: kubernetes network-programming kubernetes-ingress google-kubernetes-engine istio


【解决方案1】:

对于Istio,您可以使用VirtualService 来控制路由规则 到目标子集,由DestinationRules 定义。

DestinationRule 将通过 指定标签 pod 路由到目标 Pods

请求流希望:

+--------------------+
|                    |
|    Istio Gateway   |
|                    |
|                    |
+---------+----------+
          |traffic incoming
          |
+---------v----------+
|                    |
|   VirtualService   |
|                    |
|                    |
+---------+----------+
          |route to subset by the routing rules
          v

+--------------------+
|                    |
|  DestinationRules  |
|                    |
|                    |
+---------+----------+
          |route traffic to target pods
          v

+--------------------+
|                    |
|                    |
|       Pods         |
|                    |
+--------------------+

正如@ericstaples 所说,您应该使用不同的pod标签创建不同的部署,以实现将流量目标pod分开,示例:

  1. 使用 pod 标签创建部署:t1
  2. DestinationRule中创建一个子集:选择 t1 标签 pod 作为子集 s1
  3. 控制您在 VirtualService 中路由到 s1 子集的流量
  4. s1 路由到目标 pod

同样为了暴露Gateway,你可以像** Kubernetes** 其他服务一样使用ClusterIPNodePort,查看更多@987654323 @。

有一些参考资料可能会有所帮助:

https://istio.io/docs/concepts/traffic-management/

https://istio.io/docs/tasks/traffic-management/request-routing/

【讨论】:

    【解决方案2】:

    这个问题有点老了,但在当前的 Kubernetes 版本中,您可以使用 Nginx Ingress 轻松完成。

    如果您想从集群外部访问您的应用程序,您需要使用Services 公开它。最简单的方法是在 Deployment/PodService 中放入相同的 selector 时使用带有选择器的服务。下面的例子:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test1
    spec:
      replicas: 1
      selector:
        matchLabels:
          key: test1
      template:
        metadata:
          labels:
            key: test1
        spec:
          containers:
          - name: hello1
            image: gcr.io/google-samples/hello-app:1.0
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: test1
    spec:
      selector:
        key: test1
      ports:
        - port: 80
          targetPort: 8080
    

    路径路由将在Ingress 中配置。如下例所示:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - host: my.pod.svc 
        http:
          paths:
          - path: /pod
            backend:
              serviceName: my-pod
              servicePort: 80
      - host: nginx.test.svc
        http:
          paths:
          - path: /abc
            backend:
              serviceName: nginx1
              servicePort: 80
    

    更多详情可以查看this thread

    【讨论】:

      【解决方案3】:

      现在我在集群上安装了 istio 的解决方案:

      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: echo-gateway
      spec:
        selector:
          istio: ingressgateway # use istio default controller
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "dev.sample.com"
      

      通过该网关,我可以应用部署、服务、虚拟服务

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-echo-1000-deployment
        labels:
          echoservice: echo-1000
      spec:
        replicas: 1
        selector:
          matchLabels:
            echoservice: echo-1000
        template:
          metadata:
            labels:
              echoservice: echo-1000
          spec:
            containers:
            - image: gcr.io/google-containers/echoserver:1.10
              imagePullPolicy: IfNotPresent
              name: my-echo-run-container
              ports:
              - containerPort: 8080
                protocol: TCP
      
      ---
      
      apiVersion: v1
      kind: Service
      metadata:
        name: my-echo-1000-service
        labels:
          echoservice: echo-1000
      spec:
        ports:
        - port: 8080
          name: http
        selector:
          echoservice: echo-1000
      
      ---
      
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: my-echo-1000-vservice
      spec:
        hosts:
        - "dev.sample.com"
        gateways:
        - echo-gateway
        http:
        - match:
          - uri:
              exact: /echo-1000
          route:
          - destination:
              host: my-echo-1000-service
              port:
                number: 8080
      

      从 istio-ingressgateway 获取 LoadbalancerIP 并在 /etc/hosts 中为 dev.sample.com 输入条目

      现在我可以使用 http://dev.sample.com/echo-1000 获取特定 Pod 中的 echoserver

      这是一个好的解决方案还是有更好的解决方案?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-09
        • 2020-06-19
        • 1970-01-01
        • 1970-01-01
        • 2021-05-23
        • 1970-01-01
        相关资源
        最近更新 更多