Skip to content

XiaoL-lll/k3s-cert-webhook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

k3s-cert-webhook

A complete certificate delivery package for the following architecture:

  • OpenWrt/DDNS obtains and renews the wildcard certificate
  • OpenWrt pushes the cert/key to an in-cluster webhook
  • The webhook updates a single central Kubernetes TLS Secret
  • A Traefik-side mirror job copies that central Secret into kube-system
  • Traefik uses the mirrored Secret as its default TLS certificate

This package is designed for repeatable deployment and later maintenance.


1. Architecture

OpenWrt / DDNS
  ├─ obtains / renews certificate
  ├─ stores files under /etc/cert
  └─ runs push-k3s-cert.sh after cert change
        |
        v
K3S in-cluster webhook (namespace: infra-tls)
  ├─ receives cert/key over HTTP POST
  └─ writes central TLS Secret
        |
        v
central Secret
  └─ infra-tls/xlserver-cn-tls
        |
        v
Traefik mirror CronJob (namespace: kube-system)
  └─ mirrors central Secret to kube-system/traefik-default-tls
        |
        v
Traefik TLSStore default
  └─ uses kube-system/traefik-default-tls as the default certificate

Design goals

  • Keep certificate issuance outside the cluster
  • Keep only one central source Secret in the cluster
  • Avoid distributing wildcard private keys to many application namespaces
  • Let Traefik terminate TLS centrally
  • Make renewal automatic end-to-end

2. Directory layout

projects/k3s-cert-webhook/
├── README.md
├── OPERATIONS.md
├── install.sh
├── k3s/
│   ├── 00-namespace.yaml
│   ├── 01-serviceaccount-rbac.yaml
│   ├── 02-configmap.yaml
│   ├── 03-deployment.yaml
│   └── 04-service.yaml
├── openwrt/
│   ├── push-k3s-cert.sh
│   └── token-setup.sh
└── traefik/
    ├── README.md
    ├── install-traefik-central-tls.sh
    ├── secret-mirror-rbac.yaml
    ├── secret-mirror-cronjob.yaml
    └── tlsstore-default.yaml

Recommended path

For this environment, the recommended operating path is:

  1. Deploy the in-cluster webhook with install.sh
  2. Configure OpenWrt with openwrt/push-k3s-cert.sh
  3. Apply Traefik resources manually, one by one:
    • traefik/secret-mirror-rbac.yaml
    • traefik/secret-mirror-cronjob.yaml
    • traefik/tlsstore-default.yaml
  4. Use traefik/install-traefik-central-tls.sh only as an optional helper or reference, not as the primary procedure

3. Components

3.1 In-cluster webhook

Namespace: infra-tls

Main resources:

  • ServiceAccount: cert-webhook
  • Deployment: cert-webhook
  • Service: cert-webhook
  • ConfigMap: embedded Node.js server

Purpose:

  • Accept a webhook POST from OpenWrt
  • Validate token and cert/key format
  • Upsert infra-tls/xlserver-cn-tls

3.2 OpenWrt push script

Files:

  • openwrt/push-k3s-cert.sh
  • openwrt/token-setup.sh

Purpose:

  • Read /etc/cert/xlserver.cn.pem
  • Read /etc/cert/xlserver.cn.key
  • Read token from /etc/cert-sync/webhook_token
  • Push to the K3S NodePort endpoint

3.3 Traefik mirror layer

Namespace: kube-system

Resources:

  • ServiceAccount: traefik-secret-mirror
  • CronJob: traefik-secret-mirror
  • TLSStore: default

Purpose:

  • Mirror infra-tls/xlserver-cn-tls
  • Write kube-system/traefik-default-tls
  • Configure Traefik to use the mirrored Secret as the default TLS certificate

4. Default values

Item Value
Central namespace infra-tls
Central secret xlserver-cn-tls
Webhook path /sync-cert
Webhook NodePort 30080
Traefik mirrored secret kube-system/traefik-default-tls
Traefik TLSStore kube-system/default

5. Deployment order

Part A - in-cluster webhook

cd projects/k3s-cert-webhook
./install.sh

Manual equivalent:

kubectl apply -f k3s/00-namespace.yaml
kubectl apply -f k3s/01-serviceaccount-rbac.yaml
kubectl apply -f k3s/02-configmap.yaml
kubectl apply -f k3s/03-deployment.yaml
kubectl apply -f k3s/04-service.yaml
kubectl -n infra-tls rollout status deploy/cert-webhook

Part B - OpenWrt side

  1. Copy openwrt/push-k3s-cert.sh to OpenWrt
  2. Copy openwrt/token-setup.sh to OpenWrt
  3. Set the actual token value
  4. Set the actual K3S node URL
  5. Trigger the script manually once
  6. Put it into your DDNS / certificate-change hook

Part C - Traefik side

You can apply these manually or use the helper scripts/files in traefik/.

Core resources:

  • traefik/secret-mirror-rbac.yaml
  • traefik/secret-mirror-cronjob.yaml
  • traefik/tlsstore-default.yaml

6. Verification checklist

Verify webhook

kubectl -n infra-tls get all
kubectl -n infra-tls logs deploy/cert-webhook -f
curl http://<k3s-node-ip>:30080/healthz

Verify central secret

kubectl -n infra-tls get secret xlserver-cn-tls
kubectl -n infra-tls get secret xlserver-cn-tls -o jsonpath='{.data.tls\.crt}' \
| base64 -d \
| openssl x509 -noout -subject -issuer -dates

Verify Traefik mirrored secret

kubectl -n kube-system get secret traefik-default-tls
kubectl -n kube-system get secret traefik-default-tls -o jsonpath='{.data.tls\.crt}' \
| base64 -d \
| openssl x509 -noout -subject -issuer -dates

Verify TLSStore

kubectl -n kube-system get tlsstore
kubectl -n kube-system describe tlsstore default

Verify external handshake

echo | openssl s_client -servername app.xlserver.cn -connect app.xlserver.cn:443 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates

7. Operational model

Certificate renewal flow

  1. OpenWrt renews the certificate
  2. OpenWrt pushes cert/key to the in-cluster webhook
  3. Webhook updates infra-tls/xlserver-cn-tls
  4. CronJob mirrors it to kube-system/traefik-default-tls
  5. Traefik serves the renewed certificate

Security model

  • Wildcard private key is not copied to every application namespace
  • Only one central source Secret exists in infra-tls
  • Only one Traefik-consumption copy exists in kube-system
  • Webhook is token-protected
  • OpenWrt token is stored in a file, not hardcoded in the push script

8. Notes

  • This package assumes Traefik CRDs use apiVersion: traefik.io/v1alpha1
  • If your environment differs, adjust traefik/tlsstore-default.yaml
  • Application Ingresses that explicitly set their own tls.secretName will continue using their own certificate instead of Traefik's default certificate
  • The Traefik mirror CronJob is intentionally separate from the OpenWrt push step to keep concerns isolated

9. See also

  • OPERATIONS.md for the full operations handbook
  • traefik/README.md for Traefik-specific notes

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages