Lazy loaded image
k8s 搭配 autocert 自动注入 step-ca TLS 证书到 pod
Words 1371Read Time 4 min
2025-10-1
2025-11-10
date
related_level
slug
type
relate_date
summary
status
tags
category
last_updated
Nov 10, 2025 10:02 PM
是否已更新
orginal_page
是否推荐
 

Helm 安装 step-certificates 部署 step-ca 服务器

添加 Helm Chart 仓库
  • helm repo add smallstep https://smallstep.github.io/helm-charts/
  • helm repo update
生成用于 step-certificates chart 的 YAML,需要已安装 step-cli
  • mkdir -p ~/conf.helm.chart.d
  • step ca init --helm > ~/conf.helm.chart.d/stepca.values.yaml
    • 根据提示完成交互式配置
    • 如果需要修改 DNS 确保添加以下内容到自定义 DNS 末尾
      • ,{{fullname}}.{{namespace}}.svc.cluster.local,127.0.0.1
      假设部署实例名称为 my-release-step-certificates 则如下配置
db 默认使用 badger
  • 目前没法使用外部 db
  • echo "password" | base64 > ~/conf.helm.chart.d/.password
    • 自行更改密码字符串 "password" 为刚配置的密码
安装 release step-certificates
  • helm install -f ~/conf.helm.chart.d/stepca.values.yaml \ --set inject.secrets.ca_password=$(cat ~/conf.helm.chart.d/.password) \ --set inject.secrets.provisioner_password=$(cat ~/conf.helm.chart.d/.password) \ --set service.targetPort=9000 \ step-certificates smallstep/step-certificates
    • CA 密码与 provisioner 密码均为刚才配置的密码
    • service.targetPort 与之前配置的端口对应
  • 检查运行情况
    • kubectl get pods -n default -l app.kubernetes.io/name=step-certificates
    • kubectl get svc -n default -l app.kubernetes.io/name=step-certificates
    • kubectl describe pods -n default -l app.kubernetes.io/name=step-certificates
    • kubectl logs -n default $(kubectl get pod -n default -l app.kubernetes.io/name=step-certificates -o jsonpath='{.items[0].metadata.name}')
 

使用 autocert 自动将 TLS/HTTPS 证书注入到 k8s pod

替代方案:step-issuer 作为 cert-manager issuer 与外部 step-ca 服务器连接, 由 cert-manager 下发并配置证书
前置:需要 k8s 版本支持 admission webhooks
  • kubectl api-versions | grep "admissionregistration.k8s.io/v1"
    • 有输出则支持
需要已添加 Helm Chart 仓库
  • helm repo add smallstep https://smallstep.github.io/helm-charts/
  • helm repo update
  • 可以使用外部的 step-ca 服务器,只要能配置对应 ca 部分
使用已有的 release step-certificates 配置 autocert
vim ~/conf.helm.chart.d/autocert.values.yaml
  • 对应内容应该与之前的 step-certificates 一致
  • helm install -f ~/conf.helm.chart.d/autocert.values.yaml \ --set step-certificates.enabled=false \ --namespace step --create-namespace \ autocert smallstep/autocert
检查运行情况
  • kubectl get pods -n step -l app.kubernetes.io/name=autocert
  • kubectl get svc -n step -l app.kubernetes.io/name=autocert
  • kubectl describe pods -n step -l app.kubernetes.io/name=autocert
  • kubectl logs -n step $(kubectl get pod -n step -l app.kubernetes.io/name=autocert -o jsonpath='{.items[0].metadata.name}') --tail 50
对命名空间 default, kubernetes-dashboard 启用 autocert
  • kubectl label namespace default autocert.step.sm=enabled
  • kubectl label namespace kubernetes-dashboard autocert.step.sm=enabled
  • kubectl get namespace -L autocert.step.sm
    • 检查是否启用
    • 需要注入的命名空间均需要先启用才能生效
对需要注入的容器注解 autocert.step.sm/name: <name> 即可
  • kubectl annotate [--overwrite] pods <pod-name> autocert.step.sm/name=<pod-fqdn>
    • --all 对全部 pod 进行注解
    • <pod-fqdn> 格式类似于 <pod-name>.<namespace-name>.svc.cluster.local
      • 如果修改了默认域名 cluster.local 则自行更改
    • 如对于 default 命名空间下叫 hello-mtls 的 pod 则为 hello-mtls.default.svc.cluster.local
查看 job 是否成功获取 CA url 和 CA 根证书
  • kubectl -n kubernetes-dashboard logs job.batch/autocert
  • kubectl -n kubernetes-dashboard delete job.batch/autocert
    • 成功执行完毕后可以删除对应 job
其他可以配置的标记项
autocert.step.sm/duration
  • 可接受以下格式
    • "300ms", "1.5h" or "2h45m”
  • 可接受以下单位
    • "ns", "us" (or "µs"), "ms", "s", "m", "h”
autocert.step.sm/owner
  • 修改证书、私钥和根证书的 owner,使用 UID 和 GID 而非名称
  • 默认为 root
autocert.step.sm/mode
  • 修改证书、私钥和根证书的文件权限
  • 默认为 0644
样例:配置 mtls server 进行测试
一键部署 pod hello-mtls
  • 根据 k8s 域名情况修改 cluster.local
  • 默认证书有效期仅为 5m
(可选)部署定制配置项 pod hello-mtls-1h
  • 根据 k8s 域名情况修改 cluster.local
查看 pod hello-mtls 内的证书
  • kubectl exec -it $(kubectl get pods -l app=hello-mtls -o jsonpath='{$.items[0].metadata.name}') -c hello-mtls -- ls -al /var/run/autocert.step.sm
测试集群内 pod tls 连接
集群内暴露 443 端口
  • kubectl expose deployment hello-mtls --port 443
部署客户端 curl
  • 根据 k8s 域名情况修改 cluster.local
  • 由于是 mtls, 客户端也需要获取 ca 签名的 client.crt 才能连接到服务器
查看客户端日志
  • kubectl logs $(kubectl get pods -l app=hello-mtls-client -o jsonpath='{$.items[0].metadata.name}') -c hello-mtls-client
测试集群外 tls 连接
LoadBalancer 类型暴露 443 端口
  • kubectl expose deployment hello-mtls --name=hello-mtls-lb --port=443 --type=LoadBalancer
获取客户端证书
如果是外部 step-ca 集群
  • step ca bootstrap -f --ca-url $ca_url --fingerprint $ca_fingerprint --install
    • step 初始化注册
  • step ca certificate client client.crt client.key
    • 对应下发证书的 Subject CN 是 client
内部 release step-certificates
  • kubectl -n step port-forward $(kubectl -n step get pods -l app=ca -o jsonpath={$.items[0].metadata.name}) 4443:4443
    • 为了简单起见,通过端口转发暴露 k8s CA pod 的 4443 端口
    • -n step 根据自身配置修改命名空间
  • step ca bootstrap -f --ca-url https://127.0.0.1:4443 --fingerprint $ca_fingerprint --install
    • $ca_fingerprintstep ca init 之后生成的 value.yaml 中可以找到
      • 默认在 defaults.json 下
    • 后续需要输入的密码是在 step ca init 期间手动输入的
  • step ca bootstrap -f --ca-url $ca_url --fingerprint $ca_fingerprint --install
    • step 初始化注册
  • 后续一致
curl 测试
  • export HELLO_MTLS_IP=$(kubectl get svc hello-mtls-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}')
  • curl --resolve hello-mtls.default.svc.cluster.local:443:$HELLO_MTLS_IP \ --cacert ~/.step/certs/root_ca.crt \ --cert client.crt \ --key client.key \ https://hello-mtls.default.svc.cluster.local:443
    • 手动解析 hello-mtls.default.svc.cluster.local$HELLO_MTLS_IP
      • 不然要配置集群外 dns 解析
  • 结果会显示证书的 Subject CN, 这里应为 client
清理 hello-mtls
  • kubectl delete deployment hello-mtls
  • kubectl delete deployment hello-mtls-client
  • kubectl delete svc hello-mtls
  • kubectl delete svc hello-mtls-client
完全删除 autocert
  • helm uninstall autocert -n default
  • 清理配置等
    • kubectl delete mutatingwebhookconfiguration autocert-webhook-config
    • kubectl delete namespace step
    • kubectl delete clusterrolebinding autocert-controller
    • kubectl delete clusterrole autocert
    • kubectl delete clusterrole autocert-controller
  • 清理 label
     
    上一篇
    使用 Certbot 申请 Let's Encrypt SSL证书和自动续签
    下一篇
    redis 键值存储

    Comments
    Loading...