【问题标题】:Kubernetes Cross Namespace Ingress NetworkKubernetes 跨命名空间入口网络
【发布时间】:2019-01-23 11:33:22
【问题描述】:

我有一个简单的入口网络,我想从这个入口网络访问不同命名空间的服务。

我该怎么做? 我的入口网络 yaml 文件:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
spec:
  rules:
 - host: api.myhost.com
 http:
 paths:
  - backend:
      serviceName: bookapi-2
      servicePort: 8080
    path: /booking-service/

我已将 ExternalNames 服务类型设置为 yaml 文件:

 apiVersion: v1
 kind: Service
 metadata:
   name: bookapi-2
   namespace: booking-namespace
 spec:
   type: ExternalName
   externalName: bookapi-2
   ports:
     - name: app
     protocol: TCP
      port: 8080
      targetPort: 8080
   selector:
      app: bookapi-2
      tier: backend-2

【问题讨论】:

标签: kubernetes microservices kubernetes-ingress


【解决方案1】:

ExternalName 服务是服务的一种特殊情况,它不 有选择器并使用 DNS 名称。

您可以通过官方Kubernetes documentation了解更多关于ExternalName服务的信息:

当您想从不同的命名空间访问服务时,您的 yaml 可以为 example,如下所示:

kind: Service
apiVersion: v1
metadata:
  name: test-service-1
  namespace: namespace-a
spec:
  type: ExternalName
  externalName: test-service-2.namespace-b.svc.cluster.local
  ports:
  - port: 80

对于你的 Ingress yaml 文件,请重新检查并确保它与官方示例兼容,example 这个因为它包含一些不一致:

apiVersion: extensions/v1beta1  
kind: Ingress  
metadata:  
  name: my-ingress  
spec:  
  rules:  
  - host: www.mysite.com  
    http:  
      paths:  
      - backend:  
          serviceName: website  
          servicePort: 80  
  - host: forums.mysite.com  
    http:  
      paths:  
      - path:  
        backend:  
          serviceName: forums  
          servicePort: 80

还请重新检查 ExternalName yaml,因为它具有在此类 Service 中未使用的 TargetPorts 和选择器,并确保:

外部名称服务仅适用于 kube-dns 1.7 版 及以后。

如果你不能成功,请分享你遇到的问题。

【讨论】:

  • 以防万一它对未来的读者有所帮助:当我运行 kubectl describe ingress 时,我看到一条错误消息,提示找不到 ExternalName 服务的端点。不过,一切都很好。 (在 microk8s 上,externalName: kubernetes-dashboard.kube-system.svc.cluster.local。)
  • @Arjan 我收到错误 service "default/service-name" is type "ExternalName", expected "NodePort" or "LoadBalancer" 并且它不起作用。你做了其他不同的事情吗?
  • @aurelis 没用。得到这个错误:Translation failed: invalid ingress spec: service "hello/nginx-external" is type "ExternalName", expected "NodePort" or "LoadBalancer"
  • 首先,您是否真的要将 Ingress 指向“外部”服务 test-service-1,它指向不同命名空间中的另一个服务?我不确定您是否真的是这个意思,因为您的 Ingress 指向完全不同的服务名称...无论如何,在 GKE 上,此设置不起作用,因为它需要对后端服务进行运行状况检查,并且对于外部服务总是失败(它是正确配置并手动测试)。
【解决方案2】:

ExternaNames 服务应该在没有任何 selector 选项的情况下创建。因此,在创建 入口资源 的命名空间中创建 ExternaNames 服务,并指向外部名称服务来解析托管在不同命名空间中的应用程序的名称。

【讨论】:

【解决方案3】:
  1. 创建命名空间服务-ns
  2. 创建一个名为 nginx-service 的 ClusterIP 类型的服务(默认),在命名空间 service-ns 中侦听端口 80
  3. 在 service-ns 中创建 nginx 部署
  4. 创建命名空间入口-ns
  5. 在 Ingress-ns 中创建一个 ExternalName 类型的服务,并指向 nginx-service 的 FQDN,将其指向为 nginx-internal.service-ns.svc.cluster.local
  6. 创建入口规则

注意:演示代码不要在生产环境中运行。只是想知道它如何跨命名空间工作

---
#1
apiVersion: v1
kind: Namespace
metadata:
  name: service-ns
---
#2
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx-internal
  namespace: service-ns
spec:
  ports:
  - name: "80"
    port: 80
    targetPort: 80  
  selector:
    app: nginx
---
#3
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: service-ns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        image: nginx
        name: nginx
        ports:
        - containerPort: 80
      restartPolicy: Always
---
#4
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-ns
---
#5
kind: Service
apiVersion: v1
metadata:
  name: nginx
  namespace: ingress-ns
spec:
  type: ExternalName
  externalName: nginx-internal.service-ns.svc.cluster.local
  ports:
  - port: 80
---
#6
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
  namespace: ingress-ns    
spec:
  rules:
    - host: whatever.domain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80

【讨论】:

    【解决方案4】:

    外部流量来自ingress controller service,它负责根据定义的路由规则或我们在 k8s 世界中称为 ingress rules 的方式路由流量。

    换句话说,ingress 资源只是路由规则(认为它类似于 DNS 记录),因此当您定义 ingress 资源时,您只需为 ingress controller 定义一个规则来处理和路由流量基于此类定义的规则。

    解决方案:

    1. 由于Ingress 只是路由规则,您可以在集群中的任何位置(在任何namespace)中定义此类规则,controller 应在监控此类资源的创建并做出相应反应时选择它们。

      这里是使用kubectl轻松创建入口的方法

      创建入口

      kubectl create ingress <name> -n namespaceName --rule="host/prefix=serviceName:portNumber"

      注意:添加--dry-run=client -oyaml生成yaml清单文件

    2. 或者您可以在定义了ingress 的同一namespace 中创建ExternalName 类型的服务。此类外部服务可以指向任何 URL(位于 namespace 甚至 k8s 集群之外的服务)

      这是一个例子:

      创建ExternalName 服务

      kubectl create service externalname ingress-ns -n namespaceName --external-name=serviceName.namespace.svc.cluster.local --tcp=80:80

    注意:添加--dry-run=client -oyaml生成yaml清单文件

    kind: Service
    apiVersion: v1
    metadata:
      name: nginx
      namespace: ingress-ns
    spec:
      type: ExternalName
      externalName: serviceName.namespace.svc.cluster.local #or any external svc
      ports:
      - port: 80 #specify the port of service you want to expose 
        targetPort: 80 #port of external service 
    

    如上所述,创建一个入口如下: kubectl create ingress <name> -n namespaceName --rule="host/prefix=serviceName:portNumber"

    注意:添加--dry-run=client -oyaml生成yaml清单文件

    【讨论】:

      猜你喜欢
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 2023-03-17
      • 2021-03-05
      • 1970-01-01
      • 2021-03-25
      • 2021-01-20
      相关资源
      最近更新 更多