microk8s Ingress can't access services (503) - kubernetes

I'm running microk8s v1.18.5 from snap on Ubuntu 20.04 with addons ingress, dns, dashboard, helm3, storage.
I'm trying to externally access running services such as grafana and dashboard. I've configured proxy services and ingresses as per docs:
kind: Service
apiVersion: v1
metadata:
name: grafana
namespace: ingress
spec:
type: ExternalName
externalName: monitoring-grafana.kube-system.svc.cluster.local
ports:
- port: 80
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: grafana-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
kubernetes.io/tls-acme: "true"
spec:
tls:
- hosts:
- "grafana.example.com"
secretName: grafana-tls
rules:
- host: grafana.example.com
http:
paths:
- backend:
serviceName: grafana
servicePort: 80
path: /
---
and
kind: Service
apiVersion: v1
metadata:
name: dashboard
namespace: ingress
spec:
type: ExternalName
externalName: kubernetes-dashboard.kube-system.svc.cluster.local
ports:
- port: 443
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: dashboard-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
kubernetes.io/tls-acme: "true"
spec:
tls:
- hosts:
- "dashboard.example.com"
secretName: dashboard-tls
rules:
- host: dashboard.example.com
http:
paths:
- backend:
serviceName: dashboard
servicePort: 443
path: /
---
Trying to access either dashboard or grafana I get:
503 Service Temporarily Unavailable
openresty/1.15.8.1
What can I do to find the root cause?
I'm also running cert-manager and external-dns from helm3, could their config be related to the issue?

First you have to change your dashboard and grafana service type to NodePort for ingress to work correctly.
Besides that Kubernetes dashboard for microk8s is accessible under <master_node_ip>:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ path so you have to mention it in either your URL or in your ingress manifest. When you curl dashboard.example.com
it gives you 503 Service Temporarily Unavailable error. However when you enter full path it will show the website:
curl http://dashboard.example.com:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy
<!--
Copyright 2017 The Kubernetes Authors.
[...]
This is an example of ingress that will rewrite /api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy to /dashboard/
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: grafana-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: nginx
# Add https backend protocol support for ingress-nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Accept-Encoding "";
sub_filter '<base href="/">' '<base href="/dashboard/">';
sub_filter_once on;
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: dashboard.example.com
http:
paths:
- path: /dashboard(/|$)(.*)
backend:
serviceName: kubernetes-dashboard
servicePort: 443

Related

aws ALB ingress controller not working when I add host in ingress manifest file

With host ingress manifest file is not working. Below is my manifest file with host
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-admin
namespace: default
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
external-dns.alpha.kubernetes.io/hostname: "rakesblog.co"
spec:
rules:
- host: rakesblog.co
http:
paths:
- path: /*
backend:
serviceName: bi-admin-service
servicePort: 8080
But when I remove and host then it works file. Below is the manifest file
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: default
name: ingress-admin
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- http:
paths:
- path: /app
backend:
serviceName: bi-admin-service
servicePort: 8080
Here is the screenshot of when I applied the ingress file with the host and then describe the ingress.
Here is my service file
apiVersion: v1
kind: Service
metadata:
name: bi-admin-service
# namespace: fargate
labels:
app: bi-admin
spec:
type: NodePort
selector:
app: bi-admin
ports:
- protocol:
port: 8080
targetPort: 8080
Kubernetes version 1.21
and I followed this doc to install ingress on my EKS cluster
Please help me out to run my ingress service by adding host in the ingress manifest file.

Class name shows <none> for Ingress Object in local Kubernetes

I'm trying to deploy a simple nginx ingress object in my local kubernetes (Docker-Desktop) but I noticed that the class name is showing as "none" when I do:
➜ localk8 k get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-resource none * localhost 80 15m
My ingress definition file is defined as:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello-app
port:
number: 8080
I'm also running on a M1 macbook if that makes any difference. Thanks all for the help!
I am not sure what version of kubernetes you're using, but that annotation was deprecated in 1.18.
Also, you need to define an IngressClass resource that describes the class and then reference it with the new field ingressClassName:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: example.com/ingress-controller
Then in your ingress resource add the new field under spec and reference the class name:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
// use new field
ingressClassName: nginx
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello-app
port:
number: 8080

Ingress to redirect to service from LB ip

I'm trying to create an Ingress rule to redirect requests from LoadBalancer to Service.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hostlessendpoint
spec:
rules:
- http:
paths:
- path: /hostless
backend:
serviceName: node-red
servicePort: 1880
The above yaml script is supposed to redirect all requests from https://LOAD_BALANCER_IP/hostless to node-red on port 1880
If I try to request the above URL, I got an error Cannot GET /hostless. Requesting the root gives 404 page not found.
I can access my services with the direct URL (eg. http://LOAD_BALANCER_IP:1880 will redirect to Node-red service).
Service yaml looks like that:
apiVersion: v1
kind: Service
metadata:
labels:
app: node-red
name: node-red
spec:
ports:
- name: "1880"
port: 1880
protocol: TCP
targetPort: 1880
selector:
app: node-red
sessionAffinity: None
type: LoadBalancer
How to use ingress to reach a service whereas a custom port ?
I've found a way to make it works !
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/redirect-entry-point: https
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/router.middlewares: "kube-system-traefik-stripprefix#kubernetescrd"
name: traefik-all
namespace: partner
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: nginx-demo
servicePort: 2222
- path: /node
backend:
serviceName: node-red
servicePort: 1880
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: traefik-stripprefix
namespace: kube-system
spec:
stripPrefixRegex:
regex:
- "/[^/]+"
I use a middleware to remove the prefix as K3S Traefik does not support the traefik.ingress.kubernetes.io/rewrite-target annotation.
With the above code, all trafic from LOAD_BALANCER_IP/* will be redirected to nginx-demo:2222 service. All trafic from LOAD_BALANCER_IP/node/* will be redicted to node-red:1880 service.
I hope this could help someone !
Try setting a rewrite-target annotation, which will effectively rewrite /hostless requests to /, i.e. http://LOAD_BALANCER_IP:1880/hostless externally to http://node-red:1880 internally.
For example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: hostlessendpoint
spec:
rules:
- http:
paths:
- path: /hostless(/|$)(.*)
backend:
serviceName: node-red
servicePort: 1880
See this link, assuming you are using Nginx ingress controller.

Kibana dashboard not loading - {"statusCode":404,"error":"Not Found","message":"not found"}

I am installing kibana with helm like so
values = [
<<-EOT
replicas: 3
healthCheckPath: /admin/kibana/app/kibana
kibanaConfig:
kibana.yml: |
server.basePath: "/admin/kibana"
server.rewriteBasePath: true
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: kong
kubernetes.io/tls-acme: "true"
path: /admin/kibana
I want kibana to be served at path /admin/kibana. eg. https://my-server.com/admin/kibana
I see the error {"statusCode":404,"error":"Not Found","message":"not found"}
In the logs
"res":{"statusCode":404,"responseTime":24,"contentLength":9},"message":"GET / 404 24ms - 9.0B"}
The pods are running fine which means health check is passing at /admin/kibana.
I have the server.basePath set as per documentation. What else is missing?
If I port-forward 5601 from my box,
kubectl port-forward svc/kibana 5601:5601
I can access kibana at localhost:5601/admin/kibana. But not on the domain.
The ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: kong
kubernetes.io/tls-acme: "true"
labels:
app: kibana
heritage: Tiller
release: kibana
name: kibana-kibana
spec:
rules:
- host: xxxx.xxxx.app
http:
paths:
- backend:
serviceName: kibana-kibana
servicePort: 5601
path: /admin/kibana
tls:
- hosts:
- xxxx.xxxx.app
secretName: wildcard-alchemy-tls
The kong ingress by default was stripping path. Hence the issue.

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