Installing Helm Charts

The first thing we'll do is to confirm that Jenkins indeed exists in the official Helm repository. We could do that by executing helm search (again) and going through all the available Charts. However, the list is pretty big and growing by the day. We'll filter the search to narrow down the output.

 1  helm search jenkins

The output is as follows.

NAME           CHART VERSION APP VERSION DESCRIPTION            
stable/jenkins 0.16.1 2.107 Open source continuous integration server. It s...

We can see that the repository contains stable/jenkins Chart based on Jenkins version 2.107.

A note to minishift users
Helm will try to install Jenkins Chart with the process in a container running as user 0. By default, that is not allowed in OpenShift. We'll skip discussing the best approach to correct the permissions in OpenShift. I'll assume you already know how to set the permissions on the per-pod basis. Instead, we'll do the simplest fix. Please execute the command that follows to allow the creation of restricted Pods to run as any user.
oc patch scc restricted -p '{"runAsUser":{"type": "RunAsAny"}}'

We'll install Jenkins with the default values first. If that works as expected, we'll try to adapt it to our needs later on.

Now that we know (through search) that the name of the Chart is stable/jenkins, all we need to do is execute helm install.

 1  helm install stable/jenkins 
 2      --name jenkins 
 3      --namespace jenkins

We instructed Helm to install stable/jenkins with the name jenkins, and inside the Namespace also called jenkins.

The output is as follows.

NAME:   jenkins
LAST DEPLOYED: Sun May ...
NAMESPACE: jenkins
STATUS: DEPLOYED
    
RESOURCES:
==> v1/Service
NAME          TYPE         CLUSTER-IP     EXTERNAL-IP PORT(S)        AGE
jenkins-agent ClusterIP    10.111.123.174 <none>      50000/TCP      1s
jenkins       LoadBalancer 10.110.48.57   localhost   8080:31294/TCP 0s
    
==> v1beta1/Deployment
NAME    DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
jenkins 1       1       1          0         0s
    
==> v1/Pod(related)
NAME        READY STATUS   RESTARTS AGE
jenkins-... 0/1   Init:0/1 0        0s
    
==> v1/Secret
NAME    TYPE   DATA AGE
jenkins Opaque 2    1s
    
==> v1/ConfigMap
NAME          DATA AGE
jenkins       4    1s
jenkins-tests 1    1s
    
==> v1/PersistentVolumeClaim
NAME    STATUS VOLUME  CAPACITY ACCESS MODES STORAGECLASS AGE
jenkins Bound  pvc-... 8Gi      RWO          gp2          1s
    
    
NOTES:
1. Get your 'admin' user password by running:
   printf $(kubectl get secret --namespace jenkins jenkins -o 
jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
2. Get the Jenkins URL to visit by running these commands in the same shell: NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get svc --namespace jenkins -w jenkins' export SERVICE_IP=$(kubectl get svc --namespace jenkins jenkins --template "{{ range (index.status.loadBalancer.ingress 0) }}{{ . }}{{
end }}")
echo http://$SERVICE_IP:8080/login 3. Login with the password from step 1 and the username: admin For more information on running Jenkins on Kubernetes, visit:
https://cloud.google.com/solutions/jenkins-on-container-engine

At the top of the output, we can see some general information like the name we gave to the installed Chart (jenkins), when it was deployed, what the Namespace is, and the status.

Following the general information is the list of the installed resources. We can see that the Chart installed two services; one for the master and the other for the agents. Following is the Deployment and the Pod. It also created a secret that holds the administrative username and password. We'll use it soon. Further on, we can see that it created two ConfigMaps. One (jenkins) holds all the configurations Jenkins might need. Later on, when we customize it, the data in this ConfigMap will reflect those changes. The second ConfigMap (jenkins-tests) is, at the moment, used only to provide a command used for executing liveness and readiness probes. Finally, we can see that a PersistentVolumeClass was created as well, thus making our Jenkins fault tolerant without losing its state.

Don't worry if you feel overwhelmed. We'll do a couple of iterations of the Jenkins installation process, and that will give us plenty of opportunities to explore this Chart in more details. If you are impatient, please describe any of those resources to get more insight into what's installed.

One thing worthwhile commenting right away is the type of the jenkins Service. It is, by default, set to LoadBalancer. We did not explore that type in The DevOps 2.3 Toolkit: Kubernetes (https://www.amazon.com/dp/1980690138), primarily because the book is, for the most part, based on minikube.

On cloud providers which support external load balancers, setting the type field to LoadBalancer will provision an external load balancer for the Service. The actual creation of the load balancer happens asynchronously, and information about the provisioned balancer is published in the Service's status.loadBalancer field.

When a Service is of the LoadBalancer type, it publishes a random port just as if it is the NodePort type. The additional feature is that it also communicates that change to the external load balancer (LB) which, in turn, should open a port as well. In most cases, the port opened in the external LB will be the same as the Service's TargetPort. For example, if the TargetPort of a Service is 8080 and the published port is 32456, the external LB will be configured to accept traffic on the port 8080, and it will forward traffic to one of the healthy nodes on the port 32456. From there on, requests will be picked up by the Service and the standard process of forwarding it further towards the replicas will be initiated. From user's perspective, it seems as if the published port is the same as the TargetPort.

The problem is that not all load balancers and hosting vendors support the LoadBalancer type, so we'll have to change it to NodePort in some of the cases. Those changes will be outlined as notes specific to the Kubernetes flavor.

Going back to the Helm output...

At the bottom of the output, we can see the post-installation instructions provided by the authors of the Chart. In our case, those instructions tell us how to retrieve the administrative password from the secret, how to open Jenkins in a browser, and how to log in.

A note to minikube users
If you go back to the output, you'll notice that the type of the jenkins Service is LoadBalancer. Since we do not have a load balancer in front of our minikube cluster, that type will not work, and we should change it to NodePort. Please execute the command that follows.
helm upgrade jenkins stable/jenkins --set Master.ServiceType=NodePort
We haven't explained the upgrade process just yet. For now, just note that we changed the Service type to NodePort.
A note to minishift users
OpenShift requires Routes to make services accessible outside the cluster. To make things more complicated, they are not part of "standard Kubernetes" so we'll need to create one using oc. Please execute the command that follows.
oc -n jenkins create route edge --service jenkins --insecure-policy Allow
That command created an edge Router tied to the jenkins Service. Since we do not have SSL certificates for HTTPS communication, we also specified that it is OK to use insecure policy which will allow us to access Jenkins through plain HTTP.

Next, we'll wait until jenkins deployment is rolled out.

 1  kubectl -n jenkins 
 2    rollout status deploy jenkins
The rollout status command might exit with the error: watch closed before Until timeout message. Don't panic. Jenkins might need more time to initialize than that command's timeout. If that happens, wait until Jenkins Pod is running.

We are almost ready to open Jenkins in a browser. But, before we do that, we need to retrieve the hostname (or IP) through which we can access our first Helm install.

 1  ADDR=$(kubectl -n jenkins 
 2      get svc jenkins 
 3      -o jsonpath="{.status.loadBalancer.ingress[0].hostname}"):8080
A note to minikube users
Unlike some other Kubernetes flavors (for example, AWS with kops), minikube does not have a hostname automatically assigned to us through an external load balancer. We'll have to retrieve the IP of our minikube cluster and the port published when we changed the jenkins service to NodePort. Please execute the command that follows.
ADDR=$(minikube ip):$(kubectl -n jenkins get svc jenkins -o jsonpath="{.spec.ports[0].nodePort}")
A note to GKE users
Unlike some other Kubernetes flavors (for example, AWS with kops), GKE does not have a hostname automatically assigned to us through an external load balancer. Instead, we got the IP of Google's LB. We'll have to get that IP. Please execute the command that follows.
ADDR=$(kubectl -n jenkins get svc jenkins -o jsonpath="{.status.loadBalancer.ingress[0].ip}"):8080
A note to minishift users
Unlike all other Kubernetes flavors, OpenShift does not use Ingress. We'll have to retrieve the address from the jenkins Route we created previously. Please execute the command that follows.
ADDR=$(oc -n jenkins get route jenkins -o jsonpath="{.status.ingress[0].host}")

To be on the safe side, we'll echo the address we retrieved and confirm that it looks valid.

 1  echo $ADDR

The format of the output will differ from one Kubernetes flavor to another. In case of AWS with kops, it should be similar to the one that follows.

 1  ...us-east-2.elb.amazonaws.com

Now we can finally open Jenkins. We won't do much with it. Our goal, for now, is only to confirm that it is up-and-running.

 1  open "http://$ADDR"
Remember that if you are a Windows user, you'll have to replace open with echo, copy the output, and paste it into a new tab of your browser of choice.

You should be presented with the login screen. There is no setup wizard indicating that this Helm chart already configured Jenkins with some sensible default values. That means that, among other things, the Chart created a user with a password during the automatic setup. We need to discover it.

Fortunately, we already saw from the helm install output that we should retrieve the password by retrieving the jenkins-admin-password entry from the jenkins secret. If you need to refresh your memory, please scroll back to the output, or ignore it all together and execute the command that follows.

 1  kubectl -n jenkins 
 2      get secret jenkins 
 3      -o jsonpath="{.data.jenkins-admin-password}" 
 4      | base64 --decode; echo

The output should be a random set of characters similar to the one that follows.

shP7Fcsb9g

Please copy the output and return to Jenkins' login screen in your browser. Type admin into the User field, paste the copied output into the Password field and click the log in button.

Mission accomplished. Jenkins is up-and-running without us spending any time writing YAML file with all the resources. It was set up automatically with the administrative user and probably quite a few other goodies. We'll get to them later. For now, we'll "play" with a few other helm commands that might come in handy.

If you are ever unsure about the details behind one of the Helm Charts, you can execute helm inspect.

 1  helm inspect stable/jenkins

The output of the inspect command is too big to be presented in a book. It contains all the information you might need before installing an application (in this case Jenkins).

If you prefer to go through the available Charts visually, you might want to visit Kubeapps (https://kubeapps.com/) project hosted by bitnami (https://bitnami.com/). Click on the Explore Apps button, and you'll be sent to the hub with the list of all the official Charts. If you search for Jenkins, you'll end up on the page with the Chart's details (https://hub.kubeapps.com/charts/stable/jenkins). You'll notice that the info in that page is the same as the output of the inspect command.

We won't go back to Kubeapps since I prefer command line over UIs. A firm grip on the command line helps a lot when it comes to automation, which happens to be the goal of this book.

With time, the number of the Charts running in your cluster will increase, and you might be in need to list them. You can do that with the ls command.

 1  helm ls

The output is as follows.

NAME    REVISION UPDATED     STATUS   CHART          NAMESPACE
jenkins 1        Thu May ... DEPLOYED jenkins-0.16.1 jenkins

There is not much to look at right now since we have only one Chart. Just remember that the command exists. It'll come in handy later on.

If you need to see the details behind one of the installed Charts, please use the status command.

 1  helm status jenkins

The output should be very similar to the one you saw when we installed the Chart. The only difference is that this time all the Pods are running.

Tiller obviously stores the information about the installed Charts somewhere. Unlike most other applications that tend to save their state on disk, or replicate data across multiple instances, tiller uses Kubernetes ConfigMaps to preserve its state.

Let's take a look at the ConfigMaps in the kube-system Namespace where tiller is running.

 1  kubectl -n kube-system get cm

The output, limited to the relevant parts, is as follows.

NAME       DATA AGE
...
jenkins.v1 1    25m
...

We can see that there is a config named jenkins.v1. We did not explore revisions just yet. For now, only assume that each new installation of a Chart is version 1.

Let's take a look at the contents of the ConfigMap:

 1  kubectl -n kube-system 
 2      describe cm jenkins.v1

The output is as follows:

Name:        jenkins.v1
Namespace:   kube-system
Labels:      MODIFIED_AT=1527424681
             NAME=jenkins
             OWNER=TILLER
             STATUS=DEPLOYED
             VERSION=1
Annotations: <none>

Data
====
release:
----
[ENCRYPTED RELEASE INFO]
Events:  <none>

I replaced the content of the release Data with [ENCRYPTED RELEASE INFO] since it is too big to be presented in the book. The release contains all the info tiller used to create the first jenkins release. It is encrypted as a security precaution.

We're finished exploring our Jenkins installation, so our next step is to remove it.

 1  helm delete jenkins

The output shows that the release "jenkins" was deleted.

Since this is the first time we deleted a Helm Chart, we might just as well confirm that all the resources were indeed removed.

 2  kubectl -n jenkins get all

The output is as follows.

NAME           READY STATUS      RESTARTS AGE
po/jenkins-... 0/1   Terminating 0        5m

Everything is gone except the Pod that is still Terminating. Soon it will disappear as well, and there will be no trace of Jenkins anywhere in the cluster. At least, that's what we're hoping for.

Let's check the status of the jenkins Chart.

 1  helm status jenkins

The relevant parts of the output are as follows.

LAST DEPLOYED: Thu May 24 11:46:38 2018
NAMESPACE: jenkins
STATUS: DELETED

...

If you expected an empty output or an error stating that jenkins does not exist, you were wrong. The Chart is still in the system, only this time its status is DELETED. You'll notice that all the resources are gone though.

When we execute helm delete [THE_NAME_OF_A_CHART], we are only removing the Kubernetes resources. The Chart is still in the system. We could, for example, revert the delete action and return to the previous state with Jenkins up-and-running again.

If you want to delete not only the Kubernetes resources created by the Chart but also the Chart itself, please add --purge argument.

 1  helm delete jenkins --purge

The output is still the same as before. It states that the release "jenkins" was deleted.

Let's check the status now after we purged the system.

 1  helm status jenkins

The output is as follows.

Error: getting deployed release "jenkins": release: "jenkins" not found

This time, everything was removed, and helm cannot find the jenkins Chart anymore.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.104.238