im trying to set up a kubernetes service that points to an external api that is secured with tls so needs to keep the original host header - kubernetes

i'm trying to set up the following
external user calls https://service1.mycluster.com, my cluster calls https://service1.externalservice.com and then returns the response to the user
i'm doing this to leverage istio and kubernetes thats deployed in my cluster to provide centralised access to services but some of my legacy services can't be moved into the cluster
i believe i'm going to need a service with an externalName to represent the external service but unsure how to get it to resolve the tls and keep the hostname of service1.externalservice.com so the tls will pass
any ideas would be much appreciated thanks
Currently i have the following
service
apiVersion: v1
kind: Service
metadata:
annotations:
name: testservice1
spec:
externalName: https://service1.externalservice.com
internalTrafficPolicy: Cluster
ports:
- name: https
port: 443
protocol: TCP
targetPort: 443
sessionAffinity: None
type: ExternalName
ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: xxx
traefik.ingress.kubernetes.io/router.tls: "true"
name: test1
spec:
ingressClassName: xxx
rules:
- host: service1.mycluster.com
http:
paths:
- backend:
service:
name: testservice1
port:
number: 443
path: /
pathType: Prefix
tls:
- hosts:
- service1.mycluster.com
secretName: tls-test1-ingress

Related

Link service deployment Kubernetes

I have two services running on k8s and I am using an ingress to access my services. One of the service requires access to another view env but I added the cluster IP and the port of the required service but it seems to be unaccessible.
User Deployment yaml
...
- name: WALLET_SERVICE_URL
value: 'http://10.103.xxx.xx:30611'
- name: WALLET_SERVICE_API_VERSION
value: /api/v1
...
my Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dev-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /api/v1$uri
spec:
ingressClassName: nginx
rules:
- host: demo.localdev.me
http:
paths:
- path: /user
pathType: Prefix
backend:
service:
name: accounts-service
port:
number: 80
- path: /wallet
pathType: Prefix
backend:
service:
name: wallet-service
port:
number: 80
Wallet service
apiVersion: v1
kind: Service
metadata:
name: wallet-service
spec:
selector:
app: wallet-service
ports:
- port: 80
targetPort: 3007
type: NodePort
Use ClusterIP for wallet-service. There's no reason to use NodePort -- the ingress controller will handle routing to the internal IP.
Your value for the WALLET_SERVICE_URL should be pointing to your service by DNS name, using the port you define for your ClusterIP service. i.e. http://wallet-service:80.
Unless wallet-service should be accessible outside of the cluster, you don't need to configure ingress for it.
Ingress are for traffic from outside of the cluster, for internal network you can use the dns name of your service, you can read more about service dns in the docs

Why GCP LoadBalancer doesn't support the ECDSA certificate?

I have created kubernetes ingress with frontend config and the ECDSA P-384 TLS cert on Google Cloud Platform, after few seconds of creating process i received the followind error:
Error syncing to GCP: error running load balancer syncing routine:
loadbalancer -default--ingress-****** does not exist:
Cert creation failures -
k8s2-cr---***** Error:googleapi:
Error 400: The ECDSA curve is not supported.,
sslCertificateUnsupportedCurve
Why The ECDSA curve is not supported? Is there any way to enable this support?
Create tls-secret command:
kubectl create secret tls tls --key [key-path] --cert [cert-path]
Frontend-config:
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: frontend-config
spec:
redirectToHttps:
enabled: true
responseCodeName: MOVED_PERMANENTLY_DEFAULT
Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
namespace: default
labels:
kind: ingress
annotations:
networking.gke.io/v1beta1.FrontendConfig: frontend-config
spec:
tls:
- hosts:
- '*.mydomain.com'
secretName: tls
rules:
- host: mydomain.com
http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: spa-ingress-service
port:
number: 80
- host: api.mydomain.com
http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: api-ingress-service
port:
number: 80
spa services:
# SERVICE LOAD BALANCER
apiVersion: v1
kind: Service
metadata:
name: spa-service
labels:
app/name: spa
spec:
type: LoadBalancer
selector:
app/template: spa
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
---
# SERVICE NODE PORT - FOR INGRESS
apiVersion: v1
kind: Service
metadata:
name: spa-ingress-service
labels:
app/name: ingress.spa
spec:
type: NodePort
selector:
app/template: spa
ports:
- name: https
protocol: TCP
port: 80
targetPort: http
api services:
# SERVICE LOAD BALANCER
apiVersion: v1
kind: Service
metadata:
name: api-service
labels:
app/name: api
spec:
type: LoadBalancer
selector:
app/template: api
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
---
# SERVICE NODE PORT - FOR INGRESS
apiVersion: v1
kind: Service
metadata:
name: api-ingress-service
labels:
app/name: ingress.api
spec:
type: NodePort
selector:
app/template: api
ports:
- name: https
protocol: TCP
port: 80
targetPort: http
kubectl describe ingress response:
The gcp load balancer supports RSA-2048 or ECDSA P-256 certificates. Also DownstreamTlsContexts support multiple TLS certificates. These may be a mix of RSA and P-256 ECDSA certificates.
The following error is due to the incompatibility with the P-384 certificate currently being used rather than the P-256 certificate.
For additional information refer to the Load Balancing Overview.

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.

How can I proxy requests to an External Port in 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

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