I'm trying to connect ingress on kubernetes to external service, for example google.com
whose ip is 172.217.21.14
.
So when I go to service.test.ai
it sends me to google.com
but it doesn't work.
Here are the manifests:
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 are meant to load balance traffic to pods in your cluster. I do not think you can have a service pointing to an external endpoint. If you want to do that, set it up in your ingress.
if you external service have DNS name domain you can use the external service in kubernetes.
so flow will be something like :
ingress > service > external service
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
type: ExternalName
externalName: google.com
now ingress will be something like
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: externalNameservice
spec:
rules:
- host: service.example.com
http:
paths:
- backend:
serviceName: my-service
servicePort: 80
path: /
if you want to use the IP address you can go with your approach only
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
check the service clusterIP
also check for the SSL annotation
nginx.ingress.kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
UPdate :
as you mention if you want to redirect or rewrite the traffic I am just sharing a small example for both
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
If it's redirect
you're after then nginx ingress controller has annotation called 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.
So your ingress should look like this:
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: /
And here's test:
➜ ~ 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
The below ingress example if in case you'd want to redirect the request along with some parameters after the /
. In that case you would need
configuration-snippet
or server-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: /
With this, if I curl my ingress it's being redirected along with the 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