基于Kubernetes路径的多名称空间路由

基于Kubernetes路径的多名称空间路由,kubernetes,google-cloud-platform,kubernetes-ingress,Kubernetes,Google Cloud Platform,Kubernetes Ingress,环境:我有一个kubernetes集群,它的名称空间为“dev”、“sit”和“prod”。在每一个名称空间中,我都有多个类型为LoadBalancer的服务,其目标是停靠应用程序的特定部署(我有多个应用程序),因此我可以通过使用我想要的名称空间中服务的公开ip地址来访问每一个服务。示例服务看起来非常简单: apiVersion: v1 kind: Service metadata: name: application1 spec: ports: - port: 80 tar

环境:我有一个kubernetes集群,它的名称空间为“dev”、“sit”和“prod”。在每一个名称空间中,我都有多个类型为LoadBalancer的服务,其目标是停靠应用程序的特定部署(我有多个应用程序),因此我可以通过使用我想要的名称空间中服务的公开ip地址来访问每一个服务。示例服务看起来非常简单:

apiVersion: v1
kind: Service
metadata:
  name: application1
spec:
  ports:
  - port: 80
    targetPort: 3000
    protocol: TCP
    name: http
  type: LoadBalancer
  selector:
    app: application1
问题:我现在希望能够支持所有应用程序的多个版本(ip:/v1/、ip:/v2/等),以允许用户在准备好后迁移到新版本,我一直在尝试实现基于路径的路由。我已经成功地重组了我的体系结构,这样我就有了ReplicationController和一个入口,它可以查看路径规则以路由到正确的服务

如果我只有一个公开的服务和一个名称空间,这似乎是可行的,因为我只有用于生产环境的DNS主机名,并且希望将服务的单个ip地址用于其他环境,并且我不知道如何为没有主机名的服务指定入口规则

我可以为每个环境使用一个负载平衡器,并使用基于路径的路由为dev和sit路由到每个不同的服务,这并不理想,因为要访问任何服务,我们现在必须使用类似于此ip/application1和ip/application2的内容,而不是直接使用每个应用程序的服务ip地址。但我最大的问题是,当我按照指南在我的SIT命名空间中创建入口、复制控制器和服务时,它开始影响我的其他两个环境中的loadbalancer服务(据我所知,kubernetes有时会尝试在我的开发服务上使用SIT环境中的nginx控制器,因此会失败,其他时候它会使用GCE默认配置,并且会工作)


我尝试添加arg“---watch namespace=sit”以限制入口控制器的作用域仅影响sit,但它似乎不起作用。

我现在希望能够支持所有应用程序的多个版本(ip:/v1/、ip:/v2/等)

这正是Ingress可以做的,但问题是您希望使用IP地址进行路由,而Ingress使用DNS名称进行路由

我认为实现这一点的最佳方法是使用入口来处理请求。在GCE上,入口使用HTTP(S)负载平衡器。是的,您需要一个DNS名称,但它将帮助您创建所需的路由。
另外,我强烈建议对连接使用TLS加密。
您可以检查LetsEncrypt以获得免费的SSL证书

因此,解决方案如下所示:

1.使用类型“ClusterIP”而不是“LoadBalancer”部署服务。一个应用程序可以有多个服务对象,因此可以与当前配置并行执行。
2.选择任何名称空间(即使是特殊名称空间),例如“ingress ns”。我们需要创建这些服务对象,它们将指向其他名称空间中的服务。下面是一个服务示例(让新DNS名称为“my.shinn.new.domain”):

Kubernetes将使用您在入口对象中设置的规则创建一个新的HTTP(S)平衡器,您将拥有一个具有跨名称空间路径路由的入口点,您不必为此使用多个IP地址


实际上,您还可以通过该入口管理应用程序的主版本,并使用带有“/”路径的主域来处理到生产版本的请求。

对于通过入口路由服务负载平衡器ip地址的规则,我发现我可以将此格式用于主机:x.x.x.x.xip.io
kind: Service
apiVersion: v1  
  metadata:
    name: service-v1
    namespace: ingress-ns
 spec:  
   type: ExternalName
   externalName: <service>.<namespace>.svc.cluster.local # here is a service name and namespace of your service with version v1.
  ports:
    - port: 80 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: test
 namespace: ingress-ns
spec:
 rules:
 - host: my.shiny.new.domain
   http:
     paths:
     - path: /v1
       backend:
         serviceName: service-v1
         servicePort: 80
     - path: /v2
       backend:
         serviceName: service-v2
         servicePort: 80