+ Tools +
+Required tools for building and running Jenkins Operator +
+diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 00000000..d8c28b72 --- /dev/null +++ b/docs/404.html @@ -0,0 +1,122 @@ + + +
+ + + + + + + + + + + + + + + + + + + +Oops! This page doesn't exist. Try going back to our home page.
+ +You can learn how to make a 404 page like this in Custom 404 Pages.
+
+
+ Some of the problems we want to solve:
+
Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over).
There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs.
+ +There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs.
+ +++ +There should be no margin above this first sentence.
+ +Blockquotes should be a lighter gray with a border along the left side in the secondary color.
+ +There should be no margin below this final sentence.
+
This is a normal paragraph following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width.
+ +Lorem markdownum tuta hospes stabat; idem saxum facit quaterque repetito +occumbere, oves novem gestit haerebat frena; qui. Respicit recurvam erat: +pignora hinc reppulit nos aut, aptos, ipsa.
+ +Meae optatos passa est Epiros utiliter Talibus niveis, hoc lata, edidit. +Dixi ad aestum.
+ +++ +This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+
This is a code block following a header.
+
+
+| What | +Follows | +
|---|---|
| A table | +A header | +
| A table | +A header | +
| A table | +A header | +
There’s a horizontal rule above and below this.
+ +Here is an unordered list:
+ +And an ordered list:
+ +And an unordered task list:
+ +And a “mixed” task list:
+ +And a nested list:
+ +Definition lists can be used with Markdown syntax. Definition terms are bold.
+ +Tables should have bold headings and alternating shaded rows.
+ +| Artist | +Album | +Year | +
|---|---|---|
| Michael Jackson | +Thriller | +1982 | +
| Prince | +Purple Rain | +1984 | +
| Beastie Boys | +License to Ill | +1986 | +
If a table is too wide, it should scroll horizontally.
+ +| Artist | +Album | +Year | +Label | +Awards | +Songs | +
|---|---|---|---|---|---|
| Michael Jackson | +Thriller | +1982 | +Epic Records | +Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | +Wanna Be Startin’ Somethin’, Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life | +
| Prince | +Purple Rain | +1984 | +Warner Brothers Records | +Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | +Let’s Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I’m a Star, Purple Rain | +
| Beastie Boys | +License to Ill | +1986 | +Mercury Records | +noawardsbutthistablecelliswide | +Rhymin & Stealin, The New Style, She’s Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill | +
Code snippets like var foo = "bar"; can be shown inline.
Also, this should vertically align with thisand this.
Code can also be shown in a block element.
+ +foo := "bar";
+bar := "foo";
+
+
+Code can also use syntax highlighting.
+func main() {
+ input := `var foo = "bar";`
+
+ lexer := lexers.Get("javascript")
+ iterator, _ := lexer.Tokenise(nil, input)
+ style := styles.Get("github")
+ formatter := html.New(html.WithLineNumbers())
+
+ var buff bytes.Buffer
+ formatter.Format(&buff, style, iterator)
+
+ fmt.Println(buff.String())
+}Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
+
+
+Inline code inside table cells should still be distinguishable.
+ +| Language | +Code | +
|---|---|
| Javascript | +var foo = "bar"; |
+
| Ruby | +foo = "bar"{ |
+
Small images should be shown at their actual size.
+ +Large images should always scale down and fit in the content container.
+ ++ +
Add some sections here to see how the ToC looks like. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +This is the final element on the page and there should be no margin below this.
+
+
+
+
+ This is a typical blog post that includes images.
+ +The front matter specifies the date of the blog post, its title, a short description that will be displayed on the blog landing page, and its author.
+ +Here’s an image (featured-sunset-get.png) that includes a byline and a caption.
+
+
+Fetch and scale an image in the upcoming Hugo 0.43.
+
Photo: Riona MacNamara / CC-BY-CA
The front matter of this post specifies properties to be assigned to all image resources:
+ +resources:
+- src: "**.{png,jpg}"
+ title: "Image #:counter"
+ params:
+ byline: "Photo: Riona MacNamara / CC-BY-CA"
+
+
+To include the image in a page, specify its details like this:
+ +
+
+
+
+
+
+
+
+
+
+
+
+Fetch and scale an image in the upcoming Hugo 0.43.
+
Photo: Riona MacNamara / CC-BY-CA
+
+
+
+
+
+The image will be rendered at the size and byline specified in the front matter.
+ + + +Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over).
There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs.
+ +There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs.
+ +++ +There should be no margin above this first sentence.
+ +Blockquotes should be a lighter gray with a border along the left side in the secondary color.
+ +There should be no margin below this final sentence.
+
This is a normal paragraph following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width.
+ +Lorem markdownum tuta hospes stabat; idem saxum facit quaterque repetito +occumbere, oves novem gestit haerebat frena; qui. Respicit recurvam erat: +pignora hinc reppulit nos aut, aptos, ipsa.
+ +Meae optatos passa est Epiros utiliter Talibus niveis, hoc lata, edidit. +Dixi ad aestum.
+ +++ +This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+
This is a code block following a header.
+
+
+| What | +Follows | +
|---|---|
| A table | +A header | +
| A table | +A header | +
| A table | +A header | +
There’s a horizontal rule above and below this.
+ +Here is an unordered list:
+ +And an ordered list:
+ +And an unordered task list:
+ +And a “mixed” task list:
+ +And a nested list:
+ +Definition lists can be used with Markdown syntax. Definition terms are bold.
+ +Tables should have bold headings and alternating shaded rows.
+ +| Artist | +Album | +Year | +
|---|---|---|
| Michael Jackson | +Thriller | +1982 | +
| Prince | +Purple Rain | +1984 | +
| Beastie Boys | +License to Ill | +1986 | +
If a table is too wide, it should scroll horizontally.
+ +| Artist | +Album | +Year | +Label | +Awards | +Songs | +
|---|---|---|---|---|---|
| Michael Jackson | +Thriller | +1982 | +Epic Records | +Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | +Wanna Be Startin’ Somethin’, Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life | +
| Prince | +Purple Rain | +1984 | +Warner Brothers Records | +Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | +Let’s Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I’m a Star, Purple Rain | +
| Beastie Boys | +License to Ill | +1986 | +Mercury Records | +noawardsbutthistablecelliswide | +Rhymin & Stealin, The New Style, She’s Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill | +
Code snippets like var foo = "bar"; can be shown inline.
Also, this should vertically align with thisand this.
Code can also be shown in a block element.
+ +foo := "bar";
+bar := "foo";
+
+
+Code can also use syntax highlighting.
+func main() {
+ input := `var foo = "bar";`
+
+ lexer := lexers.Get("javascript")
+ iterator, _ := lexer.Tokenise(nil, input)
+ style := styles.Get("github")
+ formatter := html.New(html.WithLineNumbers())
+
+ var buff bytes.Buffer
+ formatter.Format(&buff, style, iterator)
+
+ fmt.Println(buff.String())
+}Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
+
+
+Inline code inside table cells should still be distinguishable.
+ +| Language | +Code | +
|---|---|
| Javascript | +var foo = "bar"; |
+
| Ruby | +foo = "bar"{ |
+
Small images should be shown at their actual size.
+ +Large images should always scale down and fit in the content container.
+ ++ +
Add some sections here to see how the ToC looks like. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
+ +This is the final element on the page and there should be no margin below this.
+
+
+
+
+ Saturday, October 06, 2018 in News
+ + + + + + +Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over). +There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. …
+ +Saturday, October 06, 2018 in News
+ + + + + + + +
+
+ This is a typical blog post that includes images. +The front matter specifies the date of the blog post, its title, a short description that will be displayed on the blog landing page, and its author. +Including images Here’s an image …
+ +Thursday, January 04, 2018 in Releases
+ + + + + + +Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over). +There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. …
+ +Saturday, October 06, 2018 in News
+ + + + + + +Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over). +There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. …
+ +Saturday, October 06, 2018 in News
+ + + + + + + +
+
+ This is a typical blog post that includes images. +The front matter specifies the date of the blog post, its title, a short description that will be displayed on the blog landing page, and its author. +Including images Here’s an image …
+ +Thursday, January 04, 2018 in Releases
+ + + + + + +Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over). +There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. …
+ +Jenkins Operator is an open source project that anyone in the community can use, improve, and enjoy. We'd love you to join us! Here's a few ways to find out what's happening and get involved. +
+Using or want to use Jenkins Operator? Find out more here: + +
If you want to get more involved by contributing to Jenkins Operator, join us here: + +
You can find out how to contribute to these docs in our Contribution Guidelines. +
This document explains how to setup your development environment.
+ +mkdir -p $GOPATH/src/github.com/jenkinsci
+cd $GOPATH/src/github.com/jenkinsci/
+git clone git@github.com:jenkinsci/kubernetes-operator.git
+cd kubernetes-operator
+make go-dependenciesBuild and run jenkins-operator locally:
+make minikube-run EXTRA_ARGS='--minikube --local'Once minikube and jenkins-operator are up and running, apply Jenkins custom resource:
+kubectl apply -f deploy/crds/jenkins_v1alpha2_jenkins_cr.yaml
+kubectl get jenkins -o yaml
+kubectl get poYou can also run the controller locally and make it listen to a remote Kubernetes server.
+make run NAMESPACE=default KUBECTL_CONTEXT=remote-k8s EXTRA_ARGS='--kubeconfig ~/.kube/config'Once minikube and jenkins-operator are up and running, apply Jenkins custom resource:
+kubectl --context remote-k8s --namespace default apply -f deploy/crds/jenkins_v1alpha2_jenkins_cr.yaml
+kubectl --context remote-k8s --namespace default get jenkins -o yaml
+kubectl --context remote-k8s --namespace default get poRun unit tests:
+make testRun e2e tests with minikube:
+make minikube-start
+eval $(minikube docker-env)
+make build e2eRun the specific e2e test:
+make build e2e E2E_TEST_SELECTOR='^TestConfiguration$'At first, you need to start minikube:
+$ make minikube-start
+$ eval $(minikube docker-env) Build Docker image inside provided Linux container by:
+$ make indockerBuild jenkins-operator inside container using:
+$ make buildThen exit the container and run:
+ +make e2e
+
+
+To be able to work with the docker daemon on minikube machine run the following command before building an image:
eval $(minikube docker-env)pkg/apis/jenkinsio/*/jenkins_types.go has changedRun:
+make deepcopy-genminikube service jenkins-operator-http-<cr_name> --url
+kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.user}' | base64 -d
+kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.password}' | base64 -dRequired tools for building and running Jenkins Operator +
+This document explains how to install the Go tools used by the development process.
+ +export GOPATH=/home/go # example value
+export GOROOT=/usr/lib/go-1.12 # example value
+export PATH=$GOPATH/bin:$PATHgo get golang.org/x/tools/cmd/goimports
+cd $GOPATH/src/golang.org/x/tools/cmd/goimports
+go build
+go install
+
+
+go get -u golang.org/x/lint/golint
+cd $GOPATH/src/golang.org/x/lint/golint
+go build
+go install
+
+
+go get github.com/mrtazz/checkmake
+cd $GOPATH/src/github.com/mrtazz/checkmake
+go build
+go install
+
+
+mkdir -p $GOPATH/src/github.com/dominikh/
+cd $GOPATH/src/github.com/dominikh/
+git clone https://github.com/dominikh/go-tools.git
+cd $GOPATH/src/github.com/dominikh/go-tools/staticcheck
+go build
+go install
+
+
+
+
+ This document describes a getting started guide for jenkins-operator
+ +Prepare your Kubernetes cluster and set up access. +Once you have running Kubernetes cluster you can focus on installing jenkins-operator according to the Installation guide.
+ +How to work with jenkins-operator legacy version. We recommend migration to v0.2.0 version +
+How to work with jenkins-operator latest version +
+Azure AKS managed Kubernetes service adds to every pod the following envs:
+- name: KUBERNETES_PORT_443_TCP_ADDR
+ value:
+- name: KUBERNETES_PORT
+ value: tcp://
+- name: KUBERNETES_PORT_443_TCP
+ value: tcp://
+- name: KUBERNETES_SERVICE_HOST
+ value:The operator is aware of it and omits these envs when checking if Jenkins pod envs have been changed. It prevents +restart Jenkins pod over and over again.
+ + + +Jenkins operator uses job-dsl and kubernetes-credentials-provider plugins for configuring jobs +and deploy keys.
+ +First you have to prepare pipelines and job definition in your GitHub repository using the following structure:
+ +cicd/
+├── jobs
+│ └── build.jenkins
+└── pipelines
+ └── build.jenkins
+
+
+cicd/jobs/build.jenkins it’s a job definition:
+ +#!/usr/bin/env groovy
+
+pipelineJob('build-jenkins-operator') {
+ displayName('Build jenkins-operator')
+
+ definition {
+ cpsScm {
+ scm {
+ git {
+ remote {
+ url('https://github.com/jenkinsci/kubernetes-operator.git')
+ credentials('jenkins-operator')
+ }
+ branches('*/master')
+ }
+ }
+ scriptPath('cicd/pipelines/build.jenkins')
+ }
+ }
+}
+
+
+cicd/jobs/build.jenkins it’s an actual Jenkins pipeline:
+ +#!/usr/bin/env groovy
+
+def label = "build-jenkins-operator-${UUID.randomUUID().toString()}"
+def home = "/home/jenkins"
+def workspace = "${home}/workspace/build-jenkins-operator"
+def workdir = "${workspace}/src/github.com/jenkinsci/kubernetes-operator/"
+
+podTemplate(label: label,
+ containers: [
+ containerTemplate(name: 'jnlp', image: 'jenkins/jnlp-slave:alpine'),
+ containerTemplate(name: 'go', image: 'golang:1-alpine', command: 'cat', ttyEnabled: true),
+ ],
+ envVars: [
+ envVar(key: 'GOPATH', value: workspace),
+ ],
+ ) {
+
+ node(label) {
+ dir(workdir) {
+ stage('Init') {
+ timeout(time: 3, unit: 'MINUTES') {
+ checkout scm
+ }
+ container('go') {
+ sh 'apk --no-cache --update add make git gcc libc-dev'
+ }
+ }
+
+ stage('Dep') {
+ container('go') {
+ sh 'make dep'
+ }
+ }
+
+ stage('Test') {
+ container('go') {
+ sh 'make test'
+ }
+ }
+
+ stage('Build') {
+ container('go') {
+ sh 'make build'
+ }
+ }
+ }
+ }
+}
+
+
+Jenkins Seed Jobs are configured using Jenkins.spec.seedJobs section from your custom resource manifest:
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ seedJobs:
+ - id: jenkins-operator
+ targets: "cicd/jobs/*.jenkins"
+ description: "Jenkins Operator repository"
+ repositoryBranch: master
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
+
+
+jenkins-operator will automatically discover and configure all seed jobs.
+ +You can verify if deploy keys were successfully configured in Jenkins Credentials tab.
+ +
You can verify if your pipelines were successfully configured in Jenkins Seed Job console output.
+ +
If your GitHub repository is private you have to configure SSH or username/password authentication.
+ +There are two methods of SSH private key generation:
+$ openssl genrsa -out <filename> 2048or
+$ ssh-keygen -t rsa -b 2048
+$ ssh-keygen -p -f <filename> -m pemThen copy content from generated file.
+ +If you want to upload your public key to your Git server you need to extract it.
+ +If key was generated by openssl then you need to type this to extract public key:
$ openssl rsa -in <filename> -pubout > <filename>.pubIf key was generated by ssh-keygen the public key content is located in
Configure seed job like:
+ +apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ seedJobs:
+ - id: jenkins-operator-ssh
+ credentialType: basicSSHUserPrivateKey
+ credentialID: k8s-ssh
+ targets: "cicd/jobs/*.jenkins"
+ description: "Jenkins Operator repository"
+ repositoryBranch: master
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git
+
+
+and create Kubernetes Secret(name of secret should be the same from credentialID field):
apiVersion: v1
+kind: Secret
+metadata:
+ name: k8s-ssh
+stringData:
+ privateKey: |
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIJKAIBAAKCAgEAxxDpleJjMCN5nusfW/AtBAZhx8UVVlhhhIKXvQ+dFODQIdzO
+ oDXybs1zVHWOj31zqbbJnsfsVZ9Uf3p9k6xpJ3WFY9b85WasqTDN1xmSd6swD4N8
+ ...
+ username: github_user_name
+
+
+Configure seed job like:
+ +apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ seedJobs:
+ - id: jenkins-operator-user-pass
+ credentialType: usernamePassword
+ credentialID: k8s-user-pass
+ targets: "cicd/jobs/*.jenkins"
+ description: "Jenkins Operator repository"
+ repositoryBranch: master
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
+
+
+and create Kubernetes Secret(name of secret should be the same from credentialID field):
apiVersion: v1
+kind: Secret
+metadata:
+ name: k8s-user-pass
+stringData:
+ username: github_user_name
+ password: password_or_token
+
+
+The operator automatically generate Jenkins user name and password and stores it in Kubernetes secret named
+jenkins-operator-credentials-<cr_name> in namespace where Jenkins CR has been deployed.
If you want change it you can override the secret:
+apiVersion: v1
+kind: Secret
+metadata:
+ name: jenkins-operator-credentials-<cr-name>
+ namespace: <namespace>
+data:
+ user: <base64-encoded-new-username>
+ password: <base64-encoded-new-password>If needed jenkins-operator will restart Jenkins master pod and then you can login with the new user and password +credentials.
+ +The default command for the Jenkins master container jenkins/jenkins:lts looks like:
command:
+- bash
+- -c
+- /var/jenkins/scripts/init.sh && /sbin/tini -s -- /usr/local/bin/jenkins.shThe script/var/jenkins/scripts/init.sh is provided be the operator and configures init.groovy.d(creates Jenkins user)
+and installs plugins.
+The /sbin/tini -s -- /usr/local/bin/jenkins.sh command runs the Jenkins master main process.
You can overwrite it in the following pattern:
+command:
+- bash
+- -c
+- /var/jenkins/scripts/init.sh && <custom-code-here> && /sbin/tini -s -- /usr/local/bin/jenkins.shBackup and restore is done by container sidecar.
+ +Save to file pvc.yaml:
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: <pvc_name>
+ namespace: <namesapce>
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 500GiRun command:
+$ kubectl -n <namesapce> create -f pvc.yamlapiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: <cr_name>
+ namespace: <namespace>
+spec:
+ master:
+ securityContext:
+ runAsUser: 1000
+ fsGroup: 1000
+ containers:
+ - name: jenkins-master
+ image: jenkins/jenkins:lts
+ - name: backup # container responsible for backup and restore
+ env:
+ - name: BACKUP_DIR
+ value: /backup
+ - name: JENKINS_HOME
+ value: /jenkins-home
+ - name: BACKUP_COUNT
+ value: "3" # keep only the 2 most recent backups
+ image: virtuslab/jenkins-operator-backup-pvc:v0.0.6 # look at backup/pvc directory
+ imagePullPolicy: IfNotPresent
+ volumeMounts:
+ - mountPath: /jenkins-home # Jenkins home volume
+ name: jenkins-home
+ - mountPath: /backup # backup volume
+ name: backup
+ volumes:
+ - name: backup # PVC volume where backups will be stored
+ persistentVolumeClaim:
+ claimName: <pvc_name>
+ backup:
+ containerName: backup # container name is responsible for backup
+ action:
+ exec:
+ command:
+ - /home/user/bin/backup.sh # this command is invoked on "backup" container to make backup, for example /home/user/bin/backup.sh <backup_number>, <backup_number> is passed by operator
+ interval: 30 # how often make backup in seconds
+ makeBackupBeforePodDeletion: true # make backup before pod deletion
+ restore:
+ containerName: backup # container name is responsible for restore backup
+ action:
+ exec:
+ command:
+ - /home/user/bin/restore.sh # this command is invoked on "backup" container to make restore backup, for example /home/user/bin/restore.sh <backup_number>, <backup_number> is passed by operator
+ #recoveryOnce: <backup_number> # if want to restore specific backup configure this field and then Jenkins will be restarted and desired backup will be restoredJenkins can be customized using groovy scripts or configuration as code plugin. All custom configuration is stored in
+the jenkins-operator-user-configuration-
jenkins-operator creates jenkins-operator-user-configuration-PASSWORD then you can use it in
+Configuration as Plugin as adminAddress: "${PASSWORD}".
kubectl get secret jenkins-operator-user-configuration-<cr_name> -o yaml
+
+kind: Secret
+apiVersion: v1
+type: Opaque
+metadata:
+ name: jenkins-operator-user-configuration-<cr_name>
+ namespace: default
+data:
+ SECRET_JENKINS_ADMIN_ADDRESS: YXNkZgo=
+
+
+
+kubectl get configmap jenkins-operator-user-configuration-<cr_name> -o yaml
+
+apiVersion: v1
+data:
+ 1-configure-theme.groovy: |2
+ import jenkins.*
+ import jenkins.model.*
+ import hudson.*
+ import hudson.model.*
+ import org.jenkinsci.plugins.simpletheme.ThemeElement
+ import org.jenkinsci.plugins.simpletheme.CssTextThemeElement
+ import org.jenkinsci.plugins.simpletheme.CssUrlThemeElement
+
+ Jenkins jenkins = Jenkins.getInstance()
+
+ def decorator = Jenkins.instance.getDescriptorByType(org.codefirst.SimpleThemeDecorator.class)
+
+ List<ThemeElement> configElements = new ArrayList<>();
+ configElements.add(new CssTextThemeElement("DEFAULT"));
+ configElements.add(new CssUrlThemeElement("https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-light-green.css"));
+ decorator.setElements(configElements);
+ decorator.save();
+
+ jenkins.save()
+ 1-system-message.yaml: |2
+ jenkins:
+ systemMessage: "Configuration as Code integration works!!!"
+ adminAddress: "${SECRET_JENKINS_ADMIN_ADDRESS}"
+kind: ConfigMap
+metadata:
+ name: jenkins-operator-user-configuration-<cr_name>
+ namespace: default
+
+
+When jenkins-operator-user-configuration-
Edit CR under spec.master.plugins:
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ master:
+ plugins:
+ - name: simple-theme-plugin
+ version: 0.5.1
+
+
+Under spec.master.basePlugins you can find plugins for valid jenkins-operator work:
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ master:
+ basePlugins:
+ - name: kubernetes
+ version: 1.18.3
+ - name: workflow-job
+ version: "2.34"
+ - name: workflow-aggregator
+ version: "2.6"
+ - name: git
+ version: 3.12.0
+ - name: job-dsl
+ version: "1.76"
+ - name: configuration-as-code
+ version: "1.29"
+ - name: configuration-as-code-support
+ version: "1.19"
+ - name: kubernetes-credentials-provider
+ version: 0.12.1You can change version of them.
+ +Then jenkins-operator will automatically install plugins after Jenkins master pod restart.
+ + + +Once jenkins-operator is up and running let’s deploy actual Jenkins instance. +Create manifest ie. jenkins_instance.yaml with following data and save it on drive.
+apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ master:
+ containers:
+ - name: jenkins-master
+ image: jenkins/jenkins:lts
+ imagePullPolicy: Always
+ livenessProbe:
+ failureThreshold: 12
+ httpGet:
+ path: /login
+ port: http
+ scheme: HTTP
+ initialDelaySeconds: 80
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /login
+ port: http
+ scheme: HTTP
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ limits:
+ cpu: 1500m
+ memory: 3Gi
+ requests:
+ cpu: "1"
+ memory: 500Mi
+ seedJobs:
+ - id: jenkins-operator
+ targets: "cicd/jobs/*.jenkins"
+ description: "Jenkins Operator repository"
+ repositoryBranch: master
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.gitDeploy Jenkins to K8s:
+kubectl create -f jenkins_instance.yamlWatch Jenkins instance being created:
+kubectl get pods -wGet Jenkins credentials:
+kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.user}' | base64 -d
+kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.password}' | base64 -dConnect to Jenkins (minikube):
+minikube service jenkins-operator-http-<cr_name> --urlConnect to Jenkins (actual Kubernetes cluster):
+kubectl port-forward jenkins-<cr_name> 8080:8080Then open browser with address http://localhost:8080.
+
Turn on debug in jenkins-operator deployment:
+sed -i 's|\(args:\).*|\1\ ["--debug"\]|' deploy/operator.yaml
+kubectl apply -f deploy/operator.yamlWatch Kubernetes events:
+kubectl get events --sort-by='{.lastTimestamp}'Verify Jenkins master logs:
+kubectl logs -f jenkins-<cr_name>Verify jenkins-operator logs:
+kubectl logs deployment/jenkins-operatorDelete Jenkins master pod and wait for the new one to come up:
+kubectl delete pod jenkins-<cr_name>This document describes a getting started guide for jenkins-operator v0.1.1 and an additional configuration.
Prepare your Kubernetes cluster and set up access. +Once you have running Kubernetes cluster you can focus on installing jenkins-operator according to the Installation guide.
+ +Deploy production ready Jenkins Operator manifest +
+How to configure Jenkins with Operator +
+How to customize Jenkins +
+Additional configuration for Azure Kubernetes Service +
+Prevent job history loss +
+How to deal with jenkins-operator problems +
+API Schema definitions for Jenkins CR +
+How to migrate to new CRD manifest +
+Please not that CRD manifests are global, not namespaced, so every jenkins operator running on the cluster +will be impacted by the new CRD manifest. Multiple operator instances with different versions should continue to work.
+ +Run command:
+$ kubectl -n <namespace> scale deployment.apps/jenkins-operator --replicas=0
+deployment.apps/jenkins-operator scaledDesired state:
+$ kubectl -n <namespace> get po
+No resources found.Run command:
+$ kubectl -n <namespace> get po
+NAME READY STATUS RESTARTS AGE
+jenkins-operator-<cr_name> 2/2 Running 0 3m35s
+$ kubectl -n <namespace> get delete po jenkins-operator-<cr_name>
+pod "jenkins-operator-<cr_name>" deletedDesired state:
+$ kubectl -n <namespace> get po
+No resources found.Run command:
+$ kubectl -n <namespace> get jenkins <cr_name> -o yaml > jenkins.yamlChange apiVersion to apiVersion: jenkins.io/v1alpha2
New plugin format without dependent plugins:
+ +spec.master.basePlugins example:
spec:
+master:
+basePlugins:
+ - name: a-plugin-name
+ version: "1.0.0"
+ ...
+spec.master.plugins example:
+spec:
+master:
+plugins:
+ - name: a-plugin-name
+ version: "1.0.0"
+...
+Move Jenkins master container properties to spec.master.containers[jenkins-master] (non exhaustive list):
+- spec.master.image -> spec.master.containers[jenkins-master].image
+- spec.master.imagePullPolicy -> spec.master.containers[jenkins-master].imagePullPolicy
+- spec.master.livenessProbe -> spec.master.containers[jenkins-master].livenessProbe
+- spec.master.readinessProbe -> spec.master.containers[jenkins-master].readinessProbe
+- spec.master.resources -> spec.master.containers[jenkins-master].resources
+- spec.master.env -> spec.master.containers[jenkins-master].env
spec:
+ master:
+ containers:
+ - name: jenkins-master
+ image: jenkins/jenkins:lts
+ ...
+
+
+See also the examples bellow for more details. For even more details please look at the source code. +Code that defines the data structures can be found here
+ +Old format:
+apiVersion: jenkins.io/v1alpha1
+kind: Jenkins
+metadata:
+ name: <cr_name>
+ namespace: <namespace>
+spec:
+ master:
+ basePlugins:
+ configuration-as-code:1.17:
+ - configuration-as-code-support:1.17
+ git:3.10.0:
+ - apache-httpcomponents-client-4-api:4.5.5-3.0
+ - credentials:2.1.19
+ - display-url-api:2.3.1
+ - git-client:2.7.7
+ - jsch:0.1.55
+ - junit:1.28
+ - mailer:1.23
+ - matrix-project:1.14
+ - scm-api:2.4.1
+ - script-security:1.59
+ - ssh-credentials:1.16
+ - structs:1.19
+ - workflow-api:2.34
+ - workflow-scm-step:2.7
+ - workflow-step-api:2.19
+ job-dsl:1.74:
+ - script-security:1.59
+ - structs:1.19
+ kubernetes-credentials-provider:0.12.1:
+ - credentials:2.1.19
+ - structs:1.19
+ - variant:1.2
+ kubernetes:1.15.5:
+ - apache-httpcomponents-client-4-api:4.5.5-3.0
+ - cloudbees-folder:6.8
+ - credentials:2.1.19
+ - durable-task:1.29
+ - jackson2-api:2.9.9
+ - kubernetes-credentials:0.4.0
+ - plain-credentials:1.5
+ - structs:1.19
+ - variant:1.2
+ - workflow-step-api:2.19
+ workflow-aggregator:2.6:
+ - ace-editor:1.1
+ - apache-httpcomponents-client-4-api:4.5.5-3.0
+ - authentication-tokens:1.3
+ - branch-api:2.5.2
+ - cloudbees-folder:6.8
+ - credentials-binding:1.18
+ - credentials:2.1.19
+ - display-url-api:2.3.1
+ - docker-commons:1.15
+ - docker-workflow:1.18
+ - durable-task:1.29
+ - git-client:2.7.7
+ - git-server:1.7
+ - handlebars:1.1.1
+ - jackson2-api:2.9.9
+ - jquery-detached:1.2.1
+ - jsch:0.1.55
+ - junit:1.28
+ - lockable-resources:2.5
+ - mailer:1.23
+ - matrix-project:1.14
+ - momentjs:1.1.1
+ - pipeline-build-step:2.9
+ - pipeline-graph-analysis:1.10
+ - pipeline-input-step:2.10
+ - pipeline-milestone-step:1.3.1
+ - pipeline-model-api:1.3.8
+ - pipeline-model-declarative-agent:1.1.1
+ - pipeline-model-definition:1.3.8
+ - pipeline-model-extensions:1.3.8
+ - pipeline-rest-api:2.11
+ - pipeline-stage-step:2.3
+ - pipeline-stage-tags-metadata:1.3.8
+ - pipeline-stage-view:2.11
+ - plain-credentials:1.5
+ - scm-api:2.4.1
+ - script-security:1.59
+ - ssh-credentials:1.16
+ - structs:1.19
+ - workflow-api:2.34
+ - workflow-basic-steps:2.16
+ - workflow-cps-global-lib:2.13
+ - workflow-cps:2.69
+ - workflow-durable-task-step:2.30
+ - workflow-job:2.32
+ - workflow-multibranch:2.21
+ - workflow-scm-step:2.7
+ - workflow-step-api:2.19
+ - workflow-support:3.3
+ workflow-job:2.32:
+ - scm-api:2.4.1
+ - script-security:1.59
+ - structs:1.19
+ - workflow-api:2.34
+ - workflow-step-api:2.19
+ - workflow-support:3.3
+ image: jenkins/jenkins:lts
+ imagePullPolicy: Always
+ livenessProbe:
+ failureThreshold: 12
+ httpGet:
+ path: /login
+ port: 8080
+ scheme: HTTP
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ plugins:
+ simple-theme-plugin:0.5.1: []
+ slack:2.24:
+ - workflow-step-api:2.19
+ - credentials:2.1.19
+ - display-url-api:2.3.1
+ - junit:1.28
+ - plain-credentials:1.5
+ - script-security:1.59
+ - structs:1.19
+ - token-macro:2.8
+ readinessProbe:
+ failureThreshold: 12
+ httpGet:
+ path: /login
+ port: 8080
+ scheme: HTTP
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ resources:
+ limits:
+ cpu: 1500m
+ memory: 3Gi
+ requests:
+ cpu: "1"
+ memory: 500MiNew format:
+apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: <cr_name>
+ namespace: <namespace>
+spec:
+ master:
+ basePlugins:
+ - name: kubernetes
+ version: 1.15.7
+ - name: workflow-job
+ version: "2.32"
+ - name: workflow-aggregator
+ version: "2.6"
+ - name: git
+ version: 3.10.0
+ - name: job-dsl
+ version: "1.74"
+ - name: configuration-as-code
+ version: "1.19"
+ - name: configuration-as-code-support
+ version: "1.19"
+ - name: kubernetes-credentials-provider
+ version: 0.12.1
+ containers:
+ - name: jenkins-master
+ image: jenkins/jenkins:lts
+ imagePullPolicy: Always
+ livenessProbe:
+ failureThreshold: 12
+ httpGet:
+ path: /login
+ port: http
+ scheme: HTTP
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /login
+ port: http
+ scheme: HTTP
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ limits:
+ cpu: 1500m
+ memory: 3Gi
+ requests:
+ cpu: "1"
+ memory: 500Mi
+ plugins:
+ - name: simple-theme-plugin
+ version: 0.5.1
+ - name: slack
+ version: 2.24New version of the Custom Resource definition for the operator needs to be applied: +-Jenkins CRD v1alpha2
+ +To use default CRD file:
+ +kubectl -n <namespace> apply -f https://github.com/jenkinsci/kubernetes-operator/blob/master/deploy/crds/jenkins_v1alpha2_jenkins_crd.yaml
+
+
+New operator version requires updated RBAC permissions:
+ +To use default Role file:
+ +$ kubectl -n <namespace> apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/role.yaml
+
+
+Replace your modified operator configuration file:
+$ kubectl -n <namespace> replace -f jenkins.yamlUpdate operator version in the deployment file to image: virtuslab/jenkins-operator:v0.1.0 and scale up,
+or use the default deployment manifest:
$ kubectl -n <namespace> apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/operator.yaml
+
+
+
+
+ This document contains API scheme for jenkins-operator manifest
Packages:
++
Package v1alpha2 contains API Schema definitions for the jenkins.io v1alpha2 API group
+ +Resource Types: ++
Jenkins is the Schema for the jenkins API
+ +| Field | +Description | +||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+apiVersion
+string |
+
+
+jenkins.io/v1alpha2
+
+ |
+||||||||||||
+kind
+string
+ |
+Jenkins |
+||||||||||||
+metadata
+
+
+Kubernetes meta/v1.ObjectMeta
+
+
+ |
+
+Refer to the Kubernetes API documentation for the fields of the
+metadata field.
+ |
+||||||||||||
+spec
+
+
+JenkinsSpec
+
+
+ |
+
+ Spec defines the desired state of the Jenkins ++ +
|
+||||||||||||
+status
+
+
+JenkinsStatus
+
+
+ |
+
+ Status defines the observed state of Jenkins + |
+
+(Appears on: +JenkinsSpec) +
++
Backup defines configuration of Jenkins backup
+ +| Field | +Description | +
|---|---|
+containerName
+
+string
+
+ |
+
+ ContainerName is the container name responsible for backup operation + |
+
+action
+
+
+Handler
+
+
+ |
+
+ Action defines action which performs backup in backup container sidecar + |
+
+interval
+
+uint64
+
+ |
+
+ Interval tells how often make backup in seconds +Defaults to 30. + |
+
+makeBackupBeforePodDeletion
+
+bool
+
+ |
+
+ MakeBackupBeforePodDeletion tells operator to make backup before Jenkins master pod deletion + |
+
+(Appears on: +JenkinsStatus) +
++
Build defines Jenkins Build status with corresponding metadata
+ +| Field | +Description | +
|---|---|
+jobName
+
+string
+
+ |
+
+ JobName is the Jenkins job name + |
+
+hash
+
+string
+
+ |
+
+ Hash is the unique data identifier used in build + |
+
+number
+
+int64
+
+ |
+
+ Number is the Jenkins build number + |
+
+status
+
+
+BuildStatus
+
+
+ |
+
+ Status is the status of Jenkins build + |
+
+retries
+
+int
+
+ |
+
+ Retires is the amount of Jenkins job build retries + |
+
+createTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ CreateTime is the time when the first build has been created + |
+
+lastUpdateTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ LastUpdateTime is the last update status time + |
+
string alias)+(Appears on: +Build) +
++
BuildStatus defines type of Jenkins build job status
+ ++(Appears on: +JenkinsMaster) +
++
Container defines Kubernetes container attributes
+ +| Field | +Description | +
|---|---|
+name
+
+string
+
+ |
+
+ Name of the container specified as a DNS_LABEL. +Each container in a pod must have a unique name (DNS_LABEL). + |
+
+image
+
+string
+
+ |
+
+ Docker image name. +More info: https://kubernetes.io/docs/concepts/containers/images + |
+
+imagePullPolicy
+
+
+Kubernetes core/v1.PullPolicy
+
+
+ |
+
+ Image pull policy. +One of Always, Never, IfNotPresent. +Defaults to Always. + |
+
+resources
+
+
+Kubernetes core/v1.ResourceRequirements
+
+
+ |
+
+ Compute Resources required by this container. +More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + |
+
+command
+
+[]string
+
+ |
+
+(Optional)
+ Entrypoint array. Not executed within a shell. +The docker image’s ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax +can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, +regardless of whether the variable exists or not. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + |
+
+args
+
+[]string
+
+ |
+
+(Optional)
+ Arguments to the entrypoint. +The docker image’s CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax +can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, +regardless of whether the variable exists or not. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + |
+
+workingDir
+
+string
+
+ |
+
+(Optional)
+ Container’s working directory. +If not specified, the container runtime’s default will be used, which +might be configured in the container image. + |
+
+ports
+
+
+[]Kubernetes core/v1.ContainerPort
+
+
+ |
+
+(Optional)
+ List of ports to expose from the container. Exposing a port here gives +the system additional information about the network connections a +container uses, but is primarily informational. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default “0.0.0.0” address inside a container will be +accessible from the network. + |
+
+envFrom
+
+
+[]Kubernetes core/v1.EnvFromSource
+
+
+ |
+
+(Optional)
+ List of sources to populate environment variables in the container. +The keys defined within a source must be a C_IDENTIFIER. All invalid keys +will be reported as an event when the container is starting. When a key exists in multiple +sources, the value associated with the last source will take precedence. +Values defined by an Env with a duplicate key will take precedence. + |
+
+env
+
+
+[]Kubernetes core/v1.EnvVar
+
+
+ |
+
+(Optional)
+ List of environment variables to set in the container. + |
+
+volumeMounts
+
+
+[]Kubernetes core/v1.VolumeMount
+
+
+ |
+
+(Optional)
+ Pod volumes to mount into the container’s filesystem. + |
+
+livenessProbe
+
+
+Kubernetes core/v1.Probe
+
+
+ |
+
+(Optional)
+ Periodic probe of container liveness. +Container will be restarted if the probe fails. + |
+
+readinessProbe
+
+
+Kubernetes core/v1.Probe
+
+
+ |
+
+(Optional)
+ Periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + |
+
+lifecycle
+
+
+Kubernetes core/v1.Lifecycle
+
+
+ |
+
+(Optional)
+ Actions that the management system should take in response to container lifecycle events. + |
+
+securityContext
+
+
+Kubernetes core/v1.SecurityContext
+
+
+ |
+
+(Optional)
+ Security options the pod should run with. +More info: https://kubernetes.io/docs/concepts/policy/security-context/ +More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + |
+
+(Appears on: +Backup, +Restore) +
++
Handler defines a specific action that should be taken
+ +| Field | +Description | +
|---|---|
+exec
+
+
+Kubernetes core/v1.ExecAction
+
+
+ |
+
+ Exec specifies the action to take. + |
+
string alias)+(Appears on: +SeedJob) +
++
JenkinsCredentialType defines type of Jenkins credential used to seed job mechanism
+ ++(Appears on: +JenkinsSpec) +
++
JenkinsMaster defines the Jenkins master pod attributes and plugins, +every single change requires a Jenkins master pod restart
+ +| Field | +Description | +
|---|---|
+masterAnnotations
+
+map[string]string
+
+ |
+
+(Optional)
+ Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. +More info: http://kubernetes.io/docs/user-guide/annotations + |
+
+nodeSelector
+
+map[string]string
+
+ |
+
+(Optional)
+ NodeSelector is a selector which must be true for the pod to fit on a node. +Selector which must match a node’s labels for the pod to be scheduled on that node. +More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + |
+
+securityContext
+
+
+Kubernetes core/v1.PodSecurityContext
+
+
+ |
+
+(Optional)
+ SecurityContext that applies to all the containers of the Jenkins +Master. As per kubernetes specification, it can be overridden +for each container individually. +Defaults to: +runAsUser: 1000 +fsGroup: 1000 + |
+
+containers
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Container
+
+
+ |
+
+ List of containers belonging to the pod. +Containers cannot currently be added or removed. +There must be at least one container in a Pod. +Defaults to: +- image: jenkins/jenkins:lts +imagePullPolicy: Always +livenessProbe: +failureThreshold: 12 +httpGet: +path: /login +port: http +scheme: HTTP +initialDelaySeconds: 80 +periodSeconds: 10 +successThreshold: 1 +timeoutSeconds: 5 +name: jenkins-master +readinessProbe: +failureThreshold: 3 +httpGet: +path: /login +port: http +scheme: HTTP +initialDelaySeconds: 30 +periodSeconds: 10 +successThreshold: 1 +timeoutSeconds: 1 +resources: +limits: +cpu: 1500m +memory: 3Gi +requests: +cpu: “1” +memory: 600Mi + |
+
+volumes
+
+
+[]Kubernetes core/v1.Volume
+
+
+ |
+
+(Optional)
+ List of volumes that can be mounted by containers belonging to the pod. +More info: https://kubernetes.io/docs/concepts/storage/volumes + |
+
+basePlugins
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Plugin
+
+
+ |
+
+ BasePlugins contains plugins required by operator +Defaults to : +- name: kubernetes +version: 1.15.7 +- name: workflow-job +version: “2.32” +- name: workflow-aggregator +version: “2.6” +- name: git +version: 3.10.0 +- name: job-dsl +version: “1.74” +- name: configuration-as-code +version: “1.19” +- name: configuration-as-code-support +version: “1.19” +- name: kubernetes-credentials-provider +version: 0.12.1 + |
+
+plugins
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Plugin
+
+
+ |
+
+(Optional)
+ Plugins contains plugins required by user + |
+
+(Appears on: +Jenkins) +
++
JenkinsSpec defines the desired state of the Jenkins
+ +| Field | +Description | +
|---|---|
+master
+
+
+JenkinsMaster
+
+
+ |
+
+ Master represents Jenkins master pod properties and Jenkins plugins. +Every single change here requires a pod restart. + |
+
+seedJobs
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.SeedJob
+
+
+ |
+
+(Optional)
+ SeedJobs defines list of Jenkins Seed Job configurations +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-seed-jobs-and-pipelines + |
+
+service
+
+
+Service
+
+
+ |
+
+(Optional)
+ Service is Kubernetes service of Jenkins master HTTP pod +Defaults to : +port: 8080 +type: ClusterIP + |
+
+slaveService
+
+
+Service
+
+
+ |
+
+(Optional)
+ Service is Kubernetes service of Jenkins slave pods +Defaults to : +port: 50000 +type: ClusterIP + |
+
+backup
+
+
+Backup
+
+
+ |
+
+(Optional)
+ Backup defines configuration of Jenkins backup +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-backup-and-restore + |
+
+restore
+
+
+Restore
+
+
+ |
+
+(Optional)
+ Backup defines configuration of Jenkins backup restore +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-backup-and-restore + |
+
+(Appears on: +Jenkins) +
++
JenkinsStatus defines the observed state of Jenkins
+ +| Field | +Description | +
|---|---|
+operatorVersion
+
+string
+
+ |
+
+(Optional)
+ OperatorVersion is the operator version which manages this CR + |
+
+provisionStartTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+(Optional)
+ ProvisionStartTime is a time when Jenkins master pod has been created + |
+
+baseConfigurationCompletedTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+(Optional)
+ BaseConfigurationCompletedTime is a time when Jenkins base configuration phase has been completed + |
+
+userConfigurationCompletedTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+(Optional)
+ UserConfigurationCompletedTime is a time when Jenkins user configuration phase has been completed + |
+
+builds
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Build
+
+
+ |
+
+(Optional)
+ Builds contains Jenkins builds statues + |
+
+restoredBackup
+
+uint64
+
+ |
+
+(Optional)
+ RestoredBackup is the restored backup number after Jenkins master pod restart + |
+
+lastBackup
+
+uint64
+
+ |
+
+(Optional)
+ LastBackup is the latest backup number + |
+
+pendingBackup
+
+uint64
+
+ |
+
+(Optional)
+ PendingBackup is the pending backup number + |
+
+backupDoneBeforePodDeletion
+
+bool
+
+ |
+
+(Optional)
+ BackupDoneBeforePodDeletion tells if backup before pod deletion has been made + |
+
+userAndPasswordHash
+
+string
+
+ |
+
+(Optional)
+ UserAndPasswordHash is a SHA256 hash made from user and password + |
+
+createdSeedJobs
+
+[]string
+
+ |
+
+(Optional)
+ CreatedSeedJobs contains list of seed job id already created in Jenkins + |
+
+(Appears on: +JenkinsMaster) +
++
Plugin defines Jenkins plugin
+ +| Field | +Description | +
|---|---|
+name
+
+string
+
+ |
+
+ Name is the name of Jenkins plugin + |
+
+version
+
+string
+
+ |
+
+ Version is the version of Jenkins plugin + |
+
+(Appears on: +JenkinsSpec) +
++
Restore defines configuration of Jenkins backup restore operation
+ +| Field | +Description | +
|---|---|
+containerName
+
+string
+
+ |
+
+ ContainerName is the container name responsible for restore backup operation + |
+
+action
+
+
+Handler
+
+
+ |
+
+ Action defines action which performs restore backup in restore container sidecar + |
+
+recoveryOnce
+
+uint64
+
+ |
+
+(Optional)
+ RecoveryOnce if want to restore specific backup set this field and then Jenkins will be restarted and desired backup will be restored + |
+
+(Appears on: +JenkinsSpec) +
++
SeedJob defines configuration for seed job +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-seed-jobs-and-pipelines
+ +| Field | +Description | +
|---|---|
+id
+
+string
+
+ |
+
+ ID is the unique seed job name + |
+
+credentialID
+
+string
+
+ |
+
+ CredentialID is the Kubernetes secret name which stores repository access credentials + |
+
+description
+
+string
+
+ |
+
+(Optional)
+ Description is the description of the seed job + |
+
+targets
+
+string
+
+ |
+
+ Targets is the repository path where are seed job definitions + |
+
+repositoryBranch
+
+string
+
+ |
+
+ RepositoryBranch is the repository branch where are seed job definitions + |
+
+repositoryUrl
+
+string
+
+ |
+
+ RepositoryURL is the repository access URL. Can be SSH or HTTPS. + |
+
+credentialType
+
+
+JenkinsCredentialType
+
+
+ |
+
+(Optional)
+ JenkinsCredentialType is the https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/ credential type + |
+
+(Appears on: +JenkinsSpec) +
++
Service defines Kubernetes service attributes
+ +| Field | +Description | +
|---|---|
+annotations
+
+map[string]string
+
+ |
+
+(Optional)
+ Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. +More info: http://kubernetes.io/docs/user-guide/annotations + |
+
+labels
+
+map[string]string
+
+ |
+
+ Route service traffic to pods with label keys and values matching this +selector. If empty or not present, the service is assumed to have an +external process managing its endpoints, which Kubernetes will not +modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. +Ignored if type is ExternalName. +More info: https://kubernetes.io/docs/concepts/services-networking/service/ + |
+
+type
+
+
+Kubernetes core/v1.ServiceType
+
+
+ |
+
+(Optional)
+ Type determines how the Service is exposed. Defaults to ClusterIP. Valid +options are ExternalName, ClusterIP, NodePort, and LoadBalancer. +“ExternalName” maps to the specified externalName. +“ClusterIP” allocates a cluster-internal IP address for load-balancing to +endpoints. Endpoints are determined by the selector or if that is not +specified, by manual construction of an Endpoints object. If clusterIP is +“None”, no virtual IP is allocated and the endpoints are published as a +set of endpoints rather than a stable IP. +“NodePort” builds on ClusterIP and allocates a port on every node which +routes to the clusterIP. +“LoadBalancer” builds on NodePort and creates an +external load-balancer (if supported in the current cloud) which routes +to the clusterIP. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services—service-types + |
+
+port
+
+int32
+
+ |
+
+ The port that are exposed by this service. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + |
+
+nodePort
+
+int32
+
+ |
+
+(Optional)
+ The port on each node on which this service is exposed when type=NodePort or LoadBalancer. +Usually assigned by the system. If specified, it will be allocated to the service +if unused or else creation of the service will fail. +Default is to auto-allocate a port if the ServiceType of this Service requires one. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + |
+
+loadBalancerSourceRanges
+
+[]string
+
+ |
+
+(Optional)
+ If specified and supported by the platform, this will restrict traffic through the cloud-provider +load-balancer will be restricted to the specified client IPs. This field will be ignored if the +cloud-provider does not support the feature.” +More info: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/ + |
+
+loadBalancerIP
+
+string
+
+ |
+
+(Optional)
+ Only applies to Service Type: LoadBalancer +LoadBalancer will get created with the IP specified in this field. +This feature depends on whether the underlying cloud-provider supports specifying +the loadBalancerIP when a load balancer is created. +This field will be ignored if the cloud-provider does not support the feature. + |
+
+Generated with gen-crd-api-reference-docs
+on git commit 37e531a.
+
Azure AKS managed Kubernetes service adds to every pod the following envs:
+- name: KUBERNETES_PORT_443_TCP_ADDR
+ value:
+- name: KUBERNETES_PORT
+ value: tcp://
+- name: KUBERNETES_PORT_443_TCP
+ value: tcp://
+- name: KUBERNETES_SERVICE_HOST
+ value:The operator is aware of it and omits these envs when checking if Jenkins pod envs have been changed. It prevents +restart Jenkins pod over and over again.
+ + + +Jenkins operator uses job-dsl and kubernetes-credentials-provider plugins for configuring jobs +and deploy keys.
+ +First you have to prepare pipelines and job definition in your GitHub repository using the following structure:
+ +cicd/
+├── jobs
+│ └── build.jenkins
+└── pipelines
+ └── build.jenkins
+
+
+cicd/jobs/build.jenkins it’s a job definition:
+ +#!/usr/bin/env groovy
+
+pipelineJob('build-jenkins-operator') {
+ displayName('Build jenkins-operator')
+
+ definition {
+ cpsScm {
+ scm {
+ git {
+ remote {
+ url('https://github.com/jenkinsci/kubernetes-operator.git')
+ credentials('jenkins-operator')
+ }
+ branches('*/master')
+ }
+ }
+ scriptPath('cicd/pipelines/build.jenkins')
+ }
+ }
+}
+
+
+cicd/jobs/build.jenkins it’s an actual Jenkins pipeline:
+ +#!/usr/bin/env groovy
+
+def label = "build-jenkins-operator-${UUID.randomUUID().toString()}"
+def home = "/home/jenkins"
+def workspace = "${home}/workspace/build-jenkins-operator"
+def workdir = "${workspace}/src/github.com/jenkinsci/kubernetes-operator/"
+
+podTemplate(label: label,
+ containers: [
+ containerTemplate(name: 'jnlp', image: 'jenkins/jnlp-slave:alpine'),
+ containerTemplate(name: 'go', image: 'golang:1-alpine', command: 'cat', ttyEnabled: true),
+ ],
+ envVars: [
+ envVar(key: 'GOPATH', value: workspace),
+ ],
+ ) {
+
+ node(label) {
+ dir(workdir) {
+ stage('Init') {
+ timeout(time: 3, unit: 'MINUTES') {
+ checkout scm
+ }
+ container('go') {
+ sh 'apk --no-cache --update add make git gcc libc-dev'
+ }
+ }
+
+ stage('Dep') {
+ container('go') {
+ sh 'make dep'
+ }
+ }
+
+ stage('Test') {
+ container('go') {
+ sh 'make test'
+ }
+ }
+
+ stage('Build') {
+ container('go') {
+ sh 'make build'
+ }
+ }
+ }
+ }
+}
+
+
+Jenkins Seed Jobs are configured using Jenkins.spec.seedJobs section from your custom resource manifest:
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ seedJobs:
+ - id: jenkins-operator
+ targets: "cicd/jobs/*.jenkins"
+ description: "Jenkins Operator repository"
+ repositoryBranch: master
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
+
+
+jenkins-operator will automatically discover and configure all seed jobs.
+ +You can verify if deploy keys were successfully configured in Jenkins Credentials tab.
+ +
You can verify if your pipelines were successfully configured in Jenkins Seed Job console output.
+ +
If your GitHub repository is private you have to configure SSH or username/password authentication.
+ +There are two methods of SSH private key generation:
+$ openssl genrsa -out <filename> 2048or
+$ ssh-keygen -t rsa -b 2048
+$ ssh-keygen -p -f <filename> -m pemThen copy content from generated file.
+ +If you want to upload your public key to your Git server you need to extract it.
+ +If key was generated by openssl then you need to type this to extract public key:
$ openssl rsa -in <filename> -pubout > <filename>.pubIf key was generated by ssh-keygen the public key content is located in
Configure seed job like:
+ +apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ seedJobs:
+ - id: jenkins-operator-ssh
+ credentialType: basicSSHUserPrivateKey
+ credentialID: k8s-ssh
+ targets: "cicd/jobs/*.jenkins"
+ description: "Jenkins Operator repository"
+ repositoryBranch: master
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git
+
+
+and create Kubernetes Secret(name of secret should be the same from credentialID field):
apiVersion: v1
+kind: Secret
+metadata:
+ name: k8s-ssh
+stringData:
+ privateKey: |
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIJKAIBAAKCAgEAxxDpleJjMCN5nusfW/AtBAZhx8UVVlhhhIKXvQ+dFODQIdzO
+ oDXybs1zVHWOj31zqbbJnsfsVZ9Uf3p9k6xpJ3WFY9b85WasqTDN1xmSd6swD4N8
+ ...
+ username: github_user_name
+
+
+Configure seed job like:
+ +apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ seedJobs:
+ - id: jenkins-operator-user-pass
+ credentialType: usernamePassword
+ credentialID: k8s-user-pass
+ targets: "cicd/jobs/*.jenkins"
+ description: "Jenkins Operator repository"
+ repositoryBranch: master
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
+
+
+and create Kubernetes Secret(name of secret should be the same from credentialID field):
apiVersion: v1
+kind: Secret
+metadata:
+ name: k8s-user-pass
+stringData:
+ username: github_user_name
+ password: password_or_token
+
+
+To pull Docker Image from private repository you can use imagePullSecrets.
Please follow the instructions on creating a secret with a docker config.
+ +To use Docker Hub additional steps are required.
+ +Edit the previously created secret:
+kubectl -n <namespace> edit secret <name>The .dockerconfigjson key’s value needs to be replaced with a modified version.
After modifications it needs to be encoded as Base64 value before setting the .dockerconfigjson key:q.
Example config file to modify and use:
+ +{
+ "auths":{
+ "https://index.docker.io/v1/":{
+ "username":"user",
+ "password":"password",
+ "email":"yourdockeremail@gmail.com",
+ "auth":"base64 of string user:password"
+ },
+ "auth.docker.io":{
+ "username":"user",
+ "password":"password",
+ "email":"yourdockeremail@gmail.com",
+ "auth":"base64 of string user:password"
+ },
+ "registry.docker.io":{
+ "username":"user",
+ "password":"password",
+ "email":"yourdockeremail@gmail.com",
+ "auth":"base64 of string user:password"
+ },
+ "docker.io":{
+ "username":"user",
+ "password":"password",
+ "email":"yourdockeremail@gmail.com",
+ "auth":"base64 of string user:password"
+ },
+ "https://registry-1.docker.io/v2/": {
+ "username":"user",
+ "password":"password",
+ "email":"yourdockeremail@gmail.com",
+ "auth":"base64 of string user:password"
+ },
+ "registry-1.docker.io/v2/": {
+ "username":"user",
+ "password":"password",
+ "email":"yourdockeremail@gmail.com",
+ "auth":"base64 of string user:password"
+ },
+ "registry-1.docker.io": {
+ "username":"user",
+ "password":"password",
+ "email":"yourdockeremail@gmail.com",
+ "auth":"base64 of string user:password"
+ },
+ "https://registry-1.docker.io": {
+ "username":"user",
+ "password":"password",
+ "email":"yourdockeremail@gmail.com",
+ "auth":"base64 of string user:password"
+ }
+ }
+}
+
+
+
+
+ Backup and restore is done by container sidecar.
+ +Save to file pvc.yaml:
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: <pvc_name>
+ namespace: <namesapce>
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 500GiRun command:
+$ kubectl -n <namesapce> create -f pvc.yamlapiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: <cr_name>
+ namespace: <namespace>
+spec:
+ master:
+ securityContext:
+ runAsUser: 1000
+ fsGroup: 1000
+ containers:
+ - name: jenkins-master
+ image: jenkins/jenkins:lts
+ - name: backup # container responsible for backup and restore
+ env:
+ - name: BACKUP_DIR
+ value: /backup
+ - name: JENKINS_HOME
+ value: /jenkins-home
+ - name: BACKUP_COUNT
+ value: "3" # keep only the 2 most recent backups
+ image: virtuslab/jenkins-operator-backup-pvc:v0.0.6 # look at backup/pvc directory
+ imagePullPolicy: IfNotPresent
+ volumeMounts:
+ - mountPath: /jenkins-home # Jenkins home volume
+ name: jenkins-home
+ - mountPath: /backup # backup volume
+ name: backup
+ volumes:
+ - name: backup # PVC volume where backups will be stored
+ persistentVolumeClaim:
+ claimName: <pvc_name>
+ backup:
+ containerName: backup # container name is responsible for backup
+ action:
+ exec:
+ command:
+ - /home/user/bin/backup.sh # this command is invoked on "backup" container to make backup, for example /home/user/bin/backup.sh <backup_number>, <backup_number> is passed by operator
+ interval: 30 # how often make backup in seconds
+ makeBackupBeforePodDeletion: true # make backup before pod deletion
+ restore:
+ containerName: backup # container name is responsible for restore backup
+ action:
+ exec:
+ command:
+ - /home/user/bin/restore.sh # this command is invoked on "backup" container to make restore backup, for example /home/user/bin/restore.sh <backup_number>, <backup_number> is passed by operator
+ #recoveryOnce: <backup_number> # if want to restore specific backup configure this field and then Jenkins will be restarted and desired backup will be restoredJenkins can be customized using groovy scripts or configuration as code plugin.
+By using ConfigMap you can create own Jenkins customized configuration.
+Then you must reference the ConfigMap in Jenkins pod customization file in spec.groovyScripts or spec.configurationAsCode
For example create ConfigMap with name jenkins-operator-user-configuration. Then, modify the Jenkins manifest to look like this:
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ configurationAsCode:
+ configurations:
+ - name: jenkins-operator-user-configuration
+ groovyScripts:
+ configurations:
+ - name: jenkins-operator-user-configurationHere is example of jenkins-operator-user-configuration:
apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: jenkins-operator-user-configuration
+data:
+ 1-configure-theme.groovy: |
+ import jenkins.*
+ import jenkins.model.*
+ import hudson.*
+ import hudson.model.*
+ import org.jenkinsci.plugins.simpletheme.ThemeElement
+ import org.jenkinsci.plugins.simpletheme.CssTextThemeElement
+ import org.jenkinsci.plugins.simpletheme.CssUrlThemeElement
+
+ Jenkins jenkins = Jenkins.getInstance()
+
+ def decorator = Jenkins.instance.getDescriptorByType(org.codefirst.SimpleThemeDecorator.class)
+
+ List<ThemeElement> configElements = new ArrayList<>();
+ configElements.add(new CssTextThemeElement("DEFAULT"));
+ configElements.add(new CssUrlThemeElement("https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-light-green.css"));
+ decorator.setElements(configElements);
+ decorator.save();
+
+ jenkins.save()
+ 1-system-message.yaml: |
+ jenkins:
+ systemMessage: "Configuration as Code integration works!!!"If you want to correct your configuration you can edit it while jenkins-operator is running. +Jenkins will reconcile and apply new configuration.
+ +If you configured spec.groovyScripts.secret.name, then this secret is available to use inside map Groovy scripts.
+The secrets are loaded to secrets map.
Create a secret with for eg. jenkins-conf-secrets name.
kind: Secret
+apiVersion: v1
+type: Opaque
+metadata:
+ name: jenkins-conf-secrets
+ namespace: default
+data:
+ SYSTEM_MESSAGE: SGVsbG8gd29ybGQ=Then modify the Jenkins pod manifest by changing spec.groovyScripts.secret.name to jenkins-conf-secrets.
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ configurationAsCode:
+ configurations:
+ - name: jenkins-operator-user-configuration
+ secret:
+ name: jenkins-conf-secrets
+ groovyScripts:
+ configurations:
+ - name: jenkins-operator-user-configuration
+ secret:
+ name: jenkins-conf-secretsNow you can test that the secret is mounted by applying this ConfigMap for Groovy script:
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: jenkins-operator-user-configuration
+data:
+ 1-system-message.groovy: |
+ import jenkins.*
+ import jenkins.model.*
+ import hudson.*
+ import hudson.model.*
+ Jenkins jenkins = Jenkins.getInstance()
+
+ jenkins.setSystemMessage(secrets["SYSTEM_MESSAGE"])
+ jenkins.save()Or by applying configuration as code:
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: jenkins-operator-user-configuration
+data:
+ 1-system-message.yaml: |
+ jenkins:
+ systemMessage: ${SYSTEM_MESSAGE}After this, you should see the Hello world system message at Jenkins homepage.
Edit CR under spec.master.plugins:
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ master:
+ plugins:
+ - name: simple-theme-plugin
+ version: 0.5.1
+
+
+Under spec.master.basePlugins you can find plugins for valid jenkins-operator work:
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ master:
+ basePlugins:
+ - name: kubernetes
+ version: 1.18.3
+ - name: workflow-job
+ version: "2.34"
+ - name: workflow-aggregator
+ version: "2.6"
+ - name: git
+ version: 3.12.0
+ - name: job-dsl
+ version: "1.76"
+ - name: configuration-as-code
+ version: "1.29"
+ - name: configuration-as-code-support
+ version: "1.19"
+ - name: kubernetes-credentials-provider
+ version: 0.12.1You can change version of them.
+ +Then jenkins-operator will automatically install plugins after Jenkins master pod restart.
+ + + +Once jenkins-operator is up and running let’s deploy actual Jenkins instance. +Create manifest ie. jenkins_instance.yaml with following data and save it on drive.
+apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ master:
+ containers:
+ - name: jenkins-master
+ image: jenkins/jenkins:lts
+ imagePullPolicy: Always
+ livenessProbe:
+ failureThreshold: 12
+ httpGet:
+ path: /login
+ port: http
+ scheme: HTTP
+ initialDelaySeconds: 80
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /login
+ port: http
+ scheme: HTTP
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ resources:
+ limits:
+ cpu: 1500m
+ memory: 3Gi
+ requests:
+ cpu: "1"
+ memory: 500Mi
+ seedJobs:
+ - id: jenkins-operator
+ targets: "cicd/jobs/*.jenkins"
+ description: "Jenkins Operator repository"
+ repositoryBranch: master
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.gitDeploy Jenkins to K8s:
+kubectl create -f jenkins_instance.yamlWatch Jenkins instance being created:
+kubectl get pods -wGet Jenkins credentials:
+kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.user}' | base64 -d
+kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.password}' | base64 -dConnect to Jenkins (minikube):
+minikube service jenkins-operator-http-<cr_name> --urlConnect to Jenkins (actual Kubernetes cluster):
+kubectl port-forward jenkins-<cr_name> 8080:8080Then open browser with address http://localhost:8080.
+
Turn on debug in jenkins-operator deployment:
+sed -i 's|\(args:\).*|\1\ ["--debug"\]|' deploy/operator.yaml
+kubectl apply -f deploy/operator.yamlWatch Kubernetes events:
+kubectl get events --sort-by='{.lastTimestamp}'Verify Jenkins master logs:
+kubectl logs -f jenkins-<cr_name>Verify jenkins-operator logs:
+kubectl logs deployment/jenkins-operatorDelete Jenkins master pod and wait for the new one to come up:
+kubectl delete pod jenkins-<cr_name>This document describes a getting started guide for jenkins-operator v0.2.0 and an additional configuration.
Prepare your Kubernetes cluster and set up access. +Once you have running Kubernetes cluster you can focus on installing jenkins-operator according to the Installation guide.
+ +Deploy production ready Jenkins Operator manifest +
+How to configure Jenkins with Operator +
+How to customize Jenkins +
+Additional configuration for Azure Kubernetes Service +
+Prevent job history loss +
+How to migrate from v0.1.1 to v0.2.0 +
+How to deal with jenkins-operator problems +
+API Schema definitions for Jenkins CR +
+Now seed jobs are not built by master executors, but by dedicated agent deployed into Kubernetes. We disabled master executors for security reasons.
+ +We have removed hardcoded configuration by Jenkins jobs.
+ +In v0.1.1 jenkins-operator configuration was stored in jenkins-operator-user-configuration-<cr_name>
+If you want to use v0.2.0 or newer you must simply write refer to old ConfigMap by modifying CR, for example:
apiVersion: jenkins.io/v1alpha2
+kind: Jenkins
+metadata:
+ name: example
+spec:
+ configurationAsCode:
+ configurations:
+ - name: jenkins-operator-user-configuration-<cr_name>
+ groovyScripts:
+ configurations:
+ - name: jenkins-operator-user-configuration-<cr_name>Jenkins configuration jobs (Configure Seed Jobs, jenkins-operator-base-configuration, jenkins-operator-user-configuration) have been removed from Jenkins.
+ +In v0.1.1 you can see if configuration failed or successfully updated in Jenkins UI (job build logs).
+Now, when Jenkins configuration jobs are removed, you must use this command to see if configuration was failed.
$ kubectl -n logs deployment/jenkins-operatorThis document contains API scheme for jenkins-operator manifest
Packages:
++
Package v1alpha2 contains API Schema definitions for the jenkins.io v1alpha2 API group
+ +Resource Types: ++
Jenkins is the Schema for the jenkins API
+ +| Field | +Description | +||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+apiVersion
+string |
+
+
+jenkins.io/v1alpha2
+
+ |
+||||||||||||
+kind
+string
+ |
+Jenkins |
+||||||||||||
+metadata
+
+
+Kubernetes meta/v1.ObjectMeta
+
+
+ |
+
+Refer to the Kubernetes API documentation for the fields of the
+metadata field.
+ |
+||||||||||||
+spec
+
+
+JenkinsSpec
+
+
+ |
+
+ Spec defines the desired state of the Jenkins ++ +
|
+||||||||||||
+status
+
+
+JenkinsStatus
+
+
+ |
+
+ Status defines the observed state of Jenkins + |
+
+(Appears on: +JenkinsSpec) +
++
Backup defines configuration of Jenkins backup
+ +| Field | +Description | +
|---|---|
+containerName
+
+string
+
+ |
+
+ ContainerName is the container name responsible for backup operation + |
+
+action
+
+
+Handler
+
+
+ |
+
+ Action defines action which performs backup in backup container sidecar + |
+
+interval
+
+uint64
+
+ |
+
+ Interval tells how often make backup in seconds +Defaults to 30. + |
+
+makeBackupBeforePodDeletion
+
+bool
+
+ |
+
+ MakeBackupBeforePodDeletion tells operator to make backup before Jenkins master pod deletion + |
+
+(Appears on: +JenkinsStatus) +
++
Build defines Jenkins Build status with corresponding metadata
+ +| Field | +Description | +
|---|---|
+jobName
+
+string
+
+ |
+
+ JobName is the Jenkins job name + |
+
+hash
+
+string
+
+ |
+
+ Hash is the unique data identifier used in build + |
+
+number
+
+int64
+
+ |
+
+ Number is the Jenkins build number + |
+
+status
+
+
+BuildStatus
+
+
+ |
+
+ Status is the status of Jenkins build + |
+
+retries
+
+int
+
+ |
+
+ Retires is the amount of Jenkins job build retries + |
+
+createTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ CreateTime is the time when the first build has been created + |
+
+lastUpdateTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ LastUpdateTime is the last update status time + |
+
string alias)+(Appears on: +Build) +
++
BuildStatus defines type of Jenkins build job status
+ ++(Appears on: +JenkinsMaster) +
++
Container defines Kubernetes container attributes
+ +| Field | +Description | +
|---|---|
+name
+
+string
+
+ |
+
+ Name of the container specified as a DNS_LABEL. +Each container in a pod must have a unique name (DNS_LABEL). + |
+
+image
+
+string
+
+ |
+
+ Docker image name. +More info: https://kubernetes.io/docs/concepts/containers/images + |
+
+imagePullPolicy
+
+
+Kubernetes core/v1.PullPolicy
+
+
+ |
+
+ Image pull policy. +One of Always, Never, IfNotPresent. +Defaults to Always. + |
+
+resources
+
+
+Kubernetes core/v1.ResourceRequirements
+
+
+ |
+
+ Compute Resources required by this container. +More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + |
+
+command
+
+[]string
+
+ |
+
+(Optional)
+ Entrypoint array. Not executed within a shell. +The docker image’s ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax +can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, +regardless of whether the variable exists or not. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + |
+
+args
+
+[]string
+
+ |
+
+(Optional)
+ Arguments to the entrypoint. +The docker image’s CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax +can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, +regardless of whether the variable exists or not. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + |
+
+workingDir
+
+string
+
+ |
+
+(Optional)
+ Container’s working directory. +If not specified, the container runtime’s default will be used, which +might be configured in the container image. + |
+
+ports
+
+
+[]Kubernetes core/v1.ContainerPort
+
+
+ |
+
+(Optional)
+ List of ports to expose from the container. Exposing a port here gives +the system additional information about the network connections a +container uses, but is primarily informational. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default “0.0.0.0” address inside a container will be +accessible from the network. + |
+
+envFrom
+
+
+[]Kubernetes core/v1.EnvFromSource
+
+
+ |
+
+(Optional)
+ List of sources to populate environment variables in the container. +The keys defined within a source must be a C_IDENTIFIER. All invalid keys +will be reported as an event when the container is starting. When a key exists in multiple +sources, the value associated with the last source will take precedence. +Values defined by an Env with a duplicate key will take precedence. + |
+
+env
+
+
+[]Kubernetes core/v1.EnvVar
+
+
+ |
+
+(Optional)
+ List of environment variables to set in the container. + |
+
+volumeMounts
+
+
+[]Kubernetes core/v1.VolumeMount
+
+
+ |
+
+(Optional)
+ Pod volumes to mount into the container’s filesystem. + |
+
+livenessProbe
+
+
+Kubernetes core/v1.Probe
+
+
+ |
+
+(Optional)
+ Periodic probe of container liveness. +Container will be restarted if the probe fails. + |
+
+readinessProbe
+
+
+Kubernetes core/v1.Probe
+
+
+ |
+
+(Optional)
+ Periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + |
+
+lifecycle
+
+
+Kubernetes core/v1.Lifecycle
+
+
+ |
+
+(Optional)
+ Actions that the management system should take in response to container lifecycle events. + |
+
+securityContext
+
+
+Kubernetes core/v1.SecurityContext
+
+
+ |
+
+(Optional)
+ Security options the pod should run with. +More info: https://kubernetes.io/docs/concepts/policy/security-context/ +More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + |
+
+(Appears on: +Backup, +Restore) +
++
Handler defines a specific action that should be taken
+ +| Field | +Description | +
|---|---|
+exec
+
+
+Kubernetes core/v1.ExecAction
+
+
+ |
+
+ Exec specifies the action to take. + |
+
string alias)+(Appears on: +SeedJob) +
++
JenkinsCredentialType defines type of Jenkins credential used to seed job mechanism
+ ++(Appears on: +JenkinsSpec) +
++
JenkinsMaster defines the Jenkins master pod attributes and plugins, +every single change requires a Jenkins master pod restart
+ +| Field | +Description | +
|---|---|
+masterAnnotations
+
+map[string]string
+
+ |
+
+(Optional)
+ Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. +More info: http://kubernetes.io/docs/user-guide/annotations + |
+
+nodeSelector
+
+map[string]string
+
+ |
+
+(Optional)
+ NodeSelector is a selector which must be true for the pod to fit on a node. +Selector which must match a node’s labels for the pod to be scheduled on that node. +More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + |
+
+securityContext
+
+
+Kubernetes core/v1.PodSecurityContext
+
+
+ |
+
+(Optional)
+ SecurityContext that applies to all the containers of the Jenkins +Master. As per kubernetes specification, it can be overridden +for each container individually. +Defaults to: +runAsUser: 1000 +fsGroup: 1000 + |
+
+containers
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Container
+
+
+ |
+
+ List of containers belonging to the pod. +Containers cannot currently be added or removed. +There must be at least one container in a Pod. +Defaults to: +- image: jenkins/jenkins:lts +imagePullPolicy: Always +livenessProbe: +failureThreshold: 12 +httpGet: +path: /login +port: http +scheme: HTTP +initialDelaySeconds: 80 +periodSeconds: 10 +successThreshold: 1 +timeoutSeconds: 5 +name: jenkins-master +readinessProbe: +failureThreshold: 3 +httpGet: +path: /login +port: http +scheme: HTTP +initialDelaySeconds: 30 +periodSeconds: 10 +successThreshold: 1 +timeoutSeconds: 1 +resources: +limits: +cpu: 1500m +memory: 3Gi +requests: +cpu: “1” +memory: 600Mi + |
+
+volumes
+
+
+[]Kubernetes core/v1.Volume
+
+
+ |
+
+(Optional)
+ List of volumes that can be mounted by containers belonging to the pod. +More info: https://kubernetes.io/docs/concepts/storage/volumes + |
+
+basePlugins
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Plugin
+
+
+ |
+
+ BasePlugins contains plugins required by operator +Defaults to : +- name: kubernetes +version: 1.15.7 +- name: workflow-job +version: “2.32” +- name: workflow-aggregator +version: “2.6” +- name: git +version: 3.10.0 +- name: job-dsl +version: “1.74” +- name: configuration-as-code +version: “1.19” +- name: configuration-as-code-support +version: “1.19” +- name: kubernetes-credentials-provider +version: 0.12.1 + |
+
+plugins
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Plugin
+
+
+ |
+
+(Optional)
+ Plugins contains plugins required by user + |
+
+(Appears on: +Jenkins) +
++
JenkinsSpec defines the desired state of the Jenkins
+ +| Field | +Description | +
|---|---|
+master
+
+
+JenkinsMaster
+
+
+ |
+
+ Master represents Jenkins master pod properties and Jenkins plugins. +Every single change here requires a pod restart. + |
+
+seedJobs
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.SeedJob
+
+
+ |
+
+(Optional)
+ SeedJobs defines list of Jenkins Seed Job configurations +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-seed-jobs-and-pipelines + |
+
+service
+
+
+Service
+
+
+ |
+
+(Optional)
+ Service is Kubernetes service of Jenkins master HTTP pod +Defaults to : +port: 8080 +type: ClusterIP + |
+
+slaveService
+
+
+Service
+
+
+ |
+
+(Optional)
+ Service is Kubernetes service of Jenkins slave pods +Defaults to : +port: 50000 +type: ClusterIP + |
+
+backup
+
+
+Backup
+
+
+ |
+
+(Optional)
+ Backup defines configuration of Jenkins backup +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-backup-and-restore + |
+
+restore
+
+
+Restore
+
+
+ |
+
+(Optional)
+ Backup defines configuration of Jenkins backup restore +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-backup-and-restore + |
+
+(Appears on: +Jenkins) +
++
JenkinsStatus defines the observed state of Jenkins
+ +| Field | +Description | +
|---|---|
+operatorVersion
+
+string
+
+ |
+
+(Optional)
+ OperatorVersion is the operator version which manages this CR + |
+
+provisionStartTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+(Optional)
+ ProvisionStartTime is a time when Jenkins master pod has been created + |
+
+baseConfigurationCompletedTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+(Optional)
+ BaseConfigurationCompletedTime is a time when Jenkins base configuration phase has been completed + |
+
+userConfigurationCompletedTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+(Optional)
+ UserConfigurationCompletedTime is a time when Jenkins user configuration phase has been completed + |
+
+builds
+
+
+[][]github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Build
+
+
+ |
+
+(Optional)
+ Builds contains Jenkins builds statues + |
+
+restoredBackup
+
+uint64
+
+ |
+
+(Optional)
+ RestoredBackup is the restored backup number after Jenkins master pod restart + |
+
+lastBackup
+
+uint64
+
+ |
+
+(Optional)
+ LastBackup is the latest backup number + |
+
+pendingBackup
+
+uint64
+
+ |
+
+(Optional)
+ PendingBackup is the pending backup number + |
+
+backupDoneBeforePodDeletion
+
+bool
+
+ |
+
+(Optional)
+ BackupDoneBeforePodDeletion tells if backup before pod deletion has been made + |
+
+userAndPasswordHash
+
+string
+
+ |
+
+(Optional)
+ UserAndPasswordHash is a SHA256 hash made from user and password + |
+
+createdSeedJobs
+
+[]string
+
+ |
+
+(Optional)
+ CreatedSeedJobs contains list of seed job id already created in Jenkins + |
+
+(Appears on: +JenkinsMaster) +
++
Plugin defines Jenkins plugin
+ +| Field | +Description | +
|---|---|
+name
+
+string
+
+ |
+
+ Name is the name of Jenkins plugin + |
+
+version
+
+string
+
+ |
+
+ Version is the version of Jenkins plugin + |
+
+(Appears on: +JenkinsSpec) +
++
Restore defines configuration of Jenkins backup restore operation
+ +| Field | +Description | +
|---|---|
+containerName
+
+string
+
+ |
+
+ ContainerName is the container name responsible for restore backup operation + |
+
+action
+
+
+Handler
+
+
+ |
+
+ Action defines action which performs restore backup in restore container sidecar + |
+
+recoveryOnce
+
+uint64
+
+ |
+
+(Optional)
+ RecoveryOnce if want to restore specific backup set this field and then Jenkins will be restarted and desired backup will be restored + |
+
+(Appears on: +JenkinsSpec) +
++
SeedJob defines configuration for seed job +More info: https://github.com/jenkinsci/kubernetes-operator/blob/master/docs/getting-started.md#configure-seed-jobs-and-pipelines
+ +| Field | +Description | +
|---|---|
+id
+
+string
+
+ |
+
+ ID is the unique seed job name + |
+
+credentialID
+
+string
+
+ |
+
+ CredentialID is the Kubernetes secret name which stores repository access credentials + |
+
+description
+
+string
+
+ |
+
+(Optional)
+ Description is the description of the seed job + |
+
+targets
+
+string
+
+ |
+
+ Targets is the repository path where are seed job definitions + |
+
+repositoryBranch
+
+string
+
+ |
+
+ RepositoryBranch is the repository branch where are seed job definitions + |
+
+repositoryUrl
+
+string
+
+ |
+
+ RepositoryURL is the repository access URL. Can be SSH or HTTPS. + |
+
+credentialType
+
+
+JenkinsCredentialType
+
+
+ |
+
+(Optional)
+ JenkinsCredentialType is the https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/ credential type + |
+
+(Appears on: +JenkinsSpec) +
++
Service defines Kubernetes service attributes
+ +| Field | +Description | +
|---|---|
+annotations
+
+map[string]string
+
+ |
+
+(Optional)
+ Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. +More info: http://kubernetes.io/docs/user-guide/annotations + |
+
+labels
+
+map[string]string
+
+ |
+
+ Route service traffic to pods with label keys and values matching this +selector. If empty or not present, the service is assumed to have an +external process managing its endpoints, which Kubernetes will not +modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. +Ignored if type is ExternalName. +More info: https://kubernetes.io/docs/concepts/services-networking/service/ + |
+
+type
+
+
+Kubernetes core/v1.ServiceType
+
+
+ |
+
+(Optional)
+ Type determines how the Service is exposed. Defaults to ClusterIP. Valid +options are ExternalName, ClusterIP, NodePort, and LoadBalancer. +“ExternalName” maps to the specified externalName. +“ClusterIP” allocates a cluster-internal IP address for load-balancing to +endpoints. Endpoints are determined by the selector or if that is not +specified, by manual construction of an Endpoints object. If clusterIP is +“None”, no virtual IP is allocated and the endpoints are published as a +set of endpoints rather than a stable IP. +“NodePort” builds on ClusterIP and allocates a port on every node which +routes to the clusterIP. +“LoadBalancer” builds on NodePort and creates an +external load-balancer (if supported in the current cloud) which routes +to the clusterIP. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services—service-types + |
+
+port
+
+int32
+
+ |
+
+ The port that are exposed by this service. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + |
+
+nodePort
+
+int32
+
+ |
+
+(Optional)
+ The port on each node on which this service is exposed when type=NodePort or LoadBalancer. +Usually assigned by the system. If specified, it will be allocated to the service +if unused or else creation of the service will fail. +Default is to auto-allocate a port if the ServiceType of this Service requires one. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + |
+
+loadBalancerSourceRanges
+
+[]string
+
+ |
+
+(Optional)
+ If specified and supported by the platform, this will restrict traffic through the cloud-provider +load-balancer will be restricted to the specified client IPs. This field will be ignored if the +cloud-provider does not support the feature.” +More info: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/ + |
+
+loadBalancerIP
+
+string
+
+ |
+
+(Optional)
+ Only applies to Service Type: LoadBalancer +LoadBalancer will get created with the IP specified in this field. +This feature depends on whether the underlying cloud-provider supports specifying +the loadBalancerIP when a load balancer is created. +This field will be ignored if the cloud-provider does not support the feature. + |
+
+Generated with gen-crd-api-reference-docs
+on git commit 37e531a.
+
The jenkins-operator design incorporates the following concepts: +- watches any changes of manifests and maintain the desired state according to deployed custom resource manifest +- implements the main reconciliation loop which consists of two smaller reconciliation loops - base and user
+ +
Base reconciliation loop takes care of reconciling base Jenkins configuration, which consists of: +- Ensure Manifests - monitors any changes in manifests +- Ensure Jenkins Pod - creates and verifies status of Jenkins master Pod +- Ensure Jenkins Configuration - configures Jenkins instance including hardening, initial configuration for plugins, etc. +- Ensure Jenkins API token - generates Jenkins API token and initialized Jenkins client
+ +User reconciliation loop takes care of reconciling user provided configuration, which consists of:
+- Ensure Restore Job - creates Restore job and ensures that restore has been successfully performed
+- Ensure Seed Jobs - creates Seed Jobs and ensures that all of them have been successfully executed
+- Ensure User Configuration - executed user provided configuration, like groovy scripts, configuration as code or plugins
+- Ensure Backup Job - creates Backup job and ensures that backup has been successfully performed

Operator state is kept in custom resource status section, which is used for storing any configuration events or job statuses managed by the operator. +It helps to maintain or recover desired state even after operator or Jenkins restarts.
+ + + +This document describes a high level overview how jenkins-operator works.
+ +Jenkins Operator fundamentals +
+Jenkins default image details +
+jenkins-operator is fully compatible with jenkins:lts docker image and does not introduce any hidden changes there. +If needed, the docker image can easily be changed in custom resource manifest as long as it supports standard Jenkins file system structure.
+ + + +This project was originally developed by VirtusLab and the following CONTRIBUTORS.
+ +How to install Jenkins Operator +
+How Jenkins Operator works +
+How to work with jenkins-operator +
+Jenkins security and hardening out of the box +
+Jenkins Operator for developers +
+This document describes installation procedure for jenkins-operator. All container images can be found at virtuslab/jenkins-operator
+ +To run jenkins-operator, you will need:
+ +running Kubernetes cluster version 1.11+
kubectl version 1.11+
Install Jenkins Custom Resource Definition:
+kubectl apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/crds/jenkins_v1alpha2_jenkins_crd.yamlApply Service Account and RBAC roles:
+kubectl apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/all-in-one-v1alpha2.yamlWatch jenkins-operator instance being created:
+kubectl get pods -wNow jenkins-operator should be up and running in default namespace.
By default jenkins-operator performs an initial security hardening of Jenkins instance via groovy scripts to prevent any security gaps.
+ +Currently jenkins-operator generates a username and random password and stores them in a Kubernetes Secret. +However any other authorization mechanisms are possible and can be done via groovy scripts or configuration as code plugin. +For more information take a look at getting-started#jenkins-customization.
+ +Any change to Security Realm or Authorization requires that user called jenkins-operator must have admin rights
+because jenkins-operator calls Jenkins API.
The list below describes all the default security setting configured by the jenkins-operator:
+- basic settings - use Mode.EXCLUSIVE - Jobs must specify that they want to run on master node
+- enable CSRF - Cross Site Request Forgery Protection is enabled
+- disable usage stats - Jenkins usage stats submitting is disabled
+- enable master access control - Slave To Master Access Control is enabled
+- disable old JNLP protocols - JNLP3-connect, JNLP2-connect and JNLP-connect are disabled
+- disable CLI - CLI access of /cli URL is disabled
+- configure kubernetes-plugin - secure configuration for Kubernetes plugin
If you would like to dig a little bit into the code, take a look here.
+ +The jenkins-operator generates and configures Basic Authentication token for Jenkins go client and stores it in a Kubernetes Secret.
+ +Kubernetes API permissions are limited by the following roles:
+- jenkins-operator role
+- Jenkins Master role
Since jenkins-operator must be able to grant permission for its’ deployed Jenkins masters to spawn pods (the Jenkins Master role above),
+the operator itself requires permission to create RBAC resources (the jenkins-operator role above).
+Deployed this way, any subject which may create a Pod (including a Jenkins job) may
+assume the jenkins-operator role by using its’ ServiceAccount, create RBAC rules, and thus escape its granted permissions.
+Any namespace to which the jenkins-operator is deployed must be considered to implicitly grant all
+possible permissions to any subject which can create a Pod in that namespace.
To mitigate this issue jenkins-operator should be deployed in one namespace and the Jenkins CR should be created in separate namespace. +To achieve it change watch namespace in https://github.com/jenkinsci/kubernetes-operator/blob/master/deploy/operator.yaml#L25
+ +You need to create two namespaces, for example we’ll call them jenkins for Jenkins and jenkins-operator for Jenkins Operator.
+$ kubectl create ns jenkins-operator
+$ kubectl create ns jenkinsNext, apply the RBAC manifests for jenkins-operator namespace
+$ kubectl -n jenkins-operator apply -f deploy/service_account.yaml
+$ kubectl -n jenkins-operator apply -f deploy/role_binding.yamlCreate file role_binding_jenkins.yaml in deploy folder:
kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: jenkins-operator
+ namespace: jenkins
+subjects:
+- kind: ServiceAccount
+ name: jenkins-operator
+ namespace: jenkins-operator
+roleRef:
+ kind: Role
+ name: jenkins-operator
+ apiGroup: rbac.authorization.k8s.ioThen, apply RBAC rules for jenkins namespace
+$ kubectl -n jenkins apply -f deploy/role.yaml
+$ kubectl -n jenkins apply -f role_binding_jenkins.yamlFinally, you must create operator pod by:
+$ kubectl -n jenkins -n jenkins-operator apply -f deploy/operator.yamlIf you find a vulnerability or any misconfiguration in Jenkins, please report it in the issues.
+ +Deploy Jenkins Operator and configure your Jenkins instances in Kubernetes +
+ +AWS EBS volume attach/detach issue when using PVC
+ + +Use groovy scripts or casc to configure your Jenkins instance
+ + +Enable CSRF, disable usage stats, enable master access control and more by default
+ + +Less chance to lose data
+ + +Improve user experience by informing what has been done
+ + +Prevent job history loss
+ + +We do a Pull Request contributions workflow on GitHub. New users are always welcome!
+ + +Learning the usage of Jenkins Operator will make your life easier. After that, you can easily contribute to the project.
+ + +Help us work on the software by reporting or fixing bugs. Make the Jenkins Operator better.
+ + +