November 07, 2021
With so many CI/CD solutions available, it would be nice if we can do a quick POC. This guide is exactly that:
Install JenkinsX v3 on a local single node k3s cluster with secrets stored externally in a vault running in a docker container in less than 30 minutes (No money back gurantees though if it takes longer than that)!
Disclaimer: This is my local set up for quickly debugging JenkinsX issue. Do not use this in production!
I used the script to install it quickly using the command
curl -sfL https://get.k3s.io | sh -
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/k3s-config
Detailed instructions to install k3s are here
Once installed, you should be able to run:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
<k3s node name> Ready control-plane,master 78d v1.21.5+k3s2
The name of the node will be used when setting the vault_addr when running jx admin operator.
Install the vault cli.
Run vault in a docker container locally
docker run --cap-add=IPC_LOCK -p 8200:8200 -e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' -e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' --net host vault:latest
In another terminal, set the VAULT_ADDR
export VAULT_ADDR='http://0.0.0.0:8200'
Enable kubernetes auth.
vault auth enable kubernetes
After we set up JenkinsX in the k3s cluster, we will configure the vault kubernetes backend.
Use the jx3-k3s template, and generate a cluster git repository by clicking here.
Clone the newly created repository.
Retrieve the name of the k3s node by running kubectl get nodes
.
Edit the jx-requirements.yaml
and set the value of vault url to "http://<replace with k3s node name>:8200"
Commit and push the changes to the cluster git repository:
git add .
git commit -m "fix: set vault url"
git push origin main
Set the GIT_USERNAME
and GIT_TOKEN
env variable and run:
jx admin operator --username $GIT_USERNAME --token $GIT_TOKEN --url <url of the cluster git repo> --set "jxBootJobEnvVarSecrets.EXTERNAL_VAULT=\"true\"" --set "jxBootJobEnvVarSecrets.VAULT_ADDR=http://<replace with k3s node name>:8200"
The first job will fail as it cannot authenticate against vault.
Once the secret-infra
namespace has been created, we can configure the kubernetes backend
The instructions are taken from here.
Configure the vault kubernetes backend (remember to run this in a terminal where you have set the VAULT_ADDR
):
VAULT_HELM_SECRET_NAME=$(kubectl -n secret-infra get secrets --output=json | jq -r '.items[].metadata | select(.name|startswith("kubernetes-external-secrets-token-")).name')
TOKEN_REVIEW_JWT=$(kubectl -n secret-infra get secret $VAULT_HELM_SECRET_NAME --output='go-template={{ .data.token }}' | base64 --decode)
KUBE_CA_CERT=$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.certificate-authority-data}' | base64 --decode)
KUBE_HOST=$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.server}')
vault write auth/kubernetes/config \
token_reviewer_jwt="$TOKEN_REVIEW_JWT" \
kubernetes_host="$KUBE_HOST" \
kubernetes_ca_cert="$KUBE_CA_CERT" \
disable_iss_validation=true
Create a vault role:
vault write /auth/kubernetes/role/jx-vault bound_service_account_names='*' bound_service_account_namespaces=secret-infra token_policies=jx-policy token_no_default_policy=true disable_iss_validation=true
Create the policy attached to the role:
vault policy write jx-policy - <<EOF
path "secret/*" {
capabilities = ["sudo", "create", "read", "update", "delete", "list"]
}
EOF
Get the external IP of the traefik service (loadbalancer)
kubectl get svc -A | grep LoadBalancer
kube-system traefik LoadBalancer 10.43.103.73 <external-ip> 80:31123/TCP,443:31783/TCP 40m
Edit the jx-requirements.yaml file by editing the ingress domain:
jx gitops requirements edit --domain <external-ip>.nip.io
Next, download and install ngrok. Run this in a new terminal window/tab:
jx ns jx
kubectl port-forward svc/hook 8090:80
ngrok http 8090
Once this tunnel is open, paste the ngrok url in the hook field in the helmfiles/jx/jxboot-helmfile-resources-values.yaml
file in the cluster git repository.
commit and push the changes.
git add .
git commit -m "chore: new ngrok ip"
git push origin main
Once the boot job has succeeded, you should see:
HTTP Requests
-------------
POST /hook 200 OK
in the ngrok terminal.
In a subsequent blog, we can look at importing projects into our jenkinsX installation.
Thanks to Steve Melo and Dave C in the jenkins-x-user slack channel for great feedback and document contributions!
Welcome to the personal blog of Ankit D Mohapatra.
I am the CTO of Trias Technology Group.
Follow me on twitter