老蒋的知识库

  • 首页
  • 文章归档
  • 关于页面

  • 搜索

Apisix创建HTTPS、WSS(Websocket SSL),使用Cert Manager管理ACME免费证书

发表于 2022-11-11 | 分类于 K8S部署 | 0 | 阅读次数 150

简介

使用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还需要配置证书。

  • 本文作者: jagger
  • 本文链接: /archives/apisix-chuang-jian-https-shi-yong-certmanager-guan-li-acme-mian-fei-zheng-shu
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
正向代理与反向代理
Apisix如何反向代理Gitlab HTTPS请求
jagger

jagger

66 日志
31 分类
0 标签
Creative Commons
0%
© 2026 jagger
由 Halo 强力驱动