Links

Expose a Kubernetes workload in a track tab

This guide explains how to expose a Kubernetes **** workload in a track tab.

What is a Kubernetes workload?

A Kubernetes workload is an application running on Kubernetes—for example, a webserver.

Exposing

After installing a Kubernetes workload on a Kubernetes virtual machine in a track, you need to expose the workload in a tab so learners can interact with it. Exposing is done through a NodePort, which is an open port on every node of your Kubernetes cluster.
By setting the NodePort, for example, port 30001, for the Kubernetes workload and the track tab, you expose the Kubernetes workload in the track tab. Because the NodePort then sits like a gateway between the Kubernetes workload and the track tab.

Expose a Kubernetes workload

Now let's install a Kubernetes workload and expose it in a track tab. You will use the NGINX web server as the Kubernetes workload that will be exposed.

Step 1: Create a track with a Kubernetes virtual machine

🌐 Web UI
💻 Instruqt CLI
  1. 1.
    Open your browser and go to play.instruqt.com. ↳ Instruqt shows your content.
  2. 2.
    Click Create track. ↳ Instruqt shows the Start creating content page.
  3. 3.
    Click Create from scratch. ↳ Instruqt shows the Track details page.
  4. 4.
    In the Title field, enter the track title. ↳ As you enter the title, Instruqt automatically generates a slug in the Track slug field.
  5. 5.
    Leave the Track slug field as created by Instruqt or enter the slug of your liking.
If you have changed the automatically created track slug and then update the title again, Instruqt regenerates the track slug.
  1. 1.
    In the Editor tab of the Description field, enter the track description in Markdown.
  2. 2.
    Click Next. ↳ Instruqt shows the Sandbox page.
  3. 3.
    Click Add a virtual machine:
    1. 1.
      In the Hostname field, enter a name for the host—for example, kubernetes-vm.
    2. 2.
      Click Kubernetes under the Predefined image tab.
    3. 3.
      Click Add virtual machine.
    4. 4.
      Click Next. ↳ Instruqt shows the Challenge page.
  4. 4.
    In the Title field, enter the challenge title—for example, NGINX.
  5. 5.
    Click Next. ↳ Instruqt shows the Challenge - Introduction page.
  6. 6.
    In the Editor tab of the Description field, enter the challenge description in Markdown.
  7. 7.
    Click Next and Next again.
  8. 8.
    In the Editor tab of the Assignment field, enter the assignment text in Markdown.
  9. 9.
    In the Tab title field, enter the name of the tab—for example, NGINX.
  10. 10.
    In the Tab type list, select Service.
  11. 11.
    In the Sandbox host list, select the kubernetes-vm sandbox.
  12. 12.
    In the The port to connect to on the sandbox host field, enter 30001. ↳ This connects the tab to port 30001 .
  13. 13.
    Click Next. ↳ Instruqt shows the Launch your track page.
  14. 14.
    Click Finish. ↳ Instruqt builds the track and shows the Track overview page.
  1. 1.
    Type the following command to create a track:
    instruqt track create
  2. 2.
    Enter your TRACK_TITLE:
    ==> Track title: TRACK_TITLE
  3. 3.
    Enter option 1 to select From scratch:
    ==> Start with an empty track or use a template:
    [1] From scratch
    For full flexibility, start with an empty track
    [2] From a template
    To get started quickly, start from one of our templates
    Please select your method: 1
    ↳ Instruqt CLI creates the track and shows this output:
    ==> Creating track TEAM/TRACK_TITLE
    ==> Creating track files
    Created track directory and configuration files:
    TRACK_TITLE
    ├── config.yml
    └── track.yml
    OK
    TEAM and TRACK_TITLE will contain your team and track title.
  4. 4.
    Move into the newly created TRACK_DIRECTORY:
    cd TRACK_DIRECTORY
  5. 5.
    Enter the following command to add a challenge to your new track:
    instruqt challenge create --title "CHALLENGE_TITLE"
    ⇨ Replace CHALLENGE_TITLE with your title.
  6. 6.
    Open the config.yml file in your code editor and replace its content with the following YAML to add a Kubernetes virtual machine to your track:
    version: "3"
    virtualmachines:
    - name: kubernetes-vm
    image: instruqt/k3s-v1-21-1
    machine_type: n1-standard-1
  7. 7.
    Move back to Instruqt CLI and create a new directory for the track lifecycle scripts:
    md track_scripts
  8. 8.
    Move back to your code editor to create a track setup script that waits for Instruqt and Kubernetes to init. To do so, open a new file, and paste the following script into the file:
    #!/bin/bash
    # Wait for the Instruqt host bootstrap to finish
    until [ -f /opt/instruqt/bootstrap/host-bootstrap-completed ]
    do
    sleep 1
    done
    # Wait for the Kubernetes API server to become available
    while ! curl --silent --fail --output /dev/null http://localhost:8001/api
    do
    sleep 1
    done
    # Enable bash completion for kubectl
    echo "source /usr/share/bash-completion/bash_completion" >> /root/.bashrc
    echo "complete -F __start_kubectl k" >> /root/.bashrc
  9. 9.
    Save the track setup file as setup-kubernetes-vm in the track_scripts directory. ↳ The kubernetes-vm part in the filename refers to the earlier created Kubernetes virtual machine.

Step 2: Install the NGINX web server as a Kubernetes workload and expose it in a track tab

🌐 Web UI
💻 Instruqt CLI
  1. 1.
    Click Edit track details followed by Sandbox. ↳ Instruqt shows the Sandbox page.
  2. 2.
    Click Lifecycle scripts followed by setup. ↳ Instruqt shows an editor window for the track setup script.
  3. 3.
    Paste the following script, which waits for Instruqt and Kubernetes to init, into the setup script:
    #!/bin/bash
    # Wait for the Instruqt host bootstrap to finish
    until [ -f /opt/instruqt/bootstrap/host-bootstrap-completed ]
    do
    sleep 1
    done
    # Wait for the Kubernetes API server to become available
    while ! curl --silent --fail --output /dev/null http://localhost:8001/api
    do
    sleep 1
    done
    # Enable bash completion for kubectl
    echo "source /usr/share/bash-completion/bash_completion" >> /root/.bashrc
    echo "complete -F __start_kubectl k" >> /root/.bashrc
  4. 4.
    Click Save followed by Close and Back.
  5. 5.
    Click Edit on the NGINX challenge, followed by Scripts and setup. ↳ Instruqt shows an editor window for the challenge setup script.
  6. 6.
    Paste the following script into the setup script:\
    #!/bin/bash
    cat <<EOF > service.yml
    apiVersion: v1
    kind: Service
    metadata:
    labels:
    app: nginx
    managedFields:
    name: nginx
    namespace: default
    spec:
    ports:
    - nodePort: 30001
    port: 80
    protocol: TCP
    selector:
    app: nginx
    type: NodePort
    EOF
    kubectl create deployment nginx --image nginx
    kubectl apply -f service.yml
    ↳ Line 2 till 19 create the service.yml file that contains the specification for setting the NodePort for the NGINX workload. ↳ Line 21 installs the NGINX web server as a Kubernetes workload. ↳ Line 23 connects the NGINX workload to port 30001. ↳ After the setup script has run, the tab and the NGINX workload are both connected to NodePort 30001, exposing the NGINX workload in the tab.
  7. 7.
    Click Save, followed by Close and Back.
  8. 8.
    Click Build track.
  9. 9.
    Click Start track. ↳ Instruqt creates the environment.
  10. 10.
    Click Start when the environment is created. ↳ Instruqt shows the Welcome to nginx! window as the NGINX workload is exposed now in the tab.
It is possible that Instruqt first shows a _Please wait window_ because the NGINX setup is still running. If so, the _Welcome to nginx! window_ appears when the setup is ready.
  1. 1.
    Open a new file for creating the challenge setup script and paste the following script into the file:
    #!/bin/bash
    cat <<EOF > service.yml
    apiVersion: v1
    kind: Service
    metadata:
    labels:
    app: nginx
    managedFields:
    name: nginx
    namespace: default
    spec:
    ports:
    - nodePort: 30001
    port: 80
    protocol: TCP
    selector:
    app: nginx
    type: NodePort
    EOF
    kubectl create deployment nginx --image nginx
    kubectl apply -f service.yml
    ↳ Line 2 till 19 create the service.yml file that contains the specification for setting the NodePort for the NGINX workload. ↳ Line 21 installs the NGINX web server as a Kubernetes workload. ↳ Line 23 connects the NGINX workload to port 30001. ↳ After the setup script has run, the track tab and the NGINX workload are both connected to NodePort 30001, exposing the NGINX workload in the tab.
  2. 2.
    Save the challenge setup file as setup-kubernetes-vm in the challenge directory.
  3. 3.
    Remove the lifecycle script files in the challenge directory that end with -shell. The instruqt challenge create command created these automatically, but you do not need them.
  4. 4.
    Open the file assignment.md in your code editor and replace its content with the following:
    ---
    slug: nginx
    id: yl0xwpeeptfw
    type: challenge
    title: NGINX
    notes:
    - type: text
    contents: Expose a Kubernetes workload in a track tab
    tabs:
    - title: NGINX
    type: service
    hostname: kubernetes-vm
    path: /
    port: 30001
    difficulty: basic
    timelimit: 600
    ---
    NGINX
    ↳ Line 14 connects the track tab to port 30001.
  5. 5.
    Move back to Instruqt CLI and push your track to the Instruqt platform:
    instruqt track push
  6. 6.
    Finally, move over to the Instruqt platform, open your track and click Start track to play the track. ↳ Instruqt creates the environment.
  7. 7.
    Click Start when the environment is created. ↳ Instruqt shows the Welcome to nginx! window as the NGINX workload is exposed now in the tab.
It is possible that Instruqt first shows a _Please wait window_ because the NGINX setup is still running. If so, the _Welcome to nginx! window_ appears when the setup is ready.
That's it! Instruqt and Kubernetes go together like peas and carrots. And did you know you can even use specific Kubernetes templates for creating tracks? Check out the Kubernetes and Multi-node Kubernetes cluster templates.