EKS cluster is not showing my an IP on the Ingress controller - kubernetes

I am new to K8S so please be gentle. I have a test hello world Flask app and I would like to deploy it on EKS. I am using the AWS load Balancer Controller Addon using the link below. At the end when I check the deployment it shows up without any issues as the link describes.
https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html
When I apply the three files below they all apply correctly and I see the pods up, but on the ingress I dont see an external IP address and cant access my Flask app.
My goal is to have AWS create a dummy DNS name and then I can point my public DNS name to it as an CNAM entry. Also the Ingress should be in port 80 and then that should forward to port 5000 for the Flask app internally.
What am I missing?
Could someone please point me in the right direction?
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "flask-test-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": 80}, {"HTTPS": 443}]'
labels:
app: hello-world
spec:
rules:
- host: testing.somesite.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: "hello-world-service"
port:
number: 80
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
selector:
matchLabels:
app: hello-world
replicas: 2
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: gitlab.privaterepo.com:5050/jmartinez/flask_helloworld:v4
ports:
- containerPort: 5000
protocol: TCP
imagePullSecrets:
- name: regcred
service.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-world-service
spec:
selector:
app: hello-world
type: NodePort
ports:
- protocol: "TCP"
port: 80
targetPort: 5000
nodePort: 30000

Finally got it working. When I realized that the ALB was not created automatically I researched and found the solution. I had to remove the ingress.class value from the annotations as well as remove the host. So now my ingress looks like the following. After deleting the old ingress and reapplying this one, I waited about 10 minutes and my hello world app is now running.
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "flask-test-ingress"
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
labels:
app: hello-world
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: "hello-world-service"
port:
number: 80

Related

Localhost kubernetes ingress not exposing services to local machine

I'm running kuberenetes in localhost, the pod is running and I can access the services when I port forwarding:
kubectl port-forward svc/my-service 8080:8080
I can get/post etc. the services in localhost.
I'm trying to use it with ingress to access it, here is the yml file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 8080
I've also installed the ingress controller. But it isn't working as expected. Anything wrong with this?
EDIT: the service that Im trying to connect with ingress:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
labels:
app: my-service
spec:
replicas: 1
selector:
matchLabels:
app: my-service
template:
metadata:
labels: my-service
app: my-service
spec:
containers:
- image: test/my-service:0.0.1-SNAPSHOT
name: my-service
ports:
- containerPort:8080
... other spring boot override properties
---
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app: my-service
spec:
type: ClusterIP
selector:
app: my-service
ports:
- name: 8080-8080
port: 8080
protocol: TCP
targetPort: 8080
service is working by itself though
EDIT:
It worked when I used https instead of http
Is ingress resource in the same namespace as the service? Can you share the manifest of service? Also, what do logs of nginx ingress-controller show and what sort of error do you face when hitting the endpoint in the browser?
Ingress's YAML file looks OK to me BTW.
I was being stupid. It worked when I used https instead of http

Kubernetes Ingress with AWS ALB Controller

I am using an EKS cluster and deployed AWS Load Balancer Controller for ingress. Using a dummy application (taken Nginx image) deployed one service. Just for the test, I am trying to access the same service from 3 different ingress paths: / and /foo/ and /bar/
AWS is successfully provisioning an ALB while ingress kubernetes object is getting deployed.
I am able to access the dummy application (Nginx homepage) by hitting external ALB on path '/'.
http://alb-dns/ # it's opening the Nginx homepage
But http://alb-dns/foo/ and http://alb-dns/bar/ are throwing "404 Not Found" error.
I searched through the internet and probably the issue is with URL rewrite. But the problem is, AWS ALB Controller does not support URL rewrite.
I tried lot of options mentioned in the below links but none of them works:
https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/ingress/annotations/#actions
https://github.com/kubernetes-sigs/aws-load-balancer-controller/issues/835
Is there any alternative to URL redirect? How do I get Nginx Homepage using http://alb-dns/foo/ url?
Or it's better to dump AWS LB Controller and move to Nginx Controller?
Thanks in advance.
These are Kubernetes manifests I am using:
---
# Source: game-app/templates/game-app-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ns-fargate-app
labels:
app.kubernetes.io/name: sample-game-app
---
# Source: game-app/templates/game-app-service.yaml
apiVersion: v1
kind: Service
metadata:
namespace: ns-fargate-app
name: game-app-service
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: NodePort
selector:
app.kubernetes.io/name: sample-game-app
---
# Source: game-app/templates/game-app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ns-fargate-app
name: sample-game-app
spec:
selector:
matchLabels:
app.kubernetes.io/name: sample-game-app
replicas: 3
template:
metadata:
labels:
app.kubernetes.io/name: sample-game-app
spec:
containers:
- image: public.ecr.aws/nginx/nginx:1.21
imagePullPolicy: Always
name: sample-game-app
ports:
- containerPort: 80
# Source: game-app-ingress/templates/game-app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: ns-fargate-app
name: game-app-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
kubernetes.io/ingress.class: alb
spec:
rules:
- http:
paths:
- path: /foo/
pathType: Prefix
backend:
service:
name: game-app-service
port:
number: 80
- path: /bar/
pathType: Prefix
backend:
service:
name: game-app-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: game-app-service
port:
number: 80
AWS ALB (Active)
Three ALB Rules
http:/alb-dns**/** (Working fine)
http:/alb-dns**/foo** (Throwing 404 error)
See https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource.
Prefix / matches all paths.
Your paths /foo/ and /bar/ are redundant in game-app-ingress.yaml. Does your Nginx instance respond to /foo/ or /bar/? If not, that's why you're getting the 404.
See Add context path for an app on nginx for adding additional contexts to your Nginx instance for /foo/ and /bar/.
Since game-app-service has the root path, you can remove the paths for /foo/ and /bar/.

GKE Ingress with Multiple Backend Services returns 404

I'm trying to create a GKE Ingress that points to two different backend services based on path. I've seen a few posts explaining this is only possible with an nginx Ingress because gke ingress doesn't support rewrite-target. However, this Google documentation, GKE Ingresss - Multiple backend services, seems to imply otherwise. I've followed the steps in the docs but haven't had any success. Only the service that is available on the path prefix of / is returned. Any other path prefix, like /v2, returns a 404 Not found.
Details of my setup are below. Is there an obvious error here -- is the Google documentation incorrect and this is only possible using nginx ingress?
-- Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: app-static-ip
networking.gke.io/managed-certificates: app-managed-cert
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /v2
pathType: Prefix
backend:
service:
name: api-2-service
port:
number: 8080
-- Service 1
apiVersion: v1
kind: Service
metadata:
name: api-service
labels:
app: api
spec:
type: NodePort
selector:
app: api
ports:
- port: 80
targetPort: 5000
-- Service 2
apiVersion: v1
kind: Service
metadata:
name: api-2-service
labels:
app: api-2
spec:
type: NodePort
selector:
app: api-2
ports:
- port: 8080
targetPort: 5000
GCP Ingress supports multiple paths. This is also well described in Setting up HTTP(S) Load Balancing with Ingress. For my test I've used both Hello-world v1 and v2.
There are 3 possible issues.
Issue is with container ports opened. You can check it using netstat:
$ kk exec -ti first-55bb869fb8-76nvq -c container -- bin/sh
/ # netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::8080 :::* LISTEN 1/hello-app
Issue might be also caused by the Firewall configuration. Make sure you have proper settings. (In general, in the new cluster I didn't need to add anything but if you have more stuff and have specific Firewall configurations it might block).
Misconfiguration between port, containerPort and targetPort.
Below my example:
1st deployment with
apiVersion: apps/v1
kind: Deployment
metadata:
name: first
labels:
app: api
spec:
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: container
image: gcr.io/google-samples/hello-app:1.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: api-service
labels:
app: api
spec:
type: NodePort
selector:
app: api
ports:
- port: 5000
targetPort: 8080
2nd deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: second
labels:
app: api-2
spec:
selector:
matchLabels:
app: api-2
template:
metadata:
labels:
app: api-2
spec:
containers:
- name: container
image: gcr.io/google-samples/hello-app:2.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: api-2-service
labels:
app: api-2
spec:
type: NodePort
selector:
app: api-2
ports:
- port: 6000
targetPort: 8080
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 5000
- path: /v2
pathType: Prefix
backend:
service:
name: api-2-service
port:
number: 6000
Outputs:
$ curl 35.190.XX.249
Hello, world!
Version: 1.0.0
Hostname: first-55bb869fb8-76nvq
$ curl 35.190.XX.249/v2
Hello, world!
Version: 2.0.0
Hostname: second-d7d87c6d8-zv9jr
Please keep in mind that you can also use Nginx Ingress on GKE by adding specific annotation.
kubernetes.io/ingress.class: "nginx"
Main reason why people use nginx ingress on GKE is using rewrite annotation and possibility to use ClusterIP or NodePort as serviceType, where GCP ingress allows only NodePort serviceType.
Additional information you can find in GKE Ingress for HTTP(S) Load Balancing

Unable to access app running on pod inside cluster using nginx Ingress controller

I'm using this nginx ingress controller on Hetzner server. After installation of ingress controller, I'm able to access the worker node by its IP, but not able to access the app running on pod inside the cluster. am I missing something?
Are Ingress and Traefik are different, a bit confused in the terminologies.
service file -
apiVersion: v1
kind: Service
metadata:
name: service-name-xxx
spec:
selector:
app: app-name
ports:
- protocol: 'TCP'
port: 80
targetPort: 4200
type: LoadBalancer
deployment file -
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-name
labels:
app: app-name
spec:
replicas: 1
selector:
matchLabels:
app: app-name
template:
metadata:
labels:
app: app-name
spec:
imagePullSecrets:
- name: my-registry-key
containers:
- name: container-name
image: my-private-docker-img
imagePullPolicy: Always
ports:
- containerPort: 4200
ingress file -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-name
spec:
rules:
- host:
http:
paths:
- pathType: Prefix
path: "/app"
backend:
service:
name: service-name-xxx
port:
number: 4200
I think you have to add the kubernetes.io/ingress.class: "nginx" to your Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-name
spec:
name: hsts-ingress-backend1-minion
annotations:
kubernetes.io/ingress.class: "nginx"
You have set port to 80 and targetPort to 4200 in your service. Should mention port 80 in your ingress yaml.
backend:
service:
name: service-name-xxx
port: 80
targetPort: 4200

externally access the application using hostname/subdomain in ingress resource

Need to access the application from external using Ingress hostname/sub-domain for the application that is specified in the below code. eg. test-app.dev-cluster-poc.company.domain.
cat app-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: app-ingress
spec:
rules:
- host: test-app.dev-cluster-poc.company.domain
http:
paths:
- backend:
serviceName: appsvc1
servicePort: 80
path: /app1
- backend:
serviceName: appsvc2
servicePort: 80
path: /app2
While troubleshooting using steps in the url, I found that there is no ADDRESS in the "kubectl get ingress" output. expecting an ip address like below.
but, I am seeing like below, 3rd column is empty.
what are the necessary configuration required to externally access the application like registering the hostname(test-app.dev-cluster-poc.company.domain) or adding A-record or running any dns service in the kubernetes cluster.
what is causing the ADDRESS column empty in "kubectl get ingress" command.
[EDIT]
apiVersion: v1
kind: Service
metadata:
name: appsvc1
namespace: ingress
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: app1
Nginx controller service like below.
cat nginx-ingress-controller-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress
namespace: ingress
spec:
type: NodePort
ports:
- port: 80
nodePort: 30000
name: http
- port: 18080
nodePort: 32000
name: http-mgmt
selector:
app: nginx-ingress-lb
1.you can deploy an ingress deployment
2.expose your ingress deployment through port 80
kubectl expose deploy your-deployment-name --port 80
source
3.you can add ingressClassName in your deploy
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: ingress
spec:
ingressClassName: nginx
ingress configuration sample