Skip to content

Instantly share code, notes, and snippets.

@Nyrox
Last active March 17, 2026 22:07
Show Gist options
  • Select an option

  • Save Nyrox/4bb939d49b6c3cdc163968b45cbc6d2f to your computer and use it in GitHub Desktop.

Select an option

Save Nyrox/4bb939d49b6c3cdc163968b45cbc6d2f to your computer and use it in GitHub Desktop.

The kubernetes instructions for deploying buildkit suggest creating certificates with this shell script:

sh SAN=$@ SAN_CLIENT=client

mkdir -p $DIR ${DIR}/daemon ${DIR}/client ( cd $DIR echo $SAN | tr " " "\n" >SAN CAROOT=$(pwd) mkcert -cert-file daemon/cert.pem -key-file daemon/key.pem ${SAN} >/dev/null 2>&1 CAROOT=$(pwd) mkcert -client -cert-file client/cert.pem -key-file client/key.pem ${SAN_CLIENT} >/dev/null 2>&1 cp -f rootCA.pem daemon/ca.pem cp -f rootCA.pem client/ca.pem rm -f rootCA.pem rootCA-key.pem

kubectl create secret generic ${PRODUCT}-daemon-certs --dry-run=client -o yaml --from-file=./daemon >${PRODUCT}-daemon-certs.yaml
kubectl create secret generic ${PRODUCT}-client-certs --dry-run=client -o yaml --from-file=./client >${PRODUCT}-client-certs.yaml

)

as I want my deployment to be fully declarative, how do I achieve the same thing (creating the certificates and secret) but using cert-manager which is already installed on my cluster?


What that script is doing is basically three things:

  1. Creating a local Certificate Authority (via mkcert)

  2. Issing two certificates:

    • one for the BuildKit daemon
    • one for the client (mutual TLS)
  3. Packaging them into Kubernetes Secrets

With cert-manager, you can make all of this declarative by replacing each step with Kubernetes resources.


1. Create a CA (ClusterIssuer or Issuer)

Instead of mkcert, you define a CA inside the cluster.

Option A — Self-signed root + CA issuer (closest to mkcert)

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: buildkit-selfsigned
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: buildkit-ca
spec:
  isCA: true
  commonName: buildkit-ca
  secretName: buildkit-ca-secret
  issuerRef:
    name: buildkit-selfsigned
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: buildkit-ca-issuer
spec:
  ca:
    secretName: buildkit-ca-secret

This replaces:

mkcert ...

2. Create the daemon certificate

This replaces:

mkcert -cert-file daemon/cert.pem -key-file daemon/key.pem ${SAN}

Example:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: buildkit-daemon
spec:
  secretName: buildkit-daemon-certs
  issuerRef:
    name: buildkit-ca-issuer
  commonName: buildkitd
  dnsNames:
    - buildkitd
    - buildkitd.default.svc
    - buildkitd.default.svc.cluster.local
  usages:
    - server auth
    - client auth

This will create a Secret:

buildkit-daemon-certs
  tls.crt
  tls.key
  ca.crt

3. Create the client certificate

This replaces:

mkcert -client ...
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: buildkit-client
spec:
  secretName: buildkit-client-certs
  issuerRef:
    name: buildkit-ca-issuer
  commonName: client
  usages:
    - client auth

4. Match the original secret structure (important!)

Your script creates secrets like:

daemon/
  cert.pem
  key.pem
  ca.pem

But cert-manager creates:

tls.crt
tls.key
ca.crt

Option A — adapt BuildKit (recommended)

Configure BuildKit to use:

  • tls.crt instead of cert.pem
  • tls.key instead of key.pem
  • ca.crt instead of ca.pem

This is cleaner and avoids hacks.


Option B — transform keys (if BuildKit expects exact names)

Use something like:

  • an initContainer
  • or projected volume with items

Example:

volumes:
  - name: daemon-certs
    secret:
      secretName: buildkit-daemon-certs
      items:
        - key: tls.crt
          path: cert.pem
        - key: tls.key
          path: key.pem
        - key: ca.crt
          path: ca.pem

5. Result: fully declarative setup

You now have:

  • CA → Issuer
  • Certificates → Certificate
  • Secrets → automatically managed
  • Rotation → automatic (huge win over mkcert script)

Key differences vs mkcert

mkcert script cert-manager equivalent
Local CA files Issuer + Certificate (isCA)
Manual cert generation Certificate resources
Manual secret creation automatic via secretName
Static auto-renewing

Bonus: Why this is better

  • Certificates rotate automatically
  • No CI/CD scripting needed
  • No local dependencies (mkcert)
  • Fully GitOps-compatible

If you want, I can tailor this specifically to your BuildKit deployment (e.g., Helm values or Pod spec) so it plugs in directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment