eksworkshop.comのApp Meshハンズオンをやってみたメモ。
環境
コンポーネント | バージョン | 備考 |
---|---|---|
eksctl | 0.14.0 | |
Kubernetes バージョン | 1.14 | |
プラットフォームのバージョン | eks.9 | |
Helm | v3.1.1 | |
appmesh-controllerチャート | 0.4.0 | |
appmesh-controller | 0.3.0 | |
appmesh-injectチャート | 0.11.0 | |
appmesh-inject | 0.4.0 |
クラスターを作成する。
eksctl create cluster --name=appmesh --version 1.14 --nodes=3 --managed --ssh-access --ssh-public-key=sotosugi
DJ Appのデプロイ
(メモ)
Istioのサンプルアプリでは、reviews
のようなDeploymentにreviews-v1
のようなバージョンつきの名前を付けていた。Serviceにはバージョン番号なし。
$ k get deploy -n bookinfo NAME READY UP-TO-DATE AVAILABLE AGE details-v1 1/1 1 1 8d productpage-v1 1/1 1 1 8d ratings-v1 1/1 1 1 8d reviews-v1 1/1 1 1 8d reviews-v2 1/1 1 1 8d reviews-v3 1/1 1 1 8d $ k get svc -n bookinfo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE details ClusterIP 10.100.75.161 <none> 9080/TCP 8d productpage ClusterIP 10.100.192.148 <none> 9080/TCP 8d ratings ClusterIP 10.100.148.131 <none> 9080/TCP 8d reviews ClusterIP 10.100.144.233 <none> 9080/TCP 8d
リポジトリをクローンしてサンプルアプリのディレクトリに移動する。
git clone https://github.com/aws/aws-app-mesh-examples
cd aws-app-mesh-examples/examples/apps/djapp/
Namespaceを作成する。
kubectl apply -n prod \ -f 1_create_the_initial_architecture/1_prod_ns.yaml
(上記YAMLの内容)
apiVersion: v1 kind: Namespace metadata: name: prod
Deploymentを作成する。
kubectl apply -n prod \ -f 1_create_the_initial_architecture/1_initial_architecture_deployment.yaml
(上記YAMLの内容)
apiVersion: apps/v1 kind: Deployment metadata: name: dj spec: replicas: 1 selector: matchLabels: app: dj version: v1 template: metadata: labels: app: dj version: v1 spec: containers: - name: dj image: "672518094988.dkr.ecr.us-west-2.amazonaws.com/hello-world:v1.0" imagePullPolicy: Always ports: - containerPort: 9080 env: - name: "HW_RESPONSE" value: "DJ Reporting for duty!" --- apiVersion: apps/v1 kind: Deployment metadata: name: metal-v1 spec: replicas: 1 selector: matchLabels: app: metal version: v1 template: metadata: labels: app: metal version: v1 spec: containers: - name: metal image: "672518094988.dkr.ecr.us-west-2.amazonaws.com/hello-world:v1.0" imagePullPolicy: Always ports: - containerPort: 9080 env: - name: "HW_RESPONSE" value: "[\"Megadeth\",\"Judas Priest\"]" --- apiVersion: apps/v1 kind: Deployment metadata: name: jazz-v1 spec: replicas: 1 selector: matchLabels: app: jazz version: v1 template: metadata: labels: app: jazz version: v1 spec: containers: - name: jazz image: "672518094988.dkr.ecr.us-west-2.amazonaws.com/hello-world:v1.0" imagePullPolicy: Always ports: - containerPort: 9080 env: - name: "HW_RESPONSE" value: "[\"Astrud Gilberto\",\"Miles Davis\"]"
Serviceを作成する。
kubectl apply -n prod \ -f 1_create_the_initial_architecture/1_initial_architecture_services.yaml
(上記YAMLの内容)
apiVersion: v1 kind: Service metadata: name: dj labels: app: dj spec: ports: - port: 9080 name: http selector: app: dj --- apiVersion: v1 kind: Service metadata: name: metal-v1 labels: app: metal version: v1 spec: ports: - port: 9080 name: http selector: app: metal version: v1 --- apiVersion: v1 kind: Service metadata: name: jazz-v1 labels: app: jazz version: v1 spec: ports: - port: 9080 name: http selector: app: jazz version: v1
確認する。
$ kubectl -n prod get pods,deploy,service NAME READY STATUS RESTARTS AGE pod/dj-8d4fc6ccd-nkhxn 1/1 Running 0 6m1s pod/jazz-v1-f94cdc64d-45kbv 1/1 Running 0 6m1s pod/metal-v1-654d4858f-cgcpl 1/1 Running 0 6m1s NAME READY UP-TO-DATE AVAILABLE AGE deployment.extensions/dj 1/1 1 1 6m1s deployment.extensions/jazz-v1 1/1 1 1 6m1s deployment.extensions/metal-v1 1/1 1 1 6m1s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/dj ClusterIP 10.100.99.124 <none> 9080/TCP 6m service/jazz-v1 ClusterIP 10.100.74.238 <none> 9080/TCP 6m service/metal-v1 ClusterIP 10.100.202.57 <none> 9080/TCP 6m
Istioのサンプルと異なり、Serviceの名前にバージョンがついている。AppMeshの場合はVirtualNodeという抽象化が増えるから?
DJのPodに入って動きを確認する。
export DJ_POD_NAME=$(kubectl get pods -n prod -l app=dj -o jsonpath='{.items[].metadata.name}') kubectl exec -n prod -it ${DJ_POD_NAME} bash
バックエンドにリクエストを投げる。
root@dj-8d4fc6ccd-nkhxn:/usr/src/app# curl -s jazz-v1:9080 | json_pp [ "Astrud Gilberto", "Miles Davis" ]
root@dj-8d4fc6ccd-nkhxn:/usr/src/app# curl -s metal-v1:9080 | json_pp [ "Megadeth", "Judas Priest" ]
コンテナをexitする。
ポートフォワードして確認する。
k port-forward svc/dj -n prod 8888:9080
別ターミナルでcurlする。djは外からのリクエストを受けてバックエンドにリクエストを投げる機能は持っていないように見える。
$ curl -w '\n' localhost:8888 DJ Reporting for duty!
ポートフォワードは終了する。
コンテナの中でソースを確認するとこれだけで、実際のマイクロサービスをイメージしたようなものではなく、ただのクライアントとなるPodである。
root@dj-8d4fc6ccd-nkhxn:/usr/src/app# cat server.js const express = require('express') const app = express() const port = 9080 const response = process.env.HW_RESPONSE ? process.env.HW_RESPONSE : "hell no world" app.get('/', (req, res) => res.send(response)) app.listen(port, () => console.log(`Example app listening on port ${port}!`))
App Meshのデプロイ
helmのバージョンを確認する。
$ helm version --short v3.1.1+gafe7058
リポジトリを追加する。
helm repo add eks https://aws.github.io/eks-charts
追加したリポジトリを確認する。
$ helm repo list | grep eks-charts
eks https://aws.github.io/eks-charts
チャートを確認する。
$ helm search repo appmesh NAME CHART VERSION APP VERSION DESCRIPTION eks/appmesh-controller 0.4.0 0.3.0 App Mesh controller Helm chart for Kubernetes eks/appmesh-grafana 0.1.0 6.4.3 App Mesh Grafana Helm chart for Kubernetes eks/appmesh-inject 0.11.0 0.4.0 App Mesh Inject Helm chart for Kubernetes eks/appmesh-jaeger 0.2.0 1.14.0 App Mesh Jaeger Helm chart for Kubernetes eks/appmesh-prometheus 0.3.0 2.13.1 App Mesh Prometheus Helm chart for Kubernetes
Namespaceを作成する。
kubectl create ns appmesh-system
App MeshのCRDをデプロイする。
kubectl apply -f https://raw.githubusercontent.com/aws/eks-charts/master/stable/appmesh-controller/crds/crds.yaml
CRDを確認する。
$ kubectl get crd | grep appmesh
meshes.appmesh.k8s.aws 2020-03-12T02:39:40Z
virtualnodes.appmesh.k8s.aws 2020-03-12T02:39:40Z
virtualservices.appmesh.k8s.aws 2020-03-12T02:39:40Z
IRSAを使ってappmesh-controller
にAWSAppMeshFullAccess
とAWSCloudMapFullAccess
の権限を付与する。
まずOIDC identity providerを作成する。
eksctl utils associate-iam-oidc-provider \ --cluster appmesh \ --approve
確認する。
$ ARN=$(aws iam list-open-id-connect-providers | jq -r '.OpenIDConnectProviderList[].Arn') $ aws iam get-open-id-connect-provider --open-id-connect-provider-arn ${ARN} { "Url": "oidc.eks.ap-northeast-1.amazonaws.com/id/6D19363CA97FEB75CEEC9713BCB86EFB", "ClientIDList": [ "sts.amazonaws.com" ], "ThumbprintList": [ "9e99a48a9960b14926bb7f3b02e22da2b0ab7280" ], "CreateDate": "2020-03-12T02:43:44.256000+00:00" }
IAMロールとServiceAccountを作成する。
eksctl create iamserviceaccount \ --cluster appmesh \ --namespace appmesh-system \ --name appmesh-controller \ --attach-policy-arn arn:aws:iam::aws:policy/AWSCloudMapFullAccess,arn:aws:iam::aws:policy/AWSAppMeshFullAccess \ --override-existing-serviceaccounts \ --approve
確認する。
$ aws iam list-roles | jq '.Roles[] | select( .RoleName | test("iamserviceaccount") )' { "Path": "/", "RoleName": "eksctl-appmesh-addon-iamserviceaccount-appme-Role1-1BSXGNXTRW623", "RoleId": "AROAYXO4ULJGQYPSQJGFH", "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/eksctl-appmesh-addon-iamserviceaccount-appme-Role1-1BSXGNXTRW623", "CreateDate": "2020-03-12T02:44:07+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::XXXXXXXXXXXX:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/6D19363CA97FEB75CEEC9713BCB86EFB" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.ap-northeast-1.amazonaws.com/id/6D19363CA97FEB75CEEC9713BCB86EFB:aud": "sts.amazonaws.com", "oidc.eks.ap-northeast-1.amazonaws.com/id/6D19363CA97FEB75CEEC9713BCB86EFB:sub": "system:serviceaccount:appmesh-system:appmesh-controller" } } } ] }, "Description": "", "MaxSessionDuration": 3600 }
$ k get sa -n appmesh-system NAME SECRETS AGE appmesh-controller 1 12m default 1 18m
App Mesh Controllerをデプロイする。なおリージョンの設定を省略したらコントローラーによるAWSリソースの作成がエラーになったので指定は必須。
helm upgrade -i appmesh-controller eks/appmesh-controller \ --namespace appmesh-system \ --set region=ap-northeast-1 \ --set serviceAccount.create=false \ --set serviceAccount.name=appmesh-controller
App Mesh Sidecar Injectorをデプロイする。オプションでmeshを作っている。
export APPMESH_NAME="dj-app" helm upgrade -i appmesh-inject eks/appmesh-inject \ --namespace appmesh-system \ --set mesh.name=${APPMESH_NAME} \ --set mesh.create=true
デプロイされたコンポーネントを確認する。
$ kubectl -n appmesh-system get deploy,pods,service NAME READY UP-TO-DATE AVAILABLE AGE deployment.extensions/appmesh-controller 1/1 1 1 6m32s deployment.extensions/appmesh-inject 1/1 1 1 41s NAME READY STATUS RESTARTS AGE pod/appmesh-controller-6b57d964c6-h9f9h 1/1 Running 0 6m32s pod/appmesh-inject-78844456d7-9w48q 1/1 Running 0 41s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/appmesh-inject ClusterIP 10.100.144.199 <none> 443/TCP 41s
Sidecar InjectorにServiceがあるのはAdmission Webhookを使っているからと思われる。
Meshリソースもできている。このリソースはNamespacesスコープではない。
$ k get mesh NAME AGE dj-app 2m52s
$ aws appmesh list-meshes { "meshes": [ { "arn": "arn:aws:appmesh:ap-northeast-1:XXXXXXXXXXXX:mesh/dj-app", "meshName": "dj-app" } ] }
prod
Namespaceにラベルをつけてサイドカーのオートインジェクションを有効にする。
kubectl label \ namespace prod appmesh.k8s.aws/sidecarInjectorWebhook=enabled
DJ AppのApp Mesh対応
VirtualNodeの作成
VirtualNodeを作成する。
もともとmetal
やjazz
というKubernetes Serviveは存在しておらず、新たに仮想的なノードを作成しているイメージ。
このVirtualNodeを使うことはなく、この定義は不要に思える。
kubectl create -f 4_create_initial_mesh_components/nodes_representing_virtual_services.yaml
(上記YAMLの内容)
apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: metal namespace: prod spec: meshName: dj-app listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: hostName: metal.prod.svc.cluster.local --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: jazz namespace: prod spec: meshName: dj-app listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: hostName: jazz.prod.svc.cluster.local
さらにVirtualNodeを作成する。今度はもともと存在しているdj
やmetal-v1
やjazz-v1
というKubernetes Serviveを示す仮想的なノード。
dj
に関してはバックエンドを定義している。これによってdj
はこのバックエンドにしかリクエストできない。
kubectl create -f 4_create_initial_mesh_components/nodes_representing_physical_services.yaml
(上記YAMLの内容)
apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: dj namespace: prod spec: meshName: dj-app listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: hostName: dj.prod.svc.cluster.local backends: - virtualService: virtualServiceName: jazz.prod.svc.cluster.local - virtualService: virtualServiceName: metal.prod.svc.cluster.local --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: jazz-v1 namespace: prod spec: meshName: dj-app listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: hostName: jazz-v1.prod.svc.cluster.local --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: metal-v1 namespace: prod spec: meshName: dj-app listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: hostName: metal-v1.prod.svc.cluster.local
VirtualNodeを確認する。
$ k get virtualnode -n prod NAME AGE dj 27m jazz 30m jazz-v1 27m metal 30m metal-v1 27m
VirtualServiceの作成
VirtualServiceを作成する。
kubectl apply -n prod -f 4_create_initial_mesh_components/virtual-services.yaml
(上記YAMLの内容)
apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualService metadata: name: jazz.prod.svc.cluster.local namespace: prod spec: meshName: dj-app virtualRouter: name: jazz-router routes: - name: jazz-route http: match: prefix: / action: weightedTargets: - virtualNodeName: jazz-v1 weight: 100 --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualService metadata: name: metal.prod.svc.cluster.local namespace: prod spec: meshName: dj-app virtualRouter: name: metal-router routes: - name: metal-route http: match: prefix: / action: weightedTargets: - virtualNodeName: metal-v1 weight: 100
確認する。
$ k get virtualservice -n prod NAME AGE jazz.prod.svc.cluster.local 17s metal.prod.svc.cluster.local 17s
これによって、以下が定義される。
jazz.prod.svc.cluster.local
へのリクエストをjazz-v1
のVirtualNodeへルーティングmetal.prod.svc.cluster.local
へのリクエストをmetal-v1
のVirtualNodeへルーティング
クライアントはこのDNS名の名前解決を最初に行うが、jazz
やmetal
というKubernetes Serviceはないので名前解決できない。
名前解決をできるようにするため、セレクタなしのServiceを定義する。
kubectl -n prod create -f 4_create_initial_mesh_components/metal_and_jazz_placeholder_services.yaml
(上記YAMLの内容)
apiVersion: v1 kind: Service metadata: name: jazz labels: app: jazz spec: ports: - port: 9080 name: http --- apiVersion: v1 kind: Service metadata: name: metal labels: app: metal spec: ports: - port: 9080 name: http
確認する。
$ k get svc -n prod NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dj ClusterIP 10.100.99.124 <none> 9080/TCP 159m jazz ClusterIP 10.100.199.235 <none> 9080/TCP 3s jazz-v1 ClusterIP 10.100.74.238 <none> 9080/TCP 159m metal ClusterIP 10.100.164.219 <none> 9080/TCP 3s metal-v1 ClusterIP 10.100.202.57 <none> 9080/TCP 159m
サイドカーのインジェクション
Sidecar InjectorはPodの作成時点でインジェクションを行うため、Sidecar Injectorを作成する前にデプロイした現在のアプリにはサイドカーが入っていない。
$ k get po -n prod NAME READY STATUS RESTARTS AGE dj-8d4fc6ccd-nkhxn 1/1 Running 0 170m jazz-v1-f94cdc64d-45kbv 1/1 Running 0 170m metal-v1-654d4858f-cgcpl 1/1 Running 0 170m
Deploymentにアノテーションを追加することでPodを再作成させる。なお、単純にPodを削除してもよい。
export TIMESTAMP=$(date +%s) kubectl -n prod patch deployment dj \ -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"${TIMESTAMP}\"}}}}}" kubectl -n prod patch deployment metal-v1 \ -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"${TIMESTAMP}\"}}}}}" kubectl -n prod patch deployment jazz-v1 -nprod \ -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"${TIMESTAMP}\"}}}}}"
サイドカーが入ったことを確認する。
$ k get po -n prod NAME READY STATUS RESTARTS AGE dj-869b4b8db-mj6jz 2/2 Running 0 43s jazz-v1-784f9d4fd8-ctv6d 2/2 Running 0 37s metal-v1-877db99d5-twcws 2/2 Running 0 42s
動作確認
DJのPodに入って動きを確認する。
export DJ_POD_NAME=$(kubectl get pods -n prod -l app=dj -o jsonpath='{.items[].metadata.name}') kubectl -n prod exec -it ${DJ_POD_NAME} -c dj bash
バックエンドにリクエストを投げる。
root@dj-869b4b8db-mj6jz:/usr/src/app# curl -s jazz.prod.svc.cluster.local:9080 | json_pp [ "Astrud Gilberto", "Miles Davis" ]
root@dj-869b4b8db-mj6jz:/usr/src/app# curl -s metal.prod.svc.cluster.local:9080 | json_pp [ "Megadeth", "Judas Priest" ]
App Mesh導入前と同じ動作。
exitする。
カナリアリリース
v2へのカナリアリリースをテストする。
jazz-v2
jazz-v2
のDeploymentとServiceとVirtualNodeをデプロイする。
kubectl -n prod apply -f 5_canary/jazz_v2.yaml
(上記YAMLの内容)
apiVersion: apps/v1 kind: Deployment metadata: name: jazz-v2 spec: replicas: 1 selector: matchLabels: app: jazz version: v2 template: metadata: labels: app: jazz version: v2 spec: containers: - name: jazz image: "672518094988.dkr.ecr.us-west-2.amazonaws.com/hello-world:v1.0" ports: - containerPort: 9080 env: - name: "HW_RESPONSE" value: "[\"Astrud Gilberto (Bahia, Brazil)\",\"Miles Davis (Alton, Illinois)\"]" --- apiVersion: v1 kind: Service metadata: name: jazz-v2 labels: app: jazz version: v2 spec: ports: - port: 9080 name: http selector: app: jazz version: v2 --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: jazz-v2 namespace: prod spec: meshName: dj-app listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: hostName: jazz-v2.prod.svc.cluster.local
jazz
のVirtualServiceを更新し、振り分けの重みを変更する。
kubectl -n prod apply -f 5_canary/jazz_service_update.yaml
変更後の定義を確認する。
$ k get virtualservice -n prod jazz.prod.svc.cluster.local -o json | jq '.spec.routes[].http.action' { "weightedTargets": [ { "virtualNodeName": "jazz-v1", "weight": 90 }, { "virtualNodeName": "jazz-v2", "weight": 10 } ] }
metal-v2
metal-v2
のDeploymentとServiceとVirtualNodeをデプロイする。
kubectl -n prod apply -f 5_canary/metal_v2.yaml
(上記YAMLの内容)
apiVersion: apps/v1 kind: Deployment metadata: name: metal-v2 spec: replicas: 1 selector: matchLabels: app: metal version: v2 template: metadata: labels: app: metal version: v2 spec: containers: - name: metal image: "672518094988.dkr.ecr.us-west-2.amazonaws.com/hello-world:v1.0" ports: - containerPort: 9080 env: - name: "HW_RESPONSE" value: "[\"Megadeth (Los Angeles, California)\",\"Judas Priest (West Bromwich, England)\"]" --- apiVersion: v1 kind: Service metadata: name: metal-v2 labels: app: metal version: v2 spec: ports: - port: 9080 name: http selector: app: metal version: v2 --- apiVersion: appmesh.k8s.aws/v1beta1 kind: VirtualNode metadata: name: metal-v2 namespace: prod spec: meshName: dj-app listeners: - portMapping: port: 9080 protocol: http serviceDiscovery: dns: hostName: metal-v2.prod.svc.cluster.local
metal
のVirtualServiceを更新し、振り分けの重みを変更する。
kubectl -n prod apply -f 5_canary/metal_service_update.yaml
変更後の定義を確認する。
$ k get virtualservice -n prod metal.prod.svc.cluster.local -o json | jq '.spec.routes[].http.action' { "weightedTargets": [ { "virtualNodeName": "metal-v1", "weight": 50 }, { "virtualNodeName": "metal-v2", "weight": 50 } ] }
動作確認
DJのPodに入って動きを確認する。
export DJ_POD_NAME=$(kubectl get pods -n prod -l app=dj -o jsonpath='{.items[].metadata.name}') kubectl -n prod exec -it ${DJ_POD_NAME} -c dj bash
metal
をテストする。
while true; do curl http://metal.prod.svc.cluster.local:9080/ echo sleep .5 done
50:50でルーティングされていることを確認する。
$ kubectl -n prod exec -it ${DJ_POD_NAME} -c dj bash root@dj-869b4b8db-mj6jz:/usr/src/app# while true; do > curl http://metal.prod.svc.cluster.local:9080/ > echo > sleep .5 > done ["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"] ["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"] ["Megadeth","Judas Priest"] ["Megadeth","Judas Priest"] ["Megadeth","Judas Priest"] ["Megadeth","Judas Priest"] ["Megadeth","Judas Priest"] ["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"] ["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"] ["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"] ["Megadeth","Judas Priest"] ["Megadeth","Judas Priest"] ["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"] ["Megadeth","Judas Priest"] ["Megadeth","Judas Priest"]
jazz
をテストする。
while true; do curl http://jazz.prod.svc.cluster.local:9080/ echo sleep .5 done
90:10でルーティングされていることを確認する。
root@dj-869b4b8db-mj6jz:/usr/src/app# while true; do > curl http://jazz.prod.svc.cluster.local:9080/ > echo > sleep .5 > done ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto (Bahia, Brazil)","Miles Davis (Alton, Illinois)"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto","Miles Davis"] ["Astrud Gilberto (Bahia, Brazil)","Miles Davis (Alton, Illinois)"] ["Astrud Gilberto","Miles Davis"]
メモ
IstioとAppMeshの違いに関するメモ。
IstioのCRD | 説明 |
---|---|
Gateway | Istioでは外部LoadBalancerからのリクエストはistio-ingressgateway というServiceが受け取るが、このリソースでistio-ingressgateway の設定を行い、どのようなリクエストを受け取るかを定義する。 |
VirtualService | ルーティングルールを定義する。サブセットへの振り分けが可能。 |
DestinationRule | サービスまでルーティングされた後のポリシーを定義する。ラベルを使ってサブセットを定義できる。 |
App MeshのCRD | 説明 |
---|---|
Mesh | AWS側の「メッシュ」リソースに対応。 |
VirtualNode | 実際のエンドポイントを指し示す仮想的なエンドポイント。エンドポイントにはKubernetes ServiceのDNS名を指定する。AWS側の「仮想ノード」リソースに対応。 |
VirtualService | ルーティングルールを定義する。AWS側のリソースとしては、「仮想サービス」に加え、「仮想ルーター」と「ルート」の定義も含まれる。 |
メッシュへの入口
Istioにはメッシュへの入口となるIngress Gatewayがあるが、App Meshにはない。 メッシュの中へ入れる外部公開されたServiceは自分で定義する。Istioでも外部公開されたServiceを定義すれば同じようにメッシュの中に入れると思われる。
Serviceを作成する単位の違い
Istioのサンプルではのスタート地点では、 - バージョン毎のDeployment - バージョンによらない単一のService を用意している。 これに対して、Service内でのバージョンを定義するDestinationRuleを作成し、振り分けルールを定義するVirtualServiceを定義する。
一方AppMeshのサンプルのスタート地点では、 - バージョン毎のDeployment - バージョン毎のService を用意している。 これに対して各バージョンのServiceに対応するVirtualNodeを作成し、振り分けルールを定義するVirtualServiceを作成。名前解決のための単一のServiceをさらに作成する。
これは、VirtulNodeがポイントする先がServiceに対応するホスト名であるため、バージョン毎のService定義が必要なため。
ルーティング定義の違い
両者のVirtualServiceはよく似た概念でどちらもルーティングを定義するが、定義の仕方は違う。 これは前述のKubernetes Serviceを定義する単位に関係する。
(Istio)
VirtualNodeのような概念がなく、DestinationRuleでラベルと使って定義したKubernetes ServiceのサブセットへルーティングをVirtualServiceで指定する。
VirtualServiceが受け取るリクエストのホスト名はspec.hosts
で定義する。
(App Mesh)
まずKubernetes ServiceをVirtualNodeとして定義する。 VirtualServiceではVirtualNodeへのルーティングルールを定義する。 VirtualServiceの名前のリクエストを受け取るので、名前自体をFQDNにする方がよい。