Send TCP traffic to the ingress's namespace with Nginx Ingress - kubernetes

I'm using an Nginx Ingress controller to open connections to a postgres database with the --tcp-services-configmap=k8s-ingress/k8s-ingress-tcp flag. That configmap looks like
apiVersion: v1
data:
"5432": namespace-a/the-postgres-svc:5432
kind: ConfigMap
This portion works perfectly, however I would like to open up another service on the same port, 5432 to namespace-b/the-postgres-svc:5432.
Is there any way to have the namespace selected be based on the namespace from the ingress resource? Since the data key would be identical if I were to just add that record to the after the "namespace-a" record I am not able to just append to the configmap data.
Thanks!

So you would like to have services on the same port in different namespaces.
I have found interesting step-by-step tutorial for this approach.
Firstly you should create two namespaces:
apiVersion: v1
kind: Namespace
metadata:
name: namespace-a
apiVersion: v1
kind: Namespace
metadata:
name: namespace-b
Than have your services and deployment definition, where the difference is between name and namespace fields:
apiVersion: v1
kind: Service
metadata:
labels:
run: nginx
name: namespacea-nginx
namespace: namespace-a
spec:
ports:
- port: 5432
protocol: TCP
targetPort: 5432
selector:
run: nginx
apiVersion: v1
kind: Service
metadata:
labels:
run: nginx
name: namespaceb-nginx
namespace: namespace-b
spec:
ports:
- port: 5432
protocol: TCP
targetPort: 5432
selector:
run: nginx
Deployment files:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
run: nginx
name: nginx
namespace: namespace-a
spec:
...
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
run: nginx
name: nginx
namespace: namespace-b
spec:
...
And finally, Ingress files definitions:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
namespace: namespace-a
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: namespacea.com
http:
paths:
- backend:
serviceName: namespacea-nginx
servicePort: 5432
path: /
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
namespace: namespace-b
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: namespaceb.com
http:
paths:
- backend:
serviceName: namespaceb-nginx
servicePort: 5432
path: /

Related

How To Enable SSL on Google Kubernetes Engine while using ingress-nginx?

I am using GKE with ingress-nginx (https://kubernetes.github.io/ingress-nginx/). I tried many tutorials using cert-manager but was unable to learn it.
Could you give me a yaml file as an example if you are able to get SSL working with ingress-nginx in google kubernetes engine?
You can use this as a starting point and expand on it
apiVersion: apps/v1
kind: Deployment
metadata:
name: arecord-depl
spec:
replicas: 1
selector:
matchLabels:
app: arecord
template:
metadata:
labels:
app: arecord
spec:
containers:
- name: arecord
image: gcr.io/clear-shell-346807/arecord
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
---
apiVersion: v1
kind: Service
metadata:
name: arecord-srv
spec:
selector:
app: arecord
ports:
- name: arecord
protocol: TCP
port: 8080
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
annotations:
kubernetes.io/ingress.class: "gce"
kubernetes.io/ingress.global-static-ip-name: ssl-ip
spec:
tls:
- hosts:
- vareniyam.me
secretName: echo-tls
rules:
- host: vareniyam.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: arecord-srv
port:
number:
8080
You have said you're using nginx ingress, but your ingress class is saying gce:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
annotations:
kubernetes.io/ingress.class: "gce"
You have not indicated which ClusterIssuer or Issuer you want to use. cert-manager issues certificates only after you tell it you want it to create a certificate
I am unsure what tutorials you have tried, but have you tried looking at the cert-manager docs here: https://cert-manager.io/docs/

Kubernetes ingress not routing

I have 2 services and deployments deployed on minikube on local dev. Both are accessible when I run minikube start service. For the sake of simplicity I have attached code with only one service
However, ingress routing is not working
CoffeeApiDeployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffeeapi-deployment
labels:
app: coffeeapi
spec:
replicas: 1
selector:
matchLabels:
app: coffeeapi
template:
metadata:
labels:
app: coffeeapi
spec:
containers:
- name: coffeeapi
image: manigupta31286/coffeeapi:latest
env:
- name: ASPNETCORE_URLS
value: "http://+"
- name: ASPNETCORE_ENVIRONMENT
value: "Development"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: coffeeapi-service
spec:
selector:
app: coffeeapi
type: NodePort
ports:
- protocol: TCP
port: 8080
targetPort: 80
nodePort: 30036
Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /coffee
pathType: Prefix
backend:
service:
name: coffeeapi-service
port:
number: 8080
You are missing the ingress class in the spec.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
spec:
ingressClassName: nginx # (or the class you configured)
Using NodePort on your service may also be problematic. At least it's not required since you want to use the ingress controller to route traffic via the ClusterIP and not use the NodePort directly.

GKE BackendConfig not working with customRequestHeaders

I have a nodejs application running on Google Kubernetes Engine (v1.20.8-gke.900)
I want to add custom header to get client's Region and lat long so I refer to this article and this one also and created below kubernetes config file, but when I am printing the header I am not getting any custom header.
#k8s.yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-app-ns-prod
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: npm-app-deployment
namespace: my-app-ns-prod
labels:
app: npm-app-deployment
tier: backend
spec:
template:
metadata:
name: npm-app-pod
namespace: my-app-ns-prod
labels:
app: npm-app-pod
tier: backend
spec:
containers:
- name: my-app-container
image: us.gcr.io/img/my-app:latest
ports:
- containerPort: 3000
protocol: TCP
envFrom:
- secretRef:
name: npm-app-secret
- configMapRef:
name: npm-app-configmap
imagePullPolicy: Always
imagePullSecrets:
- name: gcr-regcred
replicas: 3
minReadySeconds: 30
selector:
matchLabels:
app: npm-app-pod
tier: backend
---
apiVersion: v1
kind: Service
metadata:
name: npm-app-service
namespace: my-app-ns-prod
annotations:
cloud.google.com/backend-config: '{"ports": {"80":"npm-app-backendconfig"}}'
cloud.google.com/neg: '{"ingress": true}'
spec:
selector:
app: npm-app-pod
tier: backend
ports:
- name: http
protocol: TCP
port: 80
targetPort: 3000
- name: https
protocol: TCP
port: 443
targetPort: 3000
type: LoadBalancer
---
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: npm-app-backendconfig
namespace: my-app-ns-prod
spec:
customRequestHeaders:
headers:
- "HTTP-X-Client-CityLatLong:{client_city_lat_long}"
- "HTTP-X-Client-Region:{client_region}"
- "HTTP-X-Client-Region-SubDivision:{client_region_subdivision}"
- "HTTP-X-Client-City:{client_city}"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api/v1
pathType: Prefix
backend:
service:
name: npm-app-service
port:
number: 80
---
apiVersion: v1
kind: ConfigMap
metadata:
name: npm-app-configmap
namespace: my-app-ns-prod
data:
APP_ID: "My App"
PORT: "3000"
---
apiVersion: v1
kind: Secret
metadata:
name: npm-app-secret
namespace: my-app-ns-prod
type: Opaque
data:
MONGO_CONNECTION_URI: ""
SESSION_SECRET: ""
Actually the issue was with Ingress Controller, I missed to defined "cloud.google.com/backend-config". Once I had defined that I was able to get the custom header. Also I switched to GKE Ingress controller (gce) from nginx. But the same things works with nginx also
This is how my final ingress looks like.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
annotations:
cloud.google.com/backend-config: '{"default": "npm-app-backendconfig"}'
kubernetes.io/ingress.class: "gce"
spec:
...
...
Reference: User-defined request headers :

How do I make a forward-proxy server on k8s and ALB(or NLB)?

I created forward proxy server on EKS pods behind ALB(created by AWS Load Balancer Controller). All pod can take a response through 8118 port through ALB.
The resources like pod and ingress looked good to me. Then I tried if the proxy server work well with curl -Lx k8s-proxy-sample-domain.ap-uswest-1.elb.amazonaws.com:18118 ipinfo.io
Normally, I get random ip address from ipinfo.io. But it didn't.... So, I also did port-forad. Like this:
kubectl port-forward specifi-pod 8118:8118
Then I re-try redirect access on my host address.
curl -Lx localhost:8118 ipinfo.io
In this case, it went well. I cannot catch the reason. What's the difference between THROUGH ALB and port-forward. Should I use NLB for some reason? Or some misconfigure?
My environement
k8s version: v1.18.2
node type: fargate
Manifest
Here is my manifest.
---
apiVersion: v1
kind: Namespace
metadata:
name: tor-proxy
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: tor-proxy
name: tor-proxy-deployment
spec:
selector:
matchLabels:
app.kubernetes.io/name: tor-proxy
replicas: 5
template:
metadata:
labels:
app.kubernetes.io/name: tor-proxy
spec:
containers:
- image: dperson/torproxy
imagePullPolicy: Always
name: tor-proxy
ports:
- containerPort: 8118
---
apiVersion: v1
kind: Service
metadata:
labels:
name: tor-proxy
name: tor-proxy-service
namespace: tor-proxy
spec:
ports:
- port: 18118
targetPort: 8118
protocol: TCP
type: NodePort
selector:
app.kubernetes.io/name: tor-proxy
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: tor-proxy
name: tor-proxy-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 18118}]'
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: tor-proxy-service
servicePort: 18118
Use NLB not ALB, because it pass the client IP toward a target site through proxy server.

Forward to ExternalName with traefik in kubernetes as the documenation suggests

Following the Official Guide I got to the section onForwarding to ExtternalNames. Where it says:
When specifying an ExternalName, Træfik will forward requests to the given host accordingly
which points to the docs from kubernetes services without selectors
Which led me to create a service
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
Of which Traefik happily ignores when I point to it:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-service
namespace: kube-system
spec:
rules:
- host: my-service.example.com
http:
paths:
- path: /
backend:
serviceName: my-service
servicePort: 4080
I have also tried as an endpoint.
---
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: kube-system
spec:
ports:
- protocol: TCP
port: 80
targetPort: 4080
---
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- ip: 10.0.0.3
ports:
- port: 4080
Does anyone know how to get traefik to point to an externalname as the documentation suggests?
As I see, you missed at least one line in your Ingress object - traefik.frontend.passHostHeader: "false".
Also, you need to create an Ingress object in a same Namespace with your Service.
So, your Ingress should be like:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-service
namespace: prod
annotations:
traefik.frontend.passHostHeader: "false"
spec:
rules:
- host: my-service.example.com
http:
paths:
- path: /
backend:
serviceName: my-service
servicePort: 4080
And service:
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
ports:
- name: app-port
port: 4080
externalName: my.database.example.com