cert-manager 是一种自动执行证书管理的工具,它可以与 Istio Gateway 集成以管理 TLS 证书,当然也可以很方便地和前面我们配置的 ingress-nginx 或者 traefik 配合使用。对于和 Istio 的集成使用,无需特殊配置即可。

在进行本节实验之前记得将前面章节的实验内容进行清空。

安装

要在 Kubernetes 集群上安装 cert-manager 也非常简单,官方提供了一个单一的资源清单文件,包含了所有的资源对象,所以直接安装即可:

# Kubernetes 1.15+
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.16.1/cert-manager.yaml # Kubernetes <1.15
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.16.1/cert-manager-legacy.yaml

上面的命令会创建一个名为 cert-manager 的命名空间,安装大量的 CRD 以及 AdmissionWebhook 对象,可以通过如下命令来查看是否安装成功:

$ kubectl get pods --namespace cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-7ddc5b4db-56nln 1/1 Running 0 4m46s
cert-manager-cainjector-6644dc4975-zthcj 1/1 Running 0 4m47s
cert-manager-webhook-7b887475fb-9fbp4 1/1 Running 0 4m45s

正常情况下可以看到 cert-manager、cert-manager-cainjector 以及 cert-manager-webhook 这几个 Pod 处于 Running 状态。我们可以通过下面的测试来验证下是否可以签发基本的证书类型,创建一个 Issuer 资源对象来测试 webhook 工作是否正常(在开始签发证书之前,必须在群集中至少配置一个 Issuer 或 ClusterIssuer 资源):

$ cat <<EOF > test-resources.yaml
apiVersion: v1
kind: Namespace
metadata:
name: cert-manager-test
---
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: test-selfsigned
namespace: cert-manager-test
spec:
selfSigned: {} # 配置自签名的证书机构类型
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: selfsigned-cert
namespace: cert-manager-test
spec:
dnsNames:
- example.com
secretName: selfsigned-cert-tls
issuerRef:
name: test-selfsigned
EOF

这里我们创建了一个名为 cert-manager-test 的命名空间,创建了一个 Issuer 的证书颁发机构,然后使用这个 Issuer 来创建一个证书 Certificate 对象,直接创建上面的资源清单即可:

$ kubectl apply -f test-resources.yaml
namespace/cert-manager-test created
issuer.cert-manager.io/test-selfsigned created
certificate.cert-manager.io/selfsigned-cert created

创建完成后可以检查新创建的证书状态,在 cert-manager 处理证书请求之前,可能需要稍微等几秒:

$ kubectl describe certificate -n cert-manager-test
Name: selfsigned-cert
Namespace: cert-manager-test
......
Spec:
Dns Names:
example.com
Issuer Ref:
Name: test-selfsigned
Secret Name: selfsigned-cert-tls
Status:
Conditions:
Last Transition Time: 2020-08-16T01:50:40Z
Message: Certificate is up to date and has not expired
Reason: Ready
Status: True
Type: Ready
Not After: 2020-11-14T01:50:39Z
Not Before: 2020-08-16T01:50:39Z
Renewal Time: 2020-10-15T01:50:39Z
Revision: 1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 64s cert-manager Issuing certificate as Secret does not exist
Normal Generated 64s cert-manager Stored new private key in temporary Secret resource "selfsigned-cert-25ftw"
Normal Requested 64s cert-manager Created new CertificateRequest resource "selfsigned-cert-p2sbx"
Normal Issuing 63s cert-manager The certificate has been successfully issued

从上面的 Events 事件中我们可以证书已经成功签发了,到这里证明我们的 cert-manager 已经安装成功了。而且我们需要注意的是 cert-manager 的功能非常强大,不只是可以支持 ACME 类型的证书签发,还支持其他众多的类型,比如 SelfSigned(自签名)、CA、Vault、Venafi、External、ACME,只是我们一般主要是使用 ACME 来帮我们生成自动化的证书。

环境配置

由于通过 ACME 做自动化证书的时候,需要暴露 80 和 443 端口,当然如果我们使用 DNS 校验方式也可以,但是有时候我们根本就没有域名的情况下想要实现自动化证书,我们可以使用 xip.io 这类的服务来实现。前面我们部署 istio-ingressgateway 的时候是通过 NodePort 类暴露的服务,所以我们需要在前面加一个 LB 来转发下请求。这里为了简单,我直接使用 haproxy 来监听节点的 80 和 443 端口,将请求转发到后端的 NodePort 端口。

首先安装 haproxy:

$ yum install -y haproxy

然后配置 haproxy,配置文件 /etc/haproxy/haproxy.cfg,内容如下所示:

listen stats
bind *:9000
mode http
stats enable
stats hide-version
stats uri /stats
stats refresh 30s
stats realm Haproxy\ Statistics
stats auth Admin:Password frontend istio-https
bind *:443
mode tcp
option tcplog
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
default_backend istio-https-svc backend istio-https-svc
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server istio-http-svc-1 127.0.0.1:30951 check frontend istio-http
bind *:80
mode tcp
option tcplog
default_backend istio-http-svc backend istio-http-svc
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server istio-http-svc-1 127.0.0.1:32193 check

其中的 32193 与 30951 端口是 istio-ingressgateway 的 NodePort 端口:

$ kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway NodePort 10.102.120.128 <none> 15020:31093/TCP,80:32193/TCP,443:30951/TCP,31400:31871/TCP,15443:31367/TCP 68d

配置完成后直接启动 haproxy 即可:

$ sudo systemctl start haproxy
$ sudo systemctl enable haproxy
$ sudo systemctl status haproxy

然后我们可以通过上面 9000 端口监控我们的 haproxy 的运行状态:

与 Istio 集成

这里我们来通过 cert-manager 为前面的 httpbin 应用配置自动的 HTTPS,首先单独创建一个用户 cert-manager 的自定义的 Gateay,如下所示:

$ cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: acme-gateway
labels:
app: ingressgateway
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- "*.xip.io"
port:
number: 80
name: http
protocol: HTTP
# tls:
# httpsRedirect: true
- hosts:
- "*.xip.io"
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: "xip-cert"
---
EOF
gateway.networking.istio.io/acme-gateway created

需要注意的是在配置 Gateway 的时候 tls 的 credentialName 代表的是 cert-manager 自动生成的证书名称。

接下来创建 VirtulService 对象,这里我们使用 https 方式的 ACME 证书校验方式,除了 http 方式之外还有 tls 与 dns 方式的校验,dns 方式的证书校验支持通配符的域名。所以我们需要为 /.well-known/ 这个 PATH 路径做一个正确的配置,方便进行 http 校验:

$ cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
gateways:
- acme-gateway
hosts:
- httpbin.123.59.188.12.xip.io
http:
- route:
- destination:
host: httpbin
port:
number: 8000
EOF
virtualservice.networking.istio.io/httpbin created

部署完成后我们可以通过访问 http://httpbin.123.59.188.12.xip.io 来验证是否已经部署成功:

接下来创两个 ClusterIssuer,一个用于测试,一个用于正式使用:

$ cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: icnych@xxx.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: istio
EOF
clusterissuer.cert-manager.io/letsencrypt-staging created
$ cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1beta1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: icnych@xxx.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: istio
EOF
clusterissuer.cert-manager.io/letsencrypt-prod created
$ kubectl describe clusterissuer
......
Status:
Acme:
Last Registered Email: icnych@xxx.com
Uri: https://acme-v02.api.letsencrypt.org/acme/acct/94057742
Conditions:
Last Transition Time: 2020-08-16T07:37:40Z
Message: The ACME account was registered with the ACME server
Reason: ACMEAccountRegistered
Status: True
Type: Ready
Events: <none>

然后创建一个 Certificate 对象来获取证书,由于 Istio 需要在它的命名空间下面有证书,所以我们需要在 istio-system 这个命名空间下面创建:

$ cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1beta1
kind: Certificate
metadata:
name: httpbin-cert
namespace: istio-system # 这里必须是 istio-system 空间
spec:
secretName: xip-cert # 这个就是上面 gateway 所配置的证书名称
issuerRef:
kind: ClusterIssuer
name: letsencrypt-staging
commonName: httpbin.123.59.188.12.xip.io
dnsNames:
- httpbin.123.59.188.12.xip.io
EOF
certificate.cert-manager.io/httpbin-cert created

创建完成后这时候查看 istio-system 空间应该会有一个 cm-acme-http-solver- 这个开头的 Pod、Servie、Ingress 资源对象:

$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
cm-acme-http-solver-8tpbn 1/1 Running 0 16s
$ kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cm-acme-http-solver-w6sf7 NodePort 10.106.174.20 <none> 8089:32135/TCP
$ kubectl get ingress -n istio-system
NAME HOSTS ADDRESS PORTS AGE
cm-acme-http-solver-jkrs2 httpbin.123.59.188.12.xip.io 80 45s

隔一小会儿去查看上面部署的 Certificate 对象的状态:

$ kubectl describe certificate httpbin-cert -n istio-system
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 13m cert-manager Issuing certificate as Secret does not exist
Normal Generated 13m cert-manager Stored new private key in temporary Secret resource "http-cert-6cml8"
Normal Requested 13m cert-manager Created new CertificateRequest resource "http-cert-9wcg2"
Normal Issuing 6m17s cert-manager The certificate has been successfully issued

看到最后的信息 The certificate has been successfully issued 证明我们的证书获取成功了,但是这个时候如果我们通过 https 去访问的话还是会提示证书错误的,因为我们获取的是 staging 环境的证书:

这个时候我们重新更新 httpbin-cert 这个 Certificate 对象中引用的 issuer,更改为正式环境的 issuer,或者使用正式的签名机构新建一个证书对象,正常就可以获得线上环境的证书了。

Kubernetes 监控:CertManager 自动 HTTPS的更多相关文章

  1. 在阿里云托管kubernetes上利用 cert-manager 自动签发 TLS 证书[无坑版]

    前言 排错的过程是痛苦的也是有趣的. 运维乃至IT,排错能力是拉开人与人之间的重要差距. 本篇会记录我的排错之旅. 由来 现如今我司所有业务都运行在阿里云托管kubernetes环境上,因为前端需要对 ...

  2. 【译】Kubernetes监控实践(2):可行监控方案之Prometheus和Sensu

    本文介绍两个可行的K8s监控方案:Prometheus和Sensu.两个方案都能全面提供系统级的监控数据,帮助开发人员跟踪K8s关键组件的性能.定位故障.接收预警. 拓展阅读:Kubernetes监控 ...

  3. Kubernetes 监控--Prometheus 高可用: Thanos

    前面我们已经学习了 Prometheus 的使用,了解了基本的 PromQL 语句以及结合 Grafana 来进行监控图表展示,通过 AlertManager 来进行报警,这些工具结合起来已经可以帮助 ...

  4. 探索Windows Azure 监控和自动伸缩系列1 - 连接中国区Azure

    最近准备基于Microsoft Azure Management Libraries 实现虚拟机的监控.主要的需求就是获取虚拟机内置的性能计数器数据,基于性能计数器实现后续的监控和自动伸缩. 作为这一 ...

  5. [博客迁移]探索Windows Azure 监控和自动伸缩系列1 - 连接中国区Azure

    最近准备基于Microsoft Azure Management Libraries 实现虚拟机的监控.主要的需求就是获取虚拟机内置的性能计数器数据,基于性能计数器实现后续的监控和自动伸缩. 作为这一 ...

  6. Kubernetes监控:部署Heapster、InfluxDB和Grafana

    本节内容: Kubernetes 监控方案 Heapster.InfluxDB和Grafana介绍 安装配置Heapster.InfluxDB和Grafana 访问 grafana 访问 influx ...

  7. tomcat监控,自动重启shell脚本

    tomcat监控,自动重启shell脚本如下,取名 monitor_tomcat.sh: #!/bin/sh # func:自动监控tomcat脚本并且执行重启操作 # 获取tomcat进程ID(其中 ...

  8. Kubernetes 监控方案之 Prometheus Operator(十九)

    目录 一.Prometheus 介绍 1.1.Prometheus 架构 1.2.Prometheus Operator 架构 二.Helm 安装部署 2.1.Helm 客户端安装 2.2.Tille ...

  9. kubernetes监控和性能分析工具:heapster+influxdb+grafana

    1.部署heapster 下载 heapster 相关 yaml 文件 [root@master dashboard]# wget https://raw.githubusercontent.com/ ...

随机推荐

  1. springboot 中如何正确在异步线程中使用request

    起因: 有后端同事反馈在异步线程中获取了request中的参数,然后下一个请求是get请求的话,发现会偶尔出现参数丢失的问题. 示例代码: @GetMapping("/getParams&q ...

  2. C++对象的应用

    本篇文章将介绍对象数组,对象的动态分配以及对象在函数中的应用. 一.对象数组 1.对象数组的定义和初始化 定义对象数组与定义普通数组的语法形式基本相同.如定义一个Square obj[3]:表示一个正 ...

  3. 【线性DP】数字三角形

    题目链接 原题链接 题目描述 给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大. 7 3 ...

  4. 通过类名引用静态成员方法和通过super引用父类的成员方法

    package com.yang.Test.StaticMethodReference; /** * 通过类型引用静态成员方法 * 类已经存在,静态成员方法也已经存在 * 就可以通过类名直接引用静态成 ...

  5. InputStreamReader介绍&代码实现和转换文件编码_练习

    InputStreamReader介绍&代码实现 package com.yang.Test.ReverseStream; import java.io.FileInputStream; im ...

  6. Möbius 反演注记

    目录 基本理论基础 数论函数 线性筛 Mobius 反演 Dirichlet 卷积 数论分块 / 整除分块 拆函数 时间复杂度分析 基本形式 GCD 形 万能 Prod 的莫比乌斯反演 正常例题 YY ...

  7. 流量如何才能变现?实际测试谷歌广告联盟(Google Adsense)的广告效果以及如何优化相关代码

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_150 2010年,谷歌正式退出中国市场,无数人扼腕叹息,如今十年过去了,谷歌还有两条重要的业务线并没有完全退出,一个是页面统计业务 ...

  8. Win10系统下基于Docker构建Appium容器连接Android模拟器Genymotion完成移动端Python自动化测试

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_196 Python自动化,大概也许或者是今年最具热度的话题之一了.七月流火,招聘市场上对于Python自动化的追捧热度仍未消减,那 ...

  9. DL基础:cs231n assignment 2

    cs231n assignment 2 20210913 - 20211005. 目录 cs231n assignment 2 fully-connected nets 基本思想 编程细节 复习mul ...

  10. 一些有用的数学知识(Updating)

    文章目录 拉格朗日插值公式 微分中值定理 费马引理 拉格朗日中值定理 柯西中值定理 洛必达法则 连分数(NOI2021 D2T2 考点) 定义 结论 定理1 定理2 定理3 定理4 定理5 欧拉公式 ...