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:
- Install Kubernetes Cluster on Rocky Linux 8 with Kubeadm & CRI-O
- Install Kubernetes Cluster on Ubuntu using K3s
- Deploy Kubernetes Cluster on Linux With k0s
- Run Kubernetes on Debian with Minikube
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/neveropen/hello-world-nginx.git" ##Private repo-path-you-want-to-clone
- name: GIT_SYNC_USERNAME
value: "neveropen" ##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 neveropen/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]:neveropen/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-Computingforgeeks has the files above.
Delete the pods and secret using the command:
kubectl delete all --all -n demo
kubectl delete ns demo
Books For Learning Kubernetes Administration:
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.
See more: