伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

Kubernetes之Ingress自动化https

来源:本站原创 浏览:139次 时间:2021-11-30

目录

  • 1、前置条件
  • 2、部署cert-manager
    • 2.1、创建一个namespace
    • 2.2、安装cert-manager
    • 2.3、测试
  • 3、创建clusterissuer
  • 4、为域名创建certificate
  • 5、在ingress中引用对应的secret
  • 6、自动化颁发证书



cert-manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt, HashiCorp Vault 这些免费证书的签发。在Kubernetes集群中,我们可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS。

1、前置条件

在Kubernetes集群中使用 HTTPS 协议,需要一个证书管理器、一个证书自动签发服务,主要通过 Ingress 来发布 HTTPS 服务,因此需要Ingress Controller并进行配置,启用 HTTPS 及其路由。

本文环境:

  • k8s v1.17.0
  • Ingress Controller为nginx,且有对应暴露的公网ip地址
2、部署cert-manager

从cert-manager v0.11.0开始,Kubernetes的最低支持版本是v1.12.0。仍在运行Kubernetes v1.11或更低版本的用户应在安装cert-manager之前升级到受支持的版本。

cert-manager可以通过官方yaml安装或者通过helm快速安装,本文记录通过官方yaml安装的过程

2.1、创建一个namespace
# namespace.yaml ---apiVersion: v1kind: Namespacemetadata:  name: cert-manager

或者

kubectl create namespace cert-manager
2.2、安装cert-manager

官方的yaml地址为

https://github.com/jetstack/cert-manager/releases/download/v0.13.1/cert-manager.yaml

yaml中有三个镜像,分别为

  • cert-manager-controller:v0.13.1
  • cert-manager-cainjector:v0.13.1
  • cert-manager-webhook:v0.13.1

默认是从quay.io获取镜像,如果quay.io的镜像无法获取,修改image为国内源,例如Azure中国的地址quay.azk8s.cn

部署,会在集群中创建一系列的crd资源

# kubectl apply -f cert-manager.yaml customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io createdcustomresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io createdcustomresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io createdcustomresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io createdcustomresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io createdcustomresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io creatednamespace/cert-manager unchangedserviceaccount/cert-manager-cainjector createdserviceaccount/cert-manager createdserviceaccount/cert-manager-webhook createdclusterrole.rbac.authorization.k8s.io/cert-manager-cainjector createdclusterrolebinding.rbac.authorization.k8s.io/cert-manager-cainjector createdrole.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection createdrolebinding.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection createdclusterrolebinding.rbac.authorization.k8s.io/cert-manager-webhook:auth-delegator createdrolebinding.rbac.authorization.k8s.io/cert-manager-webhook:webhook-authentication-reade����ţë,������ָ��r createdclusterrole.rbac.authorization.k8s.io/cert-manager-webhook:webhook-requester createdrole.rbac.authorization.k8s.io/cert-manager:leaderelection createdrolebinding.rbac.authorization.k8s.io/cert-manager:leaderelection createdclusterrole.rbac.authorization.k8s.io/cert-manager-controller-issuers createdclusterrole.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers createdclusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificates createdclusterrole.rbac.authorization.k8s.io/cert-manager-controller-orders createdclusterrole.rbac.authorization.k8s.io/cert-manager-controller-challenges createdclusterrole.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim createdclusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-issuers createdclusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers createdclusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificates createdclusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-orders createdclusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-challenges createdclusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim createdclusterrole.rbac.authorization.k8s.io/cert-manager-view createdclusterrole.rbac.authorization.k8s.io/cert-manager-edit createdservice/cert-manager createdservice/cert-manager-webhook createddeployment.apps/cert-manager-cainjector createddeployment.apps/cert-manager createddeployment.apps/cert-manager-webhook createdmutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook createdvalidatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

检查对应的pod状态

# kubectl get pods -n cert-manager NAME                                      READY   STATUS    RESTARTS   AGEcert-manager-5cbcb9f4f5-7k6j4             1/1     Running   0          90scert-manager-cainjector-8df55567d-bspds   1/1     Running   0          90scert-manager-webhook-5d9c55bb4c-tmlck     1/1     Running   0          88s
2.3、测试

在正式使用前,先通过官方的示例做一个测试来确认正确设置了cert-manager并能够颁发基本证书类型
测试Webhook正常工作

# cat <<EOF > test-resources.yamlapiVersion: v1kind: Namespacemetadata:  name: cert-manager-test---apiVersion: cert-manager.io/v1alpha2kind: Issuermetadata:  name: test-selfsigned  namespace: cert-manager-testspec:  selfSigned: {}---apiVersion: cert-manager.io/v1alpha2kind: Certificatemetadata:  name: selfsigned-cert  namespace: cert-manager-testspec:  dnsNames:    - example.com  secretName: selfsigned-cert-tls  issuerRef:    name: test-selfsignedEOF

创建测试资源

# kubectl apply -f test-resources.yamlnamespace/cert-manager-test createdissuer.cert-manager.io/test-selfsigned createdcertificate.cert-manager.io/selfsigned-cert created

查新创建证书的状态。可能需要等待几秒钟,然后cert-manager才能处理证书请求

# kubectl -n cert-manager-test describe certificate selfsigned-cert...Spec:  Dns Names:    example.com  Issuer Ref:    Name:       test-selfsigned  Secret Name:  selfsigned-cert-tlsStatus:  Conditions:    Last Transition Time:  2020-03-05T10:01:06Z    Message:               Certificate is up to date and has not expired    Reason:                Ready    Status:                True    Type:                  Ready  Not After:               2020-06-03T10:01:06ZEvents:  Type    Reason        Age   From          Message  ----    ------        ----  ----          -------  Normal  GeneratedKey  61s   cert-manager  Generated a new private key  Normal  Requested     61s   cert-manager  Created new CertificateRequest resource "selfsigned-cert-504566127"  Normal  Issued        61s   cert-manager  Certificate issued successfully

清理测试资源

# kubectl delete -f test-resources.yaml namespace "cert-manager-test" deletedissuer.cert-manager.io "test-selfsigned" deletedcertificate.cert-manager.io "selfsigned-cert" deleted
3、创建clusterissuer

为了配置cert-manager以开始颁发证书,必须先创建Issuer或ClusterIssuer资源。这些资源代表特定的签名机构,并详细说明如何满足证书请求。Issuer只能用来签发自己所在namespace下的证书,ClusterIssuer可以签发任意namespace下的证书,这里以ClusterIssuer为例创建一个签发机构

# cat clusterissuer.yamlapiVersion: cert-manager.io/v1alpha2kind: ClusterIssuermetadata:  name: letsencrypt-prodspec:  acme:    server: https://acme-v02.api.letsencrypt.org/directory    email: ssgeek@ssgeek.com    privateKeySecretRef:      name: letsencrypt-prod    solvers:    - http01:        ingress:          class: nginx

说明:

  • metadata.name 创建的签发机构的名称,创建证书的时候会引用
  • spec.acme.email 邮箱,证书快过期的时候会有邮件提醒,不过cert-manager会利用acme协议自动给我们重新颁发证书来续期
  • spec.acme.server acme 协议的服务端,由官方给出
  • spec.acme.privateKeySecretRef 指示此签发机构的私钥将要存储到哪个Secret对象中
  • pec.acme.solvers.http01 指示签发机构使用HTTP-01的方式进行acme协议 (还可以用DNS方式,acme协议的目的是证明这台机器和域名都是属于你的,然后才准许给你颁发证书)
4、为域名创建certificate

这里通过一个我自己的域名blog.ssgeek.com来进行测试,此域名已经修改dns为公网地址

# cat certificate.yaml apiVersion: cert-manager.io/v1alpha2kind: Certificatemetadata:  name: blog  namespace: defaultspec:  secretName: blog-tls  issuerRef:    name: letsencrypt-prod    kind: ClusterIssuer  duration: 2160h  renewBefore: 360h  keyEncoding: pkcs1  dnsNames:  - blog.ssgeek.com

说明:

  • spec.secretName 指示证书最终存到哪个 Secret 中
  • spec.issuerRef.kind 值为 ClusterIssuer 说明签发机构不在本 namespace 下,而是在全局
  • spec.issuerRef.name 我们创建的签发机构的名称 (ClusterIssuer.metadata.name)
  • spec.duration 证书过期时间
  • spec.renewBefore 在过期前自动更新
  • spec.dnsNames 指示该证书的可以用于哪些域名
  • 更多选项可以参照官方文档

创建并检查相应资源

# kubectl apply -f certificate.yaml certificate.cert-manager.io/blog created# kubectl get certificateNAME   READY   SECRET     AGEblog   True    blog-tls   36s# kubectl get secrets |grep blog-tlsblog-tls               kubernetes.io/tls                     3      52s# kubectl describe secrets blog-tls Name:         blog-tlsNamespace:    defaultLabels:       <none>Annotations:  cert-manager.io/alt-names: blog.ssgeek.com              cert-manager.io/certificate-name: blog              cert-manager.io/common-name: blog.ssgeek.com              cert-manager.io/ip-sans:               cert-manager.io/issuer-kind: ClusterIssuer              cert-manager.io/issuer-name: letsencrypt-prod              cert-manager.io/uri-sans: Type:  kubernetes.io/tlsData====ca.crt:   0 bytestls.crt:  3558 bytestls.key:  1675 bytes

在创建时查看cert-namager的日志

# kubectl -n cert-manager logs -f cert-manager-5cbcb9f4f5-4kks2...I0305 05:50:13.817322       1 controller.go:129] cert-manager/controller/certificates "msg"="syncing item" "key"="default/blog" I0305 05:50:14.317351       1 conditions.go:155] Setting lastTransitionTime for Certificate "blog" condition "Ready" to 2020-03-05 05:50:14.317341236 +0000 UTC m=+2213.785243238I0305 05:50:14.525738       1 controller.go:135] cert-manager/controller/certificates "msg"="finished processing work item" "key"="default/blog" I0305 05:50:14.525812       1 controller.go:129] cert-manager/controller/certificates "msg"="syncing item" "key"="default/blog" I0305 05:50:14.526251       1 sync.go:367] cert-manager/controller/certificates "msg"="no existing CertificateRequest resource exists, creating new request..." "related_resource_kind"="Secret" "related_resource_name"="blog-tls" "related_resource_namespace"="default" "resource_kind"="Certificate" "resource_name"="blog" "resource_namespace"="default" I0305 05:50:14.774094       1 controller.go:129] cert-manager/controller/certificaterequests-issuer-ca "msg"="syncing item" "key"="default/blog-109727931" I0305 05:50:14.774118       1 controller.go:129] cert-manager/controller/certificaterequests-issuer-selfsigned "msg"="syncing item" "key"="default/blog-109727931" I0305 05:50:14.774135       1 sync.go:379] cert-manager/controller/certificates "msg"="created certificate request" "related_resource_kind"="Secret" "related_resource_name"="blog-tls" "related_resource_namespace"="default" "resource_kind"="Certificate" "resource_name"="blog" "resource_namespace"="default" "request_name"="blog-109727931"

如果创建出来的certificate状态为False,可以通过以下命令查看相关信息

# kubectl get challenge

如果有相应的challenge,通过kubectl describe检查,例如我这里之前创建失败时检查的错误信息如下

出现此问题的原因是我把此域名的解析设置为了内网地址,官方的颁发证书机构接口地址无法访问到,因此必须解析在公网,并保证服务暴露在公网

5、在ingress中引用对应的secret

生成的证书最终绑定在对应的域名服务下,这里我运行了一个nginx pod,创建了对应的service和ingress资源,在ingress资源中声明了此secret,由于部署了cert-maganer,在ingress中,还支持更多的注解,可以参考官方文档

yaml内容如下

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx  namespace: defaultspec:  replicas: 1  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - image: nginx:1.15         imagePullPolicy: IfNotPresent        name: nginx---apiVersion: v1kind: Servicemetadata:  name: nginx  namespace: defaultspec:  selector:    app: nginx  ports:  - name: nginx    port: 80    targetPort: 80---apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: nginx  namespace: default  annotations:    kubernietes.io/ingress.class: "nginx"    nginx.ingress.kubernetes.io/ssl-redirect: "true"spec:  tls:  - hosts:    - blog.ssgeek.com    secretName: blog-tls  rules:    - host: blog.ssgeek.com      http:        paths:        - path: /          backend:            serviceName: nginx            servicePort: 80

然后通过域名访问,检查证书是否正常

6、自动化颁发证书

上述内容是通过根据域名创建certificate最终得到的签名证书,再配置到ingress中使用,还不够自动化。没错,其实官方给出了自动通过ClusterIssuer颁发证书的做法,只需要在ingress中添加相应注解即可

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: nginx  namespace: default  annotations:    kubernietes.io/ingress.class: "nginx"    cert-manager.io/cluster-issuer: "letsencrypt-prod"    kubernetes.io/tls-acme: "true"spec:  tls:  - hosts:    - blog.ssgeek.com    secretName: blog-tls  rules:    - host: blog.ssgeek.com      http:        paths:        - path: /          backend:            serviceName: nginx            servicePort: 80

创建ingress资源,就会发现自动创建了certificate,得到secret
浏览器访问,出现307的http临时重定向到https,也可以继续添加一个注解强制进行强制重定向

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: nginx  namespace: default  annotations:    kubernietes.io/ingress.class: "nginx"    nginx.ingress.kubernetes.io/ssl-redirect: "true"    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"    cert-manager.io/cluster-issuer: "letsencrypt-prod"    kubernetes.io/tls-acme: "true"spec:  tls:  - hosts:    - blog.ssgeek.com    secretName: blog-tls  rules:    - host: blog.ssgeek.com      http:        paths:        - path: /          backend:            serviceName: nginx            servicePort: 80


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net