Deploying Applications to Kubernetes from your CI Pipeline

Ketch for Kubernetes

Deploying Applications to Kubernetes from your CI Pipeline:

Now that we know the advantages of leveraging Ketch over other tools such as Helm to simplify deploying applications to Kubernetes (BLOG: Helm vs. Ketch when Deploying Applications), a good next step is for us to understand how we can tie Ketch to our CI pipeline and have an automated deployment process. For this example, we will leverage Ketch, GitHub Actions, and a Kubernetes cluster on Google Kubernetes Engine (GKE).

GitHub Actions are event-driven, meaning that you can run a  series of commands after a specified event has occurred, which is excellent when automating your application deployment with Ketch as you can leverage Ketch across the different steps of your application deployment lifecycle.

For this example, we assume you already have:

Here is what we will deliver as part of this post:

GitHub: We will leverage the same podinfo application we used in our previous post. As explained before, we removed all code and files related to Helm Chart and Kustomize from the original podinfo application source code as Ketch won’t need those to deploy the application. The source code can be found here:

GitHub Actions: We will leverage GitHub actions for:

  • Building our image based on the Dockerfile provided as part of the source code.
  • Pushing the built image to Google Container Registry
  • Creating a Ketch pool
  • Creating and deploying our podinfo application

GKE: Even though you can use Ketch with pretty much any available Kubernetes provider, for this example, we will use Google’s Kubernetes Engine.

GitHub Secrets

We will use the gcloud CLI to fetch the kubeconfig from our GKE cluster, where we will deploy our podinfo application. To store the information required to create the cluster config and deploy our application to our cluster, we will use GitHub Secrets.

Let’s create our secrets! To get started, go to the “Settings” tab in your project and click “Secrets” in the sidebar. Click on “New repository secret.

Deploying Applications to Kubernetes

You will need to create the following secrets:

  • GKE_PROJECT: The name of your project where your GKE cluster is located in your Google cloud account
  • GKE_SA_KEY: The service account used for the project with the Base64 encoded JSON service account key. More info available on 
  • KETCH_APP: The name of the application we want Ketch to use when deploying our podinfo application
  • KETCH_INGRESS_SP: The ingress service endpoint that should be used by Ketch when creating the pool so Ketch can automatically provision an endpoint for our podinfo application during the deployment
  • KETCH_POOL: The name of the pool we want Ketch to create to deploy our application. Not that Ketch will create a namespace in your cluster called ketch-poolname. If you want Ketch to use an existing namespace in your cluster, in addition to setting up this secret, you need to add the –namespace flag in the CI pipeline configuration.

Using the GitHub secrets in your workflow is relatively straightforward. Each secret gets added as an environment variable prefixed with “secrets”, which means we can easily use them when creating our config file.

Pipeline Settings

branches: [ main ]
branches: [ main ]

PROJECT_ID: ${{ secrets.GKE_PROJECT }}
GKE_CLUSTER: ketch # TODO: update to cluster name
GKE_ZONE: us-west1-a # TODO: update to cluster zone
DEPLOYMENT_NAME: ketch-test # TODO: update to deployment name
IMAGE: static-site

In this example, we will use our actions when there are either push or pull requests on our “main” branch. Our pipeline config file is stored inside .github/workflows directory, using a file called gke.yml

While we are using the PROJECT_ID secret that we have set before, we are also pre-setting variables such as GKE_CLUSTER, GKE_ZONE, and DEPLOYMENT_NAME. If you want to further automate your pipeline, you can also set these as Secrets on GitHub instead of hardcoding it in the pipeline config file.

Setting Up gcloud

   # Setup gcloud CLI
- uses: GoogleCloudPlatform/github-actions/setup-gcloud@0.1.3
service_account_key: ${{ secrets.GKE_SA_KEY }}
project_id: ${{ secrets.GKE_PROJECT }}

# Configure Docker to use the gcloud command-line tool as a credential
# helper for authentication
- run: |-
gcloud --quiet auth configure-docker

# Get the GKE credentials so we can deploy to the cluster
- run: |-
gcloud container clusters get-credentials "$GKE_CLUSTER" --zone "$GKE_ZONE"

Using the steps above, we are:

  • Setting up the gcloud CLI
  • Configuring Docker to use the gcloud CLI tool as a credential helper for authentication
  • Getting the GKE credentials and kubeconfig so we can deploy to our GKE cluster
    # Build the Docker image
    - name: Build
       run: |-
           docker build \
               --tag "$PROJECT_ID/$IMAGE:$GITHUB_SHA" \
               --build-arg GITHUB_SHA="$GITHUB_SHA" \
               --build-arg GITHUB_REF="$GITHUB_REF" \

    # Push the Docker image to Google Container Registry
    - name: Publish
       run: |-
           docker push "$PROJECT_ID/$IMAGE:$GITHUB_SHA"

The steps above build our podinfo image using the Dockerfile present in the repository and, once built, storing the image in our Google Container Registry.

Setting Up Ketch and Deploying Our Application

    # Set up ketch
    - name: Set up Ketch
       run: |-
           curl -sfLo ketch
           chmod u+x ./ketch
    # Deploy the Docker image to the GKE cluster
    - name: Deploy
       run: |-
            ./ketch pool add ${{ secrets.KETCH_POOL }} --ingress-service-endpoint ${{ secrets.KETCH_INGRESS_SP }} --ingress-type istio --cluster-issuer le
            ./ketch app create ${{ secrets.KETCH_APP }} --pool ${{ secrets.KETCH_POOL }}
            ./ketch app deploy ${{ secrets.KETCH_APP }} -i$PROJECT_ID/$IMAGE:$GITHUB_SHA --ketch-yaml $GITHUB_WORKSPACE/ketch.yaml

Following the steps above, GitHub Actions will first setup Ketch by downloading Ketch’s v0.1.1 CLI and allowing it to be executed.

With Ketch’s CLI downloaded, our pipeline will then:

  • Create a Ketch pool (Creating a new or using an existing Kubernetes namespace) and assign an ingress service endpoint to it.
    • For this pool, we are assigning Istio as the ingress type, but you can also use Traefik instead, as described in Ketch’s documentation ( )
    • We are assigning a cluster issuer to our Ketch pool. Later, if we want to create and assign HTTPS CNAMEs to our applications, Ketch will automatically generate the certificates and apply them to our CNAMEs. You can find more detailed information about CNAME management using Ketch here:  
  • Create our podinfo application and assign it to the previously created Ketch pool.
  • Deploy our podinfo application pulling the image that we just stored on Google Container Registry as explained above
    • Note that during deployment, we are also passing a file called ketch.yaml, which is in our podinfo source code repository and is used to expose specific ports in Kubernetes.

Source Code

You can find the complete GitHub Action code used for this example here:

In the next blog post, we will cover how you can easily automate the deployment of applications with multiple services using Ketch, GitHub Actions, and Kubernetes. As always, Ketch’s object is to allow you to continue focusing on your application code rather than Kubernetes objects, charts, and others.

Start Using Ketch Today!

Ketch is an open-source application delivery framework created by Shipa that makes it extremely easy for developers to deploy and manage applications on Kubernetes using a simple command-line interface. No YAML is required!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>