kubernetesを使ったデモサイトに対してGremlinで攻撃してみる

2020.07.14

カオスエンジニアリングのプラットフォームであるGremlinですが、EC2やVMware,オンプレのホストだけでなくKubernetesのクラスターに対してもカオス実験が行えるようにサポートされています。

そういえばKubernetesの環境に対してGremlinを実行したことはなかったのでやってみようと思い立ちました。

やってみる

環境

  • ローカル環境はmacOS
  • ローカル環境にDocker desktopを使用(macOS)
    • Kubernetesアプリのデプロイ先としてDocker desktopを使用する(gremlinのデーモン含む)

Gremlin

Docker Desktop上にGremlinのクラスターを作成します。

参考のドキュメント:

How to Install and Use Gremlin with Kubernetes

以下の環境変数をセットします。

$ export GREMLIN_TEAM_ID=<insert team id>
$ export GREMLIN_CLUSTER_ID=<insert user defined clusteridentifier>

Docker Desktopでkubernetesを有効にするのを忘れないようにします。

CPUを少なくとも3に、メモリを少なくとも6.0 GiBに設定します

[ディスク]タブで、32GB以上のディスク容量を設定します

$ kubectl get nodes
NAME             STATUS   ROLES    AGE   VERSION
docker-desktop   Ready    master   30m   v1.16.6-beta.0

以下のコマンドを実行し、namespaceの作成とgremlinをインストールします、

$ kubectl create namespace gremlin
$ helm repo remove 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

gremlinのダッシュボードにログインし、Certificatesをダウンロードします。

URL: https://app.gremlin.com/settings/team/{team id}/configuration

zipファイルがDLできるので、解凍してから名前を変更しておきます。

$ mv certificate/<ファイル名>.priv_key.pem gremlin.key
$ mv certificate/<ファイル名>.pub_cert.pem gremlin.cert

以下のコマンドでsecretを作成します。

$ kubectl -n gremlin create secret generic gremlin-team-cert --from-file=</path/to/gremlin.cert> --from-file=</path/to/gremlin.key>

確認: podsが全てREADYになっていればおk

$ kubectl get namespace gremlin
NAME      STATUS   AGE
gremlin   Active   127m

$ kubectl get secret --namespace gremlin
NAME                            TYPE                                  DATA   AGE
chao-token-ht9vs                kubernetes.io/service-account-token   3      128m
default-token-7vbsw             kubernetes.io/service-account-token   3      129m
gremlin-team-cert               Opaque                                2      128m
sh.helm.release.v1.gremlin.v1   helm.sh/release.v1                    1      128m

$ kubectl get pods --namespace gremlin
NAME                    READY   STATUS    RESTARTS   AGE
chao-5bcfc7d4b8-9vhsf   1/1     Running   0          125m
gremlin-5rswj           1/1     Running   0          125m

Gremlinのダッシュボードにログインし,Clientsdocker-desktopが表示されている確認します。

Skaffold

本記事ではSkaffoldというKubernetesへの継続的な開発を容易にするコマンドラインツールを使ってDocker Desktopへのアプリケーションデプロイを行います。

インストール

Skaffoldのインストールを参考にインストールします。

$ brew install skaffold
$ $ skaffold version
v1.12.0

デモアプリ

本記事ではhttps://github.com/GoogleCloudPlatform/microservices-demo.gitを使用します。

アーキテクチャに関しては READMEのservice-architecture を参照してください。

インストールしたskaffoldを使ってデプロイします。

$ git clone https://github.com/GoogleCloudPlatform/microservices-demo.git
$ cd microservices-demo/
$ skaffold run

podの状態を確認します。

$ kubectl get pods
NAME                                     READY   STATUS    RESTARTS   AGE
adservice-66f5dd67f4-9rsmn               1/1     Running   0          75s
cartservice-79759c6ccf-xn777             1/1     Running   0          75s
checkoutservice-7d45fb475f-ggqhj         1/1     Running   0          75s
currencyservice-8f876bdf7-kprxf          1/1     Running   0          75s
emailservice-bc954dd9d-7z696             1/1     Running   0          75s
frontend-58cd5ffd54-8w29x                1/1     Running   0          75s
loadgenerator-764dd4f9cd-vsvmv           1/1     Running   3          75s
paymentservice-7475c7c6fb-xrlbj          1/1     Running   0          75s
productcatalogservice-5788759494-fzfhc   1/1     Running   0          74s
recommendationservice-ff5769bb4-mtm4h    1/1     Running   0          74s
redis-cart-7948bfdbfb-brccz              1/1     Running   0          74s
shippingservice-6cd559cd74-2mmxg         1/1     Running   0          74s

全てREADYとなっているのを確認後、次はブラウザからアプリケーションにアクセスします。

http://localhost にアクセスすると、以下のようなページが表示されるはずです。

GremlinでKubernetesの環境が認識されているか確認する

Gremlinのダッシュボードにログインし、kubernetesの環境に攻撃ができる状態になっているか確認します。

https://app.gremlin.com/attacks/new/kubernetes にアクセスし、

  • What do you want to attack? : kubernetes
  • 1. Choose a cluster : <GREMLIN_CLUSTER_ID>で指定した値
  • 2. Choose a namespace: default

を選択して攻撃ターゲットを表示させてみます。

以下のように選択されたcluster,namespaceのオブジェクトが表示されます。 今回のアプリケーションではDeploymentsが現れます。DeploymentsのなかにReplicaSetとPodが含まれています。

実際に攻撃を試してみる

ターゲットが認識されていることが確認できたので、実際に攻撃してみます。

redis-cartにチェックを入れます。

攻撃タイプにはシャットダウンを選択します。

  • アプリケーションのカート機能が使えなくなるか?
  • 自動的に回復されるか?

を確認してみます。

デモアプリケーションの方で、カートに商品を一つ入れておきます。 この状態で攻撃してみます。

攻撃が行われたときにデモサイトにアクセスすると、以下のようなエラー画面が表示されることがありました。

HTTP Status: 500 Internal Server Error で、cartへの接続ができないといった内容です。

kubernetesによるPodのリスタートが行われたあとは通常のアクセスが可能でした。

自動的に回復はされるが、アクセスできなくなる といった結果になりました。

最後に

今回はローカル環境ではありますが、Kubernetesを実行しているホストにGremlinをインストールし、Gremlinでの攻撃が機能することを確認しました。アプリケーションの挙動を知るのに強力なツールになりえると感じています。

CPU,I/0,Blackhole,Packetlossなどの攻撃を実行し、Kubernetes上のアプリケーションがどういった挙動をするのか学習できるので色々と試してみていきたいと思います。