Adding OpenShift doc

This commit is contained in:
Akram Ben Aissi 2020-04-29 12:37:24 +02:00
parent 83b3fa8cd0
commit 0a57ebb96e
6 changed files with 229 additions and 87 deletions

8
config.openshift.env Normal file
View File

@ -0,0 +1,8 @@
KUBERNETES_PROVIDER=crc
DOCKER_ORGANIZATION=image-registry.openshift-image-registry.svc:5000/jenkins-operator
DOCKER_REGISTRY=kubernetes-operator
IMAGE_PULL_MODE=remote
JENKINS_API_PORT=0
JENKINS_API_USE_NODEPORT=false
NAMESPACE=$(oc project -q)

View File

@ -7,64 +7,67 @@ metadata:
spec:
master:
containers:
- name: jenkins-master
command:
- /usr/bin/go-init
- '-main'
- /usr/libexec/s2i/run
env:
- name: OPENSHIFT_ENABLE_OAUTH
value: 'true'
- name: OPENSHIFT_ENABLE_REDIRECT_PROMPT
value: 'true'
- name: DISABLE_ADMINISTRATIVE_MONITORS
value: 'false'
- name: KUBERNETES_MASTER
value: 'https://kubernetes.default:443'
- name: KUBERNETES_TRUST_CERTIFICATES
value: 'true'
- name: JENKINS_SERVICE_NAME
value: jenkins-operator-http-example
- name: JNLP_SERVICE_NAME
value: jenkins-operator-slave-example
- name: JENKINS_UC_INSECURE
value: 'false'
- name: JENKINS_HOME
value: /var/lib/jenkins
- name: JAVA_OPTS
value: >-
-XX:+UnlockExperimentalVMOptions -XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1
-Djenkins.install.runSetupWizard=false -Djava.awt.headless=true
image: 'quay.io/openshift/origin-jenkins:latest'
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /login
port: 8080
scheme: HTTP
initialDelaySeconds: 420
periodSeconds: 360
timeoutSeconds: 240
readinessProbe:
httpGet:
path: /login
port: 8080
scheme: HTTP
initialDelaySeconds: 3
periodSeconds: 0
timeoutSeconds: 240
resources:
limits:
cpu: 600m
memory: 4Gi
requests:
cpu: 500m
memory: 3Gi
- name: jenkins-master
command:
- /usr/bin/go-init
- '-main'
- /usr/libexec/s2i/run
env:
- name: OPENSHIFT_ENABLE_OAUTH
value: 'true'
- name: OPENSHIFT_ENABLE_REDIRECT_PROMPT
value: 'true'
- name: DISABLE_ADMINISTRATIVE_MONITORS
value: 'false'
- name: KUBERNETES_MASTER
value: 'https://kubernetes.default:443'
- name: KUBERNETES_TRUST_CERTIFICATES
value: 'true'
- name: JENKINS_SERVICE_NAME
value: jenkins-operator-http-jenkins
- name: JNLP_SERVICE_NAME
value: jenkins-operator-slave-jenkins
- name: JENKINS_UC_INSECURE
value: 'false'
- name: JENKINS_HOME
value: /var/lib/jenkins
- name: JAVA_OPTS
value: >-
-XX:+UnlockExperimentalVMOptions -XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1
-Djenkins.install.runSetupWizard=false -Djava.awt.headless=true
image: 'quay.io/openshift/origin-jenkins:latest'
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /login
port: 8080
scheme: HTTP
initialDelaySeconds: 420
periodSeconds: 360
timeoutSeconds: 240
readinessProbe:
httpGet:
path: /login
port: 8080
scheme: HTTP
initialDelaySeconds: 3
periodSeconds: 0
timeoutSeconds: 240
resources:
limits:
cpu: 600m
memory: 4Gi
requests:
cpu: 500m
memory: 3Gi
service:
port: 8080
type: ClusterIP
slaveService:
port: 50000
type: ClusterIP
serviceAccount:
annotations:
serviceaccounts.openshift.io/oauth-redirectreference.jenkins: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"jenkins-operator"}}'

View File

@ -767,7 +767,12 @@ func TestEnsureExtraRBAC(t *testing.T) {
Roles: []rbacv1.RoleRef{},
},
}
reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{})
config := configuration.Configuration{
Client: fakeClient,
Jenkins: jenkins,
Scheme: scheme.Scheme,
}
reconciler := New(config, log.Log, client.JenkinsAPIConnectionSettings{})
metaObject := resources.NewResourceObjectMeta(jenkins)
// when
@ -803,7 +808,12 @@ func TestEnsureExtraRBAC(t *testing.T) {
},
},
}
reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{})
config := configuration.Configuration{
Client: fakeClient,
Jenkins: jenkins,
Scheme: scheme.Scheme,
}
reconciler := New(config, log.Log, client.JenkinsAPIConnectionSettings{})
metaObject := resources.NewResourceObjectMeta(jenkins)
// when
@ -845,7 +855,12 @@ func TestEnsureExtraRBAC(t *testing.T) {
},
},
}
reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{})
config := configuration.Configuration{
Client: fakeClient,
Jenkins: jenkins,
Scheme: scheme.Scheme,
}
reconciler := New(config, log.Log, client.JenkinsAPIConnectionSettings{})
metaObject := resources.NewResourceObjectMeta(jenkins)
// when
@ -888,7 +903,12 @@ func TestEnsureExtraRBAC(t *testing.T) {
},
},
}
reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, log.Log, client.JenkinsAPIConnectionSettings{})
config := configuration.Configuration{
Client: fakeClient,
Jenkins: jenkins,
Scheme: scheme.Scheme,
}
reconciler := New(config, log.Log, client.JenkinsAPIConnectionSettings{})
metaObject := resources.NewResourceObjectMeta(jenkins)
// when

View File

@ -6,17 +6,19 @@ import (
)
const (
createVerb = "create"
deleteVerb = "delete"
getVerb = "get"
listVerb = "list"
watchVerb = "watch"
patchVerb = "patch"
updateVerb = "update"
EmptyApiGroups = ""
OpenshiftApiGroup = "image.openshift.io"
BuildApiGroup = "build.openshift.io"
createVerb = "create"
deleteVerb = "delete"
getVerb = "get"
listVerb = "list"
watchVerb = "watch"
patchVerb = "patch"
updateVerb = "update"
//EmptyAPIGroup short hand for the empty API group while defining policies
EmptyAPIGroup = ""
//OpenshiftAPIGroup the openshift api group name
OpenshiftAPIGroup = "image.openshift.io"
//BuildAPIGroup the openshift api group name for builds
BuildAPIGroup = "build.openshift.io"
)
// NewRole returns rbac role for jenkins master
@ -54,22 +56,23 @@ func NewRoleBinding(name, namespace, serviceAccountName string, roleRef v1.RoleR
}
}
// NewDefaultPolicyRules sets the default policy rules
func NewDefaultPolicyRules() []v1.PolicyRule {
var rules []v1.PolicyRule
ReadOnly := []string{getVerb, listVerb, watchVerb}
Default := []string{createVerb, deleteVerb, getVerb, listVerb, patchVerb, updateVerb, watchVerb}
Create := []string{createVerb}
Default := []string{createVerb, deleteVerb, getVerb, listVerb, patchVerb, updateVerb, watchVerb}
Create := []string{createVerb}
rules = append(rules, NewPolicyRule(EmptyApiGroups, "pods/portforward", Create))
rules = append(rules, NewPolicyRule(EmptyApiGroups, "pods", Default))
rules = append(rules, NewPolicyRule(EmptyApiGroups, "pods/exec", Default))
rules = append(rules, NewPolicyRule(EmptyApiGroups, "configmaps", ReadOnly))
rules = append(rules, NewPolicyRule(EmptyApiGroups, "pods/log", ReadOnly))
rules = append(rules, NewPolicyRule(EmptyApiGroups, "secrets", ReadOnly))
rules = append(rules, NewPolicyRule(EmptyAPIGroup, "pods/portforward", Create))
rules = append(rules, NewPolicyRule(EmptyAPIGroup, "pods", Default))
rules = append(rules, NewPolicyRule(EmptyAPIGroup, "pods/exec", Default))
rules = append(rules, NewPolicyRule(EmptyAPIGroup, "configmaps", ReadOnly))
rules = append(rules, NewPolicyRule(EmptyAPIGroup, "pods/log", ReadOnly))
rules = append(rules, NewPolicyRule(EmptyAPIGroup, "secrets", ReadOnly))
rules = append(rules, NewOpenShiftPolicyRule(OpenshiftApiGroup, "imagestreams", ReadOnly))
rules = append(rules, NewOpenShiftPolicyRule(BuildApiGroup, "buildconfigs", ReadOnly))
rules = append(rules, NewOpenShiftPolicyRule(BuildApiGroup, "builds", ReadOnly))
rules = append(rules, NewOpenShiftPolicyRule(OpenshiftAPIGroup, "imagestreams", ReadOnly))
rules = append(rules, NewOpenShiftPolicyRule(BuildAPIGroup, "buildconfigs", ReadOnly))
rules = append(rules, NewOpenShiftPolicyRule(BuildAPIGroup, "builds", ReadOnly))
return rules
}
@ -84,8 +87,7 @@ func NewPolicyRule(apiGroup string, resource string, verbs []string) v1.PolicyRu
return rule
}
// NewPolicyRule returns a policyRule allowing verbs on resources
// NewOpenShiftPolicyRule returns a policyRule allowing verbs on resources
func NewOpenShiftPolicyRule(apiGroup string, resource string, verbs []string) v1.PolicyRule {
return NewPolicyRule(apiGroup,resource,verbs)
return NewPolicyRule(apiGroup, resource, verbs)
}

View File

@ -2,8 +2,10 @@ package base
import (
"context"
"fmt"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
"github.com/jenkinsci/kubernetes-operator/pkg/log"
stackerr "github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
@ -15,8 +17,11 @@ import (
func (r *ReconcileJenkinsBaseConfiguration) createServiceAccount(meta metav1.ObjectMeta) error {
serviceAccount := &corev1.ServiceAccount{}
err := r.Client.Get(context.TODO(), types.NamespacedName{Name: meta.Name, Namespace: meta.Namespace}, serviceAccount)
annotations := r.Configuration.Jenkins.Spec.ServiceAccount.Annotations
msg := fmt.Sprintf("createServiceAccount with annotations %v", annotations)
r.logger.V(log.VDebug).Info(msg)
if err != nil && apierrors.IsNotFound(err) {
serviceAccount = resources.NewServiceAccount(meta, r.Configuration.Jenkins.Spec.ServiceAccount.Annotations)
serviceAccount = resources.NewServiceAccount(meta, annotations)
if err = r.CreateResource(serviceAccount); err != nil {
return stackerr.WithStack(err)
}
@ -24,11 +29,11 @@ func (r *ReconcileJenkinsBaseConfiguration) createServiceAccount(meta metav1.Obj
return stackerr.WithStack(err)
}
if !compareMap(r.Configuration.Jenkins.Spec.ServiceAccount.Annotations, serviceAccount.Annotations) {
if !compareMap(annotations, serviceAccount.Annotations) {
if serviceAccount.Annotations == nil {
serviceAccount.Annotations = map[string]string{}
}
for key, value := range r.Configuration.Jenkins.Spec.ServiceAccount.Annotations {
for key, value := range annotations {
serviceAccount.Annotations[key] = value
}
if err = r.UpdateResource(serviceAccount); err != nil {

View File

@ -0,0 +1,104 @@
---
title: "OpenShift"
linkTitle: "OpenShift"
weight: 20
date: 2020-04-29
description: >
Additional configuration for OpenShift
---
## SecurityContext
OpenShift enforces Security Constraints Context (scc) when deploying an image.
By default, container images run in restricted scc which prevents from setting
a fixed user id to run with. You need to have ensure that you do not provide a
securityContext with a runAsUser and that your image does not use a hardcoded user.
```yaml
securityContext: {}
```
## OpenShift Jenkins image
OpenShift provides a pre-configured Jenkins image containing 3 openshift plugins for
jenkins (openshift-login-plugin, openshift-sync-plugin and openshift-client-plugin)
which allows better jenkins integration with kubernetes and OpenShift.
The OpenShift Jenkins image requires additional configuration to be fully enabled.
### Sample OpenShift CR
The following Custom Resource can be used to create a Jenkins instance using the
OpenShift Jenkins image and sets values for:
- `image: 'quay.io/openshift/origin-jenkins:latest' : This is the OpenShift Jenkins image.
- serviceAccount: to allow oauth authentication to work, the service account needs
a specific annotation pointing to the route exposing the jenkins service. Here,
the route is named `jenkins-route`
- `OPENSHIFT_ENABLE_OAUTH` environment variable for the master container is set to true.
Here is a complete Jenkins CR allowing the deployment of the Jenkins OpenShift image.
```yaml
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
annotations:
jenkins.io/openshift-mode: 'true'
name: jenkins
spec:
serviceAccount:
annotations:
serviceaccounts.openshift.io/oauth-redirectreference.jenkins: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"jenkins-route"}}'
master:
containers:
- name: jenkins-master
image: 'quay.io/openshift/origin-jenkins:latest'
command:
- /usr/bin/go-init
- '-main'
- /usr/libexec/s2i/run
env:
- name: OPENSHIFT_ENABLE_OAUTH
value: 'true'
- name: OPENSHIFT_ENABLE_REDIRECT_PROMPT
value: 'true'
- name: DISABLE_ADMINISTRATIVE_MONITORS
value: 'false'
- name: KUBERNETES_MASTER
value: 'https://kubernetes.default:443'
- name: KUBERNETES_TRUST_CERTIFICATES
value: 'true'
- name: JENKINS_SERVICE_NAME
value: jenkins-operator-http-jenkins
- name: JNLP_SERVICE_NAME
value: jenkins-operator-slave-jenkins
- name: JENKINS_UC_INSECURE
value: 'false'
- name: JENKINS_HOME
value: /var/lib/jenkins
- name: JAVA_OPTS
value: >-
-XX:+UnlockExperimentalVMOptions -XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1
-Djenkins.install.runSetupWizard=false -Djava.awt.headless=true
imagePullPolicy: Always
service:
port: 8080
type: ClusterIP
slaveService:
port: 50000
type: ClusterIP
```
### OpenShift OAuth integration
The creation of a Route is required for the integraiton of Jenkins with
OpenShift oauth authentication. By default, the jenkins http service is named
`jenkins-operator-http-${jenkins-cr-name}`
```bash
oc create route edge jenkins-route --service=jenkins-operator-http-jenkins
```
Note: the route name (jenkins-route) must match the pointed route on the serviceaccount annotation.
After the creation of the Route. It can be used to navigate to the Jenkins Login Page and login with your Openshift Credentials.