rancher 2.x thru ingress controller returns 404 - kubernetes

Rancher service:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rancher ClusterIP 10.10.17.245 <none> 80/TCP,443/TCP 1h
Ingress controller service:
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress nginx-ingress LoadBalancer 10.10.15.181 <ext-IP> 80:30324/TCP,443:31022/TCP 3h
Ingress role:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: rancher-ing
annotations:
kubernetes.io/ingress.class: "rancher"
spec:
rules:
- host: api.sample.com
http:
paths:
- path: /
backend:
serviceName: rancher
servicePort: 443
Ingress:
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
rancher api.sample.com 80 19s
When I am trying to reach rancher over the ingress controller ext-IP:
$ curl http://api.sample.com
As a response I have some not encoded string. If I do it thru web browser this string will be downloaded and I have got 404.
Similar role for some random service over http (without https) works fine so it's not a matter of wrong ingress controller configuration.

If you want to use kubernetes.io/ingress.class: "rancher" you have to deploy your ingress controller with the --ingress-class=rancher annotation.
Have a lot at
https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/multiple-ingress-controllers and https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/
Cheers

If I follow default ingress controller installation:
https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/installation.md
and apply rancher ingress role like:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
labels:
app: rancher
name: rancher
namespace: cattle-system
spec:
tls:
- hosts:
- api.sample.com
secretName: default-server-secret
rules:
- host: api.sample.com
http:
paths:
- path: /
backend:
serviceName: rancher
servicePort: 80
This solution enabled https to Rancher UI over the ingress controller without annotations.

Related

Application not accessible using ingress but works with LoadBalancer GKE

I am trying to configure a hello world application using ingress in GKE. I have been referring a GCP official documentation to deploy an application using Ingress.
Deploying an app using ingress
But this does not work i have tried to refer several documents but none of those work. I have installed the ingress controller in my kubernetes cluster.
kubectl get svc -n ingress-nginx returns below output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
AGE
ingress-nginx-controller LoadBalancer 10.125.177.232 35.232.139.102 80:31835/TCP,443:31583/TCP 7h24m
kubectl get pods-n ingress-nginx returns
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-jj72r 0/1 Completed 0 7h24m
ingress-nginx-admission-patch-pktz6 0/1 Completed 0 7h24m
ingress-nginx-controller-5cb8d9c6dd-vptkh 1/1 Running 0 7h24m
kubectl get ingress returns below output
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-resource <none> 35.232.139.102.nip.io 34.69.2.173 80 7h48m
kubectl get pods returns below output
NAME READY STATUS RESTARTS AGE
hello-app-6d7bb985fd-x5qpn 1/1 Running 0 43m
kubect get svc returns below output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-app ClusterIP 10.125.187.239 <none> 8080/TCP 43m
Ingress resource yml file used
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:
- host: 35.232.139.102.nip.io
http:
paths:
- pathType: Prefix
path: "/hello"
backend:
service:
name: hello-app
port:
number: 8080
Can someone tell me what i am doing wrong ? When i try to reach the application its not working.
So I have installed Ingress-controller and used ingress controller ip as the host in my ingress file.
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:
- host: "35.232.139.102.nip.io"
http:
paths:
- pathType: Prefix
path: "/hello"
backend:
service:
name: hello-app
port:
number: 8080
Issue here was I forgot to add the IP from which I was accessing the application. When you create a GKE cluster there will be a firewall with the cluster-name-all in this firewall you will need to add your IP address of the machine from which you are trying to access the application. Also ensure that the port number is also exposed in my case both were not provided hence it was failing.

Ingress cannot route the apis

My ingress cannot route to endpoint.
I provided everything. Nginx-controller works properly. I added the hostname bago.com as loadbalancerip. But it doesn't work.
Here is my ingres's yaml file
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
rules:
- host: bago.com
- http:
paths:
- path: /web1/
pathType: Exact
backend:
service:
name: web1-clusterip
port:
number: 8081
- path: /web2/
pathType: Exact
backend:
service:
name: web2-clusterip
port:
number: 8082
svc and ingress running
bahaddin#bahaddin-ThinkPad-E15-Gen-2:~/projects/personal/exposer/k8s-ingress$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.12.0.1 <none> 443/TCP 154m
web1-clusterip ClusterIP 10.12.6.102 <none> 8081/TCP 145m
web2-clusertip ClusterIP 10.12.9.22 <none> 8082/TCP 149m
bahaddin#bahaddin-ThinkPad-E15-Gen-2:~/projects/personal/exposer/k8s-ingress$ k get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
minimal-ingress <none> bago.com 34.102.241.199 80 121m
bahaddin#bahaddin-ThinkPad-E15-Gen-2:~/projects/personal/exposer/k8s-ingress$
Here is my API java code.
#RequestMapping("/web1")
#RestController
public class Controller {
#GetMapping("/hello")
public String foo() {
return "hello from web1 ms";
}
}
server.port=8081 on container level
my service
Web1-service.
apiVersion: v1
kind: Service
metadata:
name: web1-clusterip
spec:
ports:
- protocol: "TCP"
port: 8081
selector:
app: web1-dp
type: ClusterIP
But when I type in the browser
http://bago.com/web1/hello
http://bago.com/web1/hello
I got a 404 not found error
Screenshot
You have an issue in your ingress manifest. You have two items in the list, while you want to have one. Additionally, you are missing the ingress class.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
rules:
# these are indivudal list items
- host: bago.com
- http: ...
You have to change the manifest so that you have a single item. You should also add the ingress class.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
# this should be the ingress class, i.e. nginx
ingressClassName: my-ingress-class
rules:
# this list has only 1 items, which is an object.
# note the dash (-)
- host: bago.com
http: ...
I see that for the ingress, you have class as <none> if your nginx-controller is making use of a class then you have to define that as ingressClassName under the spec section while creating ingress (rules).
you can identify the classname by describing the ingress-controller.
kubectl describe deployments.apps <your-ingress-controller-deployment> -n=<namespace> and look for --ingress-class parameter by default the classname should be nginx.
This class name is useful if more than one ingress-controller are present on the cluster, by defining the class we can tell which ingress-controller is responsible for which specific ingress rules.

Kubernetes Exposing An Application - AWX Operator

Hope you are all well,
I am currently trying to rollout the awx-operator on to a Kubernetes Cluster and I am running into a few issues with going to the service from outside of the cluster.
Currently I have the following services set up:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
awx NodePort 10.102.30.6 <none> 8080:32155/TCP 110m
awx-operator NodePort 10.110.147.152 <none> 80:31867/TCP 125m
awx-operator-metrics ClusterIP 10.105.190.155 <none> 8383/TCP,8686/TCP 3h17m
awx-postgres ClusterIP None <none> 5432/TCP 3h16m
awx-service ClusterIP 10.102.86.14 <none> 80/TCP 121m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17h
I did set up a NodePort which is called awx-operator. I did attempt to create an ingress to the application. You can see that below:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: awx-ingress
spec:
rules:
- host: awx.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: awx
port:
number: 80
When I create the ingress, and then run kubectl describe ingress, I get the following output:
Name: awx-ingress
Namespace: default
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
awx.mycompany.com
/ awx:80 (10.244.1.8:8080)
Annotations: <none>
Events: <none>
Now I am not too sure whether the default-http-backend:80 error is a red-herring as I have seen this in a number of places and they don't seem too worried about it, but please correct me if I am wrong.
Please let me know whether there is anything else I can do to troubleshoot this, and I will get back to you as soon as I can.
You are right and the blank address is the issue here. In traditional cloud environments, where network load balancers are available on-demand, a single Kubernetes manifest suffices to provide a single point of contact to the NGINX Ingress controller to external clients and, indirectly, to any application running inside the cluster.
Bare-metal environments on the other hand lack this option, requiring from you a slightly different setup to offer the same kind of access to external consumers:
This means you have to do some additional gymnastics to make the ingress work. And you have basically two main options here (all well described here):
A pure software solution: MetalLB
Over the NodePort service.
What is happening here is that you basically creating a service type NodePort with selector that matches your ingress controller pod and then it's routes the traffic accordingly to your ingress object:
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
Full nginx deployment that conatains that service can be found here.
If you wish to skip the ingress you might be just using the nodePort service awx and reach it directly.
I am using Kubernetes 1.22 and the operator version 0.14.0.
I have a Kubernetes baremetal installation and I have to use ingress. The ingress provided with the operator is not compatible with the version of kubernetes I am using so I had to define it myself.
I am using Ansible but you could work out the values for the variables :)
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ awx_deployment_name }}-ingress-unmanaged
namespace: {{ awx_namespace }}
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
spec:
ingressClassName: nginx
rules:
- host: {{ awx_host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ awx_deployment_name }}-service
port:
number: 80
tls:
- hosts:
- {{ awx_host }}
secretName: {{ awx_tls_secret}}
you can simply expose the deployment to a service type LoadBalancer
the following command creates a service with a type loadBalancer
kubectl expose deployment awx-demo --port=80 --target-port=8052 --name=awx-lb --type=LoadBalancer

Kubernetes: load-balance across two different namespaces

I want to deploy different versions of the same application in production:
kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0 -n test-a
kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:2.0 -n test-b
kubectl expose deployment hello-server --port 80 --target-port 8080 -n test-a
kubectl expose deployment hello-server --port 80 --target-port 8080 -n test-b
I've tried to load-balance it like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/server-snippets: |
upstream test-servers-upstream {
server hello-server.test-a:80;
server hello-server.test-b:80;
}
spec:
rules:
- host: test-servers.example.com
http:
paths:
- path: /
backend:
serviceName: test-servers-upstream
servicePort: 80
but it returns an error:
/ test-servers-upstream:80 (<error: endpoints "test-servers-upstream" not found>)
Services:
$ kubectl get services -n test-b
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-server ClusterIP 10.128.199.113 <none> 80/TCP 75m
$ kubectl get services -n test-a
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-server ClusterIP 10.128.207.6 <none> 80/TCP 75m
How can I load-balance it?
Fresh ingress-nginx supports weight-based canary deployments out of box.
Looks like what you're asking for.
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary.
Great example here.
https://medium.com/#domi.stoehr/canary-deployments-on-kubernetes-without-service-mesh-425b7e4cc862
Basically, you create 2 identical ingresses, one for each namespace.
They are different only in annotations and in pointing to different services.
# ingress for a service A in namespace A
kind: Ingress
metadata:
name: demo-ingress
namespace: demo-prod
spec:
rules:
- host: canary.example.com
http:
paths:
- backend:
serviceName: demo-prod
servicePort: 80
path: /
# ingress for a service B in namespace B
# note canary annotations
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
name: demo-ingress
namespace: demo-canary
spec:
rules:
- host: canary.example.com
http:
paths:
- backend:
serviceName: demo-canary
servicePort: 80
path: /
Note, that ingress-nginx canary implementation actually requires your services to be in different namespaces.

Kubernetes: Route Kubernetes dashboard through Ingress with out host and without proxy

Cluster information:
Installation Method: kubeadm
Kubernetes: 1.19.2
Master & Nodes: Ubuntu 20.04.1 (Oracle Virutalbox)
Docker: 19.03.12
Calico: 3.16.1
Ingress : Bare-metal - 0.40.1
I want to access the Kubernetes dashboard from my laptop using ingress without proxy?
Can anyone help me with the steps... ( I tried multiple ways with the help of the internet... not sure where I am missing?)
Note: As per discussion forums I have added "hostNetwork: true" under the deployment section in ingress YAML to resolve "not working without host parameter" and commented "type: NodePort".
Updated info:
I have created ingress-controller as daemon instead of deployments/pod - this helps in accessing directly with worker IPs. (this is what I am expecting - but unable to access kubernetes dashboard as it is in different namespace)
Ingress yaml: this is running in default namespace
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kdash-in-ns
port:
number: 443
kdash-in-ns yaml - svc with External Name
kind: Service
apiVersion: v1
metadata:
name: kdash-in-ns
namespace: default
spec:
type: ExternalName
externalName: kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local
ports:
- name: https
port: 443
Below details about kdash-in-ns svc with ExternalName
dockeras#ubuntu3:~/simplek8s/kubernetes/yamls/ingress-demo$ kubectl describe svc kdash-in-ns
Name: kdash-in-ns
Namespace: default
Labels: <none>
Annotations: <none>
Selector: <none>
Type: ExternalName
IP:
External Name: kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local
Port: https 443/TCP
TargetPort: 443/TCP
Endpoints: <none>
Session Affinity: None
Events: <none>
kubectl describe for the updated ingress route: in this i have ngnix - which is working fine (i guess both ingress and nginx are in same namespace.. getting error for dashboard - as it in different namespace (kubernetes-dasbhoard))
dockeras#ubuntu3:~$ kubectl describe ing nginx-ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
Name: nginx-ingress
Namespace: default
Address: 192.168.1.31,192.168.1.32
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
*
/nginx nginx-deploy-main:80 )
/foo kubernetes-dashboard:443 (<error: endpoints "kubernetes-dashboard" not found>)
/dashboard kdash-in-ns:443 (<error: endpoints "kdash-in-ns" not found>)
Annotations: kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 4m40s nginx-ingress-controller Ingress default/nginx-ingress
When I tried the same URLs in browser below are the responses (One of my worker iP - 192.168.1.31)
192.168.1.31/nginx - responds with nginx default page (pod - nginx-deploy-main)
192.168.1.31/foo - error page - 503 service temporarily Unavailable (default nginx)
192.168.1.31/dashboard - 504 Gateway Time-out (default nginx)
running svc, pods:
All Pods and svcs
If I understand correctly, you want to access kubernetes service (dashboard) from outside cluster. You may deploy metallb LoadBalancer and manage a pull of IPs from external cluster network, assigned to your cluster.
So, you can assign an IP and a LoadBalancer through which you will access your service. Below is an example for mssql server, but you can easily adapt it to your needs with dashboard:
apiVersion: v1
kind: Service
metadata:
name: sql-server-lb
namespace: database-server
annotations:
metallb.universe.tf/address-pool: default
spec:
selector:
app: sql-server
ports:
- port: 1433
targetPort: 1433
type: LoadBalancer
https://metallb.universe.tf/