How to configure a k8s reverse proxy service with MetalLB

3/11/2021

I'd need to reach jupyter-lab from port 80 and have the k8s configuration redirect to 8888. This is a problem I have set myself to learn about k8s networking, and also get a jupyter-lab running.

Here is the MetalLB config map. Local DNS resolves "jupyter-lab.k8s.home" to these ip addresses

---
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 10.10.10.24-10.10.10.26

Here is my LoadBalancer pointing to the ingress controller, is this not exposing port 80 and redirecting to the target 8888 ?

---
apiVersion: v1
kind: Service
metadata:
  name: jupyter-lab-lb
  namespace: default
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8888
  selector:
    app: jupyter-lab-ingress

This is my ingress controller, is it correctly configured the with ingress object pointing to the CIP ?

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: jupyter-lab-ingress
  annotations:
    # nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io: /
spec:
  rules:
  - host: jupyter-lab.k8s.home
    http:                      
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: jupyter-lab-cip
            port:
              number: 8888

This is the CIP that targets my deployment of jupyer-lab

---
apiVersion: v1
kind: Service
metadata:
  name: jupyter-lab-cip
  namespace: default
spec:
  type: ClusterIP
  ports:
    - port: 8888
      targetPort: 8888
  selector:
    app: jupyter-lab

This is my deployment that is running jupyter-lab on port 8888

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jupyter-lab-dpt
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jupyter-lab
  template:
    metadata:
      labels:
        app: jupyter-lab
    spec:
      volumes:
        - name: jupyter-lab-home
          persistentVolumeClaim:
            claimName: jupyter-lab-pvc
      containers:
        - name: jupyter-lab
          image: docker.io/jupyter/tensorflow-notebook
          ports:
            - containerPort: 8888
          volumeMounts:
            - name: jupyter-lab-home
              mountPath: /var/jupyter-lab_home
          env:
            - name: "JUPYTER_ENABLE_LAB"
              value: "yes"

I do see jupyter-lab.k8s.home:8888, but I can't log in with the token I get from kubectl logs -n default jupyter-lab-dpt-dfbd554b7-bf7fk

How do I set the configuration up so that I can browse to http://jupyter-lab.k8s.home?noportnumber

-- Kickaha
jupyter-notebook
kubernetes
metallb

1 Answer

3/12/2021

After you installed nginx ingress conrtoller (this is the link from your previous question) there should be a service created:

# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-3.23.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.44.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

You can make sure it exists by running:

kubectl  get svc -n ingress-nginx ingress-nginx-controller
NAME                       TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller   NodePort   10.105.157.46   <none>        80:30835/TCP,443:31421/TCP   17s

Notice its type is NodePort and you want LoadBalancer. Run kubectl edit svc -n ingress-nginx ingress-nginx-controller and change NodePort to LoadBalancer.

Now you should se this:

kubectl get svc -n ingress-nginx ingress-nginx-controller 
NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller   LoadBalancer   10.105.157.46   <pending>     80:30835/TCP,443:31421/TCP   83s

If your metalLB is configured correctly there should be an IP in place of a \<pending>. Now point your domain to this IP.

You mentioned that: Local DNS resolves "jupyter-lab.k8s.home" to these ip addresses. Don't resolve to all addresses. Use the one that is assigned to the LB. Only this one.

Your ingress looks fine but you don't need this annotations.

jupyter-lab-cip service also looks good.

I don't like the jupyter-lab-lb service. You don't need it. What you need is a load balancer but pointing to ingress controller as described earlier.

Also i am not sure what is this:

  selector:
    app: jupyter-lab-ingress

Your deploymet doesn't have app: jupyter-lab-ingress label. Nginx ingress controller also doesn't have it (unless you added it, and didn't mention). So I am not sure what was the idea behind it and what you've tried to achieve. Anyway, you probably don't need it.


I do see jupyter-lab.k8s.home:8888, but I can't log in with the token I get from kubectl logs -n default jupyter-lab-dpt-dfbd554b7-bf7fk

I am not sure why this works because the configuration you provided shouln't allow it (Unless I am missing sth).

-- Matt
Source: StackOverflow