Skip to main content

Using Manifests and Flux with Kubernetes Clusters

Hands-On Lab


Photo of

Training Architect





This hands-on learning experience challenges the student to install and configure Flux with a repository of their own.

Note To The Student: The YAML in this lab refers to a docker image that does not exist on docker hub. This is intentional so the student may observe what happends when a YAML attempts to deploy a tagged image that does not exist. It is covered in the solution video.

Once configured, the student will:

  1. Create a namespace to deploy an application into
  2. Create a Deployment of a sample "Hello" application
  3. Update that Deployment to a new release of the same application

Some troubleshooting of YAML is required to achieve the goals of this lab.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

Using Manifests and Flux with Kubernetes Clusters


This hands-on lab challenges the student to install and configure Flux with a repository of their own. Once configured, the student will:

  1. Create a namespace to deploy an application into
  2. Create a Deployment of a sample "Hello" application
  3. Update that Deployment to a new release of the same application

Some troubleshooting of YAML is required to achieve the goals of this lab.

To complete this lab the student must have their own GitHub or GitLab account and be able to set up a repository with the required YAML files. The student should also be familiar with the installation and configuration of Flux, which is covered in a prior lab as part of the GitOps course.

Set up a GitHub or Other GitVCS Repository with the Required YAML

We're going to walk through a GitHub setup here. On the main GitHub page, once we're logged in, we'll see a list of repositories on the left. Above them there's a green New button. Click on that to create a new repository. Give it a name (call it manifests_with_flux, for example) and a description, leave it public, and click on the green Create repository button down below.

We'll land in our new repository, in the Code tab, where we can click on creating a new file. We want to create a folder called namespaces/, so type that in after the repository name (just above the Edit new file and Preview tabs). Once we type the forward slash, we'll get another text box where we can put our actual filename, myns.yml. This is the YAML we need in that file:

apiVersion: v1
kind: Namespace
    name: lamanifest
  name: lamanifest

Now we can scroll down, put a comment in, and press Commit new file.

Log into the Kubernetes Master Node

In a terminal, log into the master node using the public IP and login credentials provided in the hands-on lab overview page. Once we're in as cloud_user, let's have a look at our nodes:

$ kubectl get nodes

While we're here, let's run a quick check on Flux to make sure it's installed:

$ fluxctl version

We should get response of unversioned. This is fine, so we can go ahead and create a new namespace:

$ kubectl create namespace flux

Next we'll set the GHUSER environment variable:

$ export GHUSER=[Our GitHub Handle]

Then we can install Flux:

$ fluxctl install 
--namespace=flux | kubectl apply -f -

Note the --git-url line. If we used manifests_with_flux as a repository name, we're good. Otherwise, we'd have to switch that out with the actual repository name.

The RSA Key

Now we can get the Flux RSA key created with fluxctl:

$ fluxctl identity --k8s-fwd-ns flux

Copy that RSA key, then get back into the GitHub interface. Make sure we're in our new repository and click on the Settings tab. In there, click Deploy keys, then click the Add deploy key button. We can give it a Title of something like manifests, then paste the key we copied earlier down in the Key field. Check the Allow write access box, and then click Add key.

Sync the Cluster with the Repository and Check the Results

Now, back in the terminal, let's see if we can sync:

$ fluxctl sync --k8s-fwd-ns flux

We'll see some output showing us that there was a commit made to the repository, but let's look at our namespaces:

$ kubectl get namespaces

Our lamanifest namespace hasn't been created.

Create the Applcation Deployment YAML

Let's get back into GitHub, in the Code tab of our repository, and click the Create new file button. Just like with the other one, we're going to create a directory at the same time, so in the first text box, type workloads/ (note the forward slash) and in the next box type hello.yaml. These are the file's actual contents:

apiVersion: apps/v1
kind: Deployment
  name: hello
  namespace: lasample
    app: hello
      app: hello
        app: hello
      - name: hello
        image: linuxacademycontent/gitops:hellov1.0

Scroll down and click the green Commit new file button.

Sync Again

Set the environment variable to the Flux namepace:


This is so that when we run fluxctl commands, we don't have to type the namespace as well.

Let's sync again, and then see what happens as far as namespaces go:

$ fluxctl sync
$ kubectl get namespaces

Now we've got a namespace called lamanifest.

Check that the deployment exists:

$ kubectl get pods --all-namespaces

There Is a Problem

We've got a couple of flux pods, but where is our hello pod? There's a mistake somewhere. It's in hello.yaml. If we just pasted in the sample code, then there's a line like this:

  namespace: lasample

But if we've changed our namespace to lamanifest (when we created myns.yml), then that line instead needs to go like this:

  namespace: lamanifest

We can get back into the GitHub interface, into our hello.yaml file, make the edit, and click the green Commit new file button. Then we need to sync again, and check the pods:

$ fluxctl sync
$ kubectl get namespaces

We see our lamanifest namespace. But what about a hello pod? Let's see:

$ kubectl get pods --all-namespaces

Aha! Now we'll see it.

Check Workloads and Images

Let's look at the Flux workloads:

$ fluxctl list-workloads

We won't see anything. No namespace argument here means that it's showing the default, flux, and there are no workloads in the flux namespace. Let's try it again:

$ fluxctl -n lamanifest list-workloads

We can see that the hellov1.0 image is there, but updating.

Let's look at the container image deployed:

$ fluxctl -n lamanifest list-images

Flux is seeing the other images that we have out on Docker Hub, but there's a problem with the one we're trying to deploy. We're seeing an untagged in the output where our image should be listed.

Verify the Image Tag Names Provided in Docker Hub and Use the Automate and Release Commands to Deploy Specific Containers

Use the automate command to add automation to the deployment, and see if that changes anything:

$ fluxctl automate --workload=lamanifest:deployment/hello

Back in hello.yaml (in our GitHub repository), refresh the browser and we'll see something got added:

  annotations: 'true'

This is at the end of the metadata section. What happens now if we, back in the terminal, list our images again? Let's see:

$ fluxctl -n lamanifest list-images

Nothing has changed, so the problem is something else.

In another browser tab, go to Look at all of those images. Anything look out of place? There's no version 1.0.

Fixing the Version

We can either fix that in the GitHub site (in the editor that still has hello.yaml open) or with fluxctl. We're going to do the latter and use the release command to specify a different container:

$ fluxctl release --workload=lamanifest:deployment/hello --update-image=linuxacademycontent/gitops:hellov1.2

We'll see in the command output that it pushes to the repository and commits. Now if we go back and refresh that GitHub page, we'll see that hellov1.0 (down around line 22) has been changed to hellov1.2.

Let's try look at the pods again:

kubectl get pods -n lamanifest

We'll see the pod that was running is now terminating, and another is coming up.

Now let's have another look at workloads:

$ fluxctl -n lamanifest list-workloads

We can see that hellov1.2 is there, and ready.

Want to change versions again real quick? Let's try hello1.2.1, one of the other images that is sitting in Docker Hub:

$ fluxctl release --workload=lamanifest:deployment/hello --update-image=linuxacademycontent/gitops:hellov1.2.1

Look at workloads again (with fluxctl -n lamanifest list-workloads) and we'll see the new version (1.2.1) listed now.


In this hands-on lab, we created a namespace where we could deploy an application, created a deployment of a sample "Hello" application, and then updated that deployment to a new release of the same application. In the process, we had to fix a couple of problems we ran into along the way, but we made it through. Congratulations!