简介
使用Apisix作为网关,并配置暴露协议为HTTPS
环境与版本
K8S: 1.24+
Apisix: 2.15
Cert Manager: 1.10
参考资料
cert-manager官方安装教程: https://cert-manager.io/docs/installation/kubectl/
cert-manager Issuer、ClusterIssuer创建说明: https://cert-manager.io/docs/configuration/selfsigned/
cert-manager官方Certificate创建说明: https://cert-manager.io/docs/usage/certificate/
cert-manager证书创建失败问题排查流程: https://cert-manager.io/docs/troubleshooting/
cert-manager使用ACME Issuers教程: https://cert-manager.io/docs/configuration/acme/
cert-manager使用ACME Issuers HTTP01教程: https://cert-manager.io/docs/configuration/acme/http01/
Apisix Ingress 如何使用Cert Manager: https://apisix.apache.org/zh/docs/ingress-controller/tutorials/manage-ingress-certificates-with-cert-manager/
Apisix Ingress ApisixTls 管理与绑定tls: https://apisix.apache.org/zh/docs/ingress-controller/concepts/apisix_tls/
Apisix Ingress 注解包含如何使用Plugin: https://apisix.apache.org/zh/docs/ingress-controller/concepts/annotations/
ApisixPluginConfig 插件配置说明: https://apisix.apache.org/zh/docs/ingress-controller/references/apisix_pluginconfig_v2/
Plugin插件列表: https://apisix.apache.org/zh/docs/apisix/plugins/redirect/
letsencrypt ACME所支持客户端: https://letsencrypt.org/zh-cn/docs/client-options/
为什么使用 cert-manager?
随着HTTPS不断普及,大多数网站开始由HTTP升级到HTTPS。使用HTTPS需要向CA机构申请证书,并且需要付出一定的成本。cert-manager是Kubernetes上的全能证书管理工具,可以利用cert-manager基于ACME协议与Let’s Encrypt签发免费证书并为证书自动续期,实现永久免费使用证书。
Let’s Encrypt是什么?
为安全网站提供免费的传输层安全性协议(TLS)证书。
官网: https://letsencrypt.org/zh-cn/
维基百科: https://zh.wikipedia.org/wiki/Let's_Encrypt
ACME 协议是什么?
自动化证书管理环境(ACME)是用于自动验证X.509证书的域验证,安装和管理的标准协议。 ACME协议由Internet安全研究小组设计,并在 IETF RFC 8555。 作为具有许多可用的客户端实现的文档齐全的开放标准,ACME被广泛用作企业证书自动化解决方案。
Let’s Encrypt使用说明: https://letsencrypt.org/zh-cn/docs/client-options/
SSL团队解释: https://www.ssl.com/zh-CN/常见问题/什么是acme协议/
权威CA机构签发与私人签发证书区别
私人签发的各大浏览器识别证书会标记为不安全,权威的会认为安全的。
Cert Manager部署
# 使用官方部署脚本
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yaml
# 验证部署成功,所有的pods都是running状态就成功了
kubectl -n cert-manager get pods
Issuer、ClusterIssuer创建
Issuer、ClusterIssuer作用和区别
Issuer主要作为证书发行者,可以自行发放证书或者对接Let’s Encrypt自动签发权威证书。
Issuer作用范围Namespace,不同的ns使用时需要独立创建,部署时需要添加metadata.namespace。
ClusterIssuer作用于整个集群,我通常使用这个进行创建。
创建ClusterIssuer并连接Let’s Encrypt作为证书发行服务。
# 创建部署yaml文件
cat > cluster_issuer_letsencrypt_acme.yaml << EOF
# Let’s Encrypt ACME 证书签发
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-amce-cluster-issuer
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory # Let's Encrypt对外提供证书签发接口
# server: https://acme-staging-v02.api.letsencrypt.org/directory # 是测试证书接口,会报错不安全
email: 1111@qq.com # 你的邮箱地址,当证书过期的时候会自动发邮件提示你
privateKeySecretRef:
name: letsencrypt-amce-cluster-issuer # 用于存储 ACME/Let's Encrypt 帐户私钥,不用关注,按自己需要改命也行
solvers:
- http01:
ingress:
class: apisix
EOF
# 部署ClusterIssuer
kubectl apply -f cluster_issuer_letsencrypt_acme.yaml
# 验证部署成功,其中`letsencrypt-amce-cluster-issuer`READY是`true`就代表成功了。如果是`false`就等会
kubectl get clusterissuers.cert-manager.io
# 长时间`false`,查看下部署情况,主要看看是不是因为网络原因无法连接
kubectl describe clusterissuers.cert-manager.io letsencrypt-amce-cluster-issuer
K8S部署使用Apisix
参考: Helm部署Apisix
为Apisix的HTTPS签发证书
创建测试使用nginx服务器
cat > nginx_deployment.yaml << EOF
kind: Deployment
metadata:
name: nginx-deployment
namespace: test
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
name: http
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: http
type: ClusterIP
---
EOF
# 部署
kubectl apply -f nginx_deployment.yaml
方法一、使用Ingress签发证书
# 创建Ingress部署文件
# `metadata.annotations.cert-manager.io/cluster-issuer`
# `spec.ingressClassName`
# `spec.tls` 证书信息
cat > test_nginx_tls_ingress.yaml <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-test
namespace: test
annotations:
# 开启Websocket
k8s.apisix.apache.org/enable-websocket: "true"
# cluster-issuer 使用这个注解
cert-manager.io/cluster-issuer: "letsencrypt-amce-cluster-issuer"
# issuer 使用这个注解
#cert-manager.io/issuer: "letsencrypt-amce-cluster-issuer"
# http重定向https,ws重定向到wss
k8s.apisix.apache.org/http-to-https: "true"
spec:
ingressClassName: apisix
tls:
- hosts:
- www.test.com # 使用证书的域名,这个主意一定要有备案的域名
secretName: nginx-test-tls # 证书所存放的secret
rules:
- host: "www.test.com" # 域名
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nginx-service
port:
number: 80
### 配置连接信息
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: nginx-service # 对应 Kubernetes Service 名称
spec:
timeout:
connect: 5s # 连接后端超时时间
send: 60s # 发送数据到后端的超时
read: 600s # 从后端读取数据的超时(WebSocket 长连接建议设置较大值)
EOF
# 部署
kubectl apply -f test_nginx_tls_ingress.yaml
检查证书创建成功,READY为true表示成功,此时就可以通过浏览器访问www.test.com会发现有个锁。检查证书会发现签发方是Let’s Encrypt
kubectl -n test get certificates
如果一直false,describe排查问题,通常来说是因为该域名Let’s Encrypt无法正常访问验证存在。
kubectl -n test describe certificates nginx-test-tls
方法二、手动创建certificates、apisixtls并关联HTTPS
创建https反向代理,ingress部署(或者自己手动配置Apisix反向代理)
cat > test_ingress.yaml <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitlab
namespace: test
annotations:
# 重定向
k8s.apisix.apache.org/http-to-https: "true"
spec:
ingressClassName: apisix
rules:
- host: "www.test.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nginx-service
port:
number: 80
EOF
# 部署
kubectl apply -f test_ingress.yaml
certificates创建,主要用途:cert-manager用于创建与管理tls证书,证书会存放到spec.secretName
# 部署文件
cat > test_certificates.yaml <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: test-cert
namespace: test
spec:
dnsNames:
- www.test.com
issuerRef:
kind: ClusterIssuer
name: letsencrypt-amce-cluster-issuer # 我们之前定义的ClusterIssuer名称
secretName: test-tls # tls证书存放secret
usages: # 使用方法,关键字是枚举值。
- digital signature
- key encipherment
EOF
# 部署
kubectl apply -f test_certificates.yaml
apisixtls创建,主要用途: Apisix将域名与secret所保存的证书进行自动关联。
# 部署文件
cat > test_apisix_tls.yaml <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixTls
metadata:
name: test
namespace: test
spec:
hosts:
- www.test.com
secret:
name: test-tls # certificates部署时配置的secretName
namespace: test # 证书所属ns
EOF
# 部署
kubectl apply -f test_apisix_tls.yaml
问题
Apisix上游服务为HTTPS协议,如何配置ingress?
暂时无法配置,需要手动配置Apisix反向代理到HTTPS服务,记得选择禁用tls验证,否则Apisix访问HTTPS还需要配置证书。