Deploy Service to K3s

Tip

We recommend to use the Sandbox to play around with this example.

Tip

All the files from this section are in k3s-deploy-service.zip.

K3s is a lightweight certified Kubernetes distribution. In Installation of K3s, you learned one way to install K3s using Ansible. In this section, you will learn how to use Ansible to managed a K3s cluster.

Important

The configuration of the Kubernetes cluster will probably change less often than the services running on the Kubernetes cluster. Because of this, it is better to have one playbook for the installation and configuration of the Kubernetes cluster and another playbook for the services running on the Kubernetes cluster.

Preparation

Access to a Kubernetes cluster is done using kubectl instead of SSH. For authentication, a kubeconfig file is used. The kubeconfig file is created when installing the Kubernetes cluster and you will have to copied it to the proxy (where kubectl will run) used by Ansible. You can use as proxy:

  1. the Ansible control node.

  2. the Kubernetes control plane.

  3. another machine with kubectl and kubeconfig.

For this section, you will use Ansible control node and you will have to copy the kubeconfig.

docker compose cp k3s:/etc/rancher/k3s/k3s.yaml k3s-config
sed -i 's/127.0.0.1/kubernetes/g' k3s-config
docker compose cp k3s-config control-node:/home/ansible/.kube/config

Inventory

inventories/production.yml
k3s:
  hosts:
    localhost:
      ansible_connection: local
        

The above inventory only defines that is the same as the Ansible control node.

Playbook

playbook.yml
- name: Configure K3s
  hosts:
    - k3s
  tasks:
    - name: Get Cluster information
      kubernetes.core.k8s_cluster_info:
      register: api_status
    - name: Print Cluster information
      ansible.builtin.debug:
        msg: '{{ api_status.version }}'
    - name: Create a k8s namespace
      kubernetes.core.k8s:
        name: tutorial
        api_version: v1
        kind: Namespace
        state: present
    - name: Create a Deployment object
      kubernetes.core.k8s:
        state: present
        definition:
          # From https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            namespace: tutorial
            name: nginx-deployment
            labels:
              app: nginx
          spec:
            replicas: 1
            selector:
              matchLabels:
                app: nginx
            template:
              metadata:
                labels:
                  app: nginx
              spec:
                containers:
                  - name: nginx
                    image: nginx:1.14.2
                    ports:
                      - containerPort: 80

The above playbook has four tasks:

  1. collect information about the Kubernetes cluster.

  2. print some of the previously collected information about the Kubernetes cluster.

  3. create a new namespace called tutorial.

  4. create a new deployment that consist of one container running NGIX.

Running

cd k3s-deploy-service
ansible-playbook \
-i inventories/production.yml \
playbook.yaml

returns

PLAY [Configure K3s] ***********************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Get Cluster information] *************************************************
ok: [localhost]

TASK [Print Cluster information] ***********************************************
ok: [localhost] => {
    "msg": {
        "client": "31.0.0",
        "server": {
            "kubernetes": {
                "buildDate": "2025-07-21T18:57:33Z",
                "compiler": "gc",
                "gitCommit": "071b1ead43641c6803e0b9fce6473baeb12357cf",
                "gitTreeState": "clean",
                "gitVersion": "v1.30.14-rc1+k3s2",
                "goVersion": "go1.23.10",
                "major": "1",
                "minor": "30",
                "platform": "linux/amd64"
            }
        }
    }
}

TASK [Create a k8s namespace] **************************************************
changed: [localhost]

TASK [Create a Deployment object] **********************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0