使用cert-manager在kubernetes中管理tls证书,实现ingress https

  • 什么是cert-manager?
  • cert-manager的工作原理
  • 安装和部署cert-manager
  • 具体的使用
  • 需要注意的事项

什么是cert-manager?

cert-manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt, HashiCorp Vault 这些免费证书的签发。在Kubernetes集群中,我们可以通过 Kubernetes Ingress 和 Let’sEncrypt实现外部服务的自动化HTTPS。

在Kubernetes集群中使用 HTTPS 协议,需要一个证书管理器、一个证书自动签发服务,主要通过 Ingress 来发布 HTTPS 服务,因此需要Ingress Controller并进行配置,启用 HTTPS 及其路由。

letsencrypt:基于ACME协议, 生成免费的证书工具。</br>
ACME: 自动证书管理环境 Automated Certificate Management Environment。

cert-manager的工作原理

cert-manager的架构图

这里有2个概念就是issuer、certificate:
issuer:证书颁发者,它是k8s的资源,接受执行证书签名请求生成签名证书。有issuerclusterIssuer两个类别,区别就在与issuer要指定namespace,只能在指定的namespace下工作,而clusterIssuer是不指定namespace,可以在整个集群下工作。
certificate:可以把这个资源理解为执行证书,通过执行证书的配置,会向cert-manager对应的issuer发送一个certificateRequest,如果成功,就会将生成的密钥tls.key和证书tls.crt存到secret里面。

证书颁布原理

Let’s Encrypt 利用 ACME 协议来校验域名是否真的属于你,校验成功后就可以自动颁发免费证书,证书有效期只有 90 天,在到期前需要再校验一次来实现续期,幸运的是 cert-manager 可以自动续期,这样就可以使用永久免费的证书了。如何校验你对这个域名属于你呢?主流的两种校验方式是 HTTP-01 和 DNS-01。

HTTP-01 校验原理

HTTP-01 的校验原理是给你域名指向的 HTTP 服务增加一个临时 location ,Let’s Encrypt 会发送 http 请求到 http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN>,YOUR_DOMAIN 就是被校验的域名,TOKEN 是 ACME 协议的客户端负责放置的文件,在这里 ACME 客户端就是 cert-manager,它通过修改 Ingress 规则来增加这个临时校验路径并指向提供 TOKEN 的服务。Let’s Encrypt 会对比 TOKEN 是否符合预期,校验成功后就会颁发证书。此方法仅适用于给使用 Ingress 暴露流量的服务颁发证书,并且不支持泛域名证书。

DNS-01 校验原理

DNS-01 的校验原理是利用 DNS 提供商的 API Key 拿到你的 DNS 控制权限, 在 Let’s Encrypt 为 ACME 客户端提供令牌后,ACME 客户端 (cert-manager) 将创建从该令牌和您的帐户密钥派生的 TXT 记录,并将该记录放在 _acme-challenge.<YOUR_DOMAIN>。 然后 Let’s Encrypt 将向 DNS 系统查询该记录,如果找到匹配项,就可以颁发证书。此方法不需要你的服务使用 Ingress,并且支持泛域名证书。

安装和部署cert-manager

安装

安装方式有两种

  1. 使用helm安装:
echo $(helm version) //我这里使用的helm 是v2.14.3
// 安装Tiller
helm init --upgrade --wait

echo "Install the CustomResourceDefinition resources separately"
kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.13/deploy/manifests/00-crds.yaml

echo "Add the Jetstack Helm repository"
helm repo add jetstack https://charts.jetstack.io
helm repo update

echo "Install the cert-manager helm chart"
helm upgrade --install cert-manager --namespace cert-manager --version v0.13.1 jetstack/cert-manager

安装cert-manager chart,如果helm版本不一样,命令也不一样

# Helm v3+
$ helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --version v0.14.0
# Helm v2
$ helm install \
  --name cert-manager \
  --namespace cert-manager \
  --version v0.14.0 \
  jetstack/cert-manager

安装成功可以后,kubectl get pods -n cert-manager

cert-manager pods

cert-manager-webhook的启动时间会稍微长一点,大约也是在1min之内,到这里,cert-manager也就安装好了。

  1. 也可以使用regular manifests 进行安装,具体的可以参考 https://cert-manager.io/docs/installation/kubernetes/#installing-with-regular-manifests

具体的使用

这里是使用http01校验,给使用ingress暴露流量的服务颁发证书。
接下来需要创建一个证书颁布者Issuer:kubectl apply -f ./kubernetes/issuer.yml

issuer-stg.yml

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: evalizhangli@gmail.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
      - http01:
          ingress:
            class: nginx

需要注意的地方就是,如果还在开发测试阶段,尽可能的不要使用letsencrypt-prod,因为staging的证书颁布server对于创建证书没有限制,但是prod的证书颁布server有很严格的次数限制。

issuer.yml

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: evalizhangli@gmail.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx

创建成功以后可以kubectl get clusterIssuer 看到这个issuer的状态为ready,就代表已经创建好了。

image.png

接下来,我们只需要在你需要使用到cert-manager管理证书的ingress的configfile里面改动,然后将你的服务重新部署

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example
  namespace: ${NAMESPACE}
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
      - my.example.net
    secretName: tls-secret-my
  rules:
  - host: my.example.net
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: http

使用起来非常的方便以及简单,kubectl get certificate -n ${NAMESPACE}就能看到 tls-secret-my的certificate,等到状态ready为true, kubectl get secret -n ${NAMESPACE} 也能看到tls-secret-my的secret。
如果certificate的ready为false,可以kubectl describe certificate tls-secret-my -n ${NAMESPACE} 查看一下envents,或者查看一下cert-manager pod 的log。

需要注意的事项

  1. 在开发和测试阶段,尽可能的使用letsencrypt-staging
  2. letsencrypt-prod有rate limit,如果查看cert-manager的log一直显示waiting CertificateRequest status is not complete,有可能就是申请创建证书达到了次数限制
  • 同一个主域下一周只能申请 50 张证书 (例如 http://www.example.com 的主域是 http://example.com)
  • 每个账户每个域名每小时申请验证失败的次数为 5 次
  • 每周只能创建 5 个重复的证书,即使是通过不同账户创建
  • 每个账户同一个 IPv4 地址每 3 小时最多可创建 10 张证书
  • 每个多域名(SAN)证书最多包含 100 个子域
  • 更新证书没有次数的限制,但是更新证书会受到上述重复证书的限制
  1. 如果要重新install cert-manger,可以使用helm delete --purge cert-manager

章节外:使用DNS01校验,颁发泛域名证书

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: example-issuer
spec:
  acme:
    email: evalizhangli@gmail.com
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: example-issuer-account-key
    solvers:
      - dns01:
          clouddns:
            project: my-project
            serviceAccountSecretRef:
              name: prod-clouddns-svc-acct-secret
              key: dns01-solver-credential.json
        selector:
          dnsNames:
            - 'my.example.net'
            - '*.example.net'
          dnsZones:
            - '*.example.net'

这里我是google cloud的dns服务,对应的config可以参考https://cert-manager.io/docs/configuration/acme/dns01/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容