Run and expose Kubernetes Pod based Application using Quadlet and Inlets

Ygal Blum & Valentin Rothberg

This tutorial is inspired by a previous post from Alex Ellis’s on running inlets with compose. But instead of Compose, we want to show how to deploy inlets via Quadlet and make use of Podman’s Kubernetes capabilities. Hence, we are going to run a .kube file via Quadlet and Podman.

Quadlet is a new way of running containerized workloads in systemd with Podman. Running Podman in systemd achieves a high degree of robustness and automation since systemd can take care of the lifecycle management and monitoring of the workloads. More advanced features such as Podman auto updates and custom health-check actions make Quadlet a handy tool for modern Edge Computing.

Deploy the Inlets Server

When using inlets, users can provision the VMs acting as tunnel servers on various cloud providers. The post, inspiring this one, showed how to deploy it on Linode while a newer post describes how it can be deployed on AWS.

Follow either posts, or deploy the tunnel server on any other provider. The inlets documentation provides details and examples for various providers.

Whichever provider you choose, inletsctl will print two parameters you will need when deploying the local client:

  1. IP - The external IP address of the Inlets tunnel server
  2. Auth-token - Token the client must use when connecting to the server

Running GHost along with Inlets client

You can run Ghost on your local computer, a Raspberry Pi, or an additional EC2 instance.

Secrets

The Inlets client depends on two secrets inlets-license and inlets-token. However, because these secrets are consumed by a Kubernetes Pod, they also must take the form of a Kubernetes Secret

Inlets Token Secret

  1. Use the following jinja template inlets-token-secret.yml.j2:
     apiVersion: v1
     kind: Secret
     metadata:
         name: inlets-token
     stringData:
         inlets-token: "{{ inlets_token }}"
    
  2. Create the token_data.json file
     {
         "inlets_token": "< TOKEN >"
     }
    
  3. Generate the secret
     j2 inlets-token-secret.yml.j2 token_data.json | podman kube play -
    

Inlets License Secret

  1. Use the following jinja template inlets-license-secret.yml.j2:
     apiVersion: v1
     kind: Secret
     metadata:
         name: inlets-license
     stringData:
         inlets-license: "{{ inlets_license }}"
    
  2. Create the license_data.json file
     {
         "inlets_license": "< LICENSE >"
     }
    
  3. Generate the secret
     j2 inlets-license-secret.yml.j2 license_data.json | podman kube play -
    

Kubernetes YAML and Quadlet

Kubernetes Pod YAML

  1. Use the following jinja template inlets-ghost.yml.j2:

     ---
     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       name: ghost-pv-claim
       labels:
         app: ghost
     spec:
       accessModes:
       - ReadWriteOnce
       resources:
         requests:
           storage: 20Gi
     ---
     apiVersion: v1
     kind: Pod
     metadata:
       name: inlets-ghost-demo
     spec:
       containers:
       - name: ghost
         image: docker.io/library/ghost:5.59.0-alpine
         env:
         - name: url
           value: https://{{ inlets_server_domain }}
         - name: NODE_ENV
           value: development
         volumeMounts:
         - name: ghost-persistent-storage
           mountPath: /var/lib/ghost/content
         resources:
           requests:
             memory: "64Mi"
             cpu: "250m"
           limits:
             memory: "128Mi"
             cpu: "500m"
       - name: inlets
         image: ghcr.io/inlets/inlets-pro:{{ inlets_version | default('0.9.21') }}
         args:
         - "http"
         - "client"
         - "--url=wss://{{ inlets_server_ip }}:8123"
         - "--token-file=/var/secrets/inlets-token/inlets-token"
         - "--license-file=/var/secrets/inlets-license/inlets-license"
         - "--upstream=http://127.0.0.1:2368"
         volumeMounts:
         - mountPath: /var/secrets/inlets-token
           name: inlets-token
         - mountPath: /var/secrets/inlets-license
           name: inlets-license
         resources:
           requests:
             memory: "64Mi"
             cpu: "250m"
           limits:
             memory: "128Mi"
             cpu: "500m"
       volumes:
       - name: ghost-persistent-storage
         persistentVolumeClaim:
           claimName: ghost-pv-claim
       - name: inlets-license
         secret:
           secretName: inlets-license
       - name: inlets-token
         secret:
           secretName: inlets-token
    
  2. Create the kube_data.json file
     {
         "inlets_server_ip": "192.168.1.1",
         "inlets_server_domain": "ghost.example.com"
     }
    
  3. Generate the inlets-ghost.yaml file
     j2 inlets-ghost.yml.j2 kube_data.json > inlets-ghost.yml
    

Quadlet inlets-ghost.kube file

[Kube]
Yaml=inlets-ghost.yml

Create and run the Quadlet

Since the client does not require any root privileges, it can be executed as a user service

  1. Copy the inlets-ghost.yaml and inlets-ghost.kube files to ~/.config/containers/systemd/
     sudo cp inlets-ghost.yaml inlets-ghost.kube ~/.config/containers/systemd/
    
  2. Reload the systemd daemon
     systemctl --user daemon-reload
    
  3. Start the service
     systemctl --user start inlets-ghost.service
    

Access the blog

Once all resources are up and running you can access you blog at your at https://< inlets_server_domain >

To create your admin account, add /ghost to the end of the URL.

Wrapping up

The idea for this tutorial came during a twitter discussion about Podman’s support for Kubernetes Yaml files, a feature not enough people are aware of.

You can use the example Yaml files and customize them to run any local application and connect it to your inlets server.

Following these instructions, you can take your Kubernetes Deployments (or Pods, or DaemonSets) and deploy them directly with Podman without the need of any translation or additional tools.

Using Quadlet you can make systemd manage your deployment for you.

If you want to learn more about Quadlet check out the following resources:

Subscribe for updates and new content from OpenFaaS Ltd.

By providing your email, you agree to receive marketing emails.

Setup your first HTTPS or TCP tunnel today. It's private, self-hosted with no bandwidth or rate-limits.