【Istio】像shopify一样免费使用https证书
- 背景
- shopify流程原型
- 配置证书
- 打通流程
背景
在shopify中可以免费将一个属于自己的网址绑定到shopify指定的域名上,作为门户引流并提供shopify的售卖服务。除此之外,还会提供一张免费的https证书。本文将描述如何将这一套流程经过一定变通(接入手段),自动化地在kubernetes + istio集群中使用。
shopify流程原型
在shopfiy中,绑定一个域名分为如上三步。据我观察最重要的一步其实就是第一步,将自己的域名通过dns 指定的方式链接到shopify指定的ip地址和域名上。绑定好之后,观察自己的网站,会发现域名旁边多了一把锁,这就说明该域名已经被https证书所保护。
观察一下,发现证书的提供是Let’s Encrypt这家公司。思维发散一下,这个绑定第三方域名的业务场景其实是针对整个世界的。那么自己掏钱做https保护就是一件十分花钱的事情,所以按照利益思维,大概是免费的第三方提供的证书。google一下,果不其然是免费。
配置证书
很多时候,我们看一些网站会发现在网址左边的会出现不安全的字样
更有甚者,google浏览器会推荐你不要继续访问。
为什么会出现这种情况?大概率是因为没有配置HTTPS证书。关于这件事的危害性,我是看阮一峰大神的技术博客。
配置证书的工具是使用acme.sh来实现let’s encrypt证书申请。
打通流程
考虑到配置证书应该简单快捷,所以写了一个集成脚本做这件事,脚本分为四个步骤,接下来将逐一讲解每个步骤的作用与打算。
以下使用到的image都是我本人在私库中构建的镜像,参考时请按照需要做适合自己的修改
install-traffic:
stage: traffic
image: helm:3.1.0
tags:
- kube-runner
script:
- cd ./helm/third-website-temple
- helm upgrade --install $THIRD_WEBSITE_HOST .
--set general.sub=$SUB_DOMAIN
--set general.top=$TOP_DOMAIN
--set general.host=$THIRD_WEBSITE_HOST
这是第一个步骤,部署一套针对用户域名路由,让let’s encrypt的检测可以知道你对域名的控制权。因为业务形态需要用户先指定dns记录的原因,所以我选择了acme中的statelss 模式。部署的helm脚本是针对istio路由的规则,包括ingress、ingresscontroller、gateway、virtualservice四个组件的路由修改,提供acme.sh指定的访问方式,以达到stateless的nginx路由修改
cert-register:
stage: register
image: acme.sh:1.0.7
tags:
- kube-runner
script:
- echo $THIRD_WEBSITE_HOST
- acme.sh --issue -d $THIRD_WEBSITE_HOST --stateless
- cat /acme.sh/$THIRD_WEBSITE_HOST/$THIRD_WEBSITE_HOST.cer
- cat /acme.sh/$THIRD_WEBSITE_HOST/$THIRD_WEBSITE_HOST.key
- SSL_CERT=$(base64 /acme.sh/$THIRD_WEBSITE_HOST/$THIRD_WEBSITE_HOST.cer)
- SSL_KEY=$(base64 /acme.sh/$THIRD_WEBSITE_HOST/$THIRD_WEBSITE_HOST.key)
- echo "SSL_CERT=$SSL_CERT" >> cert
- cat cert
- echo "SSL_KEY=$SSL_KEY" >> privatekey
- cat privatekey
- cp /acme.sh/$THIRD_WEBSITE_HOST/$THIRD_WEBSITE_HOST.cer ./cert
- cp /acme.sh/$THIRD_WEBSITE_HOST/$THIRD_WEBSITE_HOST.key ./key
artifacts:
paths:
- cert
- key
第二步就是按照acme的stateless模型使用客户端向服务端发起请求,并将证书传导到下一个步骤中,这里便不加赘述。
bind-third-websit-host:
stage: cert-install
image: helm:3.1.0
only:
refs:
- master
variables:
- $THIRD_WEBSITE_HOST
tags:
- kube-runner
script:
- SSL_CERT=$(base64 cert | tr -d \\n)
- SSL_KEY=$(base64 key | tr -d \\n)
- cd ./helm/third-website-temple
- helm upgrade --install $THIRD_WEBSITE_HOST .
--set general.sub=$SUB_DOMAIN
--set general.top=$TOP_DOMAIN
--set general.host=$THIRD_WEBSITE_HOST
--set ssl.cert=$SSL_CERT
--set ssl.key=$SSL_KEY
在第三步中,将达到像shopify中绑定首页并提供证书绑定的效果。使用在第二步传导过来的证书,通过helm将其安装在被使用到的namespace之下。
其实到此为止,我所绑定的域名已经可以在外网中访问到,并且也有相应的证书了。但是读一读let’s encrypt的文档,或者观察一下证书的有效期就可以发现有效期其实只有90天,官方推荐的做法是在30天的时候,进行证书的更新。为了让一步也自动化,所以就有了第四步。
cycle-obtain-cert:
stage: re-acme
image: helm:2.4.0
only:
refs:
- master
variables:
- $THIRD_WEBSITE_HOST
tags:
- kube-runner
script:
- cd ./helm/re-acme
- name=$(echo ${THIRD_WEBSITE_HOST} |tr . -)
- helm upgrade --install --force ${THIRD_WEBSITE_HOST}-update-cert-cronjob .
--set general.host=$THIRD_WEBSITE_HOST
--set general.name=$name
在这一步中,通过部署一个基于shell的脚本cronjob,会以三十天为一个期限,持续进行这四个步骤,以达到证书更替的效果。
总结
因为业务场景的需求不同,所以代码实现也就不同了。不同点就在于,用户指定完dns记录之后,并不能自助的进行下面的操作,而是需要业务方来进行。
不同场景需要分析不同的业务流程,打造适合的代码实现。多思考,多质疑,多探索。