前回に続き、EKS上でのAWS App Meshをやっていきます。
今回は、仮想ルーターと仮想サービスです。
前回作った仮想ノードにアクセスするには仮想ルーターか仮想ゲートウェイが必要になるので、いよいよメッシュができていきます💪
あまりしっかり説明されたドキュメントが見つからず経験ベースな部分が多いので、正しい説明になっているかどうか怪しい部分もありますがご了承ください🙇
- 仮想ルーター作成
仮想ノードへトラフィックを振り分ける仮想ルーターを作成します。
振り分け先は weightedTargets
の virtualNodeRef.name
で仮想ノード名を指定します。
プロトコルはHTTPにしましたが、他にもGRPC, HTTP2, TCPが設定できるようです。
apiVersion: appmesh.k8s.aws/v1beta2
kind: VirtualRouter
metadata:
namespace: mesh-test
name: vrouter-1
spec:
listeners:
- portMapping:
port: 80
protocol: http
routes:
- name: route-1
httpRoute:
match:
prefix: /
action:
weightedTargets:
- virtualNodeRef:
name: vnode-1
weight: 1
- virtualNodeRef:
name: vnode-2
weight: 1
- 仮想サービス用サービス作成
仮想サービスの実体にするserviceを作成します。
selecter
は、仮想サービスを介してアクセスする先のpodが全て含まれるように指定する必要があるみたいです。
今回の例だと、仮想サービス → 仮想ルーター(vrouter-1) → 仮想ノード(vnode-1, vnode-2) というトラフィックの流れになるので、vnode-1とvnode-2の実体になるpodに app: sample1
のラベルをつけてあります。
apiVersion: v1
kind: Service
metadata:
name: svc-v
namespace: mesh-test
labels:
app: sample1
spec:
type: ClusterIP
selector:
app: sample1
ports:
- protocol: TCP
port: 80
targetPort: 80
- 仮想サービス作成
先の svc-v
を実体とする仮想サービスを作成します。
name
は上で仮想サービス用に作ったサービス名と等しくする必要があるみたいです。
provider
には仮想サービスを通してアクセスする先を指定を指定します。単一のvirtualNodeかvirtualRouterを選択できるので、トラフィックを複数ノードに分けたいならvirtualRouter、分けなくていいならvirtualNodeにするとよさそうです。
apiVersion: appmesh.k8s.aws/v1beta2
kind: VirtualService
metadata:
namespace: mesh-test
name: svc-v
spec:
provider:
virtualRouter:
virtualRouterRef:
name: vrouter-1
- 仮想サービスをバックエンドに設定
作った仮想サービスにアクセスするには、「仮想ノードのバックエンド」にその仮想サービスを指定する必要があります。
仮想ノードのyamlで、backends
に仮想サービスを追加しておきます。
apiVersion: appmesh.k8s.aws/v1beta2
kind: VirtualNode
metadata:
name: vnode-x
namespace: mesh-test
spec:
# 主要部分は省略
backends:
- virtualService:
virtualServiceRef:
name: svc-v
仮想ノード化されたPodから仮想サービスへリクエストを送ると、
ルーティングに従ったレスポンスが返ってくるはずです。
$ kubectl exec -it somepod-524b1761b4-vg8kw -- bash
root@somepod-524b1761b4-vg8kw:/# curl svc-v.mesh-test.svc.cluster.local
いろいろ試してみたところ、「バックエンドにその仮想サービスを指定したpod」で「仮想サービス名.名前空間.svc.cluster.local
へトラフィックを送る」場合に仮想サービスで設定したトラフィック振り分けが行われる仕様のようです。
それ以外の条件、例えばバックエンドを指定していないpodからのリクエストや仮想サービス名だけのホスト名にトラフィックを送る($ curl svc-v
)場合は(仮想ではない)Serviceの svc-v
に行くようです。
なかなかややこしいですね。