参考にしたサイト
Managing TLS keys and certs in Istio using Amazon’s ACM
TLS support on AWS - Kubernetes Doc
環境
Kubernetes: v1.16.15
Istio control plane: v1.7.4
Istio data plane: v1.7.4
設定
外部からのIngress用のELBにACMを展開します
手順は...
-
istio-ingressgateway LoadBalancer Serviceの
annotations
にELBの証明書等を設定 - GatewayとVirtualServiceをデプロイ
- Route53にDNSレコード登録
以上
公式ドキュメント には自己署名認証局作って、証明書発行して、ということをしてますが、ここではACM一発で終わらせちゃいます。
ACMの証明書は予め作成しておいてね
1. istio-ingressgateway LoadBalancer Service
gateways:
istio-ingressgateway:
...
serviceAnnotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:REGION:ACCOUNT_ID:certificate/ACM_IDENTIFIER"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443,15443"
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60"
# S3にアクセスログを送るなら以下の設定も
service.beta.kubernetes.io/aws-load-balancer-access-log-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval: "5"
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name: "my-bucket"
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix: "my-prefix"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert
には作成したACMのARNを入れてください
service.beta.kubernetes.io/aws-load-balancer-backend-protocol
は http
でオッケー
service.beta.kubernetes.io/aws-load-balancer-ssl-ports
はistio-ingressgatewayサービスでSSL使うポートを指定しましょう
以下コマンドで設定を展開
istioctl install --manifests ~/istio-1.7.4/manifests
2. GatewayとVirtualServiceをデプロイ
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTP
hosts:
- "gateway.example.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-virturalservice
spec:
hosts:
- "*"
gateways:
- my-gateway
http:
- match:
- uri:
exact: /api/v1/hoge
route:
- destination:
port:
number: 8080
host: hoge-service
- match:
- uri:
exact: /api/v1/fuga
route:
- destination:
port:
number: 9090
host: fuge-service
注意すべきポイントは以下
- Gatewayのselectorは
istio: ingressgateway
を指定してちゃんとistio-ingressgatewayにルーティングすること - Gatewayのport 443で
protocol: HTTP
を指定すること(バックエンドはhttpプロトコルだから)
2番目が特に要注意です
最初設定したとき、何も考えずに HTTPS
を指定したせいでPOSTリクエストが 100 Continue から進まずコネクションがタイムアウトしてしまいました
ちゃんと調べず設定してたので、無駄に1時間くらい悩んでました
3. Route53にレコード登録
Gatewayのport 443で指定したhost(今回の場合は gateway.example.com
ね)を、istio-ingressのEXTERNAL-IP
(ELBのアドレス)にCNAMEしましょう
kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer xxx.xx.x.xxx 1234567890abcdef1234567890abcdef-1234567890.us-west-2.elb.amazonaws.com 15021:31278/TCP,80:32524/TCP,443:30756/TCP,15443:32071/TCP 143d
実際にHTTPSリクエスト試してみよう
curlでもなんでも良いので、実際にリクエスト出して試してみよう
TLS handshakeしてますね
curl -v https://gateway.example.com/api/v1/hoge
...
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
...
おわりに
非常に簡単な設定ですが、変なところでつまずいたのと、意外と日本語でこのユースケースについて記載してある情報が見つからなかったので、書いてみました
誰かの役に立つといいなあ