Using helm inside a k8s job - ssl

What configuration is needed to use helm within a k8s job? The error given is x509: certificate signed by unknown authority. What is needed to verify the certificates?
I am trying to use helm CLI tool within a k8s job using the alpine/helm. My cluster is running locally using minikube. For testing, I am trying to simply list all helm charts. Regular kubectl commands work on the cluster within a job. I suspect there is something special needed to configure to the CA certificate and have it be accessible by helm.
apiVersion: batch/v1
kind: Job
metadata:
name: helm-job
spec:
template:
spec:
containers:
- name: helm
image: alpine/helm
imagePullPolicy: Always
env:
- name: HELM_KUBEAPISERVER
value: "https://kubernetes.default.svc"
- name: HELM_DEBUG
value: "true"
command: [ "helm", "list" ]
restartPolicy: Never
automountServiceAccountToken: false
If automountServiceAccountToken is not set to false the Job crashes with the following error on start up: MountVolume.SetUp failed for volume "kube-api-access-rqc6l" : object "default"/"kube-root-ca.crt" not registered. When it is set to false the job has the following debug logs:
Error: Kubernetes cluster unreachable: Get "https://kubernetes.default.svc/version": x509: certificate signed by unknown authority
helm.go:84: [debug] Get "https://kubernetes.default.svc/version": x509: certificate signed by unknown authority
Kubernetes cluster unreachable
helm.sh/helm/v3/pkg/kube.(*Client).IsReachable
helm.sh/helm/v3/pkg/kube/client.go:121
helm.sh/helm/v3/pkg/action.(*List).Run
helm.sh/helm/v3/pkg/action/list.go:148
main.newListCmd.func1
helm.sh/helm/v3/cmd/helm/list.go:80
github.com/spf13/cobra.(*Command).execute
github.com/spf13/cobra#v1.3.0/command.go:856
github.com/spf13/cobra.(*Command).ExecuteC
github.com/spf13/cobra#v1.3.0/command.go:974
github.com/spf13/cobra.(*Command).Execute
github.com/spf13/cobra#v1.3.0/command.go:902
main.main
helm.sh/helm/v3/cmd/helm/helm.go:83
runtime.main
runtime/proc.go:255
runtime.goexit
runtime/asm_amd64.s:1581
Unfortunately, helm: x509: certificate signed by unknown authority is not a solution. The answers given using helm init is for helm v2 not v3. When setting insecure-skip-tls-verify: true the following error is thrown: Unable to restart cluster, will reset it: getting k8s client: specifying a root certificates file with the insecure flag is not allowed.
Edit:
The default service account is available on all my nodes. I did also try create separate service accounts.

Related

Consul Helm TLS erro: unknown PEM block type for signing key: CERTIFICATE

I'm trying to understand this error. I am deploying Consul with TLS and Consul Server and Clients. On the tls init containers I get this error.
kubectl logs consul-consul-tls-init-b2rfv
==> WARNING: Server Certificates grants authority to become a
server and access all state in the cluster including root keys
and all ACL tokens. Do not distribute them to production hosts
that are not server nodes. Store them as securely as CA keys.
==> Using /consul/tls/ca/cert/tls.crt and /consul/tls/ca/key/tls.key
unknown PEM block type for signing key: CERTIFICATE
I have tried to create CA certificate and the key in a number of ways. First I tried with openssl, then I tried with cfssl and finally I tried with the consul client. All the same error.
From best I can tell, the volumes are mounting from the secrets. Here is an example of my values.yaml I am deploying consul with through helm 3.
global:
gossipEncryption:
secretName: "gossip"
secretKey: "key"
tls:
enabled: true
verify: false # only for troubleshooting hoping it would help, also tried with true
caCert:
secretName: "consul-tls-ca"
secretKey: "tls.crt"
caKey:
secretName: "consul-server-tls"
secretKey: "tls.crt"
Examples of how I create my gossip and tls secrets
export GOSSIP_ENCRYPTION_KEY=$(consul keygen)
kubectl create secret generic gossip --from-literal="key=${GOSSIP_ENCRYPTION_KEY}"
kubectl create secret generic consul-tls-ca --from-file="tls.crt=./ca.pem"
kubectl create secret generic consul-server-tls --from-file="tls.crt=./server.pem" --from-file="tls.key=./server-key.pem"
I have not found any similar reported errors from others by googling or searching SO. Hashicorps documentation says nothing about it, or I have not found it.
They fixed it in consul 1.10 - previously it knew only ECP certificates. More in https://github.com/hashicorp/consul/issues/7622

Cert Manager - Cluster Issuer Error - tls: handshake failure

I've setup cert mananger on microk8s following these instructions, I had it working 6 months ago but have since had to start again from scratch. Now when I setup my Cluster Issuer I'm getting the error below.
Everything else seems fine and in a good state. I'm struggling to know where to start debugging this.
Error initializing issuer: Get "https://acme-v02.api.letsencrypt.org/directory": remote error: tls: handshake failure
Cluster Issuer yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: <myemail>
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: prod-issuer-account-key
solvers:
- http01:
ingress:
class: nginx
UPDATE
Some extra info
All pods for cert manager are running, here are the logs
cert-manager pod logs
cert-manager-cainjector logs only shows some warnings about deprecated apis
cert-mananger-webhook logs
Describe ClusterIssuer
I've tried to get a cert for an ingress resource but it errors saying the cluster issuer isn't in a ready state
After uninstalling and reinstalling everything including Microk8s I tried again no luck. Then I tried using the latest helm chart v1.0.2 which had a newer cert-manager version, seemed to work straight away.
Another note, mainly to myself. This issue was also caused by having search domains setup in netplan, once removed everything started working.

Is it possible to use PodPresets in OpenShift 3.11 (3.7+)?

I've installed an OpenShift cluster for testing purposes, and since I'm behind a corporate network, I need to include some Root Certificates in any Pod that wants to make external requests. What can I do to inject those certificates automatically at Pod creation?
I'm running OpenShift Origin (OKD) 3.11 in a local CentOS 7 VM, with a GlusterFS storage provisioning on top of it. I already had multiple issues with the VM itself, which gave me errors when trying to access the network: x509: certificate signed by unknown authority. I fixed that by adding my corporation root certificates in /etc/pki/ca-trust/source/anchors and by running the update-ca-trust command.
When I was running for example the docker-registry deployment in the OpenShift cluster, since the created Pods didn't have access to the host root certificates, they gave again x509: certificate signed by unknown authority errors when trying to pull images from docker.io. I resolved that by creating a ConfigMap containing all needed root certificates, and mounting them in a volume on the registry deployment config.
I thought I only needed to mount a volume in all deployment configs which want to request the external network. But then I provisioned a Jenkins instance and I realised something new: When a pipeline runs, Jenkins creates a Pod with an adapted agent (example: a Spring Boot app will need a Maven agent). Since I have no control to those created pods, they can't have the mounted volume with all root certificates. So for instance I have a pipeline that runs helm init --client-only before releasing my app chart, and this command gives a x509: certificate signed by unknown authority error, because this pod hasn't the root certificates.
x509 Error screenshot
I found that a PodPreset could be the perfect way to resolve my problem, but when I enable this feature in the cluster and create the PodPreset, no new pod is populated. I read on the OpenShift documentation that PodPresets are no longer supported as of 3.7, so I think that it could be the reason it is not working.
OpenShift docs screenshot
Here is my PodPreset definition file:
kind: PodPreset
apiVersion: settings.k8s.io/v1alpha1
metadata:
name: inject-certs
spec:
selector: {}
volumeMounts:
- mountPath: /etc/ssl/certs/cert1.pem
name: ca
subPath: cert1.pem
- mountPath: /etc/ssl/certs/cert2.pem
name: ca
subPath: cert2.pem
- mountPath: /etc/ssl/certs/cert3.pem
name: ca
subPath: cert3.pem
- mountPath: /etc/ssl/certs/cert4.pem
name: ca
subPath: cert4.pem
- mountPath: /etc/ssl/certs/cert5.pem
name: ca
subPath: cert5.pem
- mountPath: /etc/ssl/certs/cert6.pem
name: ca
subPath: cert6.pem
volumes:
- configMap:
defaultMode: 420
name: ca-pemstore
name: ca
I don't know if there is any way to make PodPresets work on OpenShift 3.11, or if there is another solution to inject certs file like this in created pods. This would be really great.
The RedHat COP on GitHub contains a project with a podpresent admission webhook controller you can use:
https://github.com/redhat-cop/podpreset-webhook
basically you deploy that project and change the apiVersion in your PodPresent to apiVersion: redhatcop.redhat.io/v1alpha1

Kubernetes/Ingress Nginx/Cert Manager certificates have namespaces?

I am trying to deploy the "cert-manager" (https://github.com/jetstack/cert-manager) project which is the successor to "kube-lego". I'm finding that the certificates don't match what is being created, and I'm wondering if anybody else has tried this before.
I am creating a tls secretName with "monitoring-xxx-com", and in the ingress-nginx logs I find that it's trying to search for namespace/monitoring-xxx-com and not finding what it expects.
I am wondering whether this is because ingress-nginx is trying to use the pods namespace automatically and cert-manager is creating certs without a namespace, therefore that's why the cert can never be found.
error obtaining PEM from secret kube-system/monitoring-xxx-com: error
retrieving secret kube-system/monitoring-xxx-com: secret kube-
system/monitoring-xxx-com was not found
and in the certificate created by "cert-manager":
Issuer Ref:
Kind: ClusterIssuer
Name: letsencrypt-staging
Secret Name: monitoring-xxx-com
The secret and the nginx ingress controller are in a different namespace, there is an option where you can set the certificate from another namespace.
https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/cli-arguments.md
--default-ssl-certificate string Name of the secret
that contains a SSL certificate to be used as default for a HTTPS catch-all server.
Takes the form <namespace>/<secret name>.
To find the namespace of your secret:
kubectl describe secrets/monitoring-xxx-com
Using the default-ssl-certificate in the deployment template
spec:
template:
spec:
containers:
- args:
- /nginx-ingress-controller
- "--default-backend-service=$(POD_NAMESPACE)/default-http-backend"
- "--default-ssl-certificate=$(POD_NAMESPACE)/tls-certificate"

helm: x509: certificate signed by unknown authority

I'm using Kubernetes and I recently updated my admin certs used in the kubeconfig. However, after I did that, all the helm commands fail thus:
Error: Get https://cluster.mysite.com/api/v1/namespaces/kube-system/pods?labelSelector=app%3Dhelm%2Cname%3Dtiller: x509: certificate signed by unknown authority
kubectl works as expected:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-1-0-34.eu-central-1.compute.internal Ready master 42d v1.7.10+coreos.0
ip-10-1-1-51.eu-central-1.compute.internal Ready master 42d v1.7.10+coreos.0
ip-10-1-10-120.eu-central-1.compute.internal Ready <none> 42d v1.7.10+coreos.0
ip-10-1-10-135.eu-central-1.compute.internal Ready <none> 27d v1.7.10+coreos.0
ip-10-1-11-71.eu-central-1.compute.internal Ready <none> 42d v1.7.10+coreos.0
ip-10-1-12-199.eu-central-1.compute.internal Ready <none> 8d v1.7.10+coreos.0
ip-10-1-2-110.eu-central-1.compute.internal Ready master 42d v1.7.10+coreos.0
As far as I've been able to read, helm is supposed to use the same certificates as kubectl, which makes me curious as how how kubectl works, but helm doesn't?
This is a production cluster with internal releases handled through helm charts, so it being solved is imperative.
Any hints would be greatly appreciated.
As a workaround you can try to disable certificate verification. Helm uses the kube config file (by default ~/.kube/config). You can add insecure-skip-tls-verify: true for the cluster section:
clusters:
- cluster:
server: https://cluster.mysite.com
insecure-skip-tls-verify: true
name: default
Did you already try to reinstall helm/tiller?
kubectl delete deployment tiller-deploy --namespace kube-system
helm init
Also check if you have configured an invalid certificate in the cluster configuration.
In my case, I was running for a single self-manage and the config file was also container ca-file, so the following the above answer was throwing below error
Error: Kubernetes cluster unreachable: Get "https://XX.XX.85.154:6443/version?timeout=32s": x509: certificate is valid for 10.96.0.1, 172.31.25.161, not XX.XX.85.154
And my config was
- cluster:
certificate-authority-data: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
server: https://54.176.85.154:6443
insecure-skip-tls-verify: true
So I had to remove the certificate-authority-data.
- cluster:
server: https://54.176.85.154:6443
insecure-skip-tls-verify: true
Use --insecure-skip-tls-verify to skip tls verification via command line
helm repo add stable --insecure-skip-tls-verify https://charts.helm.sh/stable
In my case the error was caused by an untrusted certificate from the Helm repository.
Downloading the certificate and specifying it using the --ca-file option solved the issue (at least in Helm version 3).
helm repo add --ca-file /path/to/certificate.crt repoName https://example/repository
--ca-file string, verify certificates of HTTPS-enabled servers using this CA bundle
Adding the line below the -cluster to /home/centos/.kube/config file fixed my issue
insecure-skip-tls-verify: true
fixed my issue.
my config file now looks like this.
apiVersion: v1
clusters:
- cluster:
certificate-authority: /home/centos/.minikube/ca.crt
extensions:
- extension:
last-update: Tue, 02 Nov 2021 20:51:44 EDT
provider: minikube.sigs.k8s.io
version: v1.23.2
name: cluster_info
server: https://192.168.49.2:8443
insecure-skip-tls-verify: true
name: minikube
contexts:
I encountered an edge case for this. You can also get this error if you have multiple kubeconfig files referenced in the KUBECONFIG variable, and more than one file has clusters with the same name.
For my case, it was an old version of helm (v. 3.6.3 in my case) after I upgraded to helm v.3.9.0 brew upgrade helm everything worked again.
Although adding repo with --ca-file did the thing, when it tried to download from that repo with the command posted under, I still got the x509: certificate signed by unknown authority
helm dependency update helm/myStuff
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "myRepo" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 18 charts
Downloading myService from repo https://myCharts.me/
Save error occurred: could not download https://myCharts.me/stuff.tgz ...
x509: certificate signed by unknown authority
Deleting newly downloaded charts, restoring pre-update state
What I needed to do, apart from adding repo with --ca-file was to download the repository certificate and install it as Current User:
Place all certificates in the following store: Trusted Root Certification Authorities:
After installing the certificate I also needed to restart the computer. After restart, when you open the browser and paste the repo URL it should connect without giving a warning and trusting the site (this way you know you installed the certificate successfully).
You can go ahead and run the command, it should pick the certificate this time.
helm dependency update helm/myStuff
....
Saving 18 charts
Downloading service1 from repo https://myCharts.me/
Downloading service2 from repo https://myCharts.me/
....