OpenShift CI/CD Concepts: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 41: Line 41:
{{External|https://docs.openshift.org/latest/using_images/other_images/jenkins.html#using-the-jenkins-kubernetes-plug-in-to-run-jobs}}
{{External|https://docs.openshift.org/latest/using_images/other_images/jenkins.html#using-the-jenkins-kubernetes-plug-in-to-run-jobs}}


The Kubernetes plug-in is a Jenkins extension that uses a Kubernetes cluster to dynamically provision [[Jenkins_Concepts#Agent|Jenkins agents]], use them to run builds and then dispose of them. It does do by using Kubernetes scheduling mechanism to optimize the load.
The Kubernetes plug-in is a Jenkins extension that uses a Kubernetes cluster to dynamically provision [[Jenkins_Concepts#Agent|Jenkins agents]], use them to run builds and then dispose of them. It does do by using Kubernetes scheduling mechanism to optimize the load. The Jenkins images that ship with OpenShift comes with the Kubernetes plug-in pre-installed.


<font color=red>'''TODO''': deplete https://docs.openshift.org/latest/using_images/other_images/jenkins.html#using-the-jenkins-kubernetes-plug-in-to-run-jobs</font>
<font color=red>'''TODO''': deplete https://docs.openshift.org/latest/using_images/other_images/jenkins.html#using-the-jenkins-kubernetes-plug-in-to-run-jobs</font>

Revision as of 20:40, 28 November 2017

External

Internal

Overview

OpenShift provides a certified Jenkins container for building Continuous Delivery pipelines. Jenkins can be deployed as a pod in OpenShift. OpenShift comes with two templates ("jerkins-ephemeral" and "jenkins-persistent", both available in the "openshift" namespace), which can be used to deploy an "ephemeral" or a "persistent" Jenkins. The "persistent" Jenkins will save its state between the pod restarts, and needs a persistent volume with sufficient storage space to be available at the time of the installation.

Once deployed, Jenkins spins up two pods: the main "jenkins" pod which contains the functionality that drives the build logic, and a "jenkins-jnlp" pod that is an auxiliary service used for master/slave communication. Why doesn't the CI/CD project have a jenkins-jnlp pod? The service exists, maybe the pod was not needed yet? There is no container template for jenkins-jnlp. The template also creates a "jenkins" service account used by the Jenkins pod to authenticate. The service account is automatically bound to the "edit" role in the target project.

The Jenkins pod can be collocated with the application it is intended to build, within the same project, or it can inhabit its own dedicated project and can provide CI/CD services to other projects, which share the common instance. The Collocated Jenkins section addresses aspects that are specific to a Jenkins instance that lives in the same OpenShift project with the application it services. The Shared Jenkins section describes the particularities of the situation when a single Jenkins instance is shared by multiple projects.

The Jenkins instance can be left with a default build environment, which is completely oblivious of OpenShift, but in this case it will attempt to run a build inside de pod and it will fail due to lack of Maven or other utilities. The alternative is to use a Kubernetes plugin build environment, which dynamically provisions Jenkins slaves on OpenShift nodes. More details are available in the Kubernetes Plugin section.

OpenShift Jenkins Docker Image

The Jenkins image intended to use with OpenShift is developed under this repository https://github.com/openshift/jenkins. The repository contains the Dockerfiles that can be used to build the image. The images are pushed to DockerHub as openshift/jenkins-2-centos7, openshift/jenkins-slave-base-centos7, openshift/jenkins-slave-maven-centos7, and openshift/jenkins-slave-nodejs-centos7 and OpenShift Container Platform integrates them with the enterprise product.

Build Environment

OpenShift Jenkins image comes pre-preconfigured to allow access to a Kubernetes CLI (kubectl) build environment, which uses the Kubernetes plugin to provision Kubernetes-based Jenkins agents.

Jenkins Build Environment.png

For more details about Jenkins build environment, see:

Jenkins Build Environment

Kubernetes Plugin

https://plugins.jenkins.io/kubernetes
https://wiki.jenkins.io/display/JENKINS/Kubernetes+Plugin
https://docs.openshift.org/latest/using_images/other_images/jenkins.html#using-the-jenkins-kubernetes-plug-in-to-run-jobs

The Kubernetes plug-in is a Jenkins extension that uses a Kubernetes cluster to dynamically provision Jenkins agents, use them to run builds and then dispose of them. It does do by using Kubernetes scheduling mechanism to optimize the load. The Jenkins images that ship with OpenShift comes with the Kubernetes plug-in pre-installed.

TODO: deplete https://docs.openshift.org/latest/using_images/other_images/jenkins.html#using-the-jenkins-kubernetes-plug-in-to-run-jobs

Collocated Jenkins

This section addresses aspects that are specific to a Jenkins instance that lives in the same OpenShift project with the application it services.

Shared Jenkins

This section describes the particularities of the situation when a single Jenkins instance is shared by multiple projects.

TO DEPLETE


Deplete anything under this.


When necessary, it scales the pipeline execution by on-demand provisioning of multiple Jenkins containers, allowing Jenkins to run many jobs in parallel. OpenShift can integrate with Git-based source code repositories. When a developer pushes code to the GIt repository, Jenkins pulls the code and performs a project build. After the build is complete, Jenkins invokes the OpenShift master node API to initiate a "source-to-image" (S2I) build. As part of the SI process, the latest project artifact is downloaded from Jenkins and included in the image that runs in the OpenShift node.

Jenkins Pods and Projects

Jenkins infrastructure can run in an arbitrary project, on a per-project basis, but a more common setup is to create a dedicated CI/CD project and configure it to perform CI/CD services for other "client" projects.

The Jenkins application that is deployed with an OpenShift template comes pre-configured for slave pods - they are configured in Jenkins system configuration as Kubernetes pods. Jenkins executes builds in separated pods in the same project it belongs. This is possible due to the Jenkins Kubernetes Plug-in. However, the builds do not use Jenkins pod resources. The slave pods included with OpenShift are the base pod to build custom slave pods, Node.js and Maven ("jenkins-slave-maven-rhel7").

OpenShift Plug-in for Jenkins

https://github.com/openshift/jenkins-plugin

What is the difference between OpenShift Plug-in for Jenkins and Jenkins Kubernetes Plug-in.

Security Considerations

Jenkins components need to access the OpenShift API exposed by the master for various operations: to access container images, to trigger a build, to check the status of a build, etc. so special privileges need to be assigned to the service account under whose credentials Jenkins runs. By default, Jenkins authenticates to the API using the "system:serviceaccount:<project-name>:default service account, where <project-name> is the name of the project the Jenkins pod runs in. The service account must be granted the "admin" role:

oc policy add-role-to-user admin system:serviceaccount:<jenkins-project-name>:default

"default" is a generic account, so in general is a good idea to created a dedicated "jenkins" service account, to be used by the Jenkins processes: "system:serviceaccount:<project-name>:jenkins. When Jenkins is created from template, the "jenkins" service account is created automatically.

oc policy add-role-to-user admin system:serviceaccount:<jenkins-project-name>:jenkins

Jenkins performs CI/CD services for other projects, so the service account running the Jenkins pods in the Jenkins project must be granted elevated privileges in the projects serviced by it:

oc policy add-role-to-user edit system:serviceaccount:<jenkins-project-name>:jenkins -n <client-project>

To list the roles associated with a service account, use oc get rolebindings or oc describe policyBindings.

Also see:

Grant Jenkins Needed Privileges for the Projects that Require CI/CD Services

TODO: OAuth authentication: https://docs.openshift.com/container-platform/latest/using_images/other_images/jenkins.html#jenkins-openshift-oauth-authentication

TODO: Standard authentication: https://docs.openshift.com/container-platform/latest/using_images/other_images/jenkins.html#jenkins-jenkins-standard-authentication

TODO: Cross-project access: https://docs.openshift.com/container-platform/latest/using_images/other_images/jenkins.html#jenkins-cross-project-access

Pipeline

https://jenkins.io/doc/book/pipeline/overview/
https://docs.openshift.com/container-platform/latest/install_config/configuring_pipeline_execution.html

Pipelines can be defined in-line in the Jenkins job, or in the source code repository, in a file named "Jenkinsfile". The pipelines are written in Groovy. Jenkins drives the pipeline, but it uses OpenShift to perform the build and the deployment, by invoking OpenShift API via "openshiftBuild", "openshiftVerifyBuild", "openshiftDeploy", "openshiftVerifyDeployment", "openshiftVerifyService". Used by the pipeline build.

The pipeline definition starts with a node() statement.

node('maven') {
...
}

defines a pipeline that runs inside of a Maven pod.

node {
...
}

defines a pipeline that executes in a Jenkins pod.

Possible node values: "maven", "nodejs", "custom".

A pipeline consists of stages, which have graphical representation in Jenkins or OpenShift UI. A stage can be used to group tasks, and they should be scoped with { and }.

Pipeline Definition

node {

 stage ("Build") {
   ...
   openshiftBuild 
                  apiURL: 'https://openshift.default.svc.cluster.local', 
                  authToken: , 
                  bldCfg: 'hello-nodejs', 
                  buildName: , 
                  checkForTriggeredDeployments: 'false', 
                  commitID: , 
                  namespace: , 
                  showBuildLogs: 'false', 
                  verbose: 'false', 
                  waitTime: 
   openshiftVerifyBuild 
                  apiURL: 'https://openshift.default.svc.cluster.local', 
                  authToken: ,
                   bldCfg: 'hello-nodejs',
                   checkForTriggeredDeployments: 
                  'false', namespace: , 
                  verbose: 'false'
   openshiftTag 
                  ...
 }
 stage ("Deploy") {
   ...
   openshiftDeploy  
                  apiURL: 'https://openshift.default.svc.cluster.local', 
                  authToken: , 
                  depCfg: 'hello-nodejs', 
                  namespace: , 
                  verbose: 'false', 
                  waitTime: 
   openshiftVerifyDeployment  
                  apiURL: 'https://openshift.default.svc.cluster.local', 
                  authToken: , 
                  depCfg: 'hello-nodejs', 
                  namespace: , 
                  replicaCount: '1',                    
                  verbose: 'false', 
                  verifyReplicaCount: 'false', 
                  waitTime: 
 }
 stage ("Verify") {
   ...
    openshiftVerifyService  
                  apiURL: 'https://openshift.default.svc.cluster.local', 
                  authToken: , 
                  namespace: , 
                  svcName: 'hello-nodejs', 
                  verbose: 'false'
 }
}

Auxiliary Tools