Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Kubernetes Ingress Port 80 working on baremetal single node cluster

I have a bare-metal kubernetes (v1.11.0) cluster created with kubeadm and working fine without any issues. Network with calico and made it a single node cluster using kubectl taint nodes command. (single node is a requirement).

I need to run mydockerhub/sampleweb static website image on host port 80. Assume the IP address of the ubuntu server running this kubernetes is 192.168.8.10.

How to make my static website available on 192.168.8.10:80 or a hostname mapped to it on local DNS server? (Example: frontend.sampleweb.local:80). Later I need to run other services on different port mapped to another subdomain. (Example: backend.sampleweb.local:80 which routes to a service run on port 8080).

I need to know:

  1. Can I achieve this without a load balancer?

  2. What resources needed to create? (ingress, deployment, etc)

  3. What additional configurations needed on the cluster? (network policy, etc)

    Much appreciated if sample yaml files are provided.

I'm new to kubernetes world. I got sample kubernetes deployments (like sock-shop) working end-to-end without any issues. I tried NodePort to access the service but instead of running it on a different port I need to run it exact port 80 on the host. I tried many ingress solutions but didn't work.

Screenshot of my setup:
enter image description here

like image 811
sith Avatar asked Jul 16 '18 08:07

sith


People also ask

Which ingress is used to route traffic from single IP to multiple services?

Kubernetes ingress resources are used to configure the ingress rules and routes for individual Kubernetes services. When you use an ingress controller and ingress rules, a single IP address can be used to route traffic to multiple services in a Kubernetes cluster.

What object fulfills the ingress in Kubernetes?

An Ingress controller is responsible for fulfilling the Ingress, usually with a load balancer, though it may also configure your edge router or additional frontends to help handle the traffic.

How many ingress controllers are currently supported in Kubernetes?

The three most popular Ingress Controllers deployed on Kubernetes are: Nginx. Traefik. HAProxy.


1 Answers

I recently used traefik.io to configure a project with similar requirements to yours.

So I'll show a basic solution with traefik and ingresses.

I dedicated a whole namespace (you can use kube-system), called traefik, and created a kubernetes serviceAccount:

apiVersion: v1
kind: Namespace
metadata:
  name: traefik
---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: traefik
  name: traefik-ingress-controller

The traefik controller which is invoked by ingress rules requires a ClusterRole and its binding:

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
  namespace: traefik
  name: traefik-ingress-controller

The traefin controller will be deployed as daemonset (i.e. by definition one for each node in your cluster) and a Kubernetes service is dedicated to the controller:

kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: traefik
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      containers:
      - name: traefik-ingress-lb
        image: traefik
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        args:
        - --api
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  namespace: traefik
  name: traefik-ingress-service
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin

The final part requires you to create a service for each microservice in you project, here an example:

apiVersion: v1
kind: Service
metadata:
  namespace: traefik
  name: my-svc-1
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - port: 80 
    targetPort: 8080

and also the ingress (set of rules) that will forward the request to the proper service:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: traefik
  name: ingress-ms-1
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: my-address-url
    http:
      paths:
      - backend:
          serviceName: my-svc-1
          servicePort: 80

In this ingress I wrote a host URL, this will be the entry point in your cluster, so you need to resolve the name to your master K8S node. If you have more nodes which could be master, then a loadbalancer is suggested (in this case the host URL will be the LB).

Take a look to kubernetes.io documentation to have clear the concepts for kubernetes. Also traefik.io is useful.

I hope this helps you.

like image 172
Nicola Ben Avatar answered Oct 16 '22 23:10

Nicola Ben