はじめに
昨年IstioでAmbient Meshというサイドカープロキシなしのサービスメッシュデータプレーンのアーキテクチャがアナウンスされました。
この前日にService Meshがっつり入門というセッションをやっていたので、翌日にコンテンツが陳腐化するという悪夢でした。
もちろん、従来のサイドカープロキシを廃止するわけではなく、2つのアーキテクチャは共存させていく(相互運用もサポートされているようです)ということをIstioが表明していますが、Ambient Meshを無視するわけにはいかないので、今回試してみました。
注意事項
Ambient Meshはα版であり、今回利用するOKEはIstioとして公式サポートしていません。
そのため、あくまでも参考情報として読んで頂ければと思います。
Ambient Meshについて
Istioは、2022年9月7日に"Ambient Mesh"と呼ばれる新しいデータプレーンのアーキテクチャを発表しました。
Ambient Meshは次期バージョンであるv1.18でメインブランチにマージされる予定です。
前述したサイドカープロキシを利用したデータプレーンには更新時の再起動やリソースの利活用の観点でいくつか課題があります。
これらの課題に対応するために、従来は全ての通信をサイドカープロキシに任せていたアーキテクチャをAmbient Meshでは2つのレイヤーに分割しています。
1つ目のレイヤーは"Secure Overlay Layer"と呼ばれ、mTLS、(TCPレベルの)Observabilityなどを管轄します。
2つ目のレイヤーは"L7 Processing Layer"と呼ばれ、L7レイヤーでのルーティング、サーキットブレイカー、リトライ/タイムアウトの制御や(HTTPレベルの)Observabilityを管轄します。
前者のレイヤーでは、Mesh内の各Nodeで動作するエージェントを利用します。
Node間の通信はそれぞれのエージェント間でリダイレクトされます。
Kubernetesでは、このエージェントはDaemonsetとなります。
後者のレイヤーでは、KubernetesのNamespaceで動作する"waypoint proxies"というコンポーネントを利用します。
このコンポーネントはEnvoyがベースとなっており、NamespaceでL7レイヤーでのトラフィック制御が必要な場合は、前述したエージェントから"waypoint proxies"にトラフィックが渡されます。
Kubernetesでは、"waypoint proxies"はDeploymentとして動作しており、トラフィックの需要に合わせてオートスケールさせることができます。
サイドカープロキシとAmbient Meshは、いずれもサポートされ続けていく予定になっており、ユースケースに応じてユーザがどちらを利用するかを選択できます。
また、サイドカープロキシとAmbient Meshは相互運用をサポートしています。
参考:https://istio.io/latest/blog/2022/introducing-ambient-mesh/
事前準備
OKEの構築はこちらを参考に行なってください。
ただし、以下の環境を前提に実施します。
- AMDインスタンス×1
- Worker NodeのOSバージョンはOracle Linux7.9(Oracle Linux8.x系はサービスメッシュがうまく動作しない可能性があります)
- シェイプは2oCPU/16GB
この記事ではAMDインスタンスを前提に解説していきます。
また、シェイプは2oCPU/16GBくらいあれば十分動作します。
Ambient Meshのインストール
Ambient Meshをインストールします。
この記事ではこちらの記事を参考にインストールしていきます。
まずは、資材をダウンロードします。
Ambiemt Meshは、まだIstioのメインブランチにマージされていないので、個別に資材のダウンロードが必要です。
ちなみにメインブランチには次期バージョンであるv1.18でマージされる予定です。
今回は、Istio 1.18.0-beta.1
を利用します。
資材はクライアントによってこちらから選択してください。
この記事では、AMD用の資材を利用します。
資材はwgetで取得します。
wget https://github.com/istio/istio/releases/download/1.18.0-beta.1/istio-1.18.0-beta.1-linux-amd64.tar.gz
解凍します。
tar zxvf istio-1.18.0-beta.1-linux-amd64.tar.gz
ディレクトリを移動します。
cd istio-1.18.0-beta.1
binディレクトリ配下にistioctl
が含まれているので、こちらを利用してインストールします。
必要に応じてPATHを通しても問題ありません。
今回はPATHを設定せずに利用します。
Ambient Meshでは、Ingressの後継であるGateway APIがトラフィック管理のデフォルトなりますが、今回はIngress Gatewayを利用します。
そのための設定も追加します。
bin/istioctl install --set profile=ambient --set components.ingressGateways[0].enabled=true --set components.ingressGateways[0].name=istio-ingressgateway --skip-confirmation
以下のように出力されればOKです。
bin/istioctl install --set profile=ambient --set components.ingressGateways[0].enabled=true --set components.ingressGateways[0].name=istio-ingressgateway --skip-confirmation
✔ Istio core installed
✔ Istiod installed
✔ CNI installed
✔ Ingress gateways installed
✔ Ztunnel installed
✔ Installation complete
Making this installation the default for injection and validation.
インストールされているコンポーネントを確認します。
$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istio-cni-node-c6xpv 1/1 Running 0 142m
istio-ingressgateway-5886cdc7f-2khgb 1/1 Running 0 142m
istiod-67d5f5c5f4-nsfl9 1/1 Running 0 142m
ztunnel-x7lb8 1/1 Running 0 142m
ztunnel
という見慣れないコンポーネントが確認できます。
これは、前述した"Secure Overlay Layer"に相当するものです。
このコンポーネントはDaemonsetとして動作していることが確認できます。
$ kubectl get daemonset -n istio-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
istio-cni-node 1 1 1 1 1 kubernetes.io/os=linux 149m
ztunnel 1 1 1 1 1 <none> 149m
これでインストールは完了です。
サンプルアプリケーションのデプロイと動作確認
サンプルアプリケーションをデプロイします。
サンプルアプリケーションはお馴染みのBookInfoを利用していきます。
資材の中にあるBookInfoアプリケーションのManifestをデプロイします。
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
IstioのGatewayリソースとVirtual Serviceも作成しておきます。
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
後ほど利用するクライアントをインストールします。
kubectl apply -f samples/sleep/sleep.yaml
kubectl apply -f samples/sleep/notsleep.yaml
最後に環境変数にGateway(LoadBalancer)のIPアドレスとGatewayのService Accountを環境変数に設定しておきます。
export GATEWAY_HOST=istio-ingressgateway.istio-system
export GATEWAY_SERVICE_ACCOUNT=ns/istio-system/sa/istio-ingressgateway-service-account
これでサンプルアプリケーションのデプロイは完了です。
ここで一旦アクセス確認をしておきます。
- 先ほどデプロイしたクライアント
sleep
からGateway(LoadBalancer)へのアクセス(ブラウザからでもアクセスできます)
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
- 先ほどデプロイしたクライアント
sleep
からproductpageアプリケーションへのアクセス
kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
- 先ほどデプロイしたクライアント
notsleep
からproductpageアプリケーションへのアクセス
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
どのパターンの場合も以下の出力になればOKです。
<title>Simple Bookstore App</title>
Ambient Meshの構築
いよいよ、Ambint Meshを構築していきます。
と言っても、構築は非常に簡単で、Ambient Mesh用のラベルを追加するだけです。
kubectl label namespace default istio.io/dataplane-mode=ambient
ちなみにサイドカープロキシの場合は以下のようなラベルを追加するので、 ラベルが少し異なることが確認できます。
kubectl label namespace default istio-injection=enabled
これでサンプルアプリケーションがAmbient Mesh内に追加されました。
Podの状態を確認します。
$ kubectl get pods
details-v1-6997d94bb9-w7dnc 1/1 Running 0 136m
notsleep-5fb85fb789-pppfz 1/1 Running 0 100m
productpage-v1-58b4c9bff8-4zgrf 1/1 Running 0 136m
ratings-v1-b8f8fcf49-lvr5d 1/1 Running 0 136m
reviews-v1-5896f547f5-vkwnk 1/1 Running 0 136m
reviews-v2-5d99885bc9-mznkz 1/1 Running 0 136m
reviews-v3-589cb4d56c-7wks7 1/1 Running 0 136m
sleep-bc9998558-65cxk 1/1 Running 0 102m
サイドカープロキシの場合はサイドカーがインジェクションされるようにPodを再起動する必要がありますが、Ambient Meshの場合はその必要はありません。
このように、再起動やアップデートなしにMesh環境を構築できるのがAmbient Meshのメリットの一つです。
これで、Ambient Meshの構築は完了です。
Ambiemt Meshの動作確認
ここからは動作確認を行います。
今回は以下の2つの観点を確認します。
- 認可
- トラフィックルーティング
認可
L4認可
まずはL4レイヤーでの認可ポリシーを試します。
この認可ポリシーはDaemonsetとして動作しているztunnel
が担当します。
以下のManifestを適用します。
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: productpage-viewer
namespace: default
spec:
selector:
matchLabels:
app: productpage
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/default/sa/sleep
- cluster.local/$GATEWAY_SERVICE_ACCOUNT
EOF
ここで作成しているAuthorizationPolicy
はこちらをご確認ください。
これによって、productpageアプリケーションにアクセスできるのはクライアントsleep
かGateway経由のトラフィックのみということになります。
つまり、クライアントnotsleep
からのアクセスはできません。
確認してみましょう。
$ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
command terminated with exit code 56
クライアントnotsleep
からのアクセスは拒否されました。
L7認可
L7レイヤーの場合は前述した"L7 Processing Layer"を担当するwaypoint proxyが必要になります。
waypoint proxyはサイドカープロキシでも利用されいているEnvoyになります。
まずはwaypoint proxyをインストールします。
waypoint proxyはService Accountごとにデプロイします。
今回はproductpageアプリケーションのService Accountであるbookinfo-productpage
用のwaypoint proxyを追加します。
bin/istioctl x waypoint apply --service-account bookinfo-productpage
以下のようにデプロイされます。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
bookinfo-productpage-istio-waypoint-5d6f6f54c9-b5f7q 1/1 Running 0 98m
details-v1-6997d94bb9-w7dnc 1/1 Running 0 136m
notsleep-5fb85fb789-pppfz 1/1 Running 0 100m
productpage-v1-58b4c9bff8-4zgrf 1/1 Running 0 136m
ratings-v1-b8f8fcf49-lvr5d 1/1 Running 0 136m
reviews-v1-5896f547f5-vkwnk 1/1 Running 0 136m
reviews-v2-5d99885bc9-mznkz 1/1 Running 0 136m
reviews-v3-589cb4d56c-7wks7 1/1 Running 0 136m
sleep-bc9998558-65cxk 1/1 Running 0 102m
これでL7認可が実施できるので、試します。
今回はHTTPメソッドでGET以外のリクエストを拒否するように設定してみます。
L4認可の設定は先ほどと同じです。
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: productpage-viewer
namespace: default
spec:
selector:
matchLabels:
istio.io/gateway-name: bookinfo-productpage
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/default/sa/sleep
- cluster.local/$GATEWAY_SERVICE_ACCOUNT
to:
- operation:
methods: ["GET"]
EOF
これで再度動作確認してみます。
$ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" -X DELETE
RBAC: access denied
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
RBAC: access denied
kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
このようにL7レイヤーで認可ポリシーを適用できます。
トラフィックルーティング
最後にトラフィックルーティングを試します。
BookInfoではreviewsアプリケーションに3つのバージョンが存在しているので、こちらを利用します。
まずは、reviewsアプリケーション用のwaypoint proxyをデプロイします。
reviewsアプリケーションのService Accountはbookinfo-reviews
になります。
bin/istioctl x waypoint apply --service-account bookinfo-reviews
以下のようにデプロイされます。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
bookinfo-productpage-istio-waypoint-5d6f6f54c9-b5f7q 1/1 Running 0 98m
bookinfo-reviews-istio-waypoint-7ccc759f55-lp8xc 1/1 Running 0 95m
details-v1-6997d94bb9-w7dnc 1/1 Running 0 136m
notsleep-5fb85fb789-pppfz 1/1 Running 0 100m
productpage-v1-58b4c9bff8-4zgrf 1/1 Running 0 136m
ratings-v1-b8f8fcf49-lvr5d 1/1 Running 0 136m
reviews-v1-5896f547f5-vkwnk 1/1 Running 0 136m
reviews-v2-5d99885bc9-mznkz 1/1 Running 0 136m
reviews-v3-589cb4d56c-7wks7 1/1 Running 0 136m
sleep-bc9998558-65cxk 1/1 Running 0 102m
今回は、v1(レビューの☆なし)とv2(レビューの☆が★)にそれぞれ90%、10%の割合でルーティングするポリシーを適用します。
$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-90-10.yaml
$ kubectl apply -f samples/bookinfo/networking/destination-rule-reviews.yaml
ブラウザから確認するとほとんど、v1(レビューの☆なし)が表示され、稀にv2(レビューの☆が★)が表示されることが確認できます。
以上で、トラフィックルーティングの確認は完了です。
まとめ
Ambient Meshを多少無理やりOKEで動作させてみました。
サイドカープロキシとは手順が異なりますが、できることはあまり変わらないようです。
これからはユースケースに応じて、サイドカープロキシとAmbient Meshを選択してIstioを利用することが求められそうですね。
参考資料