OpenShift CI/CD Concepts: Difference between revisions
Line 157: | Line 157: | ||
* [[OpenShift Nexus|Nexus]] | * [[OpenShift Nexus|Nexus]] | ||
* [[OpenShift Gogs|Gogs]] | * [[OpenShift Gogs|Gogs]] | ||
* [[OpenShift | * [[OpenShift SonarQube|SonarQube]] |
Revision as of 17:53, 28 November 2017
External
- https://docs.openshift.com/container-platform/latest/using_images/other_images/jenkins.html#jenkins-as-s2i-builder
- https://blog.openshift.com/cicd-with-openshift/, youtu.be demos: 65BnTLcDAJI, wSFyg6Etwx8
- https://github.com/OpenShiftDemos/openshift-cd-demo, https://github.com/OpenShiftDemos/openshift-cd-demo/tree/ocp-3.5
Internal
Overview
OpenShift provides a certified Jenkins container for building Continuous Delivery pipelines. 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
The Jenkins Docker image for OpenShift: https://github.com/openshift/jenkins
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").
Jenkins Kubernetes Plug-in
OpenShift Plug-in for Jenkins
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:
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
State Persistence Considerations
The "jenkins-persistent" template requires a persistent volume, which is configured upon creation of the new application.
Pipeline
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' } }