cert-manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt, HashiCorp Vault 这些免费证书的签发。在Kubernetes集群中,我们可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS。 今天我们来配置一下kubernetes的ingress-controller使用cert-manager签发免费通信并实现正常的访问请求.
环境介绍:
主机名称 | 功能 | ip地址 |
---|---|---|
loadbalance | 负责模拟公有云环境的负载均衡器 | 172.20.128.49 |
master | k8s单节点环境 | 172.20.128.50 |
实验拓扑图:
实验说明:因为实验环境没有公有云的loadbalance设备,所以此处使用haproxy替代公有云环境的负载均衡,最后整个请求流程为客户端请求发送到haproxy,然后将请求转发的k8s-master节点。ingress-nginx的service通过nodeport的方式暴漏端其口号。
1.首先运行一个nginx的Pod,作为测试资源,然后通过ingress-nginx暴漏的外部端口对其进行访问。
创建一个cert-manager的名称空间作为测试的名称空间 kubectl create ns cert-manager 然后创建资源清单,生成所需的测试资源
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: cert-manager
spec:
replicas: 1
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: httpd:latest
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
name: http-service
namespace: cert-manager
spec:
selector:
app: httpd
type: ClusterIP
ports:
- port: 80
targetPort: 80
此时我们查看cert-manager整个名称空间下的资源 并且用curl命令在k8s节点直接请求nginx服务
2.添加一个ingress的访问规则
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: http-ingress
namespace: cert-manager
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: httpd.test.com
http:
paths:
- path:
backend:
serviceName: http-service
servicePort: 80
在本地的hosts文件中将master节点IP地址跟ingress规则指定的域名做对应解析,然后再浏览器发送请求进行验证
3.接下来使用cert-manager的管理组件配置证书的生成策略
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-http01
namespace: cert-manager
spec:
selfSigned: {}
配置Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: httpd-test-com
namespace: cert-manager
spec:
dnsNames:
- httpd.test.com # 要签发证书的域名
issuerRef:
name: letsencrypt-http01 # 引用 Issuer,指示采用 http01 方式进行校验
secretName: httpd-test-com # 最终签发出来的证书会保存在这个 Secret 里面
查看刚才生成的证书,k8s已将其封装到secret中 kubectl get certificate -n cert-manager
4.修改刚才的ingress访问规则,为其添加一个tls认证字段
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: http-ingress
namespace: cert-manager
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: httpd.test.com
http:
paths:
- path:
backend:
serviceName: http-service
servicePort: 80
tls:
- hosts:
- httpd.test.com # ingress定义的域名
secretName: httpd-test-com # Certificate资源清单中定义的secretName
在浏览器中使用https的协议进行请求,此时要请求32232端口
因为是自签的证书所有会提示连接不安全。由于本地测试环境没有负载均衡,所以我们访问服务使用的地址是域名加端口号,此时可以用haproxy模拟配置一个负载均衡
5.修改haproxy配置文件,将客户端请求代理到master节点
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode tcp
log global
retries 3
timeout connect 10s
timeout client 1m
timeout server 1m
frontend kube-apiserver
bind *:443 # 指定前端端口
mode tcp
default_backend master
backend master # 指定后端机器及端口,负载方式为轮询
balance roundrobin
server master 172.20.128.50:32232 check maxconn 2000 // 此处指定的是master节点ingress-nginx暴漏的用于https协议的端口号
然后我们把客户端本地hosts文件中将原来的域名解析修改成现在的haproxy的地址 172.20.128.49 httpd.test.com 在浏览器中直接使用域名进行测试 整个配置示例完成