What is necessary to make an ingress deployed as a demonset listening on port 80 on a raspberrypi kubernetes cluster

8/28/2018

Hello kubernetes experts,

I've a kubernetes cluster running on 4 raspberry pis with docker 18.04ce and kubernetes 1.9.7.

I deployed a service and this service can be accessed from within the cluster via the cluster IP. I also deployed an ingress as described in https://docs.traefik.io/user-guide/kubernetes/ and in How to get Kubernetes Ingress Port 80 working on baremetal single node cluster as a DaemonSet based on an ingress-controller-service. The DaemonSet also has NET_BIND_SERVICE set which should achieve that the host is listening on the same port as the service.

Everything works like described but my ingress doesn't listen on the hosts port 80. Somehow the setting NET_BIND_SERVICE doesn't work as intended. Does anyone know how to fix that?

If I deploy the ingress-controller as a Deployment with NodePort instead of as a DaemonSet it works but that limits me to the ports kubernetes allows for assigns for NodePorts.

https://hackernoon.com/kubernetes-ingress-controllers-and-traefik-a32648a4ae95 tells that hostPort of an ingress DaemonSet doesn't work with a CNI networking plugin (I tested with flannel and weave) but the Kubernetes@RaspberryPI sites (like https://blog.hypriot.com/post/setup-kubernetes-raspberry-pi-cluster/) tell that it works so this issue should be solved.

Thanks in advance Heinz

-- hkoessler
kubernetes
kubernetes-ingress
raspberry-pi

1 Answer

8/28/2018

I found a configuration how the ingress based on traefik works on my Raspberry Pi cluster with docker 18.04CE, kubernetes 1.9.7 and 2018-06-27-raspbian-stretch-lite.img:

Use the DaemonSet definition from https://docs.traefik.io/user-guide/kubernetes/ and in particular the yaml file https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml

but you have to add hostNetwork: true to the spec of the DaemonSet and type: ClusterIP to the spec of the Service.

My working yaml is as follows:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  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
      hostNetwork: true
      containers:
      - image: traefik
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
          hostPort: 8080
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        args:
        - --api
        - --kubernetes
        - --logLevel=DEBUG
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  type: ClusterIP
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin

According to the kubernetes documentation ClusterIP is the default for the type of a service. But my sample only works if I explicitly add type: ClusterIP to the service that backs the ingress-controller.

I also checked whether it works if I only add either "hostNetwork: true" to the spec.template.spec of the DeamonSet or "type: ClusterIP" to the spec of the service but it only works if I add both.

-- hkoessler
Source: StackOverflow