Clone Private Git Repository in Kubernetes With User Authentication

Posted on 122 views

Welcome to this guide on how to clone a private Git Repository in Kubernetes with user authentication. May at times, we have config variables that keep being updated regularly by developers and thus need to update the environment in our containers. This problem can be solved by creating a pod with multiple containers sharing a volume. Git can be used to store the data and each time the code is updated, the data is pulled to the volume.

Git-sync is a sidecar container that perfectly clones a git repo and keeps it synchronized with the upstream. It can be configured to pull one time or regularly as per your preferences. It allows one to pull over SSH or via HTTPS (with or without authentication)

Now let’s dive in and see how we can clone a private Git Repository in Kubernetes with user authentication.

Getting Started

This guide requires one to have a Kubernetes cluster already set up. There are many methods one can use to set up a Kubernetes cluster. Some of them are demonstrated in the guides below:

With a cluster set up, proceed as below.

Using Git-sync to Clone Git Repository in Kubernetes

There are two methods here i.e using HTTPS which works with or without authentication and using SSH which requires SSH keys.

In this guide, we will run two containers in a pod:

  • Nginx webserver
  • Git-sync as an init container to clone the private Git Repository.

Create the deployment manifest. In this guide, we will generate an Nginx template and modify it to accommodate git-sync

## Generate deployment YAML file ##
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml >nginx-deployment.yml

## Generate Pod creation YAML file ###
kubectl run nginx-helloworld  --image nginx --restart=Never --dry-run=client -o yaml >nginx-helloworld-pod.yml

You will have a YAML file with the below lines.

$ cat nginx-deployment.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: 
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: 
status: 

Let’s create a namespace called “demo” for these tasks

$ kubectl create ns demo
namespace/demo created

Let’s set the current context to the demo namespace

$ kubectl config set-context --current --namespace demo
Context "Default" modified.

Option 1. Clone a Private Repository Using HTTPS

For git-sync to clone the private git repo over HTTPS, you need to have the repository’s username and a Personal Access Token.

Proceed and modify your deployment file

vim nginx-deployment.yml

Paste and modify the contents below accordingly.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx-helloworld
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: www-data
      initContainers:
      - name: git-sync
        image: k8s.gcr.io/git-sync:v3.1.5
        volumeMounts:
        - name: www-data
          mountPath: /data
        env:
        - name: GIT_SYNC_REPO
          value: "https://github.com/computingpost/hello-world-nginx.git" ##Private repo-path-you-want-to-clone
        - name: GIT_SYNC_USERNAME
          value: "computingpost"  ##The username for the repository
        - name: GIT_SYNC_PASSWORD
          value: "ghpsdhkshkdj_kndk...." ##The Personal Access Token for the repository
        - name: GIT_SYNC_BRANCH
          value: "master" ##repo-branch
        - name: GIT_SYNC_ROOT
          value: /data
        - name: GIT_SYNC_DEST
          value:  "hello" ##path-where-you-want-to-clone
        - name: GIT_SYNC_PERMISSIONS
          value: "0777"
        - name: GIT_SYNC_ONE_TIME
          value: "true"
        securityContext:
          runAsUser: 0
      volumes:
      - name: www-data
        emptyDir: 

Option 2. Clone a Private Repository using SSH

Ensure that you already have SSH keys generated from your server and copied to the GIT HOST. Verify if you can connect via SSH

$ ssh -T [email protected]
The authenticity of host 'github.com (140.82.121.3)' can't be established.
ECDSA key fingerprint is SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com,140.82.121.3' (ECDSA) to the list of known hosts.
Hi computingpost/hello-world-nginx! You've successfully authenticated, but GitHub does not provide shell access.

Obtain the host keys for the Git server

ssh-keyscan YOUR_GIT_HOST > /tmp/known_hosts

For example.

ssh-keyscan github.com > /tmp/known_hosts

With the keys, create the secrets as below:

kubectl create secret generic git-creds \
    --from-file=ssh=$HOME/.ssh/id_rsa \
    --from-file=known_hosts=/tmp/known_hosts

Verify if the secret has been deployed.

$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-nz74s   kubernetes.io/service-account-token   3      72m
git-creds             Opaque                                2      11s

Edit the YAML to be able to run git-sync as an init container that clones a private Git Repository.

vim nginx-deployment.yml

The will contain the below lines.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx-helloworld
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: www-data
      initContainers:
      - name: git-sync
        image: k8s.gcr.io/git-sync:v3.1.5
        volumeMounts:
        - name: www-data
          mountPath: /data
        env:
        - name: GIT_SYNC_REPO
         value: "[email protected]:computingpost/hello-world-nginx.git" ##repo-path-you-want-to-clone
       - name: GIT_SYNC_BRANCH
         value: "master" ##repo-branch
       - name: GIT_SYNC_SSH
         value: "true"
       - name: GIT_SYNC_ROOT
         value: /data
       - name: GIT_SYNC_DEST
         value:  "hello" ##path-where-you-want-to-clone
       - name: GIT_SYNC_PERMISSIONS
         value: "0777"
       - name: GIT_SYNC_ONE_TIME
         value: "true"
       securityContext:
         runAsUser: 0
      volumes:
      - name: www-data
        emptyDir: 
      - name: git-secret
        secret:
          defaultMode: 256
          secretName: git-creds # your-ssh-key

Run the Application

In the above configuration files, we have an init container named git-sync that clones a repository to /data which is a volume mount called www-data. This volume is shared between the two containers.

Deploy the manifest.

kubectl create -f nginx-deployment.yml 

Verify if the pod has been created:

###First run
$ kubectl get pods
NAME               READY   STATUS     RESTARTS   AGE
nginx-helloworld   0/1     Init:0/1   0          7s

#Second run
$ kubectl get pods
NAME               READY   STATUS            RESTARTS   AGE
nginx-helloworld   0/1     PodInitializing   0          10s

#Third run
$ kubectl get pods
NAME               READY   STATUS    RESTARTS   AGE
nginx-helloworld   1/1     Running   0          13s

If you want to use persistent volume claim instead, you need to update your manifest as below.

volumes:
    - name: my-pv-storage
      persistentVolumeClaim:
        claimName: mypv-claim

Now you should have your file cloned to /data/hello and /data share the same volume with /usr/share/nginx/html verified as below:

$ kubectl exec --stdin --tty nginx-helloworld -- /bin/bash
# ls -al /usr/share/nginx/html/hello/
.git        README.md   index.html 

My cloned git repo HelloWord-Computingpost has the files above.

Clone-Private-Git-Repository-in-Kubernetes-With-User-Authentication-1

Delete the pods and secret using the command:

kubectl delete all --all -n demo
kubectl delete ns demo

Conclusion.

That marks the end of this guide. We have successfully walked through how to clone a private Git Repository in Kubernetes With User Authentication. Futhermore I have demonstrated how a public repository can be cloned via HTTPS without authentication. I hope this was significant.

coffee

Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.