Search code examples
sslkubernetesssl-certificatex509

k8s-signed certificate not trusted within pod


I'm trying to sort out certificates for applications deployed to a k8s cluster (running on docker-for-win, WSL2 on Windows 10 20H2).

I would like to use the DNS to connect to services, e.g. registry.default.svc.cluster.local, which I've verified is reachable. I created a certificate by following these steps:

  1. Create an openssl.conf with content
[ req ]
default_bits = 2048
prompt = no
encrypt_key = no
distinguished_name = req_dn
req_extensions = req_ext

[ req_dn ]
CN = *.default.svc.cluster.local

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = *.default.svc.cluster.local
  1. Create csr and key file with openssl req -new -config openssl.conf -out wildcard.csr -keyout wildcard.key
  2. Created a certificate signing request with
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: wildcard_csr
spec:
  groups:
  - system:authenticated
  request: $(cat wildcard.csr | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - server auth
EOF
  1. Approved the request: kubectl certificate approve wildcard_csr
  2. Extracted the crt file: kubectl get csr wildcard_csr -o jsonpath='{.status.certificate}' | base64 -d > wildcard.crt
  3. Deleted the request kubectl delete csr wildcard_csr.

I've then started a pod with the registry:2 image and configured it to use the wildcard.crt and wildcard.key files.

In a different pod, I then tried to push to that registry, but got the error

Error response from daemon: Get https://registry.default.svc.cluster.local:2100/v2/: x509: certificate signed by unknown authority

So it seems that within the pod, the k8s CA isn't trusted. Am I right with this observation? If so, how can I make k8s trust itself (after all, it was a k8s component that signed the certificate)?


Solution

  • I found a way to achieve this with changes to the yaml only: On my machine (not sure how universal that is), the CA certificate is available in the service-account-token secret default-token-7g75m (kubectl describe secrets to find out the name, look for the secret of type kubernetes.io/service-account-token that contains an entry ca.crt).

    So to trust this certificate, add a volume

    name: "kube-certificate"
    secret:
      secretName: "default-token-7g75m"
    

    and to the pod that requires the certificate, add a volumeMount

    name: "kube-certificate"
    mountPath: "/etc/ssl/certs/kube-ca.crt",
    subPath: "ca.crt"