Istio 1.6 使用 Cert-Manager 加密 Istio網(wǎng)關(guān)

這個例子演示了在 Istio 中使用 Let's Encrypt 簽發(fā) TLS 證書為Istio網(wǎng)關(guān)提供安全加固的過程。最終實(shí)現(xiàn)通過https的方式訪問官方的Bookinfo應(yīng)用。

istio1.6版本最新的文檔中,刪除了使用cert-manager加密k8s ingress部分的內(nèi)容,本文將從cert-manager的安裝開始,介紹如何使用Let's Encrypt簽發(fā)證書給我們的Istio網(wǎng)關(guān)使用。
istio1.6版本默認(rèn)開啟了 Secrets Discovery Service (SDS) 提供 hot-swapped 功能,因此配置過程相對簡單很多。

安裝cert-manager

cert-manager是Kubernetes原生的證書管理控制器。 它可以幫助您從多種來源頒發(fā)證書,例如Let’s Encrypt,HashiCorp Vault,Venafi,簡單的簽名密鑰對或自簽名。

它將確保證書有效并且是最新的,證書到期會自動申請續(xù)期。

可以將其與Istio網(wǎng)關(guān)集成以管理TLS證書。

其架構(gòu)圖如下:


ar.jpg

如上圖所示,cert-manager會負(fù)責(zé)從各種渠道的申請證書,然后自動生成kubernetes secrets以供您使用。

部署cert-manager非常容易,在您的k8s集群創(chuàng)建以下資源即可:

kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.yaml

默認(rèn)情況下,cert-manager將安裝到cert-manager名稱空間中。

安裝istio 1.6

istio 1.6的安裝完全參考官方文檔即可,按順序執(zhí)行如下命令:

$ curl -L https://istio.io/downloadIstio | sh -

$ cd istio-1.6.0

$ export PATH=$PWD/bin:$PATH

$ istioctl manifest apply

如果需要自定義部署的參數(shù),可在istio-1.6.0/manifests/profiles目錄內(nèi)拷貝一個默認(rèn)的配置進(jìn)行更改,然后通過下面的命令安裝:

istioctl manifest apply --set profile=istio-1.6.0/manifests/profiles/xxx.yaml

正常情況下默認(rèn)配置即可,由于我本人的環(huán)境用的是某云的容器服務(wù),默認(rèn)開啟了LoadBalance,是收費(fèi)的服務(wù)哦,所以我把istio-ingressgateway的type改為了NodePort,然后通過另一臺服務(wù)器把80,443端口用nginx做4層轉(zhuǎn)發(fā)到NodePort,確保通過外網(wǎng)IP能直接訪問到ingressgateway。

這樣,我們的Istio就安裝完畢了。

配置cert-manager的證書頒發(fā)機(jī)構(gòu)(Issuer)

我暫時不說為什么要到這步才配置issuer,大家可以思考一下,本節(jié)結(jié)尾會給大家解釋。

本例使用Let’s Encrypt的證書,Issuer配置如下:

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-issuer-account-key
    solvers:
    - http01:
       ingress:
         ingressTemplate:
           metadata:
             annotations:
               kubernetes.io/ingress.class: istio
---
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-staging-issuer-account-key
    solvers:
    - http01:
       ingress:
         ingressTemplate:
           metadata:
             annotations:
               kubernetes.io/ingress.class: istio

我們配置成ClusterIssuer,保存在所有的namespace都可以使用這個Issure為申請證書。

在Let’s Encrypt申請證書的第一步就是要驗(yàn)證申請方對域名的控制權(quán)(所有權(quán)),有兩種驗(yàn)證方式:

  • 通過配置DNS。
  • 通過Http回調(diào),即Let’s Encrypt會像您申請的域名發(fā)送一個http請求,獲取相應(yīng)的憑證,以驗(yàn)證域名的所有權(quán)。

DNS方式需要域名服務(wù)商提供相應(yīng)的SDK才能實(shí)現(xiàn),目前國內(nèi)主流的廠商都還不支持,所以我們使用Http的方式。

配置中solvers就是配置http方式驗(yàn)證域名的所有權(quán),申請證書時cert-manager會啟動一個pod來響應(yīng)Let’s Encrypt的請求,并使用kubernetes ingress來暴露在公網(wǎng)。

那在我們的環(huán)境中,使用istio gateway來配置ingress的訪問,所以需要加上annotations: kubernetes.io/ingress.class: istio 來告訴istio gateway來處理這個網(wǎng)關(guān)的映射。

這就是為什么我們先要把istio部署上的原因。

部署B(yǎng)ookInfo應(yīng)用

執(zhí)行如下命令部署B(yǎng)ookInfo:

#創(chuàng)建一個新的命名空間:
kubectl create ns istiodemo

#將BookInfo部署到istiodemo命名空間
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n istiodemo

配置證書

在正式進(jìn)入這一步之前,我們需要確保我們申請證書的域名test.app.nafanli.com正確的解析到istio gateway對應(yīng)的公網(wǎng)地址。

創(chuàng)建證書申請請求:

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: ingress-cert
  namespace: istio-system
spec:
  dnsNames:
    - hello.app.nafanli.com
  secretName: ingress-cert
  issuerRef:
    name: letsencrypt
    kind: ClusterIssuer

執(zhí)行下面的命令查看證書申請狀態(tài):

kubectl describe cert ingress-cert -n istio-system

如果一切正常,您將會看到如下輸出:

Events:
  Type    Reason        Age   From          Message
  ----    ------        ----  ----          -------
  Normal  GeneratedKey  92s   cert-manager  Generated a new private key
  Normal  Requested     92s   cert-manager  Created new CertificateRequest resource "ingress-cert-538540713"
  Normal  Issued        14s   cert-manager  Certificate issued successfully

表示我們的證書已經(jīng)申請成功。

執(zhí)行以下命令可以查看證書內(nèi)容:

kubectl get secret ingress-cert -o yaml -n istio-system

這里就不貼出證書內(nèi)容了。

配置BookInfo應(yīng)用網(wǎng)關(guān)

istio官方的BookInof默認(rèn)網(wǎng)關(guān)是http的,因此,我們先從istio-1.6.0/samples/bookinfo/networking/bookinfo-gateway.yaml拷貝一份來改一改,我們重名命為bookinfo-gateway-tls.yaml,最后修改為https后如下:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: ingress-cert
    hosts:
    - hello.app.nafanli.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - hello.app.nafanli.com
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080

這里面要特別注意credentialName: ingress-cert必須和我們剛才申請證書的secret名字完全相同。

執(zhí)行下面的命令創(chuàng)建https網(wǎng)關(guān):

kubectl create -f bookinfo-gateway-tls.yaml -n istiodemo

OK,我們的應(yīng)用不出意外的話可以通過https://hello.app.nafanli.com/productpage訪問到了。

如下圖所示:

640.png

我們可以看到由Let's Encrypt頒發(fā)的證書,所有主流瀏覽器都是綠色的。

Let's Encrypt頒發(fā)的證書有效期為3個月,但是cert-manager會在證書到期時自動為你續(xù)期,你也不用關(guān)心證書會過期的問題了。

您還會在花很多錢去買證書嗎?

本文到些結(jié)束,喜歡關(guān)注我們的公眾號:fancoder。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容