Spinning up Google Kubernetes Engine – Continuous Integration with GitHub Actions and Jenkins
Once you’ve signed up and are in your console, open the Google Cloud Shell CLI to run the following commands.
You need to enable the Kubernetes Engine API first using the following command:
$ gcloud services enable container.googleapis.com
To create a two-node autoscaling GKE cluster that scales from one to five nodes, run the following command:
$ gcloud container clusters create cluster-1 –num-nodes 2 \
–enable-autoscaling –min-nodes 1 –max-nodes 5 –zone us-central1-a
And that’s it! The cluster will be up and running.
You must also clone the following GitHub repository for some of the exercises provided: https:// github.com/PacktPublishing/Modern-DevOps-Practices-2e.
Run the following command to clone the repository into your home directory and cd into the following directory to access the required resources:
$ git clone https://github.com/PacktPublishing/Modern-DevOps-Practices-2e.git \ modern-devops
$ cd modern-devops/ch11/jenkins/jenkins-controller
We will use the Jenkins Configuration as Code feature to configure Jenkins as it is a declarative way of managing your configuration and is also GitOps-friendly. You need to create a simple YAML file with all the required configurations and then copy the file to the Jenkins controller after setting an environment variable that points to the file. Jenkins will then automatically configure all aspects defined in the YAML file on bootup.
Let’s start by creating the casc.yaml file to define our configuration.
Creating the Jenkins CaC (JCasC) file
The Jenkins CaC (JCasC) file is a simple YAML file that helps us define Jenkins configuration declaratively. We will create a single casc.yaml file for that purpose, and I will explain parts of it. Let’s start by defining Jenkins Global Security.
Configuring Jenkins Global Security
By default Jenkins is insecure – that is, if you fire up a vanilla Jenkins from the official Docker image and expose it, anyone can do anything with that Jenkins instance. To ensure that we protect it, we need the following configuration:
jenkins:
remotingSecurity:
enabled: true
securityRealm:
local:
allowsSignup: false
users:
id: ${JENKINS_ADMIN_ID}
password: ${JENKINS_ADMIN_PASSWORD}
authorizationStrategy:
globalMatrix:
permissions:
“Overall/Administer:admin”
“Overall/Read:authenticated”
In the preceding configuration, we’ve defined the following:
- remotingSecurity: We’ve enabled this feature, which will secure the communication between the Jenkins controller and agents that we will create dynamically using Kubernetes.
- securityRealm: We’ve set the security realm to local, which means that the Jenkins controller itself will do all authentication and user management. We could have also offloaded this to an external entity such as LDAP:
- allowsSignup: This is set tofalse. This means you don’t see a sign-up link on the Jenkins home page, and the Jenkins admin should manually create users.
- users: We’ll create a single user with id and password sourced from two environment variables called JENKINS_ADMIN_ID and JENKINS_ADMIN_PASSWORD, respectively.
- authorizationStrategy: We’ve defined a matrix-based authorization strategy where we provide administrator privileges to admin and read privileges to authenticated non-admin users.
Also, as we want Jenkins to execute all their builds in the agents and not the controller machine, we need to specify the following settings:
jenkins:
systemMessage: “Welcome to Jenkins!”
numExecutors: 0
We’ve set numExecutors to 0 to allow no builds on the controller and also set systemMessage on the Jenkins welcome screen.
Now that we’ve set up the security aspects of the Jenkins controller, we will configure Jenkins to connect with the Kubernetes cluster.