How can I proxy requests to an External Port in Kubernetes? - kubernetes

I have a web service running on a port on my local network exposed at port 6003. I also have a Kubernetes Cluster running on a different machine on the same network that uses and Nginx Ingress to proxy to all the services in the cluster. How can I set up an ingress to proxy to the machine? I had a set up that worked. But now, I am either getting DNS errors on the nginx pod or the response times out in the browser and nothing happens.
Here is the manifest I have been using.
apiVersion: v1
kind: Service
metadata:
name: myservice-service
spec:
type: ExternalName
externalName: 192.xxx.xx.x
ports:
- name: myservice
port: 80
protocol: TCP
targetPort: 6003
---
apiVersion: v1
kind: Endpoints
metadata:
name: myservice-ip
subsets:
- addresses:
# list all external ips for this service
- ip: 192.xxx.xx.x
ports:
- name: myservice
port: 6003
protocol: TCP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: service.example.com
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: service.example.com
http:
paths:
- backend:
serviceName: myservice-service
servicePort: 80
path: /
tls:
- secretName: secret-prod-tls
hosts:
- service.example.com
Edit for more information:
This manifest does work. What I realized is that you must specify https even though the ingress has a tls block. This still is showing Lua DNS errors in the Nginx-ingress pod though.

You MUST specify nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" in your ingress resource if upstream listening for HTTPS requests. So, this is related to backend, not ingress itself.
TLS configuration is for Ingress (frontend), and not for backend application.

You don't need ExternalName here. Usual headless service will do the job:
apiVersion: v1
kind: Service
metadata:
name: external-ip
spec:
ports:
- name: http
port: 80
clusterIP: None
type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-ip
subsets:
- addresses:
- ip: 172.17.0.5
ports:
- name: http
port: 80

Related

Connect local Docker Kubernetes to localhost's app

I have Mac OS and local Docker Desktop with Kubernetes enabled.
I want to have a service in local Kubernetes connected to my local java app running on port 8087.
Here is what I have so far:
Service
apiVersion: v1
kind: Service
metadata:
name: auth
spec:
selector:
app: app-auth
ports:
- protocol: TCP
port: 80
targetPort: 8087
---
kind: Endpoints
apiVersion: v1
metadata:
name: auth
subsets:
- addresses:
- ip: <127.0.0.1 outside of cluster>
ports:
- port: 8087
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: router
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: localhost
http:
paths:
- path: /api/user
pathType: Prefix
backend:
service:
name: auth
port:
number: 80
I already checked this, but without success since I am not using either minikube either virtual box
access-mysql-running-on-localhost-from-minikube
how-to-access-hosts-localhost-from-inside-kubernetes-cluster
The Question: what IP should I use for my to-os-localhost-service?
Thank you

Ingress redirect to a localhost tcp service

I have a local website.
The website was created by a docker-compose and it is listening on a localhost port 3000.
When I try:
curl 127.0.0.1:3000
I can see the response.
What I did:
From my domain provider I edited the DNS to point to my server, then I changed nginx-ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: virtual-host-ingress
namespace: ingress-basic
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
cert-manager.io/cluster-issuer: "letsencrypt-pp"
spec:
tls:
- hosts:
- nextformulainvesting.com
secretName: ***
rules:
- host: "nextformulainvesting.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: e-frontend-saleor
port:
number: 80
and I created the service:
apiVersion: v1
kind: Service
metadata:
name: e-frontend-saleor
spec:
ports:
- protocol: TCP
port: 80
targetPort: 3000
But with the service or without the service I receive the error 503 Service Temporarily Unavailable.
How can I use nginx-ingress to point to my local TCP service?
To clarify the issue I am posting a community wiki answer.
The answer that helped to resolve this issue is available at this link. Based on that - the clue of the case is to create manually a Service and an Endpoint objects for external server.
After that one can create an Ingress object that will point to Service external-ip with adequate port .
Here are the examples of objects provided in similar question.
Service and an Endpoint objects:
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
Ingress object:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: external-service
spec:
rules:
- host: service.example.com
http:
paths:
- backend:
serviceName: external-ip
servicePort: 80
path: /
See also this reference.
Your service that you have created is for forwarding the traffic to deployments
As your service is running out side of Kubernetes cluster you should be using the Endpoint in this case
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- IP: <External IP>
ports:
- port: 3000
and you can use this Endpoint to ingress so that it will route the traffic.
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: virtual-host-ingress
namespace: ingress-basic
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
cert-manager.io/cluster-issuer: "letsencrypt-pp"
spec:
tls:
- hosts:
- nextformulainvesting.com
secretName: ***
rules:
- host: "nextformulainvesting.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-service
port:
number: 3000

kubernetes ingress-nginx gives 502 error and the address field is empty

I am setting up kubernetes on a AWS environment using kubeadm. I have setup ingress-nginx to access the service on port 443. I have checked the service configurations which look good. I am receiving 502 bad gateway and also the Address field in ingress is empty.
Front end service
apiVersion: v1
kind: Service
metadata:
labels:
name: voyager-configurator-webapp
name: voyager-configurator-webapp
spec:
ports:
-
port: 443
targetPort: 443
selector:
component: app
name: voyager-configurator-webapp
type: ClusterIP
Ingress yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress-resource
spec:
tls:
- hosts:
- kubernetes-test.xyz.com
secretName: default-server-secret
rules:
- host: kubernetes-test.xyz.com
http:
paths:
- backend:
serviceName: voyager-configurator-webapp
servicePort: 443
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress-resource <none> kubernetes-test.xyz.com 80, 443 45m
What could be the issue here ? Any help will be appreciated.
Make sure that your service is created in proper namespace - if not add namespace field in service definition. It is not good approach to add label called name with the same name as your service, instead you can use different one to avoid mistake and configurations problem.
Read more about selectors and labels: labels-selectors.
Your frontend service should look like that:
piVersion: v1
kind: Service
name: voyager-configurator-webapp
metadata:
labels:
component: app
appservice: your-example-app
spec:
ports:
- protocol: TCP
port: 443
targetPort: 443
selector:
component: app
app: your-example-app
type: ClusterIP
Your ingress should look like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress-resource
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts:
- kubernetes-test.xyz.com
secretName: default-server-secret
rules:
- host: kubernetes-test.xyz.com
http:
paths:
- path: /
backend:
serviceName: voyager-configurator-webapp
servicePort: 443
You have to define path to backend to with Ingress should send traffic.
Remember that is good to follow some examples and instructions during setup to avoid problems and waste of time during debugging.
Take a look: nginx-ingress-502-bad-gateway, aws-kubernetes-ingress-nginx.

Kubernetes Ingress to External Service?

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.
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
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: /
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
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
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

Traefik Kubernetes: Expose non Kubernetes service

I'm using Kubernetes with Traefik as Ingress Controller. I've some web services within my network that can't be containerized yet. Therefore I'm looking for a way to expose my non-Kubernetes web services through the Traefik Ingress. I've no more public IP's, so splitting both environments is not an option.
I've made an endpoint + service to solve this issue, but when I try to connect I get an SSL Protocol Error. Am I doing something wrong or does someone have another solution?
These are my (test)endpoints and service yaml:
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- ip: 10.4.0.6
ports:
- port: 443
---
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 443
name: https
targetPort: 443
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: host.com
http:
paths:
- path: /*
backend:
serviceName: my-service
servicePort: 443
For starters, I bet that when you kubectl describe svc my-service you have empty endpoints, even though endpoints do exist, right ?
To fix that, you need to adapt your endpoints ports key to have the same ports definition as your service has (name, protocol etc.). You should then see these endpoints in describe service results and be able to use it normally.
You could try this: Creating a K8s service of type ExternalName that binds to your external web service and add an Ingress as you would to with a "native" K8s service.
ExternalName Service --> https://kubernetes.io/docs/concepts/services-networking/service/#externalname
Exp.
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
There we're multiple issue regarding this problem.
First of all I deployed Traefik with helm. I found out that SSL is disabled by default...
my values.yaml is as follows:
imageTag: 1.6.6
rbac:
enabled: true
dashboard:
enabled: true
domain: traefik.dahsboard.local
ssl:
enabled: true
insecureSkipVerify: true
upstream: true
Like Radek mentioned the port definition of the endpoints and service have to be the same.
mine are:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 443
targetPort: 443
name: https
---
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- ip: 10.4.0.6
ports:
- protocol: TCP
port: 443
name: https