mirror of
https://github.com/helm/charts.git
synced 2026-08-23 22:37:45 +00:00
Jenkins (#61)
* initial commit * Jenkins chart * Move jenkins to incubator * Update chart metadata * Optimize image layers * Update Jenkins readme * Use fullname template where possible * Templatize configmap name * Add icon to chart metadata * Add configurable JAVA_OPTS * Add NOTES.txt explaining next steps * Update to support namespaces * Update tests * Update test image
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
name: jenkins
|
||||
home: https://jenkins.io/
|
||||
version: 0.1.0
|
||||
description: A Jenkins Helm chart for Kubernetes.
|
||||
sources:
|
||||
- https://github.com/jenkinsci/jenkins
|
||||
- https://github.com/jenkinsci/docker-jnlp-slave
|
||||
maintainers:
|
||||
- name: Lachlan Evenson
|
||||
email: lachlan@deis.com
|
||||
- name: Vic Iglesias
|
||||
email: viglesias@google.com
|
||||
icon: https://wiki.jenkins-ci.org/download/attachments/2916393/logo.png
|
||||
@@ -0,0 +1,77 @@
|
||||
# Jenkins Helm Chart
|
||||
|
||||
Jenkins master and slave cluster utilizing the Jenkins Kubernetes plugin
|
||||
|
||||
* https://wiki.jenkins-ci.org/display/JENKINS/Kubernetes+Plugin
|
||||
|
||||
Inspired by the awesome work of Carlos Sanchez <carlos@apache.org>
|
||||
|
||||
## Chart Details
|
||||
This chart will do the following:
|
||||
|
||||
* 1 x Jenkins Master with port 8080 exposed on an external LoadBalancer
|
||||
* All using Kubernetes Deployments
|
||||
|
||||
## Get this chart
|
||||
|
||||
Download the latest release of the chart from the [releases](../../../releases) page.
|
||||
|
||||
Alternatively, clone the repo if you wish to use the development snapshot:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/kubernetes/charts.git
|
||||
```
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
$ helm install --name my-release jenkins-x.x.x.tgz
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The following tables lists the configurable parameters of the Jenkins chart and their default values.
|
||||
|
||||
### Jenkins Master
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------------------|----------------------------------|----------------------------------------------------------|
|
||||
| `Master.Name` | Jenkins master name | `jenkins-master` |
|
||||
| `Master.Image` | Master image name | `gcr.io/kubernetes-charts-ci/jenkins-master-k8s` |
|
||||
| `Master.ImageTag` | Master image tag | `v0.1.0` |
|
||||
| `Master.ImagePullPolicy` | Master image pull policy | `Always` |
|
||||
| `Master.Component` | k8s selector key | `jenkins-master` |
|
||||
| `Master.Cpu` | Master requested cpu | `200m` |
|
||||
| `Master.Memory` | Master requested memory | `256Mi` |
|
||||
| `Master.ServicePort` | k8s service port | `8080` |
|
||||
| `Master.ContainerPort`| Master listening port | `8080` |
|
||||
| `Master.SlaveListenerPort`| Listening port for agents | `50000` |
|
||||
|
||||
### Jenkins Agent
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------------------|----------------------------------|----------------------------------------------------------|
|
||||
| `Agent.Image` | Agent image name | `jenkinsci/jnlp-slave` |
|
||||
| `Agent.ImageTag` | Agent image tag | `2.52` | |
|
||||
| `Agent.Cpu` | Agent requested cpu | `200m` |
|
||||
| `Agent.Memory` | Agent requested memory | `256Mi` |
|
||||
|
||||
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`.
|
||||
|
||||
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
|
||||
|
||||
```bash
|
||||
$ helm install --name my-release -f values.yaml jenkins-x.x.x.tgz
|
||||
```
|
||||
|
||||
> **Tip**: You can use the default [values.yaml](values.yaml)
|
||||
|
||||
## Persistence
|
||||
|
||||
The Jenkins image stores persistence under `/var/jenkins_home` path of the container. A Persistent Volume
|
||||
Claim is used to keep the data across deployments. This is known to work in GCE, AWS, and minikube.
|
||||
|
||||
# Todo
|
||||
* Enable Docker-in-Docker or Docker-on-Docker support on the Jenkins agents
|
||||
@@ -0,0 +1,4 @@
|
||||
FROM jenkins:2.7.3
|
||||
RUN /usr/local/bin/install-plugins.sh kubernetes:0.8 workflow-aggregator:2.3 \
|
||||
&& mkdir -p /usr/share/jenkins/ref/secrets/ \
|
||||
&& echo "false" > /usr/share/jenkins/ref/secrets/slave-to-master-security-kill-switch
|
||||
@@ -0,0 +1,36 @@
|
||||
Getting Started:
|
||||
|
||||
1. Get your '{{ .Values.Master.AdminUser }}' user password by running:
|
||||
printf $(printf '\%o' `kubectl get secret --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath="{.data.jenkins-admin-password[*]}"`);echo
|
||||
|
||||
2. Get the Jenkins URL to visit by running these commands in the same shell:
|
||||
{{- if contains "NodePort" .Values.Master.ServiceType }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT/login
|
||||
|
||||
{{- else if contains "LoadBalancer" .Values.Master.ServiceType }}
|
||||
**** NOTE: It may take a few minutes for the LoadBalancer IP to be available. ****
|
||||
**** You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' ****
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
|
||||
echo http://$SERVICE_IP:{{ .Values.Master.ServicePort }}/login
|
||||
{{- else if contains "ClusterIP" .Values.Master.ServiceType }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "component={{ template "fullname" . }}-master" -o jsonpath="{.items[0].metadata.name}")
|
||||
echo http://127.0.0.1:{{ .Values.Master.ServicePort }}
|
||||
kubectl port-forward $POD_NAME {{ .Values.Master.ServicePort }}:{{ .Values.Master.ServicePort }}
|
||||
|
||||
{{- end }}
|
||||
|
||||
3. Login with the password from step 1 and the username: {{ .Values.Master.AdminUser }}
|
||||
|
||||
For more information on running Jenkins on Kubernetes, visit:
|
||||
https://cloud.google.com/solutions/jenkins-on-container-engine
|
||||
|
||||
{{- if .Values.Persistence.Enabled }}
|
||||
{{- else }}
|
||||
#################################################################################
|
||||
###### WARNING: Persistence is disabled!!! You will lose your data when #####
|
||||
###### the Jenkins pod is terminated. #####
|
||||
#################################################################################
|
||||
{{- end }}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 24 -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 24 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
*/}}
|
||||
{{- define "fullname" -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 24 -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,77 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ template "fullname" . }}
|
||||
data:
|
||||
config.xml: |-
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<hudson>
|
||||
<disabledAdministrativeMonitors/>
|
||||
<version>2.7.3</version>
|
||||
<numExecutors>0</numExecutors>
|
||||
<mode>NORMAL</mode>
|
||||
<useSecurity>true</useSecurity>
|
||||
<authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
|
||||
<denyAnonymousReadAccess>true</denyAnonymousReadAccess>
|
||||
</authorizationStrategy>
|
||||
<securityRealm class="hudson.security.LegacySecurityRealm"/>
|
||||
<disableRememberMe>false</disableRememberMe>
|
||||
<projectNamingStrategy class="jenkins.model.ProjectNamingStrategy$DefaultProjectNamingStrategy"/>
|
||||
<workspaceDir>${JENKINS_HOME}/workspace/${ITEM_FULLNAME}</workspaceDir>
|
||||
<buildsDir>${ITEM_ROOTDIR}/builds</buildsDir>
|
||||
<markupFormatter class="hudson.markup.EscapedMarkupFormatter"/>
|
||||
<jdks/>
|
||||
<viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
|
||||
<myViewsTabBar class="hudson.views.DefaultMyViewsTabBar"/>
|
||||
<clouds>
|
||||
<org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud plugin="kubernetes@0.8">
|
||||
<name>default</name>
|
||||
<templates>
|
||||
<org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
|
||||
<name>default</name>
|
||||
<image>{{ .Values.Agent.Image }}:{{ .Values.Agent.ImageTag }}</image>
|
||||
<privileged>false</privileged>
|
||||
<alwaysPullImage>false</alwaysPullImage>
|
||||
<command></command>
|
||||
<args></args>
|
||||
<remoteFs>/home/jenkins</remoteFs>
|
||||
<instanceCap>2147483647</instanceCap>
|
||||
<label></label>
|
||||
<nodeSelector></nodeSelector>
|
||||
<resourceRequestCpu>{{.Values.Agent.Cpu}}</resourceRequestCpu>
|
||||
<resourceRequestMemory>{{.Values.Agent.Memory}}</resourceRequestMemory>
|
||||
<resourceLimitCpu>{{.Values.Agent.Cpu}}</resourceLimitCpu>
|
||||
<resourceLimitMemory>{{.Values.Agent.Memory}}</resourceLimitMemory>
|
||||
<volumes/>
|
||||
<envVars/>
|
||||
<annotations/>
|
||||
<imagePullSecrets/>
|
||||
</org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
|
||||
</templates>
|
||||
<serverUrl>https://kubernetes.default</serverUrl>
|
||||
<skipTlsVerify>false</skipTlsVerify>
|
||||
<namespace>{{ .Release.Namespace }}</namespace>
|
||||
<jenkinsUrl>http://{{ template "fullname" . }}:8080</jenkinsUrl>
|
||||
<jenkinsTunnel>{{ template "fullname" . }}:50000</jenkinsTunnel>
|
||||
<containerCap>10</containerCap>
|
||||
<retentionTimeout>5</retentionTimeout>
|
||||
</org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud>
|
||||
</clouds>
|
||||
<quietPeriod>5</quietPeriod>
|
||||
<scmCheckoutRetryCount>0</scmCheckoutRetryCount>
|
||||
<views>
|
||||
<hudson.model.AllView>
|
||||
<owner class="hudson" reference="../../.."/>
|
||||
<name>All</name>
|
||||
<filterExecutors>false</filterExecutors>
|
||||
<filterQueue>false</filterQueue>
|
||||
<properties class="hudson.model.View$PropertyList"/>
|
||||
</hudson.model.AllView>
|
||||
</views>
|
||||
<primaryView>All</primaryView>
|
||||
<slaveAgentPort>50000</slaveAgentPort>
|
||||
<label></label>
|
||||
<nodeProperties/>
|
||||
<globalNodeProperties/>
|
||||
<noUsageStatistics>true</noUsageStatistics>
|
||||
</hudson>
|
||||
@@ -0,0 +1,15 @@
|
||||
{{- if .Values.Persistence.Enabled }}
|
||||
---
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ template "fullname" . }}
|
||||
annotations:
|
||||
volume.alpha.kubernetes.io/storage-class: {{ .Values.Persistence.StorageClass | quote }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.Persistence.AccessMode | quote }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.Persistence.Size | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,93 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ template "fullname" . }}
|
||||
labels:
|
||||
heritage: {{.Release.Service | quote }}
|
||||
release: {{.Release.Name | quote }}
|
||||
chart: "{{.Chart.Name}}-{{.Chart.Version}}"
|
||||
component: "{{.Release.Name}}-{{.Values.Master.Name}}"
|
||||
annotations:
|
||||
"helm.sh/created": {{.Release.Time.Seconds | quote }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
selector:
|
||||
matchLabels:
|
||||
component: "{{.Release.Name}}-{{.Values.Master.Component}}"
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
heritage: {{.Release.Service | quote }}
|
||||
release: {{.Release.Name | quote }}
|
||||
chart: "{{.Chart.Name}}-{{.Chart.Version}}"
|
||||
component: "{{.Release.Name}}-{{.Values.Master.Component}}"
|
||||
annotations:
|
||||
pod.alpha.kubernetes.io/init-containers: '[
|
||||
{
|
||||
"name": "copy-default-config",
|
||||
"image": "{{.Values.Master.Image}}:{{.Values.Master.ImageTag}}",
|
||||
"command": ["cp", "-n", "/var/jenkins_config/config.xml", "/var/jenkins_home"],
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "jenkins-config",
|
||||
"mountPath": "/var/jenkins_config"
|
||||
},
|
||||
{
|
||||
"name": "jenkins-home",
|
||||
"mountPath": "/var/jenkins_home"
|
||||
}
|
||||
]
|
||||
}
|
||||
]'
|
||||
spec:
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
containers:
|
||||
- name: {{ template "fullname" . }}
|
||||
image: "{{.Values.Master.Image}}:{{.Values.Master.ImageTag}}"
|
||||
imagePullPolicy: "{{.Values.Master.ImagePullPolicy}}"
|
||||
args: [ "--argumentsRealm.passwd.$(ADMIN_USER)=$(ADMIN_PASSWORD)", "--argumentsRealm.roles.$(ADMIN_USER)=admin"]
|
||||
env:
|
||||
- name: JAVA_OPTS
|
||||
value: "{{ default "" .Values.Master.JavaOpts}}"
|
||||
- name: ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ template "fullname" . }}
|
||||
key: jenkins-admin-password
|
||||
- name: ADMIN_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ template "fullname" . }}
|
||||
key: jenkins-admin-user
|
||||
ports:
|
||||
- containerPort: {{.Values.Master.ContainerPort}}
|
||||
name: http
|
||||
- containerPort: {{.Values.Master.SlaveListenerPort}}
|
||||
name: slavelistener
|
||||
resources:
|
||||
requests:
|
||||
cpu: "{{.Values.Master.Cpu}}"
|
||||
memory: "{{.Values.Master.Memory}}"
|
||||
volumeMounts:
|
||||
-
|
||||
mountPath: /var/jenkins_home
|
||||
name: jenkins-home
|
||||
readOnly: false
|
||||
-
|
||||
mountPath: /var/jenkins_config
|
||||
name: jenkins-config
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: jenkins-config
|
||||
configMap:
|
||||
name: {{ template "fullname" . }}
|
||||
- name: jenkins-home
|
||||
{{- if .Values.Persistence.Enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ template "fullname" . }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,22 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{template "fullname" . }}
|
||||
labels:
|
||||
heritage: {{.Release.Service | quote }}
|
||||
release: {{.Release.Name | quote }}
|
||||
chart: "{{.Chart.Name}}-{{.Chart.Version}}"
|
||||
component: "{{.Release.Name}}-{{.Values.Master.Component}}"
|
||||
annotations:
|
||||
"helm.sh/created": {{.Release.Time.Seconds | quote }}
|
||||
spec:
|
||||
ports:
|
||||
- port: {{.Values.Master.ServicePort}}
|
||||
name: http
|
||||
targetPort: {{.Values.Master.ContainerPort}}
|
||||
- port: {{.Values.Master.SlaveListenerPort}}
|
||||
targetPort: {{.Values.Master.SlaveListenerPort}}
|
||||
name: slavelistener
|
||||
selector:
|
||||
component: "{{.Release.Name}}-{{.Values.Master.Component}}"
|
||||
type: {{.Values.Master.ServiceType}}
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ template "fullname" . }}
|
||||
labels:
|
||||
app: {{ template "fullname" . }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: "{{ .Release.Name }}"
|
||||
heritage: "{{ .Release.Service }}"
|
||||
type: Opaque
|
||||
data:
|
||||
{{ if .Values.Master.AdminPassword }}
|
||||
jenkins-admin-password: {{ .Values.Master.AdminPassword | b64enc | quote }}
|
||||
{{ else }}
|
||||
jenkins-admin-password: {{ randAlphaNum 10 | b64enc | quote }}
|
||||
{{ end }}
|
||||
jenkins-admin-user: {{ .Values.Master.AdminUser | b64enc | quote }}
|
||||
@@ -0,0 +1,34 @@
|
||||
# Default values for jenkins.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare name/value pairs to be passed into your templates.
|
||||
# name: value
|
||||
|
||||
Master:
|
||||
Name: jenkins-master
|
||||
Image: "gcr.io/kubernetes-charts-ci/jenkins-master-k8s"
|
||||
ImageTag: "v0.1.0"
|
||||
ImagePullPolicy: "Always"
|
||||
Component: "jenkins-master"
|
||||
AdminUser: admin
|
||||
# AdminPassword: <defaults to random>
|
||||
Cpu: "200m"
|
||||
Memory: "256Mi"
|
||||
# Set min/max heap here if needed with:
|
||||
# JavaOpts: "-Xms512m -Xmx512m"
|
||||
ServicePort: 8080
|
||||
# For minikube, set this to NodePort, elsewhere use LoadBalancer
|
||||
ServiceType: LoadBalancer
|
||||
ContainerPort: 8080
|
||||
SlaveListenerPort: 50000
|
||||
|
||||
Agent:
|
||||
Image: jenkinsci/jnlp-slave
|
||||
ImageTag: 2.52
|
||||
Cpu: "200m"
|
||||
Memory: "256Mi"
|
||||
|
||||
Persistence:
|
||||
Enabled: true
|
||||
StorageClass: generic
|
||||
AccessMode: ReadWriteOnce
|
||||
Size: 8Gi
|
||||
+3
-3
@@ -24,15 +24,15 @@ ENV CLOUDSDK_CORE_DISABLE_PROMPTS=1 \
|
||||
RUN set -x \
|
||||
&& cd /opt \
|
||||
&& echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections \
|
||||
&& apt-get update -y \
|
||||
&& apt-get update \
|
||||
&& apt-get install --no-install-recommends -y jq wget python git localepurge ca-certificates \
|
||||
&& wget -q https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-x86_64.tar.gz \
|
||||
&& tar xfv google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-x86_64.tar.gz \
|
||||
&& tar zxfv google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-x86_64.tar.gz \
|
||||
&& ./google-cloud-sdk/install.sh \
|
||||
&& gcloud components install kubectl \
|
||||
&& gcloud config set project ${GOOGLE_PROJECT}
|
||||
RUN cd /opt && wget -q ${HELM_URL} \
|
||||
&& tar xzfv helm-${HELM_VERSION}-linux-amd64.tar.gz \
|
||||
&& tar xzfv helm-${HELM_VERSION}-linux-amd64.tar.gz
|
||||
RUN apt-get -y purge wget localepurge \
|
||||
&& apt-get clean \
|
||||
&& cd / \
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# TODO should we inject this. This is creating problems bumping the Docker version
|
||||
IMAGE_VERSION="test-image:v1.7"
|
||||
IMAGE_VERSION="test-image:v1.9"
|
||||
CHART_ROOT=${CHART_ROOT:-$(git rev-parse --show-toplevel)}
|
||||
IMAGE_NAME=${IMAGE_NAME:-"gcr.io/kubernetes-charts-ci/${IMAGE_VERSION}"}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
VERSION=v1.7
|
||||
VERSION=v1.9
|
||||
CONTAINER_NAME=test-image
|
||||
|
||||
usage() {
|
||||
|
||||
Reference in New Issue
Block a user