将入口连接到外部服务

connect ingress to external service

我正在尝试将 kubernetes 上的入口连接到外部服务,例如 google.com 其 ip 是 172.217.21.14.

所以当我去 service.test.ai 时它会把我送到 google.com 但它不起作用。

清单如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    #kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ingress.class: "nginx"
  name: external-service
spec:
  rules:
  - host: service.test.ai
    http:
      paths:
      - backend:
          serviceName: external-ip
          servicePort: 80
        path: /
apiVersion: v1
kind: Service
metadata:
  name: external-ip
spec:
  ports:
  - name: app
    port: 80
    protocol: TCP
    targetPort: 80

---
apiVersion: v1
kind: Endpoints
metadata:
  name: external-ip
subsets:
- addresses:
  - ip: 172.217.21.14
  ports:
  - name: app
    port: 80
    protocol: TCP

Services 用于负载均衡集群中 pods 的流量。我认为您不能拥有指向外部端点的服务。如果你想这样做,请在你的 ingress 中设置它。

如果您的外部服务有 DNS 域名,您可以在 kubernetes 中使用外部服务。

所以流量会是这样的:

ingress > service > external service 

apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  type: ExternalName
  externalName: google.com

现在入口将类似于

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: externalNameservice
spec:
  rules:
  - host: service.example.com
    http:
      paths:
      - backend:
          serviceName: my-service
          servicePort: 80
        path: /

如果你想使用 IP 地址,你可以只使用你的方法

apiVersion: v1
kind: Service
metadata:
  name: external-ip
spec:
  ports:
  - name: app
    port: 80
    protocol: TCP
    targetPort: 5678
  clusterIP: None
  type: ClusterIP

---
apiVersion: v1
kind: Endpoints
metadata:
  name: external-ip
subsets:
- addresses:
  - ip: 172.217.21.14
  ports:
  - name: app
    port: 80
    protocol: TCP

检查服务 clusterIP 同时检查 SSL 注释

nginx.ingress.kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"

更新 :

正如你提到的,如果你想重定向或重写流量,我只是为两者分享一个小例子

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: wordpress-prod
    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($host = 'www.example.io' ) {
        rewrite ^ https://example.io$request_uri permanent;
      }
      if ($scheme = http) {
        return 301 https://exmple.io$request_uri;
      }
      if ($scheme = 'http') {
        return 301 https://example.io$request_uri;
      }
    nginx.ingress.kubernetes.io/force-ssl-redirect: "True"
    nginx.ingress.kubernetes.io/from-to-www-redirect: "True"
    nginx.ingress.kubernetes.io/server-snippet: |
      location ~ /test-check {
         rewrite /test-check https://app.example.io$uri permanent;
      }
      location = /login {
         rewrite / https://app.example.io/login permanent;
      }
  name: wordpress-prod-ingress
  namespace: default
spec:
  rules:
  - host: example.io
    http:
      paths:
      - backend:
          serviceName: wordpress-site
          servicePort: 80
        path: /
  - host: www.example.io
    http:
      paths:
      - backend:
          serviceName: wordpress-site
          servicePort: 80
        path: /
  tls:
  - hosts:
    - example.io
    - www.example.io
    secretName: www-ssl-certificate

如果它是 redirect,那么 nginx 入口控制器有一个名为 permanent redirect:

的注解

This annotation allows to return a permanent redirect (Return Code 301) instead of sending data to the upstream. For example nginx.ingress.kubernetes.io/permanent-redirect: https://www.google.com would redirect everything to Google.

所以你的入口应该是这样的:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/permanent-redirect: "www.google.com"
  name: external-service
spec:
  rules:
  - host: service.test.ai
    http:
      paths:
      - backend:
          serviceName: external-ip
          servicePort: 80
        path: /

这是测试:

➜  ~ curl  -H "Host:  service.test.ai"  192.168.49.2/test -v

*   Trying 192.168.49.2...
* TCP_NODELAY set
* Connected to 192.168.49.2 (192.168.49.2) port 80 (#0)
> GET /test HTTP/1.1
> Host:  service.test.ai
> User-Agent: curl/7.52.1
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Date: Sun, 30 May 2021 19:27:52 GMT
< Content-Type: text/html
< Content-Length: 162
< Connection: keep-alive
< Location: www.google.com

如果您想在 / 之后重定向请求以及一些参数,请使用下面的入口示例。在那种情况下你需要 configuration-snippetserver-snippet:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    #kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/server-snippet: |
      return 301 http://www.google.com$request_uri;
  name: external-service
spec:
  rules:
  - host: service.test.ai
    http:
      paths:
      - backend:
          serviceName: external-ip
          servicePort: 80
        path: /

有了这个,如果我卷曲我的入口,它就会随着路径被重定向:

➜  ~ curl  -H "Host:  service.test.ai"  192.168.49.2/service-query-ai  -v

*   Trying 192.168.49.2...
* TCP_NODELAY set
* Connected to 192.168.49.2 (192.168.49.2) port 80 (#0)
> GET /service-query-ai HTTP/1.1
> Host:  service.test.ai
> User-Agent: curl/7.52.1
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Date: Sun, 30 May 2021 19:31:57 GMT
< Content-Type: text/html
< Content-Length: 162
< Connection: keep-alive
< Location: http://www.google.com/service-query-ai