やってみた、Gremlinを使ってEKSのクラスターにカオスエンジニアリングの実験を実行するチュートリアルを

2019.11.21

どうも、森です。

今月は AWSJ社のChaosConf2019 Recapに行き、カオスエンジニアリングの歴史から最近のトレンドまで学びカオス筋が少しはついてきたと感じています。

【レポート】Chaos Engineering が合うもの/合わないもの – ChaosConf2019 recap –

聞くだけではなく実際にやってみようという天の声(わっしょい)が聞こえたので ChaosConfつながりのGremlin,AWSつながりのEKSを使って実験しようと思います。

ちょうどいいGremlin公式のチュートリアルがあるので、これに沿って行なっていきます。コンテナ環境に対して実験をやった経験もないのでちょうどよかった。

前提条件

AWSアカウント、Gremlinのアカウントが必要なので用意します。さらに、AWS CLIも必要です。

region; ap-northeast-1

チュートリアル概要

EKSクラスターで2つのアプリケーションを展開し、Gremlinを使用してカオスエンジニアリングの実験を行います。 実験はコンテナに対してシャットダウン攻撃を行うものです。

チュートリアル実験における仮説

EKSの信頼性を検証したい。

コンテナをシャットダウンすると、ダウンタイムに悩まされることなくEKSによって新しいものに置き換えられるはずである。

実験手順

  • eksctlは、Amazon EKSでKubernetesクラスターを作成および管理するためのコマンドラインツールです。
  • kubectlは、Kubernetesクラスターに対してコマンドを実行するためのコマンドラインツールです。

1. eksctlを使用してEKSクラスターを作成する

ローカルPCにeksctlをインストールします。

$ brew install https://raw.githubusercontent.com/weaveworks/homebrew-tap/75596a00ca13dcffe184bb1f7ed60227e4b0891e/Formula/eksctl.rb

※ version 0.10.1だと AWS node/instance security group - misuse of cluster tag に書かれている問題にぶち当たってしまったので0.9.0をインストールしました

$ eksctl version
[ℹ]  version.Info{BuiltAt:"", GitCommit:"", GitTag:"0.9.0"}

インストール後、クラスターを作成します。

eksctl create cluster

これにより、クラスターと必要なリソースがに作成されます。クラスター名を自動生成し、公式のAWS EKS AMIを使用して2つのm5.large ec2インスタンスを作成し、専用のVPCをセットアップします。

2. EKSクラスターがセットアップされているかどうかの確認

クラスターの名前と次のようなリージョンが表示されます。

$ eksctl get clusters
NAME		REGION

<クラスター名>	ap-northeast-1

AWSからkubeconfigファイルを取得し、eksctlが設定したホストを確認します。

$ sudo aws eks --region ap-northeast-1 update-kubeconfig --name <クラスター名>
$ kubectl get nodes

NAME                                                STATUS   ROLES    AGE   VERSION
ip-192-168-39-231.ap-northeast-1.compute.internal   Ready    <none>   11m   v1.14.7-eks-1861c5
ip-192-168-80-217.ap-northeast-1.compute.internal   Ready    <none>   11m   v1.14.7-eks-1861c5

3. Kubernetesダッシュボード, heapster, influxdbをデプロイする

ダッシュボードをEKSクラスターにデプロイするには:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml

heapsterは:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/heapster.yaml

※ heapsterは、Kubernetes(バージョンv1.0.6以降)およびそれを含むプラットフォームのコンテナクラスター監視とパフォーマンス分析を有効にします

influxdbは:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml

※ influxdbはheapsterで取得したメトリクスを保存するための時系列DBです

デプロイ後、

  • ダッシュボード用のheapsterクラスターロールバインディングとクラスターロールバインディングを作成します。
    $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml

  • eks-adminサービスアカウントを作成します

    $ kubectl apply -f https://raw.githubusercontent.com/tammybutow/eks-aws/master/eks-admin-service-account.yaml

  • Kubernetesダッシュボードに接続するための認証トークンを取得します

    $ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk '{print $1}')

  • ローカルマシンでKubernetesダッシュボードにアクセスできるように実行します

    kubectl proxy

  • webブラウザでアクセスします

    URL: http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login

    トークンは Kubernetesダッシュボードに接続するための認証トークンを取得します で取得したものを使います。

     

4. EKSクラスターにGremlinクライアントをインストールする

Gremlin証明書をダウンロードする

Gremlinアプリにログインし、チーム設定のページに移動してチームをクリックします。DownLoadボタンを押して証明書を取得します。

certificate.zipを解凍し、任意の場所のgremlinフォルダーに保存します。証明書とキーファイルの名前をgremlin.certとgremlin.keyに変更します。

GremlinのKubernetes名前空間を作成

kubectl create namespace gremlin

証明書と秘密キーのKubernetesシークレットを作成します

kubectl create secret generic gremlin-team-cert \
\--namespace=gremlin  \
\--from-file=/path/to/gremlin.cert \
\--from-file=/path/to/gremlin.key

Helmをインストール

Helmは、Kubernetesアプリケーションのインストールと管理を効率化するツールです。Kubernetesのapt / yum / homebrewのように考えてください

https://helm.sh/docs/intro/install/ を参考にインストールします。今回のクライアントPCはMACなので

brew install kubernetes-helm

Helmを使用したGremlinクライアントのインストール

Gremlin Team IDと任意のクラスターIDを環境変数にセットします。 Gremlin Team IDはチーム設定のページにて取得します。

$ export GREMLIN_TEAM_ID="<Your tema ID>"
$ export GREMLIN_CLUSTER_ID="cm_mori_gremlin_cluster"

セット後、Gremlin Helmリポジトリを追加し、Gremlinをインストールします。

helm repo add gremlin https://helm.gremlin.com
helm install gremlin \
gremlin/gremlin \
\--namespace gremlin \
\--set gremlin.teamID=$GREMLIN_TEAM_ID \
\--set gremlin.clusterID=$GREMLIN_CLUSTER_ID

5. デモアプリをインストールする

EKSクラスターに展開するデモアプリとして、kubernetes-guestbookを使います

ローカルマシンで,

git clone https://github.com/GoogleCloudPlatform/microservices-demo.git
cd microservices-demo
kubectl apply -f ./release/kubernetes-manifests.yaml

ポッドが準備完了状態になるまで待ちます。実行準備を確認するには

kubectl get pods

ポッドが準備完了状態になったらフロントエンドのIPアドレスを取得します

kubectl get svc frontend-external -o wide

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE     SELECTOR
frontend-external   LoadBalancer   10.100.121.154   <URL>     80:30130/TCP   2m19s   app=frontend

EXTERNAL-IPに出力されたURLにアクセスします。

6. Gremlinを使用してコンテナーにシャットダウン攻撃を実行する

Gremlin UIに戻り、左側のメニューから「Attacks」を選択し、緑色の「New Attack」ボタンを押します。Kubernetesリソースをターゲットとするため、右上の[Kubernetes]をクリックします。

cartservice コンテナをシャットダウンします。

[Deployments]フィールドを展開し、cartserviceを選択することにより、ターゲットにするコンテナーを見つけることができます。

次は Choose a Gremlin に進み、[State]を選択し、オプションから[Shutdown]を選択します。Delayを1分に設定したままにして、再起動をオフにします。次に、緑色の「Unleash Gremlin」ボタンをクリックします。

Kubernetesダッシュボードに戻り、左側のメニューバーでポッドを選択して、ポッドの状態を表示します。また、デモアプリをチェックして、ユーザーエクスペリエンスをテストし、仮説が正しいかどうかを確認してください。

結果

コンテナをシャットダウンすると、ダウンタイムに悩まされることなくEKSによって新しいものに置き換えられるはずである。

という仮説を立て実験を行いましたが、正しくはありませんでした。 サイトをみると、500エラーが表示されたことがわかりました。

チュートリアルページにある通り、この問題を軽減するには、

まずエラーが発生した理由を調査し、ログを調べる必要があります。kubectl get podsを実行すると、cartserviceが1つだけ実行され、冗長性がないことがわかります。カートサービスではredisが使用されていますが、クラスター化されたredisは使用されていないことがわかります https://github.com/GoogleCloudPlatform/microservices-demo/blob/master/kubernetes-manifests/cartservice.yaml

$ kubectl get pods
NAME                                     READY   STATUS    RESTARTS   AGE
adservice-f79574c97-cczvz                1/1     Running   0          31m
cartservice-666876c7bd-56v4m             1/1     Running   3          31m

まとめ

この記事ではAmazon EKSの信頼性を検証するために、以下のことを行いました。

  • EKSクラスターのセットアップ
  • Kubernetesダッシュボードをデプロイ
  • マイクロサービスデモアプリケーションをデプロイ
  • Gremlinエージェントをデーモンセットとしてインストール
  • Chaos Engineering 攻撃を実行

Gremlin が native K8 support を発表していましたが( Simple Kubernetes Targeting for Your Chaos Experiments),このおかげで簡単に実験を行えるようになっています。 コンテナの障害テストってどうするの?と思っていた方、EKSでアプリケーションを実行している方など、多くの人のヒントになるチュートリアルだったと思います。

Gremlin 無料プランでも実験可能ですよ! さあ、やってみましょう。

参考