Helm fails to pass double quotes into values.yaml from the command line? - kubernetes

I have a Helm chart with values.yaml containing:
# Elided
tolerations: []
I'm trying to pass the tolerations via the command line but it always removes the quotes (or adds double quotes inside single quotes) despite all the below attempts. As a result it fails on install saying it expected a string.
# Attempt 0
helm install traefik traefik/traefik --set tolerations[0].key=CriticalAddonsOnly --set tolerations[0].value="true" --set tolerations[0].operator=Equal --set tolerations[0].effect=NoExecute
# Attempt 1
helm install traefik traefik/traefik --set tolerations[0].key=CriticalAddonsOnly --set "tolerations[0].value="true"" --set tolerations[0].operator=Equal --set tolerations[0].effect=NoExecute
# Attempt 2
helm install traefik traefik/traefik --set tolerations[0].key=CriticalAddonsOnly --set "tolerations[0].value=\"true\"" --set tolerations[0].operator=Equal --set tolerations[0].effect=NoExecute
# Attempt 3
helm install traefik traefik/traefik --set tolerations[0].key=CriticalAddonsOnly --set tolerations[0].value="\"true\"" --set tolerations[0].operator=Equal --set tolerations[0].effect=NoExecute
# Attempt 4
helm install traefik traefik/traefik --set tolerations[0].key=CriticalAddonsOnly --set tolerations[0].value='"true"' --set tolerations[0].operator=Equal --set tolerations[0].effect=NoExecute
They all end up creating a yaml with value: true or value: '"true"', neither of which will install.

There appears to be two answers: the exceptionally verbose one that you're trying has a solution, or the more succinct one which doesn't prompt stack overflow questions for future readers to understand:
Helm offers --set-string which is the interpolation-free version of --set
helm install traefik traefik/traefik \
--set tolerations[0].key=CriticalAddonsOnly \
--set-string tolerations[0].value=true \
--set tolerations[0].operator=Equal \
--set tolerations[0].effect=NoExecute
However, as you experienced, that --set syntax is designed for the simplest cases only, for more complex cases --values is the correct mechanism. You can read them from stdin if created a temporary yaml file is too much work
printf 'tolerations: [{key: CriticalAddonsOnly, value: "true", operator: Equal, effect: NoExecute}]\n' | \
helm install traefik traefik/traefik --values /dev/stdin

Related

Datadog: API Key invalid dropping transaction when installing Datadog agent

I'm trying to install Datadog agent for a Kubernetes cluster using Helm.
This is the helm command I'm using for it:
helm repo add datadog https://helm.datadoghq.com
helm repo update
helm upgrade --install datadog datadog/datadog \
--namespace monitoring \
--create-namespace \
--atomic \
--set datadog.apiKey=<MY-DATADOG-API-KEY> \
--set targetSystem=linux \
--values values.yaml
Values file:
datadog:
kubelet:
host:
valueFrom:
fieldRef:
fieldPath: spec.nodeName
hostCAPath: /etc/kubernetes/certs/kubeletserver.crt
tlsVerify: false # Required as of Agent 7.35. See Notes.
However, when I run the liveness probe error with error 500 which shows the error below:
CLUSTER | ERROR | (pkg/forwarder/transaction/transaction.go:344 in internalProcess) | API Key invalid, dropping transaction for https://orchestrator.datadoghq.com/api/v1/orchestrator.
Here's how I solved it:
The issue had to do with the Datadog Destination Site. The Destination site for my metrics, traces, and logs is supposed to be datadoghq.eu. This is set using the variable DD_SITE, and it defaults to datadoghq.com if it is not set.
To check what your Datadog Destination Site just look at the URL of your Datadog dashboard:
For US it will be - https://app.datadoghq.com/
For EU it will be - https://app.datadoghq.eu/
To set this in your helm chart simply do either of the following:
helm repo add datadog https://helm.datadoghq.com
helm repo update
helm upgrade --install datadog datadog/datadog \
--namespace monitoring \
--create-namespace \
--atomic \
--set datadog.apiKey=<MY-DATADOG-API-KEY> \
--set targetSystem=linux \
--set datadog.site=datadoghq.eu \
--values values.yaml
OR set it in your values file:
datadog:
site: datadoghq.eu
kubelet:
host:
valueFrom:
fieldRef:
fieldPath: spec.nodeName
hostCAPath: /etc/kubernetes/certs/kubeletserver.crt
tlsVerify: false # Required as of Agent 7.35. See Notes.
References:
Datadog Agent Forwarder fails liveness probe when new spot instance joins cluster, causing multiple restarts #1697
DD_SITE Set to us3.datadoghq.com, but process-agent and security-agent Still Try to Connect to non us3 endpoints #9180

Provide nodeSelector to nginx ingress using helm

I spent some time looking into how to pass the parameters to helm in order to configure the nodeSelector properly.
Different tries led to different errors like:
Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: ValidationError(Deployment.spec.template.spec.nodeSelector.kubernetes): invalid type for io.k8s.api.core.v1.PodSpec.nodeSelector: got "map", expected "string"
coalesce.go:196: warning: cannot overwrite table with non table for nodeSelector (map[])
Reference: https://learn.microsoft.com/en-us/azure/aks/ingress-static-ip
In the link above, we can see how it should be used:
helm install nginx-ingress stable/nginx-ingress \
--namespace $NAMESPACE \
--set controller.replicaCount=1 \
--set controller.nodeSelector."kubernetes\.io/hostname"=$LOADBALANCER_NODE \
--set controller.service.loadBalancerIP="$LOADBALANCER_IP" \
--set controller.extraArgs.default-ssl-certificate="$NAMESPACE/$LOADBALANCER_NODE-ssl"
In general it is a good source to look into helm help: https://helm.sh/docs/intro/using_helm/#the-format-and-limitations-of---set
Here you can find all the nginx parameters: https://github.com/helm/charts/tree/master/stable/nginx-ingress

Set extraEnvs ingress variable

I'm trying to use extraEnv property in order to add additional environment variables to set in the pod using helm charts.
I have a values.yaml file that includes:
controller:
service:
loadBalancerIP:
extraEnvs:
- name: ev1
value:
- name: ev2
value
first I've set the loadBalancerIP the following way:
helm template path/charts/ingress --set nginx-ingress.controller.service.loadBalancerIP=1.1.1.1 --output-dir .
In order to set extraEnvs values I've tried to use the same logic by doing:
helm template path/charts/ingress --set nginx-ingress.controller.service.loadBalancerIP=1.1.1.1 --set nginx-ingress.controller.extraEnvs[0].value=valueEnv1--set nginx.controller.extraEnvs[1].value=valueEnv2--output-dir .
But it doesn't work. I looked for the right way to set those variables but couldn't find anything.
Helm --set has some limitations.
Your best option is to avoid using the --set, and use the --values flag with your values.yaml file instead:
helm template path/charts/ingress \
--values=values.yaml
If you want to use --set anyway, the equivalent command should have this notation:
helm template path/charts/ingress \
--set=controller.service.loadBalancerIP=1.1.1.1 \
--set=controller.extraEnvs[0].name=ev1,controller.extraEnvs[0].value=valueEnv1 \
--set=controller.extraEnvs[1].name=ev2,controller.extraEnvs[1].value=valueEnv2 \
--output-dir .

Helm [stable/nginx-ingress] Getting issue while passing headers

Version of Helm and Kubernetes: Client: &version.Version{SemVer:"v2.14.1" and 1.13.7-gke.24
Which chart: stable/nginx-ingress [v0.24.1]
What happened: Trying to override headers using--set-string but it does not work as expected. It always gives issues with the parsing
/usr/sbin/helm install --name cx-nginx-1 --set controller.name=cx-nginx-1 --set controller.kind=Deployment --set controller.service.loadBalancerIP= --set controller.metrics.enabled=true --set-string 'controller.headers={"X-Different-Name":"true","X-Request-Start":"test-header","X-Using-Nginx-Controller":"true"}' . Error: release cx-nginx-1 failed: ConfigMap in version "v1" cannot be handled as a ConfigMap: v1.ConfigMap.Data: ReadMapCB: expect { or n, but found [, error found in #10 byte of ...|","data":["\"X-Diffe|..., bigger context ...|{"apiVersion":"v1","data":["\"X-Different-Name\":\"true\"","\"X-Request-Start|...
What you expected to happen: I want to override the header which the there by default in values.yam with custom headers
How to reproduce it (as minimally and precisely as possible):
I have provided the comment to reproduce,
helm install --name cx-nginx-1 --set controller.name=cx-nginx-1 --set controller.kind=Deployment --set controller.service.loadBalancerIP= --set controller.metrics.enabled=true --set-string 'controller.headers={"X-Different-Name":"true","X-Request-Start":"test-header","X-Using-Nginx-Controller":"true"}' .
I tried to run in debug mode (--dry-run --debug), It shows me configmap like below,
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1
component: "cx-nginx-1"
heritage: Tiller
release: foiled-coral
name: foiled-coral-nginx-ingress-custom-headers
namespace: cx-ingress
data:
- X-Different-Name:true
- X-Request-Start:test-header
- X-Using-Nginx-Controller:true
It seems like its adding intent 4 instead of intent 2. Below warning also i'm getting,
Warning: Merging destination map for chart 'nginx-ingress'. Cannot overwrite table item 'headers', with non table value: map[X-Different-Name:true X-Request-Start:test-header X-Using-Nginx-Controller:true]
Kindly help me to pass the headers in the right way.
Note: controller.headers is deprecated, make sure to use the controller.proxySetHeaders instead.
Helm --set has some limitations.
Your best option is to avoid using the --set, and use the --values instead.
You can declare all your custom values in a file like this:
# values.yaml
controller:
name: "cx-nginx-1"
kind: "Deployment"
service:
loadBalancerIP: ""
metrics:
enable: true
proxySetHeaders:
X-Different-Name: "true"
X-Request-Start: "true"
X-Using-Nginx-Controller: "true"
Then use it on install:
helm install --name cx-nginx-1 stable/nginx-ingress \
--values=values.yaml
If you want to use --set anyway, you should use this notation:
helm install --name cx-nginx-1 stable/nginx-ingress \
--set controller.name=cx-nginx-1 \
--set controller.kind=Deployment \
--set controller.service.loadBalancerIP= \
--set controller.metrics.enabled=true \
--set-string controller.proxySetHeaders.X-Different-Name="true" \
--set-string controller.proxySetHeaders.X-Request-Start="true" \
--set-string controller.proxySetHeaders.X-Using-Nginx-Controller="true"

how install grafana with helm and with a path "/grafana" instead of path "/"

I've define a Ingress rule on path /grafana
I understand that I need also to configure root_url
I'm looking for the correct way to pass the root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana/ with a command line like :
helm install --namespace grafana -n grafana stable/grafana --set rbac.pspEnabled=false --set grafana.ini="{root_path = https://ingress-ops.nd-int-ops-paas.itn/grafana/ }"
I don't know what's wrong
--set 'grafana\.ini'.server.root_url=https://ingress-ops.nd-int-ops-paas.itn/grafana
works fine