FIS から EKS の Chaos Mesh を実行する
背景
2022/07/07 に FIS の新しいアクション aws:eks:inject-kubernetes-custom-resource
が追加されました。
これは EKS の Cluster に入っている Chaos Mesh または Litmus を実行するアクションです。
実行には何が必要か、どういった制約があるか確認するためにやってみました。
やってみた
https://gitlab.com/kojima.takashi/2022-07-13-fis-itg-chaosmesh
まず CDK で EKS を構築します。
const vpc = new ec2.Vpc(this, "Vpc", { maxAzs: 2 }); const cluster = new eks.Cluster(this, "Cluster", { version: eks.KubernetesVersion.V1_21, vpc, vpcSubnets: [{ subnetType: ec2.SubnetType.PUBLIC }], defaultCapacity: 1, endpointAccess: eks.EndpointAccess.PUBLIC, defaultCapacityInstance: ec2.InstanceType.of( ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM ), clusterLogging: [eks.ClusterLoggingTypes.API], });
Chaos Mesh をインストールする namespace を作成します。
cluster.addManifest("chaosmesh-namespace", { apiVersion: "v1", kind: "Namespace", metadata: { name: "chaos-testing" }, });
Chaos Mesh 用のロールも作成します。
このロールを使って FIS から操作するためです。
const cmManagerRole = { kind: "ClusterRole", apiVersion: "rbac.authorization.k8s.io/v1", metadata: { name: "role-chaosmesh-manager" }, rules: [ { apiGroups: [""], resources: ["pods", "namespaces"], verbs: ["get", "watch", "list"], }, { apiGroups: ["chaos-mesh.org"], resources: ["*"], verbs: ["get", "list", "watch", "create", "delete", "patch", "update"], }, ], }; cluster.addManifest("chaosmesh-manager-role", cmManagerRole);
FIS で実行するためのロールも作成します。
権限にはログ書込み用の権限のみ渡しました。
const fisLog = new logs.LogGroup(this, "FisLogs", { retention: 3 }); const fisRole = new iam.Role(this, "FisRole", { assumedBy: new iam.ServicePrincipal("fis.amazonaws.com"), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName("AWSLambdaExecute"), ], inlinePolicies: { ExecutePolicy: new iam.PolicyDocument({ statements: [ new iam.PolicyStatement({ sid: "AllowLogging", effect: iam.Effect.ALLOW, actions: ["logs:CreateLogDelivery"], resources: ["*"], }), ], }), }, });
k8s の Chaos Mesh 用のロール と AWS の FIS 用の Role を mapping します。
cluster.awsAuth.addRoleMapping(fisRole, { groups: ["system:masters", cmManagerRole.metadata.name], });
では実際に実験の対象となる nginx を作成します。
const nginxDeployment = { apiVersion: "apps/v1", kind: "Deployment", metadata: { name: "nginx-deployment" }, spec: { selector: { matchLabels: { app: "nginx" } }, replicas: 2, template: { metadata: { labels: { app: "nginx" } }, spec: { containers: [ { name: "nginx", image: "nginx:1.14.2", ports: [{ containerPort: 80 }], }, ], }, }, }, }; cluster.addManifest("nginx", nginxDeployment);
その対象に対して実験する実験テンプレートを用意しました。
new fis.CfnExperimentTemplate(this, "InjectChaosMesh", { description: "InjectChaosMesh", roleArn: fisRole.roleArn, tags: { Name: "InjectChaosMesh" }, logConfiguration: { logSchemaVersion: 1, cloudWatchLogsConfiguration: { LogGroupArn: fisLog.logGroupArn }, }, targets: { cluster: { resourceType: "aws:eks:cluster", resourceArns: [cluster.clusterArn], selectionMode: "ALL", }, }, actions: { InjectChaosMesh: { actionId: "aws:eks:inject-kubernetes-custom-resource", targets: { Cluster: "cluster" }, parameters: { kubernetesApiVersion: "chaos-mesh.org/v1alpha1", kubernetesKind: "PodChaos", kubernetesNamespace: "chaos-testing", kubernetesSpec: JSON.stringify({ action: "pod-kill", mode: "one", selector: { namespaces: ["default"], labelSelectors: nginxDeployment.spec.template.metadata.labels, }, gracePeriod: 0, }), maxDuration: "PT5M", }, }, }, stopConditions: [{ source: "none" }], });
本来であれば addHelmChart
でchaos-mesh
もインストールしたいのですが、
動作が確認できなかったので、手動でインストールすることにしました。
/*** cluster.addHelmChart("ChaosMesh", { repository: "https://charts.chaos-mesh.org", chart: "chaos-mesh/chaos-mesh", release: "chaos-mesh", version: "2.2.2", namespace: "chaos-testing", createNamespace: true, }); ***/
$ aws eks update-kubeconfig --name ${CLUSTER_NAME} --role-arn ${CLUSTER_ROLE_ARN} $ helm repo add chaos-mesh https://charts.chaos-mesh.org $ helm install chaos-mesh chaos-mesh/chaos-mesh --namespace=chaos-testing --version=2.2.2
FIS 経由で実行してみると動いていることが確認できました。
$ aws fis start-experiment --experiment-template-id "${TEMPLATE_ID}" $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-66b6c48dd5-584xb 1/1 Running 0 134m nginx-deployment-66b6c48dd5-hnl79 0/1 ContainerCreating 0 1s $ kubectl get podchaos -A --watch NAMESPACE NAME AGE chaos-testing fis-8lc50oqd9hjmstjq9ha7csqmdtt34ba9dpl6aork8dk62rrj9lin6q1deoog 0s chaos-testing fis-8lc50oqd9hjmstjq9ha7csqmdtt34ba9dpl6aork8dk62rrj9lin6q1deoog 21s
やってみての感想
Chaos Mesh と結合することでより柔軟な実験できるようになりました。
また、Chaos Mesh 側の実験を Cloudwatch Alarm 経由で停止したり、FIS の内容と組み合わせて実験するということができるようになります。
Chaos Mesh のダッシュボードも大変使いやすいのですが、実行権限やユーザを FIS で統一することで AWS でコントロールできるようになります。
ただ、Chaos Mesh のダッシュボードや Gremlin のダッシュボードでグリグリしながら実験することに慣れていると、JSON で実験テンプレートを作るのは少し難易度が高かったです。
なので実際に作った実験結果を FIS 側にも保存していく、といった用途で使っていくのが良さそうですね。