istioで Redisのクライアント証明書認証 をやってあげるという話

こんにちは、たけるです。

今日はistioでk8s外においてあるRedisのクライアント証明書認証 をやってあげようという話をします。

  • アプリケーションはTCPでサイドカーのistio-proxyに対して
  • サイドカーのistio-proxyが外部のRedisに対して暗号化しつつトラフィックを送る

メリット的なのは以下?

  • アプリケーションで証明書を管理する必要がない
  • アプリケーション側のライブラリがMutual TLSによるクライアント認証に対応していなくても問題なく使える

こんな感じのServiceEntryとDestinationRuleを宣言してあげます

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-redis
spec:
  hosts:
  - hoge.redislabs.com
  location: MESH_EXTERNAL
  resolution: DNS
  ports:
  - name: tcp-redis
    protocol: TCP
    number: 16936
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: external-redis
spec:
  host: hoge.redislabs.com
  trafficPolicy:
    tls:
      mode: MUTUAL
      clientCertificate: /etc/cert/redislabs_user.crt
      privateKey: /etc/cert/redislabs_user_private.key
      caCertificates: /etc/cert/redislabs_ca.pem

あとは証明書類のSecretを作ってあげてSidecarにマウントしてあげれば、あとは勝手にistioがhoge.redislabs.comへの通信を全てよしなにやってくれるようになります。

$ kubectl create secret generic redis-credential --from-file=redislabs_ca.pem=./redislabs_ca.pem   --from-file=redislabs_user.crt=./redislabs_user.crt --from-file=redislabs_user_private.key=./redislabs_user_private.key

↓Podのannotationにこんな感じに書いてあげればSecretをSidecarにマウントしてくれます。

apiVersion: v1
kind: Pod
metadata:
  annotations:
    sidecar.istio.io/userVolumeMount: '[{"name":"redisc-redential", "mountPath":"/etc/cert", "readonly":true}]'
    sidecar.istio.io/userVolume: '[{"name":"redis-credential", "secret":{"secretName":"redis-credential"}}]'
  labels:
    name: redis
  name: redis
spec:
  containers:
    - name: redis
      image: redis:6.2.6-alpine3.15