Search code examples
kubernetesjupyter-notebookmetallb

How to configure a k8s reverse proxy service with MetalLB


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


Solution

  • 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).