OpenShift CI/CD Concepts TODEPLETE: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
m (Ovidiu moved page Tmp to OpenShift CI/CD Concepts TODEPLETE without leaving a redirect)
 
(21 intermediate revisions by the same user not shown)
Line 1: Line 1:
=tmp=


=Container=
<font color=red>TODO Merge this into [[OpenShift CI/CD Concepts]]</font>




=Overview=


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. <font color=red>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.</font> 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|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|Shared Jenkins]] section describes the particularities of the situation when a single Jenkins instance is shared by multiple projects.


<font color=red>The Jenkins instance can be left with a default [[#Build_Environment|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|Kubernetes plugin]] build environment, which dynamically provisions [[Jenkins_Concepts#Slave|Jenkins slaves]] on OpenShift nodes. More details are available in the [[#Kubernetes_Plugin|Kubernetes Plugin]] section.</font>


=Jenkins=


==Jenkins Instance Lookup Process==


* Physically, a container is a reference to a [[#Layered_Image|layered filesystem image]] and some metadata about configuration ([[#Environment_Variables|environment variables]], for example). <font color=red>A running container has a name and a [[#Tag|tag]]. The tag is generally used to identify a particular release of an image.</font>
* A specific container can only exist once.
* [[#Privileged_Container|Privileged container]].
* Any output directed to stdout in a running container is captured in a log file that can be viewed with [[docker logs]] command.
* Containers are ephemeral. Any in-memory state is lost when the container stops. When a container is deleted, any data written to the container’s file system is deleted as well.


==Restart Policy==


The container's restart policy specifies how container are restarted when the docker server is restarted. It is maintained in <tt>/var/lib/docker/containers/<container-id>/hostconfig.json</tt> as:


<pre>
{ ... "RestartPolicy":{"Name":"no","MaximumRetryCount":0}, ... }
</pre>


Note that the json file must not be edited directly. If the restart policy has to be changed, that must be done with [[docker update]].
Jenkins is used by OpenShift to provide the execution engine behind [[OpenShift Concepts#Pipeline_Build|OpenShift pipeline builds]]. The first time a project defines a pipeline build configuration, OpenShift instantiates a Jenkins server using the jenkins-ephemeral template from the 'openshift' namespace to execute the pipeline. Subsequent pipeline build configurations in the project share this Jenkins server instance. The instance is not automatically removed, even if all pipeline build configurations are deleted. It must be manually deleted. The auto-provisioning configuration, as well as the template to use to instantiate the instance and other configuration details are set in the [[Master-config.yml#jenkinsPipelineConfig|jenkinsPipelineConfig]] section in [[master-config.yml]].


The policy for a specific container can be retrieved with [[Docker_inspect|docker inspect]].
==Shared Jenkins Instance==


Also see {{Internal|Docker - Start a Container Automatically|Start a Container Automatically}}
Jenkins instance(s) is/are deployed as a pod. The Jenkins pod can be deployed within the project that needs CI/CD services, or it can be deployed in a shared project, accessed by all projects that need CI/CD services. The system-wide Jenkins instance must be declared in [[Master-config.yml#Shared_Jenkins_Instance_Configuration|master-config.yaml]].


=.dockerignore=
==Build Environment==


Contains files and directories that won't be uploaded to the docker host when the image is built.
<font color=red>


OpenShift Jenkins image comes pre-preconfigured to allow access to a Kubernetes CLI (kubectl) build environment, which uses the [[#Kubernetes_Plugin|Kubernetes plugin]] to provision Kubernetes-based [[Jenkins_Concepts#Agent|Jenkins agents]].


=Mounted Volumes=
::[[Image:Jenkins_Build_Environment.png]]


Defined by the Dockerfile [[Dockerfile#VOLUME|VOLUME]] directive.
For more details about Jenkins build environment, see: {{Internal|Jenkins_Concepts#Build_Environment|Jenkins Build Environment}}
 
</font>
 
==Pipeline==
 
An ''OpenShift Jenkins pipeline'' is a  [[Jenkins_Concepts#Pipeline|Jenkins Pipeline]] .... <font color=red>'''TODO'''</font>. OpenShift Jenkins pipeline are an essential component of the [[OpenShift Concepts#Pipeline_Build|OpenShift pipeline builds]].
 
<font color=red>'''TODO'''</font>
 
 
 
 
 
{{External|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 [[OpenShift Concepts#Pipeline_Build|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 ("<font color=darkblue>'''Build'''</font>") {
    ...
    <font color=teal>'''openshiftBuild'''</font>
                  apiURL: 'https&#58;//openshift.default.svc.cluster.local',
                  authToken: '',
                  bldCfg: 'hello-nodejs',
                  buildName: '',
                  checkForTriggeredDeployments: 'false',
                  commitID: '',
                  namespace: '',
                  showBuildLogs: 'false',
                  verbose: 'false',
                  waitTime: ''
    <font color=teal>'''openshiftVerifyBuild'''</font>
                  apiURL: 'https&#58;//openshift.default.svc.cluster.local',
                  authToken: '',
                    bldCfg: 'hello-nodejs',
                    checkForTriggeredDeployments:
                  'false', namespace: '',
                  verbose: 'false'
    <font color=teal>'''openshiftTag'''</font>
                  ...
  }
  stage ("<font color=darkblue>'''Deploy'''</font>") {
    ...
    <font color=teal>'''openshiftDeploy'''</font> 
                  apiURL: 'https&#58;//openshift.default.svc.cluster.local',
                  authToken: '',
                  depCfg: 'hello-nodejs',
                  namespace: '',
                  verbose: 'false',
                  waitTime: ''
    <font color=teal>'''openshiftVerifyDeployment'''</font> 
                  apiURL: 'https&#58;//openshift.default.svc.cluster.local',
                  authToken: '',
                  depCfg: 'hello-nodejs',
                  namespace: '',
                  replicaCount: '1',                   
                  verbose: 'false',
                  verifyReplicaCount: 'false',
                  waitTime: ''
  }
  stage ("<font color=darkblue>'''Verify'''</font>") {
    ...
    <font color=teal>'''openshiftVerifyService'''</font> 
                  apiURL: 'https&#58;//openshift.default.svc.cluster.local',
                  authToken: '',
                  namespace: '',
                  svcName: 'hello-nodejs',
                  verbose: 'false'
  }
}
 
=OpenShift Jenkins Plugin=
 
{{External|https://github.com/openshift/jenkins-plugin}}
 
The OpenShift Jenkins Plugin is another Jenkins extension that exposes OpenShift-specific build and post-build actions in Jenkins:
 
::[[Image:OpenShift_Jenkins_Plugin.png]]
 
A step-by-step example of how to use the OpenShift Jenkins Plugin is available here: {{Internal|OpenShift CI/CD Operations - Collocated Persistent Jenkins Set Up|Collocated Jenkins Deployment and Set Up}}
 
=OpenShift Pipeline Plugin=
 
=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.
 
This is an example of a project that sets up a collocated Jenkins instance and uses it to build and deploy an application:
 
{{Internal|OpenShift CI/CD Operations - Collocated Persistent Jenkins Set Up|Collocated Jenkins Deployment and Set Up}}
 
=Shared Jenkins=
 
This section describes the particularities of the situation when a single Jenkins instance is shared by multiple projects.
 
<font color=red>'''TODO''': [[#Cross-Project_Access]].</font>
 
=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 associated with the Jenkins deployment. By default, Jenkins authenticates to the API using the "system:serviceaccount:<''project-name''>:default [[OpenShift_Security_Concepts#Service_Account|service account]], where <''project-name''> is the name of the project the Jenkins pod runs in. The service account must be granted the "edit" role. "default" is a generic account, so in some cases it may be better to created a dedicated "jenkins" service account, to be used by the Jenkins processes: "system:serviceaccount:<''project-name''>:jenkins. The [[OpenShift_CI/CD_Concepts#OpenShift_Jenkins_Templates|standard Jenkins templates that come with OpenShift]] create the "jenkins" service account and give it the appropriate privileges automatically.
 
* <font color=red>'''TODO''': OAuth authentication: https://docs.openshift.com/container-platform/latest/using_images/other_images/jenkins.html#jenkins-openshift-oauth-authentication</font>
* <font color=red>'''TODO''': Standard authentication: https://docs.openshift.com/container-platform/latest/using_images/other_images/jenkins.html#jenkins-jenkins-standard-authentication</font>
 
==Cross-Project Access==
 
If Jenkins is configured to perform CI/CD services for other projects, the service account associated with the Jenkins pods in the Jenkins project must be granted elevated privileges in the client projects:
 
[[Oc_policy#add-role-to-user|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 [[OpenShift_Security_Operations#List_All_Project_Role_Bindings|oc get rolebindings or oc describe policyBindings]].
 
* <font color=red>'''TODO''': Cross-project access: https://docs.openshift.com/container-platform/latest/using_images/other_images/jenkins.html#jenkins-cross-project-access</font>
 
==OpenShift Login Plugin==
 
Authentication is managed by default by the OpenShift Login plugin, when the access is done via a public [[OpenShift Concepts#Route|route]]. If you intend to log into Jenkins via the [[OpenShift Concepts#Service|service]] IP, you will need to annotate the Jenkins service account with a redirect URL so that the OAuth server's whitelist is updated and it allows the login to complete.
oc annotate sa/jenkins serviceaccounts.openshift.io/oauth-redirecturi.1=http&#58;//<''jenkins_service_ip'':''jenkins_service_port''>/securityRealm/finishLogin --overwrite
 
=TO DEPLETE=
 
 
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_.28S2I.29_Build|"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.
 
=Auxiliary Tools=
 
* [[OpenShift Nexus|Nexus]]
* [[OpenShift Gogs|Gogs]]
* [[OpenShift SonarQube|SonarQube]]

Latest revision as of 18:33, 12 December 2017

TODO Merge this into OpenShift CI/CD Concepts


Overview

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.

Jenkins

Jenkins Instance Lookup Process

Jenkins is used by OpenShift to provide the execution engine behind OpenShift pipeline builds. The first time a project defines a pipeline build configuration, OpenShift instantiates a Jenkins server using the jenkins-ephemeral template from the 'openshift' namespace to execute the pipeline. Subsequent pipeline build configurations in the project share this Jenkins server instance. The instance is not automatically removed, even if all pipeline build configurations are deleted. It must be manually deleted. The auto-provisioning configuration, as well as the template to use to instantiate the instance and other configuration details are set in the jenkinsPipelineConfig section in master-config.yml.

Shared Jenkins Instance

Jenkins instance(s) is/are deployed as a pod. The Jenkins pod can be deployed within the project that needs CI/CD services, or it can be deployed in a shared project, accessed by all projects that need CI/CD services. The system-wide Jenkins instance must be declared in master-config.yaml.

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

Pipeline

An OpenShift Jenkins pipeline is a Jenkins Pipeline .... TODO. OpenShift Jenkins pipeline are an essential component of the OpenShift pipeline builds.

TODO



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'
 }
}

OpenShift Jenkins Plugin

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

The OpenShift Jenkins Plugin is another Jenkins extension that exposes OpenShift-specific build and post-build actions in Jenkins:

OpenShift Jenkins Plugin.png

A step-by-step example of how to use the OpenShift Jenkins Plugin is available here:

Collocated Jenkins Deployment and Set Up

OpenShift Pipeline Plugin

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.

This is an example of a project that sets up a collocated Jenkins instance and uses it to build and deploy an application:

Collocated Jenkins Deployment and Set Up

Shared Jenkins

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

TODO: #Cross-Project_Access.

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 associated with the Jenkins deployment. 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 "edit" role. "default" is a generic account, so in some cases it may be better to created a dedicated "jenkins" service account, to be used by the Jenkins processes: "system:serviceaccount:<project-name>:jenkins. The standard Jenkins templates that come with OpenShift create the "jenkins" service account and give it the appropriate privileges automatically.

Cross-Project Access

If Jenkins is configured to perform CI/CD services for other projects, the service account associated with the Jenkins pods in the Jenkins project must be granted elevated privileges in the client projects:

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.

OpenShift Login Plugin

Authentication is managed by default by the OpenShift Login plugin, when the access is done via a public route. If you intend to log into Jenkins via the service IP, you will need to annotate the Jenkins service account with a redirect URL so that the OAuth server's whitelist is updated and it allows the login to complete.

oc annotate sa/jenkins serviceaccounts.openshift.io/oauth-redirecturi.1=http://<jenkins_service_ip:jenkins_service_port>/securityRealm/finishLogin --overwrite

TO DEPLETE

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.

Auxiliary Tools