- Published on
How To Debug Helm Installs
- Authors
- Name
- Yair Mark
- @yairmark
When working with Helm charts it can take a bit of fiddling with chart values until you get it right. To debug this process I copy the values.yaml from the original chart and tweak these values.
To get the chart's values file:
- Download the Helm chart for example
helm fetch stable/gocd -d .
- This will download the chart for
stable/gocd
to the current directory
- This will download the chart for
- The chart downloads as a tar which you will need to untar and then copy the values.yaml somewhere
- Open the copied file up and delete the values you are not interested in and change the values for the ones you want to try out
- Helm will use defaults for values you do not specify
- The default values are those that were in the original values.yaml file or if the given chart does something based on a given value in its templates
You can test whether a chart runs without errors using a provided values.yaml file by doing a dry run as follows:
> helm install -f values.yaml stable/gocd --name gocd --namespace pipeline --dry-run
NAME: gocd
If this release already exists you will get the following error when trying to do a dry run:
Error: a release named gocd already exists.
Run: helm ls --all gocd; to check the status of the release
Or run: helm del --purge gocd; to delete it
If you want to see what is going with Helm in terms of how it is resolving values in the templates then use --dry-run
and --debug
as below:
> helm install -f values.yaml stable/gocd --name gocd --namespace pipeline --dry-run --debug
[debug] Created tunnel using local port: '38721'
[debug] SERVER: "127.0.0.1:38721"
[debug] Original chart version: ""
[debug] Fetched stable/gocd to /home/youruser/.helm/cache/archive/gocd-1.2.0.tgz
[debug] CHART PATH: /home/youruser/.helm/cache/archive/gocd-1.2.0.tgz
NAME: gocd
REVISION: 1
RELEASED: Thu Jul 26 17:03:33 2018
CHART: gocd-1.2.0
USER-SUPPLIED VALUES:
server:
persistence:
storageClassName: gluster
COMPUTED VALUES:
agent:
env:
agentAutoRegisterEnvironemnts: null
agentAutoRegisterHostname: null
agentAutoRegisterKey: null
agentAutoRegisterResources: null
goAgentBootstrapperArgs: null
goAgentBootstrapperJvmArgs: null
goAgentSystemProperties: null
goServerUrl: null
healthCheck:
enabled: false
failureThreshold: 60
initialDelaySeconds: 60
periodSeconds: 60
image:
pullPolicy: IfNotPresent
repository: gocd/gocd-agent-alpine-3.6
tag: null
nodeSelector: {}
persistence:
accessMode: ReadWriteOnce
enabled: false
existingClaim: null
pvSelector: null
size: 1Gi
subpath:
dockerEntryPoint: scripts
homego: homego
replicaCount: 0
resources: {}
rbac:
apiVersion: v1beta1
create: true
roleRef: null
server:
enabled: true
env:
extraEnvVars:
- name: GOCD_PLUGIN_INSTALL_kubernetes-elastic-agents
value: https://github.com/gocd/kubernetes-elastic-agents/releases/download/v1.0.1/kubernetes-elastic-agent-1.0.1-107.jar
- name: GOCD_PLUGIN_INSTALL_docker-registry-artifact-plugin
value: https://github.com/gocd/docker-registry-artifact-plugin/releases/download/1.0.0/docker-registry-artifact-plugin-1.0.0-3.jar
goServerSystemProperties: null
healthCheck:
failureThreshold: 10
initialDelaySeconds: 90
periodSeconds: 15
image:
pullPolicy: IfNotPresent
repository: gocd/gocd-server
tag: null
ingress:
annotations: null
enabled: true
tls: null
nodeSelector: {}
persistence:
accessMode: ReadWriteOnce
enabled: true
existingClaim: null
pvSelector: null
size: 2Gi
storageClassName: gluster
subpath:
dockerEntryPoint: scripts
godata: godata
homego: homego
resources: {}
service:
annotations: null
httpPort: 8153
httpsPort: 8154
nodeHttpPort: null
nodeHttpsPort: null
type: NodePort
shouldPreconfigure: true
serviceAccount:
create: true
name: null
HOOKS:
---
# gocd-test-gpk0a
apiVersion: v1
kind: Pod
metadata:
name: "gocd-test-gpk0a"
labels:
app: gocd
chart: "gocd-1.2.0"
release: "gocd"
heritage: "Tiller"
annotations:
"helm.sh/hook": test-success
spec:
initContainers:
- name: "test-framework"
image: "dduportal/bats:0.4.0"
command:
- "bash"
- "-c"
- |
set -ex
# copy bats to tools dir
cp -R /usr/local/libexec/ /tools/bats/
volumeMounts:
- mountPath: /tools
name: tools
containers:
- name: gocd-ui-test
image: "gocddev/gocd-helm-build:v0.1.0"
command: ["/tools/bats/bats", "-t", "/tests/run.sh"]
volumeMounts:
- mountPath: /tests
name: tests
readOnly: true
- mountPath: /tools
name: tools
volumes:
- name: tests
configMap:
name: gocd-tests
- name: tools
emptyDir: {}
restartPolicy: Never
MANIFEST:
---
# Source: gocd/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: gocd
labels:
app: gocd
chart: "gocd-1.2.0"
release: "gocd"
heritage: "Tiller"
data:
preconfigure_server.sh: |-
#!/bin/bash
SERVICE_ACCOUNT_PATH=/var/run/secrets/kubernetes.io/serviceaccount
KUBE_TOKEN=$(<${SERVICE_ACCOUNT_PATH}/token)
while true
do
status_code=$(curl 'http://localhost:8153/go/api/v1/health' -o /dev/null -w "%{http_code}")
if [ $status_code == 200 ]; then
break
fi
sleep 10
done
set -e
echo "checking if server has already been configured" >> /godata/logs/preconfigure.log
if [ -f /godata/logs/preconfigure_complete.log ]
then
echo "Existing server configuration found in cruise-config.xml. Skipping preconfigure_server scripts." >> /godata/logs/preconfigure.log
exit 0
fi
echo "No configuration found in cruise-config.xml. Using default preconfigure_server scripts to configure server" >> /godata/logs/preconfigure.log
echo "Trying to create an elastic profile now." >> /godata/logs/preconfigure.log
(curl --fail -i 'http://localhost:8153/go/api/elastic/profiles' \
-H 'Accept: application/vnd.go.cd.v1+json' \
-H 'Content-Type: application/json' \
-X POST -d '{
"id": "demo-app",
"plugin_id": "cd.go.contrib.elasticagent.kubernetes",
"properties": [
{
"key": "Image",
"value": "gocd/gocd-agent-docker-dind:v18.7.0"
},
{
"key": "PodConfiguration",
"value": "apiVersion: v1\nkind: Pod\nmetadata:\n name: pod-name-prefix-{\{ POD_POSTFIX }\}\n labels:\n app: web\nspec:\n containers:\n - name: gocd-agent-container-{\{ CONTAINER_POSTFIX }\}\n image: {\{ GOCD_AGENT_IMAGE }\}:{\{ LATEST_VERSION }\}\n securityContext:\n privileged: true"
},
{
"key": "SpecifiedUsingPodConfiguration",
"value": "false"
},
{
"key": "Privileged",
"value": "true"
}
]
}' >> /godata/logs/preconfigure.log)
echo "Trying to configure plugin settings." >> /godata/logs/preconfigure.log
(curl --fail -i 'http://localhost:8153/go/api/admin/plugin_settings' \
-H 'Accept: application/vnd.go.cd.v1+json' \
-H 'Content-Type: application/json' \
-X POST -d '{
"plugin_id": "cd.go.contrib.elasticagent.kubernetes",
"configuration": [
{
"key": "go_server_url",
"value": "https://gocd-server:8154/go"
},
{
"key": "kubernetes_cluster_url",
"value": "https://'$KUBERNETES_SERVICE_HOST':'$KUBERNETES_SERVICE_PORT_HTTPS'"
},
{
"key": "namespace",
"value": "pipeline"
},
{
"key": "security_token",
"value": "'$KUBE_TOKEN'"
}
]
}' >> /godata/logs/preconfigure.log)
echo "Trying to creating a hello world pipeline." >> /godata/logs/preconfigure.log
(curl --fail -i 'http://localhost:8153/go/api/admin/pipelines' \
-H 'Accept: application/vnd.go.cd.v5+json' \
-H 'Content-Type: application/json' \
-X POST -d '{ "group": "sample",
"pipeline": {
"label_template": "${COUNT}",
"name": "hello_world",
"materials": [
{
"type": "git",
"attributes": {
"url": "https://github.com/gocd-contrib/getting-started-repo",
"shallow_clone": true
}
}
],
"stages": [
{
"name": "default_stage",
"jobs": [
{
"name": "default_job",
"elastic_profile_id": "demo-app",
"tasks": [
{
"type": "exec",
"attributes": {
"command": "echo",
"arguments": [
"Hello World"
]
}
}
]
}
]
}
]
}
}' >> /godata/logs/preconfigure.log )
echo "Unpausing the pipeline." >> /godata/logs/preconfigure.log
(curl --fail -i 'http://localhost:8153/go/api/pipelines/hello_world/unpause' \
-H 'Accept: application/vnd.go.cd.v1+json' \
-H 'X-GoCD-Confirm: true' \
-X POST >> /godata/logs/preconfigure.log)
echo "Done preconfiguring the GoCD server" > /godata/logs/preconfigure_complete.log
---
# Source: gocd/templates/test-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: gocd-tests
labels:
app: gocd
chart: "gocd-1.2.0"
release: "gocd"
heritage: "Tiller"
data:
run.sh: |-
@test "Testing GoCD UI is accessible" {
curl --connect-timeout 10 --retry 12 --retry-delay 10 --retry-max-time 90 "http://gocd-server:8153/go/auth/login"
}
@test "Testing GoCD application is accessible through service" {
curl --retry 2 --retry-delay 10 --retry-max-time 90 http://gocd-server:8153/go
}
---
# Source: gocd/templates/gocd-server-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: gocd-server
labels:
app: gocd
chart: "gocd-1.2.0"
release: "gocd"
heritage: "Tiller"
component: server
spec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: "2Gi"
---
# Source: gocd/templates/gocd-ea-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: gocd
labels:
chart: "gocd-1.2.0"
app: "gocd"
heritage: "Tiller"
release: "gocd"
---
# Source: gocd/templates/gocd-ea-cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: gocd
labels:
chart: "gocd-1.2.0"
app: "gocd"
heritage: "Tiller"
release: "gocd"
rules:
- apiGroups: [""]
resources:
- pods
- pods/log
verbs: ["*"]
- apiGroups: [""]
resources:
- nodes
verbs: ["get", "list"]
- apiGroups: [""]
resources:
- events
verbs: ["list", "watch"]
- apiGroups: [""]
resources:
- namespaces
verbs: ["list", "get"]
---
# Source: gocd/templates/gocd-ea-cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: gocd
labels:
chart: "gocd-1.2.0"
app: "gocd"
heritage: "Tiller"
release: "gocd"
subjects:
- kind: ServiceAccount
name: gocd
namespace: pipeline
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: gocd
---
# Source: gocd/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: gocd-server
annotations:
labels:
app: gocd
chart: "gocd-1.2.0"
release: "gocd"
heritage: "Tiller"
component: server
spec:
type: NodePort
ports:
- port: 8153
targetPort: 8153
protocol: TCP
name: http
- port: 8154
targetPort: 8154
protocol: TCP
name: https
selector:
app: gocd
release: "gocd"
component: server
---
# Source: gocd/templates/gocd-agent-deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: gocd-agent
labels:
app: gocd
chart: "gocd-1.2.0"
release: "gocd"
heritage: "Tiller"
component: agent
spec:
replicas: 0
selector:
matchLabels:
app: gocd
release: "gocd"
component: agent
template:
metadata:
labels:
app: gocd
release: "gocd"
component: agent
spec:
containers:
- name: gocd-agent
image: "gocd/gocd-agent-alpine-3.6:v18.7.0"
imagePullPolicy: IfNotPresent
resources:
{}
env:
- name: GO_SERVER_URL
value: "https://gocd-server:8154/go"
---
# Source: gocd/templates/gocd-server-deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: gocd-server
labels:
app: gocd
chart: "gocd-1.2.0"
release: "gocd"
heritage: "Tiller"
component: server
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: gocd
release: "gocd"
component: server
template:
metadata:
labels:
app: gocd
release: "gocd"
component: server
spec:
serviceAccountName: gocd
volumes:
- name: goserver-vol
persistentVolumeClaim:
claimName: gocd-server
- name: config-vol
configMap:
name: gocd
containers:
- name: gocd-server
image: "gocd/gocd-server:v18.7.0"
imagePullPolicy: IfNotPresent
env:
- name: GOCD_PLUGIN_INSTALL_kubernetes-elastic-agents
value: https://github.com/gocd/kubernetes-elastic-agents/releases/download/v1.0.1/kubernetes-elastic-agent-1.0.1-107.jar
- name: GOCD_PLUGIN_INSTALL_docker-registry-artifact-plugin
value: https://github.com/gocd/docker-registry-artifact-plugin/releases/download/1.0.0/docker-registry-artifact-plugin-1.0.0-3.jar
ports:
- containerPort: 8153
- containerPort: 8154
livenessProbe:
httpGet:
path: /go/api/v1/health
port: 8153
initialDelaySeconds: 90
periodSeconds: 15
failureThreshold: 10
readinessProbe:
httpGet:
path: /go/api/v1/health
port: 8153
initialDelaySeconds: 90
periodSeconds: 15
failureThreshold: 10
volumeMounts:
- name: goserver-vol
mountPath: /godata
subPath: godata
- name: goserver-vol
mountPath: /home/go
subPath: homego
- name: goserver-vol
mountPath: /docker-entrypoint.d
subPath: scripts
- name: config-vol
mountPath: /preconfigure_server.sh
subPath: preconfigure_server.sh
lifecycle:
postStart:
exec:
command: ["/bin/bash","/preconfigure_server.sh"]
resources:
{}
---
# Source: gocd/templates/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gocd-server
labels:
app: gocd
chart: "gocd-1.2.0"
release: "gocd"
heritage: "Tiller"
component: server
annotations:
spec:
backend:
serviceName: gocd-server
servicePort: 8153
rules: