Science and technology

Directing Kubernetes visitors with Traefik

In this text, we’ll deploy a few easy web sites and learn to ingress visitors from the surface world into our cluster utilizing Traefik. After that, we’ll learn to take away Kubernetes assets as nicely. Let’s get began!

Materials wanted

To observe together with the article, you solely want the k3s Raspberry Pi cluster we inbuilt a earlier article. Since your cluster shall be pulling photographs from the online, the cluster will want to have the ability to entry the web.

Some configuration recordsdata and pattern HTML recordsdata shall be proven on this article for rationalization functions. All pattern recordsdata will be downloaded here.

Deploying a easy web site

Previously, we did a direct deploy with kubectl. This shouldn’t be the everyday solution to deploy issues, nonetheless. Generally, YAML configuration recordsdata are used, and that’s what we’ll use on this article. We will begin on the high and create our configuration recordsdata in a top-down strategy.

Deployment configuration

First up is the deployment configuration. The configuration is proven under, and the reason follows. I sometimes use the samples from the Kubernetes documentation as a place to begin after which modify them to swimsuit my wants. For instance, the configuration under was modified after copying the pattern from the deployment docs.

Create a file, mysite.yaml, with the next contents:

apiVersion: apps/v1
form: Deployment
metadata:
  title: mysite-nginx
  labels:
    app: mysite-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysite-nginx
  template:
    metadata:
      labels:
        app: mysite-nginx
    spec:
      containers:
      - title: nginx
        picture: nginx
        ports:
        - containerPort: 80

Most of that is boilerplate. The necessary elements, we’ve got named our deployment mysite-nginx with an app label of mysite-nginx as nicely. We have specified that we wish one duplicate which implies there’ll solely be one pod created. We additionally specified one container, which we named nginx. We specified the picture to be nginx. This means, on deployment, k3s will obtain the nginx picture from DockerHub and create a pod from it. Finally, we specified a containerPort of 80, which simply implies that contained in the container the pod will hear on port 80.

I emphasised “inside the container” above as a result of it is a crucial distinction. As we’ve got the container configured, it’s only accessible contained in the container, and it’s additional restricted to an inside community. This is important to permit a number of containers to hear on the identical container ports. In different phrases, with this configuration, another pod might hear on its container port 80 as nicely and never battle with this one. To present formal entry to this pod, we want a service configuration.

Service configuration

In Kubernetes, a service is an abstraction. It supplies a way to entry a pod or set of pods. One connects to the service and the service routes to a single pod or load balances to a number of pods if a number of pod replicas are outlined.

The service will be laid out in the identical configuration file, and that’s what we’ll do right here. Separate configuration areas with ---. Add the next to mysite.yaml:

---
apiVersion: v1
form: Service
metadata:
  title: mysite-nginx-service
spec:
  selector:
    app: mysite-nginx
  ports:
    - protocol: TCP
      port: 80

In this configuration, we’ve got named our service mysite-nginx-service. We supplied a selector of app: mysite-nginx. This is how the service chooses the applying containers it routes to. Remember, we supplied an app label for our container as mysite-nginx. This is what the service will use to search out our container. Finally, we specified that the service protocol is TCP and the service listens on port 80.

Ingress configuration

The ingress configuration specifies methods to get visitors from outdoors our cluster to providers inside our cluster. Remember, k3s comes pre-configured with Traefik as an ingress controller. Therefore, we’ll write our ingress configuration particular to Traefik. Add the next to mysite.yaml ( and don’t neglect to separate with ---):

---
apiVersion: networking.k8s.io/v1beta1
form: Ingress
metadata:
  title: mysite-nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "traefik"
spec:
  guidelines:
  - http:
      paths:
      - path: /
        backend:
          serviceName: mysite-nginx-service
          servicePort: 80

In this configuration, we’ve got named the ingress document mysite-nginx-ingress. And we instructed Kubernetes that we anticipate traefik to be our ingress controller with the kubernetes.io/ingress.class annotation.

In the guidelines part, we’re mainly saying, when http visitors is available in, and the path matches / (or something under that), route it to the backend service specified by the serviceName mysite-nginx-service, and route it to servicePort 80. This connects incoming HTTP visitors to the service we outlined earlier.

Something to deploy

That is absolutely it so far as configuration goes. If we deployed now, we might get the default nginx web page, however that’s not what we wish. Let’s create one thing easy however customized to deploy. Create the file index.html with the next contents:

<html>
<head><title>K3S!</title>
  <type>
    html
      font-dimension: 62.5%;
   
    physique
      font-household: sans-serif;
      background-coloration: midnightblue;
      coloration: white;
      show: flex;
      flex-path: column;
      justify-content material: heart;
      peak: 100vh;
   
    div
      textual content-align: heart;
      font-dimension: 8rem;
      textual content-shadow: 3px 3px 4px dimgrey;
   
  </type>
</head>
<physique>
  <div>Hello from K3S!</div>
</physique>
</html>

We haven’t but lined storage mechanisms in Kubernetes, so we’re going to cheat a bit and simply retailer this file in a Kubernetes config map. This is not the beneficial solution to deploy a web site, however it would work for our functions. Run the next:

kubectl create configmap mysite-html --from-file index.html

This command creates a configmap useful resource named mysite-html from the native file index.html. This primarily shops a file (or set of recordsdata) inside a Kubernetes useful resource that we are able to name out in configuration. It is usually used to retailer configuration recordsdata (therefore the title), so we’re abusing it a bit right here. In a later article, we’ll focus on correct storage options in Kubernetes.

With the config map created, let’s mount it inside our nginx container. We do that in two steps. First, we have to specify a quantity, calling out the config map. Then we have to mount the quantity into the nginx container. Complete step one by including the next underneath the spec label, simply after containers in mysite.yaml:

      volumes:
      - title: html-quantity
        configMap:
          title: mysite-html

This tells Kubernetes that we wish to outline a quantity, with the title html-volume and that quantity ought to comprise the contents of the configMap named html-volume (which we created within the earlier step).

Next, within the nginx container specification, slightly below ports, add the next:

        volumeMounts:
        - title: html-quantity
          mountPath: /usr/share/nginx/html

This tells Kubernetes, for the nginx container, we wish to mount a quantity named html-volume on the path (within the container) /usr/share/nginx/html. Why /usr/share/nginx/html? That is the place the nginx picture serves HTML from. By mounting our quantity at that path, we’ve got changed the default contents with our quantity contents.

For reference, the deployment part of the configuration file ought to now appear like this:

apiVersion: apps/v1
form: Deployment
metadata:
  title: mysite-nginx
  labels:
    app: mysite-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysite-nginx
  template:
    metadata:
      labels:
        app: mysite-nginx
    spec:
      containers:
      - title: nginx
        picture: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - title: html-quantity
          mountPath: /usr/share/nginx/html
      volumes:
      - title: html-quantity
        configMap:
          title: mysite-html

Deploy it!

Now we’re able to deploy! We can try this with:

kubectl apply -f mysite.yaml

You ought to see one thing just like the next:

deployment.apps/mysite-nginx created
service/mysite-nginx-service created
ingress.networking.k8s.io/mysite-nginx-ingress created

This implies that Kubernetes created assets for every of the three configurations we specified. Check on the standing of the pods with:

kubectl get pods

If you see a standing of ContainerCreating, give it a while and run kubectl get pods once more. Typically, the primary time, it would take some time as a result of k3s has to obtain the nginx picture to create the pod. After some time, it’s best to get a standing of Running.

Try it!

Once the pod is working, it’s time to strive it. Open up a browser and sort kmaster into the handle bar.

Congratulations! You’ve deployed a web site in your k3s cluster!

Another one

So now we’ve got a complete k3s cluster working a single web site. But we are able to do extra! What if we’ve got one other web site we wish to serve on the identical cluster? Let’s see how to do this.

Again, we want one thing to deploy. It simply so occurs that my canine has a message she has wished the world to know for a while. So, I crafted some HTML only for her (accessible from the samples zip file). Again, we’ll use the config map trick to host our HTML. This time we’re going to poke a complete listing (the html listing) right into a config map, however the invocation is similar.

kubectl create configmap mydog-html --from-file html

Now we have to create a configuration file for this web site. It is sort of precisely the identical because the one for mysite.yaml, so begin by copying mysite.yaml to mydog.yaml. Now edit mydog.yaml to be:

apiVersion: apps/v1
form: Deployment
metadata:
  title: mydog-nginx
  labels:
    app: mydog-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mydog-nginx
  template:
    metadata:
      labels:
        app: mydog-nginx
    spec:
      containers:
      - title: nginx
        picture: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - title: html-quantity
          mountPath: /usr/share/nginx/html
      volumes:
      - title: html-quantity
        configMap:
          title: mydog-html
---
apiVersion: v1
form: Service
metadata:
  title: mydog-nginx-service
spec:
  selector:
    app: mydog-nginx
  ports:
    - protocol: TCP
      port: 80
---
apiVersion: networking.k8s.io/v1beta1
form: Ingress
metadata:
  title: mydog-nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "traefik"
    traefik.frontend.rule.kind: PathPrefixStrip
spec:
  guidelines:
  - http:
      paths:
      - path: /mydog
        backend:
          serviceName: mydog-nginx-service
          servicePort: 80

We can do a lot of the edits by merely doing a search and exchange of mysite to mydog. The two different edits are within the ingress part. We modified path to /mydog and we added an annotation, traefik.frontend.rule.kind: PathPrefixStrip.

The specification of the trail /mydog instructs Traefik to route any incoming request that requests a path beginning with /mydog to the mydog-nginx-service. Any different path will proceed to be routed to mysite-nginx-service.

The new annotation, PathPrefixStrip, tells Traefik to strip off the prefix /mydog earlier than sending the request to mydog-nginx-service. We did this as a result of the mydog-nginx software doesn’t anticipate a prefix. This means we might change the place the service was mounted just by altering the prefix within the ingress document.

Now we are able to deploy like we did earlier than:

kubectl apply -f mydog.yaml

And now, my canine’s message ought to be accessible at http://kmaster/mydog/.

Phew! The message is out! Maybe we are able to all get some sleep tonight.

So now, we’ve got a k3s cluster internet hosting two web sites with Traefik making selections, primarily based on path names, as to which service to cross the request to! We usually are not restricted to path-based routing, nonetheless. We might use hostname primarily based routing as nicely, which we’ll discover in a future article.

Also, the web sites we simply hosted are customary unencrypted HTML websites. Everything nowadays is encrypted with SSL/TLS. In our subsequent article, we’ll add assist to our k3s cluster to host SSL/TLS HTTPS websites as nicely!

Cleaning up

Before you go, since this text principally handled pattern websites, I want to present you methods to delete issues in case you don’t need the samples hanging round in your cluster.

For most configurations, you’ll be able to undo the configuration just by working the delete command with the identical configuration file you deployed with. So let’s clear up each mysite and mydog.

kubectl delete -f mysite.yaml
kubectl delete -f mydog.yaml

Since we manually created the config maps, we’ll must delete these manually as nicely.

kubectl delete configmap mysite-html
kubectl delete configmap mydog-html

Now if we do a kubectl get pods, we should always see that our nginx pods are now not round.

$ kubectl get pods
No assets present in default namespace.

Everything is cleaned up.

Tell me what ideas you’ve on this mission within the feedback under.

Most Popular

To Top