Deploying to Kubernetes with Gitness
Tags: kubernetes, deployment, nginx, gitness
Published: 2023-10-12 14:43:43


---
canonical_url: https://www.harness.io/blog/deploying-to-k8s-gitness
---

Gitness is an open-source Git solution designed with developers in mind. At its core, it offers a reliable space to host git repositories. However, its capabilities extend far beyond that. If you've been keeping up with recent news and announcements, you've likely come across its features for code hosting, collaboration, and continuous integration. In this blog, I'll demonstrate how you can leverage this platform to deploy to Kubernetes, thereby completing the full DevOps cycle of build and deploy.

If videos are more your style, we've got you covered:

{% youtube WCG8AtRBbuo %}

### Before you begin

You will be running Gitness as a containerized application, and during this process, you'll also deploy a sample application to a Kubernetes cluster. To get started, ensure you have the following:

- [Docker engine running](https://docs.docker.com/engine/install/).
- [Install Gitness and sign up](https://docs.gitness.com/)
- A Kubernetes cluster (You can use [k3d](https://k3d.io/) or a managed Kubernetes service).
- [kubectl](https://kubernetes.io/docs/reference/kubectl/) installed and user is authenticated 
- Your own Kubernetes manifest (this is optional).

Ensure your user or service account on the Kubernetes cluster has the ability to create and list deployments, service accounts, roles, rolebindings, and more. It's typically advised to use a service account and its associated token instead of a user account token within a build/deploy system. 

Here's a manifest that includes definitions for a service account, role, role binding, and secret. By using this, you'll be able to leverage the `gitness-sa` service account to initiate deployments from Gitness.

{% gist https://gist.github.com/dewan-ahmed/ba8bb870f5cf0b84d5ee01bc456c8328 file=gitness-sa-manifest.yaml %}

Save the provided content as `gitness-sa-manifest.yaml`.

Let's use a dedicated namespace called `gitness`:

```
kubectl create namespace gitness

kubectl config set-context --current --namespace=gitness
```

Once done, execute the following command to create the necessary resources:

```
kubectl apply -f gitness-sa-manifest.yaml
```

Make a note of the `gitness-sa-token`. We’ll use it later:

```
TOKEN=$(kubectl get secret gitness-sa-token -n default -o=jsonpath='{.data.token}' | base64 --decode)

echo -e $TOKEN | tr -d '\n'
```

The `echo` command trims any newline character from within the token to avoid formatting errors when copying over.

### Setup and configure Gitness

Setting up Gitness is straightforward and it's suitable for lightweight machines — yes, even on a $4 DigitalOcean VM. If you already have the Docker engine up and running, you can [get started with Gitness](https://docs.gitness.com) with the following command:

{% gist https://gist.github.com/dewan-ahmed/ba8bb870f5cf0b84d5ee01bc456c8328 file=gitness-docker-run.sh %}

![gitness signup](https://github.com/dewan-ahmed/memes-and-gifs/blob/fc5c82dc33b9e08220b1ddbc848e7fbae8f33e8c/signup.gif)

Visit `localhost:3000` in your browser and sign up using a User ID, Email, and Password. Once you've successfully registered and are presented with the initial Gitness interface, you can choose to create a new project or import an existing one. A project in Gitness is similar to a group in GitLab or an organization in GitHub.

Let's initiate a project named `gitness-cd`. After it's set up, we will proceed to add two secrets that Gitness requires to orchestrate a deployment on your Kubernetes cluster. From the left navigation pane, select **Secrets** followed by **+ New Secret**. You'll then create the following two secrets: `k8s-server` and `gitness-sa-token`.

For the `k8s-server` secret, use the output from the subsequent instructions as its value. To retrieve the URL of the Kubernetes API server:

```
kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'
```

We already made a note of `gitness-sa-token` in the previous section so use that value to create `gitness-sa-token` secret.

### A Word on Gitness's Current Stage

Gitness is still in the early days and is going through rapid development. [One of the known issues](https://github.com/harness/gitness/issues/3403) is that when using a script within a [run step](https://docs.gitness.com/pipelines/steps/run), the Gitness secrets are printed in the pipeline execution log in plain text. The Gitness community continues to report [similar issues](https://github.com/harness/gitness/issues) and this feedback will guide this platform's evolution. With your help, we aspire to set new industry standards for open-source code hosting & pipeline engine.

You might observe numerous shell script commands embedded within the CD pipeline and wonder, "Aren't we transitioning away from custom shell scripts?" Indeed, as Gitness matures, expect plugins and integrations that will streamline Kubernetes cluster configurations. This will eventually enable application deployments without reliance on shell scripting. For the time being, bear with the temporary solutions. The essence of this blog is to showcase the promising horizon awaiting Gitness.

### Using Gitness for source code management

You can import an existing GitHub or GitLab repository but for this blog, let’s create a new repository in Gitness. From the left navigation bar, select **Repository** and click on **New Repository**. Give this repository a name, for example, `demo-repo` and click **Create Repository**. You can keep all other options as default. 

Once the repository is created, you’ll see an option to add a new file. You can generate git credentials, clone the repository, and work from a terminal. Since we’ll be adding one file, let’s use the Gitness UI to add that file. Click on **+ New File**, give the file a name `nginx-deployment.yaml`, and paste the following code:

{% gist https://gist.github.com/dewan-ahmed/ba8bb870f5cf0b84d5ee01bc456c8328 file=nginx-deployment.yaml %}

Alright, let's just commit those changes straight to the main branch. By the way, if you've got a Kubernetes app and some manifests lying around, feel free to use yours. Otherwise, our sample `nginx-deployment.yaml` has got you covered.

### Create a deployment pipeline in Gitness

The pipeline concept in Gitness is a child concept under the Repository entity. You can create one or more pipelines for a given repository. For this blog, assume that you have a continuous integration pipeline that can build your code, run tests, and push an image to an image registry. In this section, we’ll create a deployment pipeline that can deploy that image to your Kubernetes cluster. Let’s use `nginx:latest` as an example but you can swap this with your choice of a container image. 

Getting started is straightforward:

- Navigate to Repository → Pipelines and then click **+ New Pipeline**.
- Name it something relevant like `k8s-deploy`.
- The branch, by default, should be set to `main`, and the YAML path will indicate where Gitness archives the pipeline in a code format.
- Once you hit **Create**, a template pipeline will be at your disposal.

Replace the sample pipeline with the following pipeline definition:

{% gist https://gist.github.com/dewan-ahmed/ba8bb870f5cf0b84d5ee01bc456c8328 file=cd-pipeline.yaml %}


Click **Save and Run** from the top-right corner and watch your deployment pipeline logs to ensure that Gitness deployed an nginx application on your Kubernetes cluster. A successful pipeline execution will look something like this:

![Successful pipeline run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70i6277zulqsmcvv8qqf.png)


Unfolding the `cdstep` will reveal the smooth sailing of the `nginx-deployment` pods. You're probably brimming with questions about this pipeline definition, right? No worries – we're diving deep into those in the next section.

### Breaking down the pipeline definition

Let's delve a bit deeper into the Gitness pipeline structure. A pipeline in Gitness can have one or multiple stages. In our example, we have two defined stages: `cistage` and `cdstage`.

Both of these stages utilize the `alpine/k8s:1.26.9` container image, which includes the kubectl tool. The `cistage` is more of a placeholder right now, simply executing an echo command.

The `cdstage`, however, does the heavy lifting. It initiates the deployment through a series of shell commands. First, it establishes a connection to the Kubernetes cluster, leveraging two secrets provided by Gitness during runtime. Next, it triggers a deployment using the `nginx-deployment` file from our Gitness `demo-repo`. To round things off, it checks to confirm the successful launch of the pods.

It's worth noting that these commands are executed within the [Gitness run step](https://docs.gitness.com/pipelines/steps/run), and they operate from the root directory of your git repository.

### Challenges with deployment from a Continuous Integration (CI) tool

While Continuous Integration (CI) tools are indispensable for maintaining code quality, they aren't always suitable for deployment tasks. Here's why:

1. Nature of CI Tools: CI tools are essentially designed to run workloads sequentially. Deploying to dynamic environments requires a level of adaptability that CI tools might not offer.
2. Deployment Strategies: Advanced deployment methods, like blue-green or canary releases, can be challenging to execute with standard CI platforms.
3. Statelessness of CI: CI processes generally don't retain state. This can lead to deployment inconsistencies or errors due to the lack of contextual awareness.
4. Security Concerns: Deployments often need high-level permissions. Using CI tools for such tasks can expose systems to security vulnerabilities. Now, you might be thinking, "Why did we let Gitness into our Kubernetes cluster then?" Think of 
5. Gitness less like a regular CI tool and more like a complete software delivery platform.
Scalability Challenges: As a business grows, it might deploy to multiple regions or across environments. CI tools can struggle to keep pace with such expanding requirements.

From deploying multiple services across multiple environments to comprehensive GitOps support, Harness CD can deploy any app, anywhere without any scripting involved. If you’re looking for an advanced continuous delivery platform ⤵️

{% cta https://www.harness.io/products/continuous-delivery?utm_source=dewan&utm_medium=harness-blog&utm_campaign=cd-devrel&utm_content=dewan-devrel %} Give Harness Continuous Delivery (CD) a try. {% endcta %}