話說上週安裝時,istio 才更新到 1.2.0 ,這禮拜又變成了 1.2.2 ....
在講 istio 之前,先講一下 cert-manager 。
簡單來說,cert-manager 是一個可以自動產生或取得 ssl 憑證的套件。如果用 helm 安裝 cert-manager 的話,記得要先安裝 cert-manager 的 CRD (官網上有寫)。
這篇文章對於安裝設定 cert-manger 蠻完整的,如果用 letsencrypt 的話,差不多就是這樣了。不過很不幸的是,我用的是自己虛擬出來的 domain name,沒辦法透過 letsencrypt 取得憑證,所以要用自行產生憑證的方式來設定。
cert-manager 建立的 CRD 主要有 Issuer / ClusterIssuer / Certificates,前兩個是設定取得憑證的方式,最後一個則是要產生哪些 domain 的憑證。建立和產生憑證的流程稍後再談,先回頭看 istio。
istio 如果不搭配 cert-manager 而是自行產生憑證來使用的話,可以直接參考官網的做法。
不過每個網站都要自行產生憑證太麻煩了,既然 istio 支援搭配 cert-manager 的方式,那就來試看看吧。
搭配 cert-manager 的設定方式,可先參考官網。
首先是要變更 values.yaml 裡的設定,主要在於 enable istio 的 ingress 和 cert-manager。
相關變更過的設定如下:
gateways:
enabled: true
istio-ingressgateway:
sds:
enabled: true
istio-egressgateway:
enabled: false
certmanager:
enabled: true
email: duan@example.com
global:
k8sIngress:
enabled: true
gatewayName: ingressgateway
enableHttps: true
上面這設定花不少時間測試,目前在 istio 1.2.2 是可以 work 的。重點是要 enable ingressgateway 的 sds ,而 istio-egressgateway 預設是沒啟用的,不過我在測試過程中曾經 enable 而造成問題,所以修改成 enabled: false
設定更新上去後,會發現 istio-ingressgateway 這個 pod 裡的 containeer 由原本的一個變成兩個,多了一個名稱為 ingress-sds 的 container。
sds 全名是 secret discovery service ,這是官網的介紹。
這邊有一個坑,不過不會馬上發現,我是到所有東西都設定好後,發現連不上 https 網頁,去查資料才發現的。
檢查 istio-system namespace 裡的 CRD gateways.networking.istio.io 的 istio-autogenerated-k8s-ingress 的設定裡,有 https 的相關設定。我參考這篇文章後,把 https 的部分移除後,原本的問題就解決了。
kubectl -n istio-system edit gateways.networking.istio.io istio-autogenerated-k8s-ingress基礎建設的部分都好了之後,可以開始著手實際的設定了,首先設定 cert-manager 的 Issuer。如前面提到的,因為是虛擬的 domain name,所以要設定為自行產生的方式。
# 移除以下部分
- hosts:
- '*'
port:
name: https-default
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
privateKey: /etc/istio/ingress-certs/tls.key
serverCertificate: /etc/istio/ingress-certs/tls.crt
apiVersion: certmanager.k8s.io/v1alpha1
kind: Issuer
metadata:
name: test-selfsigned
namespace: istio-system
spec:
selfSigned: {}
然後設定要產生哪個 domain name 的憑證,假設叫 bookinfo.example.com
apiVersion: certmanager.k8s.io/v1alpha1設定完以後,檢查一下憑證是否有產生
kind: Certificate
metadata:
name: test-certificate
namespace: istio-system
spec:
secretName: test-certificate
issuerRef:
name: test-selfsigned
commonName: bookinfo.example.com
dnsNames:
- bookinfo.example.com
acme:
config:
- http01:
ingressClass: istio
domains:
- bookinfo.example.com
# 檢查 status接下來就可以拿 istio 提供的 sample 來驗證一下了。先用 sample 裡的 httpbin ,然後替 httpbin 建立 gateway 及 virtualservice 。
kubectl -n istio-system describe certificates
# 檢查是否將產生的金鑰放在指定的 secret 裡
kubectl -n istio-system get secrets test-certificate
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- bookinfo.example.com
port:
name: http
number: 80
protocol: HTTP
- hosts:
- bookinfo.example.com
port:
name: https-default
number: 443
protocol: HTTPS
tls:
credentialName: test-certificate
mode: SIMPLE
privateKey: sds
serverCertificate: sds
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "bookinfo.example.com"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
host: httpbin
port:
number: 8000
在這邊簡單講一下 gateway、virtualservice 與 kubernetes 本身的 service 元件之間的關係。httpbin 這個 sample application 本身是 listen 80 port ,而它建立的 svc 是 listen 8000 port ,然後轉給 pods 的 80 port。
上面的 virtualservice 則是設定說 "bookinfo.example.com" 這個 url 會連到 cluster 內部名稱為 httpbin 的 host (實際上就是 svc name) 的 8000 port。
透過這樣的機制,讓後端的 app (以這個案例來說就是 httpbin) 本身不需要提供 tls/https ,而是在 gateway 的部分就處理掉了,也就是 ssl termination。
都設定完之後,可以用 curl 來驗證一下 https 的情況了
curl -k https://bookinfo.example.com/status/418
用瀏覽器的話驗證的話,可以確認一下看到的憑證是不是 cert-manager 產生的。
沒有留言:
張貼留言