前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubebuilder Webhook 开发之创建 TLS 证书

Kubebuilder Webhook 开发之创建 TLS 证书

原创
作者头像
blazehu
发布2022-08-16 17:22:47
1.7K0
发布2022-08-16 17:22:47
举报
文章被收录于专栏:小千世界

在编写一个准入 Webhook 服务时,需要配置相关证书,k8s 提供了 api 用于对用户自主创建的证书进行认证签发。以下部分演示为 Webhook 服务创建 TLS 证书。

创建 TLS 证书

创建你的证书

通过运行以下命令生成私钥:

代码语言:shell
复制
cat <<EOF | cfssl genkey - | cfssljson -bare server
{
  "hosts": [
    "my-svc.my-namespace.svc.cluster.local",
    "my-pod.my-namespace.pod.cluster.local",
    "192.0.2.24",
    "10.0.34.2"
  ],
  "CN": "my-pod.my-namespace.pod.cluster.local",
  "key": {
    "algo": "ecdsa",
    "size": 256
  }
}
EOF

此命令生成两个文件;它生成包含 PEM 编码 PKCS#10 证书请求的 server.csr, 以及 PEM 编码密钥的 server-key.pem,用于待生成的证书。

创建证书签名请求(CSR)
代码语言:shell
复制
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: example
spec:
  request: $(cat server.csr | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - server auth
EOF

你能看到的输出类似于:

代码语言:shell
复制
certificatesigningrequest.certificates.k8s.io/example created

Warning: certificates.k8s.io/v1beta1 CertificateSigningRequest is deprecated in v1.19+, unavailable in v1.22+; use certificates.k8s.io/v1 CertificateSigningRequest

CSR 处于 Pending 状态。执行下面的命令你将可以看到:

代码语言:shell
复制
kubectl get csr
代码语言:shell
复制
NAME      AGE   SIGNERNAME                     REQUESTOR                 CONDITION
example   17s   kubernetes.io/legacy-unknown   100015926370-1650441195   Pending
批准证书签名请求(CSR)
代码语言:shell
复制
kubectl certificate approve example
代码语言:shell
复制
certificatesigningrequest.certificates.k8s.io/example approved

你现在应该能看到如下输出:

代码语言:shell
复制
kubectl get csr
代码语言:shell
复制
NAME      AGE    SIGNERNAME                     REQUESTOR                 CONDITION
example   5m4s   kubernetes.io/legacy-unknown   100015926370-1650441195   Approved,Issued
下载证书并使用它
代码语言:shell
复制
kubectl get csr example -o jsonpath='{.status.certificate}' | base64 --decode > server.crt

现在你可以将 server.crtserver-key.pem 作为你的服务的 https 认证了。

例如 kubebuilder 中使用 TLS 证书,将 server.crtserver-key.pem 放在 cert 目录中并修改名称为 tls.crttls.key,然后指定证书目录:

代码语言:go
复制
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
		Scheme:                 scheme,
		MetricsBindAddress:     metricsAddr,
		Port:                   9443,
		HealthProbeBindAddress: probeAddr,
		LeaderElection:         enableLeaderElection,
		LeaderElectionID:       "27e1b0af.blazehu.com",
		CertDir:                "./cert/",
	})

从 v1beta1 迁移到 v1

上述例子使用 certificates.k8s.io/v1beta1 API 版本的 CertificateSigningRequest 不在 v1.22 版本中继续提供。官方迁移指南点这里。 我们可以使用 certificates.k8s.io/v1 API 版本,此 API 从 v1.19 版本开始可用。

  • certificates.k8s.io/v1 中需要额外注意的变更:
    • 对于请求证书的 API 客户端而言:
      • spec.signerName 现在变成必需字段(参阅 已知的 Kubernetes 签署者), 并且通过 certificates.k8s.io/v1 API 不可以创建签署者为 kubernetes.io/legacy-unknown 的请求
      • spec.usages 现在变成必需字段,其中不可以包含重复的字符串值, 并且只能包含已知的用法字符串
创建你的证书

通过运行以下命令生成私钥:

代码语言:shell
复制
cat <<EOF | cfssl genkey - | cfssljson -bare server
{
  "hosts": [
    "my-svc.my-namespace.svc.cluster.local",
    "my-pod.my-namespace.pod.cluster.local",
    "192.0.2.24",
    "10.0.34.2"
  ],
  "CN": "my-pod.my-namespace.pod.cluster.local",
  "key": {
    "algo": "ecdsa",
    "size": 256
  }
}
EOF
创建证书签名请求(CSR)

这里 csr signerName 不能是 kubernetes.io/legacy-unknown,演示我们随便指定一个为 example.com/serving,v1beta1 版本默认是 kubernetes.io/legacy-unknown

代码语言:shell
复制
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: example
spec:
  request: $(cat server.csr | base64 | tr -d '\n')
  signerName: example.com/serving
  usages:
  - digital signature
  - key encipherment
  - server auth
EOF
批准证书签名请求(CSR)
代码语言:shell
复制
kubectl certificate approve example
代码语言:shell
复制
certificatesigningrequest.certificates.k8s.io/example approved

你现在应该能看到如下输出:

代码语言:shell
复制
kubectl get csr
代码语言:shell
复制
NAME      AGE   SIGNERNAME            REQUESTOR                 CONDITION
example   11s   example.com/serving   100015926370-1650441195   Approved

这里可以看到证书请求已被批准,但是没有自动签名,正在等待请求的签名者对其签名。

签名证书签名请求(CSR)

我们扮演证书签署者的角色,颁发证书并将其上传到 API 服务器。

创建证书颁发机构

通过运行以下命令创建签名证书:

代码语言:shell
复制
cat <<EOF | cfssl gencert -initca - | cfssljson -bare ca
{
  "CN": "example.com/serving",
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
EOF

这会产生一个证书颁发机构密钥文件(ca-key.pem)和证书(ca.pem)。

颁发证书

创建文件 server-signing-config.json 内容如下:

代码语言:json
复制
{
  "signing": {
    "default": {
      "usages": [
        "digital signature",
        "key encipherment",
        "server auth"
      ],
      "expiry": "876000h",
      "ca_constraint": {
        "is_ca": false
      }
    }
  }
}

使用 server-signing-config.json 签名配置、证书颁发机构密钥文件和证书来签署证书请求:

代码语言:shell
复制
kubectl get csr example -o jsonpath='{.spec.request}' | \
  base64 --decode | \
  cfssl sign -ca ca.pem -ca-key ca-key.pem -config server-signing-config.json - | \
  cfssljson -bare ca-signed-server

这会生成一个签名的服务证书文件,ca-signed-server.pem

上传签名证书
代码语言:shell
复制
kubectl get csr example -o json | \
  jq '.status.certificate = "'$(base64 ca-signed-server.pem | tr -d '\n')'"' | \
  kubectl replace --raw /apis/certificates.k8s.io/v1/certificatesigningrequests/example/status -f -

批准 CSR 并上传签名证书后,你现在应该能看到如下输出:

代码语言:shell
复制
kubectl get csr
代码语言:shell
复制
NAME      AGE   SIGNERNAME            REQUESTOR                 CONDITION
example   10m   example.com/serving   100015926370-1650441195   Approved,Issued

这是你可以正常下载证书并使用它了。

参考文档

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建 TLS 证书
    • 创建你的证书
      • 创建证书签名请求(CSR)
        • 批准证书签名请求(CSR)
          • 下载证书并使用它
          • 从 v1beta1 迁移到 v1
            • 创建你的证书
              • 创建证书签名请求(CSR)
                • 批准证书签名请求(CSR)
                  • 签名证书签名请求(CSR)
                    • 创建证书颁发机构
                    • 颁发证书
                    • 上传签名证书
                • 参考文档
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档