c2sr bootcamp docs Help

Task 7: Deploying an Application with GitHub Actions

This task demonstrates the practical application of the Role-Based Access Control (RBAC) you configured in Task 6. You will set up a complete Continuous Integration/Continuous Deployment (CI/CD) pipeline using GitHub Actions. This pipeline will automatically build a container image from a sample Flask application, push it to a registry, and deploy it to your K3s cluster.

The key learning objective is to understand how an external system (GitHub Actions) uses the Service Account token to securely authenticate with your cluster's API server to perform deployment tasks.

Before you start

Before you start, ensure you have the following:

  • Your GitHub Repository: A copy of the c2sr-bootcamp-demo-flask repository.

  • The Service Account Token Secret: The full YAML content for the c2sr-sa-token secret that you saved to a text file in Task 6.

  • Your Control Plane's IP: The IP address that is reachable from the self-hosted runner, which GitHub Actions will connect to.

Step 1: Configure Your GitHub Repository Secrets

Your GitHub Actions workflow needs credentials to connect to your K3s cluster. You will provide these credentials as secrets in your repository settings.

  1. Navigate to your c2sr-bootcamp-demo-flask repository on GitHub.

  2. Go to Settings > Secrets and variables > Actions.

  3. Click the New repository secret button to create the following two secrets:

    Secret 1: The Cluster URL

    • Name: K8S_URL

    • Secret: Enter the URL of your control plane's API server. Replace <YOUR_CONTROL_PLANE_PUBLIC_IP> with the IP address.

      https://<CONTROL PLANE IP>:6443

    Secret 2: The Service Account Credentials

    • Name: K8S_SECRET

    • Secret: Open the c2sr-sa-token.txt file you saved in Task 6. Copy the ENTIRE YAML CONTENTS and paste them here. It must start with apiVersion: v1 and end with type: kubernetes.io/service-account-token.

Step 2: Personalize the Application via GitHub

To see your own unique change get deployed, you will modify the sample Flask application directly on the GitHub website.

  1. Navigate to the main page of your c2sr-bootcamp-demo-flask repository on GitHub.

  2. Click on the src directory, and then click on the main.py file to open it.

  3. In the upper-right corner of the file view, click the pencil icon to edit the file.

  4. Find the following line:

    username = "Spock"
  5. Replace "Spock" with your own name or a unique identifier. For example:

    username = "Captain Kirk"
  6. Scroll down to the bottom of the page to the Commit changes section.

  7. Enter a brief commit message (e.g., "Personalize flask application").

  8. Ensure the "Commit directly to the main branch" option is selected.

  9. Click the Commit changes button.

This action will commit the change directly to your main branch and automatically trigger the GitHub Actions workflow.

Step 3: Trigger the CI/CD Pipeline

Go to the Actions tab in your GitHub repository. You will see a new workflow run titled "Build and Deploy." Click on it to monitor its progress. Wait for both the build-and-push and deploy jobs to complete successfully (they should have green checkmarks).

Step 4: Verify the Deployment in Kubernetes

Once the workflow is complete, return to the terminal on your control-plane node (k3smain) to verify that the application has been deployed successfully.

4.1 Check the Deployment and Pods

First, we will switch to the k3s user, and then execute kubectl commands.

sudo su - k3s kubectl get deployment <REPO NAME> kubectl get pods

Expected Output: You should see that 1/1 pods are READY and AVAILABLE for the deployment, and two pods should be in the Running state.

4.2 Find the Service Port The application was exposed using a NodePort service. Find out which port it was assigned.

kubectl get service <service name>

Here, replace <service name> with the name of your repo followed by -service. For exmaple, if your repo name was c2sr-bootcamp-demo-flask-user1, your service name will be c2sr-bootcamp-demo-flask-user1-service.

Expected Output:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE c2sr-bootcamp-demo-flask NodePort 10.43.123.45 <none> 80:30500/TCP 5m

4.3 Access Your Personalized Application

Using any of your cluster node IPs (control plane or worker) and the NodePort from the previous step, use curl to see your personalized message.

curl http://<cluster ip>:<port number>

Expected Output: You should see the message with the name you added in Step 2!

Hello, Kubernetes! This is pod: c2sr-bootcamp-demo-flask-.... I am Captain Kirk's first Kubernetes deployment!

Step 5: (Optional) Further Inspection

Now is a great time to explore the running application using the commands from your Kubernetes cheat sheet. This will help you get more familiar with inspecting live resources.

Here are a few examples to get you started:

# View the real-time logs streaming from that pod kubectl logs --follow <pod name> # Press Ctrl+C to stop viewing logs. # Execute a command inside the running pod's container to get an interactive shell kubectl exec -it <pod name> -- /bin/sh # Once inside the pod, you can look around. Type 'exit' to leave. # For example, see the application file that's running: # cat main.py # exit

Delete the hello-world deployment to clear out the cluster.

  1. Get all the deployments in the cluster.

kubectl get deployments
  1. Find the name of your deployment (it will be the same name as the github repo assigned to you.), and delete it.

kubectl delete deployment <deployment name>

Accomplishments

  • End-to-End CI/CD Pipeline Implemented: A complete, automated CI/CD workflow was successfully created using GitHub Actions, bridging the gap between code repository and the Kubernetes cluster.

  • Secure Authentication Established: The Service Account token was successfully used as a GitHub Secret to securely authenticate the deployment pipeline with the K3s cluster's API server.

  • Automated Deployment Verified: A code change pushed to the GitHub repository automatically triggered the workflow, which successfully built a container image and deployed the application to the cluster without manual intervention.

  • Application Health Confirmed: The deployed "hello-world" application was verified to be running correctly within the cluster, with its pods in a Ready state and accessible via its NodePort service.

The system is now configured with an automated CI/CD pipeline using GitHub Actions. This pipeline enables the automatic deployment of code changes from the source repository directly to the live Kubernetes cluster, establishing a functional GitOps workflow.

The system is fully operational. The next logical step is to perform cleanup by removing the deployed "hello-world" application resources thereby returning the cluster to a clean state for future workloads.

Reflection

Please take a moment to write down any questions, issues, or doubts you encountered during this milestone.
This will help guide the subsequent discussion and ensure everyone is on the same page before moving forward.

Next Steps

  • exit from the ssh session on the control plane.

  • Return to the terminal on your computer.

  • Rejoin the common Discord lobby to await further instructions or support your peers.

Last modified: 23 June 2025