24. 07. 2024 Lorenzo Candeago DevOps

How to Add SSH Keys to ArgoCD and Tekton on OpenShift to Access Gitea: Part 3 – A Simple Tekton TaskRun

In the first blog post of this series I showed you how to set up an OpenShift test environment and set up Gitea via helm chart and add an ssh key to Gitea. In the second blog post we created a deployment with ArgoCD that clones via ssh from our Gitea instance. In this final blog post we’ll look at a simple TaskRun that clones a repo via ssh from our Gitea instance using Tekton. Specifically, we’d like to clone from our Gitea repo as an unprivileged user (taking inspiration from the Tekton sample git clone task and adapting it to our case).

As a first step, let’s fix a bug in openshift-pipelines 1.15.1 that seems to be present at the time that I’m writing this blog post: in some cases the default service account (pipeline) that should be created in the openshift-pipelines namespace is not created.

Following the RedHat solution, we can create it by applying the following yaml:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: pipeline
  namespace: openshift-pipelines
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: pipelines-as-code-cleanup-job
  namespace: openshift-pipelines
rules:
  - apiGroups: ["tekton.dev"]
    resources: ["taskruns"]
    verbs: ["get", "delete", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pipelines-as-code-cleanup-job
  namespace: openshift-pipelines
subjects:
  - kind: ServiceAccount
    name: pipeline
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pipelines-as-code-cleanup-job

With that out of the way, we can start working at our task.

As for the default installation, we won’t be able to run a task that requires a fixed UID, because the default SCC on openshift-pipelines for the service account pipeline is restricted. For this test we will allow the task to run with some more permissive SCC: we can change the max allowed scc in tekton config: let’s edit the instance of Tekton CRD that is created by default by openshift-pipelines: the default instance of the TektonConfig CRD created by Openshift Piplines is called config.

 oc edit TektonConfig config
 [...]    
    scc:
        default: pipelines-scc
        maxAllowed: privileged 
[...]

This will allow us to set a higher-privileged scc for single Tekton workloads or namespaces by the use of the annotation operator.tekton.dev/scc: nonroot-v2 . Lets create a namespace where the TaskRun that clones from Gitea will run:

---
apiVersion: v1
kind: Namespace
metadata:
  name: nonroot-namespace
  annotations:
    operator.tekton.dev/scc: nonroot-v2 

And a secret that will contain our private ssh key.

apiVersion: v1
kind: Secret
metadata:
  name: ssh-key-for-git
  namespace: nonroot-namespace
  annotations:
    tekton.dev/git-0: gitea-ssh.default.svc.cluster.local:2222 
type: kubernetes.io/ssh-auth
stringData:
  ssh-privatekey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
    QyNTUxOQAAACDFYyNY63m59HexkT03xbdio8Z+PGfLth/PKYADqrZPXgAAAKA4gznWOIM5
    1gAAAAtzc2gtZWQyNTUxOQAAACDFYyNY63m59HexkT03xbdio8Z+PGfLth/PKYADqrZPXg
    AAAEBMqwPDwzIvw24HOrdmqHgwpuEtXKNLxCV7CItlUBMNtMVjI1jrebn0d7GRPTfFt2Kj
    xn48Z8u2H88pgAOqtk9eAAAAGGxvQGxvY2FsaG9zdC5sb2NhbGRvbWFpbgECAwQF
    -----END OPENSSH PRIVATE KEY-----

As specified in the documentation, by the annotation tekton.dev/git-0, Tekton will automatically copy the ssh key in $HOME/.ssh/ of our pod and create the correct ssh config to match the specified domain when git cloning. Please note that if we don’t specify the known_hosts file in the secret, we will need to take care to add it as part of our task run. This is not a security best practice because in this way we will accept any signature that is returned, but for this toy example it’s good enough.

Now that we have the secret, we can link it to the default pipeline account:

oc secret link pipeline ssh-key-for-git -n  nonroot-namespace

And finally create our TaskRun:

---
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  namespace: nonroot-namespace
  name: authenticating-git-commands
spec:
  taskSpec:
    steps:  
    - name: git-clone-and-check
      # Lets set the home to the correct directory for the container we are using
      env:
        - name: HOME
          value: /home/nonroot/
      image: gcr.io/tekton-releases/dogfooding/alpine-git-nonroot:latest
      securityContext:
        runAsUser: 1000
        runAsNonRoot: true
        capabilities:
          drop:
            - ALL
      workingDir: /home/nonroot
      script: |
        #!/usr/bin/env ash
        set -xe
        # since we didn't add the known_host string to ssh-key-for-git secret we need to add it here
        ssh-keyscan  -p 2222 gitea-ssh.default.svc.cluster.local > ~/.ssh/known_hosts      
        git clone  ssh://git@gitea-ssh.default.svc.cluster.local:2222/gitea_admin/test-repo.git
        cd test-repo
 

Note that we need to set the $HOME environment variable to the correct home for the unprivileged user with which our pod is running (in our case, nonroot with UID 1000). As we can see, Tekton automatically copied the ssh key we created as a secret to /home/nonroot/.ssh/ and created a ssh config file that matches the domain specified in the secret.

# cat .ssh/config 
Host gitea-ssh.default.svc.cluster.local
    HostName gitea-ssh.default.svc.cluster.local
    Port 2222
    IdentityFile /tekton/creds/.ssh/id_ssh-key-for-git

and so we’re able to clone from Gitea via ssh!

Lorenzo Candeago

Lorenzo Candeago

DevOps Engineer at Würth Phoenix

Author

Lorenzo Candeago

DevOps Engineer at Würth Phoenix

Leave a Reply

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

Archive