Help

Vars editor

Variables in articles are noted {{myVar}}

Legend

A link to a page of this blog
A link to a section of this page
A link to a template of this guide. Templates are files in which you should replace your variables
A variable
A link to an external tool documentation
This page looks best with JavaScript enabled

Make services reachable from the world

 ·  via commit 1c91ff1 (chore: change shortcodes format (HTML tag like)) by Gerkin  ·  ☕ 4 min read
What's on this Page

Now that you have a router installed, you have to pass requests on your server to it. This setup use a single entry point directly binding some ports on the host server.

1. Make a static and previsible configuration

As you may have noticed in the step  Kickstart the cluster, the metallb configuration use only dynamic adresses. But for the reverse proxy to work, we’ll need to be sure that our traefik router has a constant IP in your VPN. For this, modify your metallb configuration using the new  kubernetes/metallb-configmap.yaml template. This new configuration declares a new address pool named frontend with a single IP in it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - {{cluster.networkAddress}}.100-{{cluster.networkAddress}}.250
    - name: frontend
      protocol: layer2
      addresses:
      - {{cluster.networkAddress}}.99-{{cluster.networkAddress}}.99    
1
2
# Update the configuration
kubectl apply -f ./kubernetes/metallb-configmap.yaml

2. Set the router’s IP

Once the configmap has been changed, force our traefik service to use this new address “pool”. This is done using the annotation metallb.universe.tf/address-pool. Use the new  kubernetes/traefik/05-Services.yaml template, and check that its IP is correct.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File: ./kubernetes/traefik/05-Services.yaml
# https://doc.traefik.io/traefik/v2.4/user-guides/crd-acme/#services
# With custom address pool for metallb
apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace: traefik
  annotations:
    metallb.universe.tf/address-pool: frontend

spec:
  ports:
    - protocol: TCP
      name: web
      port: 8000
    - protocol: TCP
      name: admin
      port: 8080
    - protocol: TCP
      name: websecure
      port: 4443
  selector:
    app: traefik
    component: ingress-controller
  type: LoadBalancer
1
2
3
4
# Update the configuration
kubectl apply -f ./kubernetes/traefik/05-Services.yaml
# Check the IP. It should be the single one in the pool defined by `frontend` in the metallb configuration
kubectl --namespace traefik get svc 

3. Setup the bare metal proxy

We’ll use nginx as our bare reverse proxy. It will simply redirect every requests on the specified ports to traefik, that was  previously installed in kubernetes. In the case of an SSL connection, it won’t be unwrapped.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Install nginx
dnf install nginx
# Get our traefik entry point
clusterEntry="$(kubectl --namespace traefik get svc traefik -o json | jq --raw-output '.status.loadBalancer.ingress[].ip')"
# Omit IPv6 if local interface (VM, or anything not being a real interface)
if [[ $pubAddrv6 == fe80:* ]]; then pubAddrv6="::"; fi
# Create the nginx stream configuration for kubernetes
mkdir /etc/nginx/streams.d
cat <<EOF | tee /etc/nginx/streams.d/kubernetes-proxy.conf
stream {
    server {
        listen     443;
        listen     [::]:443;
        proxy_pass $clusterEntry:4443;
    }
    server {
        listen     80;
        listen     [::]:80;
        proxy_pass $clusterEntry:8000;
    }
}
EOF
# Include it in the nginx config
# Check that the base config does not already bind on port 80
echo '\ninclude /etc/nginx/streams.d/*.conf;\n' | tee -a /etc/nginx/nginx.conf
# Start & auto-start nginx
systemctl enable --now nginx.service

Now, you should be able to reach your traefik router by requesting directly your entry point server. Test this with the  kubernetes/xx-WhoAmI.yaml template.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
apiVersion: v1
kind: Namespace
metadata:
  name: whoami
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: whoami
  namespace: whoami
  labels:
    app: whoami
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: traefik/whoami
          ports:
            - name: web
              containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: whoami
spec:
  ports:
    - protocol: TCP
      name: web
      port: 80
  selector:
    app: whoami
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingress-tls
  namespace: whoami # Must be the same as the service
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`whoami.{{cluster.baseHostName}}`) && PathPrefix(`/tls`)
    kind: Rule
    services:
    # Beware: the service MUST be in the same namespace than the IngressRoute.
    - name: whoami
      kind: Service
      port: 80
  tls:
    certResolver: myresolver
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingress-notls
  namespace: whoami # Must be the same as the service
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`whoami.{{cluster.baseHostName}}`) && PathPrefix(`/notls`)
    kind: Rule
    services:
    # Beware: the service MUST be in the same namespace than the IngressRoute.
    - name: whoami
      kind: Service
      port: 80
1
2
# Deploy it
kubectl apply -f ./kubernetes/xx-WhoAmI.yaml

Make sure that whoami.{{cluster.baseHostName}} correctly resolves to your entry-point server (either via real DNS records or editing /etc/hosts), then try to access to:

If this works, you’re good to go !

1
kubectl delete -f ./kubernetes/xx-WhoAmI.yaml

Hey, we’ve done important things here ! Maybe it’s time to commit…

1
2
3
4
git add .
git commit -m "Make services reachable from the world

Following guide @ https://gerkindev.github.io/devblog/walkthroughs/kubernetes/04-reverse-proxy/"
Share on

GerkinDev
WRITTEN BY
GerkinDev
Fullstack developer, on its journey to DevOps.

 
What's on this Page