Reputation: 9225
Say I have a service that isn't hosted on Kubernetes. I also have an ingress controller and cert-manager set up on my kubernetes cluster.
Because it's so much simpler and easy to use kubernetes ingress to control access to services, I wanted to have a kubernetes ingress that points to a non-kubernetes service.
For example, I have a service that's hosted at https://10.0.40.1:5678
(ssl required, but self signed certificate) and want to access at service.example.com
.
Upvotes: 59
Views: 62029
Reputation: 1
Maybe also add "nsm.nginx.com/internal-route: "true" as mentioned in https://docs.nginx.com/mesh/tutorials/kic/egress-walkthrough/ or https://www.f5.com/company/blog/nginx/how-to-simplify-kubernetes-ingress-egress-traffic-management as to expose the route only internally.
Upvotes: 0
Reputation: 9033
You can do it by manual creation of Service and Endpoint objects for your external server.
Objects will looks like that:
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: 10.0.40.1
ports:
- name: app
port: 5678
protocol: TCP
Also, it is possible to use an EndpointSlice object instead of Endpoints.
Then, you can create an Ingress object which will point to Service external-ip
with port 80
:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: external-service
spec:
rules:
- host: service.example.com
http:
paths:
- backend:
serviceName: external-ip
servicePort: 80
path: /
Upvotes: 64
Reputation: 963
Here's a working copy of my configuration for Kubernetes 1.26 with the EndpointSlice approach and NGINX Ingress 1.7 :
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- name: https
port: 5678
targetPort: 5678
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: external-service-1
labels:
kubernetes.io/service-name: external-service
addressType: IPv4
ports:
- name: ''
appProtocol: http
protocol: TCP
port: 5678
endpoints:
- addresses:
- "10.0.40.1"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: external-service
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: service.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: external-service
port:
number: 5678
Upvotes: 4
Reputation: 4812
So I got this working using ingress-nginx to proxy an managed external service over a non-standard port
apiVersion: v1
kind: Service
metadata:
name: external-service-expose
namespace: default
spec:
type: ExternalName
externalName: <external-service> # eg example.example.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: external-service-expose
namespace: default
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" #important
spec:
rules:
- host: <some-host-on-your-side> # eg external-service.yourdomain.com
http:
- path: /
pathType: Prefix
backend:
service:
name: external-service
port:
number: <port of external service> # eg 4589
tls:
- hosts:
- external-service.yourdomain.com
secretName: <tls secret for your domain>
of-course you need to make sure that the managed url is reachable from inside the cluster, a simple check can be done by launching a debug pod and doing
curl -v https://example.example.com:4589
Upvotes: 20
Reputation: 4868
I just want to update @Moulick answer here according to Kubernetes version v1.21.1, as for ingress the configuration has changed a little bit. In my example I am using Let's Encrypt for my nginx controller:
apiVersion: v1
kind: Service
metadata:
name: external-service
namespace: default
spec:
type: ExternalName
externalName: <some-host-on-your-side> eg managed.yourdomain.com
ports:
- port: <port of external service> eg 4589
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: external-service
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: 100m
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" #important
spec:
tls:
- hosts:
- <some-host-on-your-side> eg managed.yourdomain.com
secretName: tls-external-service
rules:
- host: <some-host-on-your-side> eg managed.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: external-service
port:
number: <port of external service> eg 4589
Upvotes: 9
Reputation: 1641
If your external service has a dns entry configured on it, you can use kubernetes externalName service.
---
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: myexternal.http.service.com
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: externalNameservice
namespace: prod
spec:
rules:
- host: service.example.com
http:
paths:
- backend:
serviceName: my-service
servicePort: 80
path: /
In this way, kubernetes create cname record my-service pointing to myexternal.http.service.com
Upvotes: 11