Unhealthy targets when provisioning ALB Ingress with Istio Ingress Gateway as backend - kubernetes

The EKS nodes targets show unhealthy when deploying ALB ingress in AWS with Load Balancer Controller.
Istio Ingress Gateway is provisioned as NodePort and I have obtained the correct port which in my case is 32403. The nodes security groups allow traffic on 32403 from load balancer.
Here is the ingress, which creates the following:
ALB
only one listener on 443
listener rule 1 - /healthz/ready/* that forwards to target group 1
listener rule 2 - /* that forwards to target group 2
listener rule 3 - Request is not otherwise routed - returns 404
Not sure what I'm missing but shouldn't there be a listener for 15201 as well?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/load-balancer-name: k8s-lb
alb.ingress.kubernetes.io/load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=recp-entres-cb-alblogs,access_logs.s3.prefix=lb-logs,routing.http.drop_invalid_header_fields.enabled=true,deletion_protection.enabled=true
alb.ingress.kubernetes.io/security-groups: sg-xxxxxxxxxxx
alb.ingress.kubernetes.io/manage-backend-security-group-rules: "true"
alb.ingress.kubernetes.io/subnets: subnet-xxxxxxxxxxx, subnet-xxxxxxxxxxx, subnet-xxxxxxxxxxx
alb.ingress.kubernetes.io/healthcheck-path: /healthz/ready
alb.ingress.kubernetes.io/healthcheck-port: "32403"
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
alb.ingress.kubernetes.io/backend-protocol: HTTPS
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-west-1:11111111111111:certificate/7773d18b-842c-488e-91ea-a36gh9866232
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-2-Ext-2018-06
alb.ingress.kubernetes.io/shield-advanced-protection: 'false'
name: gateway-ingress
namespace: istio-ingress
spec:
ingressClassName: alb
rules:
- http:
paths:
- backend:
service:
name: istio-ingressgateway
port:
number: 15021
path: /healthz/ready
pathType: Prefix
- backend:
service:
name: istio-ingressgateway
port:
number: 443
path: /
pathType: Prefix

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

How to map only specific services to a specific listener port in ALB (k8s ingress)

For example, guestbook-ui service and bbs-ui service are installed in k8s.
And I want to map guestbook-ui only to the 8080 listener port and bbs-ui service to the 8081 listener port to the pre-generated k8s ALB ingress.
However, if you write and store the following in spec, all guestbook-ui and bbs-ui services are deployed to all ports of 8080, 8081, and routing is twisted.
# skip
metadata:
annotations:
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":8080}, {"HTTP":8081}]'
# skip
spec:
rules:
- http:
paths:
- backend:
service:
name: bbs-ui
port:
number: 80
path: /*
pathType: ImplementationSpecific
- http:
paths:
- backend:
service:
name: guestbook-ui
port:
number: 80
path: /*
pathType: ImplementationSpecific
How can I deploy the service to the listener port I want?
There is a feature to automatically merge multiple ingress rules for all ingresses in the same ingress group. The AWS ALB ingress controller supports them with a single ALB.
metadata:
annotations:
alb.ingress.kubernetes.io/group.name: my-group
In the AWS ALB ingress controller, prior to version 2.0, each ingress object you created in Kubernetes would get its own ALB. Customers wanted a way to lower their cost and duplicate configuration by sharing the same ALB for multiple services and namespaces.
By sharing an ALB, you can still use annotations for advanced routing but share a single load balancer for a team, or any combination of apps by specifying the alb.ingress.kubernetes.io/group.name annotation. All services with the same group.name will use the same load balancer.
So, you can create ingress like this:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress1
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/tags: mytag=tag
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/group.name: my-group
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 8080}]'
spec:
rules:
- http:
paths:
- backend:
service:
name: bbs-ui
port:
number: 80
path: /*
pathType: ImplementationSpecific
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress2
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/tags: mytag=tag
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/group.name: my-group
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 8081}]'
spec:
rules:
- http:
paths:
- backend:
service:
name: guestbook-ui
port:
number: 80
path: /*
pathType: ImplementationSpecific
You can read more info about IngressGroup here.

Ingress resource hostname

I have kube cluster & its control plane endpoint is haproxy. I want to use hostname of system where haproxy lies and use it as hostname in the ingress resource. Is it possible to achieve this. The request ha proxy backend config is below:
frontend k8s_frontend
bind *:6443
mode tcp
default_backend k8s_backend
backend k8s_backend
mode tcp
balance roundrobin
server master1 10.50.8.117:6443
server master2 10.50.8.118:6443
server master3 10.50.8.119:6443
frontend http_frontend
bind :80
bind :443 ssl crt /com.pem
default_backend servers
backend servers
balance roundrobin
server worker1 10.50.8.120:443 ssl verify none
server worker2 10.50.8.121:443 ssl verify none
Below is my ingress resource:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kubernetes-dashboard
annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: "HAPROXY_HOSTNAME"
http:
paths:
- pathType: Prefix
path: "/k8s"
backend:
service:
name: kubernetes-dashboard
port:
number: 443
Yes, you can mention the hostname of HAProxy in the ingress source. The ingress controller node can be resolved as hostname along with deploying and exposing the echo server service as shown below. Kindly refer to this document.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: haproxy
name: echoserver
spec:
rules:
host: $HOST
http:
paths:
backend:
serviceName: echoserver
servicePort: 8080
path: /
EOF
More details on HAProxy Ingress Controller can be found here.

ingress can not get the default http backend

The ingress I config to run with the controller ingress-nginx.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
tls:
- hosts:
- XXX.XX.com
secretName: app-tls
rules:
- host: XXX.XX.com
http:
paths:
- path: /my-api(/|$)(.*)
backend:
serviceName: app
servicePort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-api
spec:
selector:
app: my-api
ports:
- name: app
port: 3000
targetPort: 3000
I can run the api locally curl localIP:3000/testapi, but it can not run remotely.
# kubectl describe ingress app-ingress
Name: app-ingress
Namespace: default
Address: XX.XX.XX.XX
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
app-tls terminates www.daichenchen.cn
Rules:
Host Path Backends
---- ---- --------
XXX.XX.com
/my-api(/|$)(.*) app:80 (<error: endpoints "app" not found>)
I already succeed install the ingress-nginx and all the pod work without error.
Your defined serviceName in Ingress rules and Service should be same.
Like this :
...
rules:
- host: XXX.XX.com
http:
paths:
- path: /my-api(/|$)(.*)
backend:
serviceName: app
servicePort: 80
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: my-api
ports:
- name: app
port: 3000
targetPort: 3000
If Ingress and the Service is in different namespace, you can also add the service name to the ingress rule. In this case you need to use dns name for service <service-name>.<namespace>.
For example:
rules:
- host: example.com
http:
paths:
- path: /my-api
backend:
serviceName: test-service.test-namespace
servicePort: 80
apiVersion: v1
kind: Service
metadata:
name: test-service
namespace: test-namespace
The way ingress controller finds out Endpoints of a service is it searches for a kubernetes service with the serviceName provided in the ingress resource in the namespace where you have created the ingress resource. If there is no kubernetes service with serviceName found you get endpoints not found.
The Endpoints of the service contains the IPs of pods behind the kubernetes service.
So in your case either the kubernetes service does not exist or it's in a different namespace than where ingress resource is created.
Some variant of nginx ingress controller does not support default backend and for this it's expected to have the error: endpoints "default-http-backend" not found
Another variant of nginx ingress controller supports default backend.
Double check which variant of nginx ingress controller you installed

How can I generate External IP when creating an ingress that uses nginx controller in kubernetes

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: helloworld-rules
spec:
rules:
- host: helloworld-v1.example.com
http:
paths:
- path: /
backend:
serviceName: helloworld-v1
servicePort: 80
- host: helloworld-v2.example.com
http:
paths:
- path: /
backend:
serviceName: helloworld-v2
servicePort: 80
I'm making kubernetes cluster and I will apply that cloudPlatform Isolated(not aws or google).
When creating an ingress for service I can choose host url but that is not exist anywhere(that address is not registrated something like DNS server) So I can't access that url. Visiting this IP just gives a 404.
how can I get or configure URL that can access external browser
:(...
It depends on how you configure your nginx controller.
You should have a Service configured which is the entry point when accessing from outside see the docs https://kubernetes.io/docs/concepts/services-networking/ingress/#what-is-ingress.
So basically you have a Service that points to the ingress controller and this will redirect the traffic to your pods based on Ingress Objects.
Ingress -> Services -> Pods
Since you don't run on aws or google You would have to use externalIp or NodePort and configure the service accordingly
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app: ingress-nginx
spec:
selector:
app: ingress-nginx
ports:
- name: http
port: 80
targetPort: http
- name: https
port: 443
targetPort: http
externalIPs:
- 80.11.12.10
And DNS needs to be managed with whatever you have for your domains in order to resolve, or for locally testing you can just edit your /etc/hostnames
Basically in AWS or Google you just create a service with type: LoadBalancer and point your dns records to the balancer address (CNAME for aws and the IP for google)