本文主要介绍怎么使用istio+cert-manager+istio-gatewayingress+Virtual service实现 Let’s Encrypt 获取 TLS https免费证书
安装cert-manager
其实istio也有cert-manager 安装时直接开启也可以使用,我这里使用了最新版本所以自己安装了
helm repo add jetstack https://charts.jetstack.io
kubectl apply \
-f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.7/deploy/manifests/00-crds.yaml
kubectl label namespace cert-manager certmanager.k8s.io/disable-validation="true"
helm install --name cert-manager --namespace cert-manage jetstack/cert-manager --version v0.7.0
参考链接:https://hub.helm.sh/charts/jetstack/cert-manager/v0.7.0
安装istio
这里我采用的是先默认安装istio,然后在更新配置成自己想要的配置
- 默认安装
helm install install/kubernetes/helm/istio \
--name istio --namespace \
istio-system
- 更新(开启sds)
这里和https相关的参数主要是 gateways.istio-ingressgateway.sds.enabled=true,此配置是开启了证书自动发现
下面是我的配置
helm upgrade istio install/kubernetes/helm/istio --namespace istio-system \
--set gateways.istio-ingressgateway.type=NodePort \
--set gateways.istio-egressgateway.type=NodePort \
--set ingress.service.type=NodePort \
--set grafana.enabled=true \
--set kiali.enabled=true \
--set tracing.enabled=true \
--set pilot.traceSampling=100.0 \
--set gateways.istio-ingressgateway.sds.enabled=true
参考连接:https://istio.io/zh/docs/setup/kubernetes/install/helm/
DNS解析
需要把想要https的域名做DNS A记录解析,最终能访问到istio-gateway上所配置的域名即可
创建istio配置
- 创建Gateway
注意credentialName 代表是cert-manager 生成证书的名称
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mytest1 #namespace: istio-system
spec: selector:
istio: ingressgateway
servers:
- hosts:
- "mytest1.xxx.com"
port:
name: http
number: 80
protocol: HTTP
#tls:
# httpsRedirect: true
- hosts:
- mytest1.xxx.com
port:
name: https
number: 443
protocol: HTTPS
tls:
credentialName: mytest1.xxx.com
mode: SIMPLE
privateKey: sds
serverCertificate: sds
- 创建VirtualService
prefix: "/.well-known/" 这个地方是配置VirtualService 路由到cert-manager创建的校验的pod上,(主要是为了证明域名是不是你的)
host: cm-acme-http-solver-cert.istio-system.svc.cluster.local
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mytest1
#namespace: istio-system
spec:
gateways:
- mytest1
hosts:
- mytest1.xxx.com
http:
- match:
- uri:
prefix: "/.well-known/"
route:
- destination:
host: cm-acme-http-solver-cert.istio-system.svc.cluster.local
port:
number: 8089
创建ClusterIssuer
这个只需要创建一次,以后可以直接调用即可
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod
http01: {}
创建证书(Certificate)
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
annotations:
name: mytest1
namespace: istio-system #这里必须是istio-system 空间(目前是这样子的)
spec:
acme:
config:
- domains:
- mytest1.xxx.com #要配置https的域名(支持多个域名)
http01:
ingressClass: none
dnsNames:
- mytest1.xxx.com #要配置https的域名(支持多个域名)
issuerRef:
kind: ClusterIssuer
name: letsencrypt-prod #这里是上面创建的ClusterIssuer
secretName: mytest1.xxx.com #这个就是上面gateway所配置的证书名称
这时候查看istio-system 空间应该会有一个cm-acme-http-solver-这个开头的pod,svc,ingress,
接下里两种做法,一种是将VirtualService 中的cm-acme-http-solver-cert 替换成svc的名称,另一中是 创建一个新的svc来指向cert-manager生产的校验pod
生产新的额svc
kubectl -n istio-system get svc $(kubectl -n istio-system get svc | grep -v cert|grep cm-acme-http-solver | awk '{print $1}'
) -o yaml |sed "/publicEndpoints/d" | sed "s/cm-acme-http-solver-\(.*\)/cm-acme-http-solver-cert/g" | sed "/selfLink/d"| sed
"/crea/d"| sed "/IP/d"| sed "/nodePort/d"|sed "/uid/d"| sed "/generateName/d"| sed "/ownerReferences/,/resourceVersion/d" |
sed "/externalTraffi/d"|sed "/annota/,/auth/d"|sed "/status/,/loadBalancer/d"|sed "/sessionA/d"
检查是否颁发证书
- 可以看cert-manager日志
- 查看isito-system 空间的kubectl -n istio-system get secrets mytest1.xxx.xyz -o yaml