構成
- Multi-AZ High Availability
- Kubernetes: Amazon EKS
- MongoDB: helm で
stable/mongodb-replicaset
の chart をインストールして使う - RabbitMQ: helm で
stable/rabbitmq-ha
の chart をインストールして使う - Redis: Amazon ElastiCache の Redis インスタンスを使う
- PostgreSQL: Amazon RDS の Aurora Postgres インスタンスを使う
-
/opt/stackstorm/packs
,/opt/stackstorm/virtualenvs
に必要な RWX PV は kubernetes-incubator にある efs-provisioner を使う - AWS region: us-west-2 (Oregon) に構築する
- 前述した全てのAWSコンポーネントが揃っているため。
構築手順
EKS
-
eksctl
をインストール -
eksctl create cluster
でクラスタを作成 -
export KUBECONFIG=/path/to/eksctl/generated/kubeconfig
しておく - ノード用に作成された Auto Scaling Group の Launch Configuration を編集して nfs-utils がインストールされたノードを作り直す
- EC2 -> Launch Configurations のページで
eksctl
によって作成された Launch Configuration をコピー - Edit details -> Advanced Details -> User data のフィールドに、ノード初期化用の shell sccript が記載されているので、一番最後の行 (
/opt/aws/bin/cfn-signal
) の一つ前にyum -y install nfs-utils
を追加し、保存 - Auto Scaling Groups のページで
eksctl
によって作成された Node Group を編集、上で複製して作成した Launch Configuration に変更 - いったんノード数の項目 (Desired Capacity / Min / Max) を全て0に変更して、インスタンスが全て削除されるのを待ってから、再度ノード数を適当な数に変更してノードを作成し直す
-
kubectl get nods --watch
で、指定した数のノードが Ready になるまで待機する
- EC2 -> Launch Configurations のページで
- EKS で EBS PV を使えるようにする
- https://docs.aws.amazon.com/eks/latest/userguide/storage-classes.html に書いてあるとおり
- gp2 を default の Storage Class にしておく
kubectl create -f <(cat << EOF
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp2
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
mountOptions:
- debug
EOF
)
kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
EFS, efs-provisioner
- EFS を作成する
- VPC:
eksctl
によって作成されたVPCを選択する - Create mount targets で Security Groups を
eksctl
によって作成された ノード 用のセキュリティグループに変更する- こんな感じのやつ:
EKS-fabulous-unicorn-1528645311-DefaultNodeGroup-NodeSecurityGroup-1OC66QBNRBY0J
- default は不要なので、外して良い
- こんな感じのやつ:
- VPC:
- EKS で作成した k8s cluster に efs-provisioner を設定する
- https://github.com/kubernetes-incubator/external-storage/tree/master/aws/efs に書いてあるとおり
- EKS は RBAC 有効なので Service Account の設定も必要。忘れずに実施する
git clone https://github.com/kubernetes-incubator/external-storage
cd external-storage
cd aws/efs
vim deploy/manifest.yaml
git diff
diff --git a/aws/efs/deploy/manifest.yaml b/aws/efs/deploy/manifest.yaml
index fd36c3d8..70b82f2e 100644
--- a/aws/efs/deploy/manifest.yaml
+++ b/aws/efs/deploy/manifest.yaml
@@ -4,8 +4,8 @@ kind: ConfigMap
metadata:
name: efs-provisioner
data:
- file.system.id: yourEFSsystemid
- aws.region: regionyourEFSisin
+ file.system.id: fs-f247245b
+ aws.region: us-west-2
provisioner.name: example.com/aws-efs
---
kind: Deployment
@@ -46,7 +46,7 @@ spec:
volumes:
- name: pv-volume
nfs:
- server: yourEFSsystemID.efs.yourEFSregion.amazonaws.com
+ server: fs-f247245b.efs.us-west-2.amazonaws.com
path: /
---
kind: StorageClass
kubectl create -f deploy/auth/serviceaccount.yaml
kubectl create -f deploy/auth/clusterrole.yaml
kubectl create -f deploy/auth/clusterrolebinding.yaml
kubectl patch deployment efs-provisioner -p '{"spec":{"template":{"spec":{"serviceAccount":"efs-provisioner"}}}}'
サンプルとして作成されるPVCを削除しておく
kubectl delete pvc efs
kubectl logs
で efs-provisioner
のログを確認した際に表示される以下のエラーは無視してよい
W0611 01:06:08.872993 1 efs-provisioner.go:86] couldn't confirm that the EFS file system exists: AccessDeniedException: User: arn:aws:sts::540305223857:assumed-role/EKS-fabulous-unicorn-1528645311-D-NodeInstanceRole-16115XNK8G8JT/i-0019e5ba334295701 is not authorized to perform: elasticfilesystem:DescribeFileSystems on the specified resource
status code: 403, request id: 9fd8513c-6d13-11e8-9b5f-d338798934b5
Helm
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
helm init --service-account tiller
MongoDB
- MongoDB 3.6 は StackStorm でサポートされていないので、要注意
helm install --name st2-mongodb --set image.tag=3.4 stable/mongodb-replicaset
RabbitMQ
helm install --name st2-rabbitmq --set persistentVolume.enabled=true stable/rabbitmq-ha
パスワードをメモしておく
echo $(kubectl get secret --namespace default st2-rabbitmq-rabbitmq-ha -o jsonpath="{.data.rabbitmq-password}" | base64 --decode)
!!!パスワードにスラッシュが含まれていた場合は、一旦 helm delete --purge
してやり直す!!!
パスワードにスラッシュが含まれていると mistral-server が起動できない。mistral-server では設定した URL が oslo_messaging -> kombu の流れで処理されるようだが、どうやら komub に渡る手前の段階で一旦部分的に url decode されるようで、パスワードの部分にスラッシュが含まれていると、それが kombu で url parse する際にホスト部の終わりのスラッシュと間違って解釈されてしまい、結果的にユーザー名がホスト名、パスワードの途中までがポート番号と誤った内容になってしまう。もしかしたら他にも駄目な記号があるかもしれないが、とりあえずバックスラッシュやコロンは入っていても問題ないことを確認済み。
helm install
する際に自分で使用するユーザー名・パスワードを与えることも出来るので、運に任せるよりは、こちらの方が楽かもしれない。
helm install --name st2-rabbitmq --set persistentVolume.enabled=true,rabbitmqUsername=st2,rabbitmqPassword=changeme stable/rabbitmq-ha
Amazon RDS Aurora PostgreSQL
- RDS メニューからウィザードに従って新規に Aurora PostgreSQL インスタンスを作成する
- Multi-AZ deployment で Create Replica in Different Zone を選択
- VPC:
eksctl
が作成したものを選択する - Public accessibility: no
- VPC security groups は Choose existing VPC security groups を選択し
eksctl
によって作成された ノード 用のセキュリティグループに変更する- こんな感じのやつ:
EKS-fabulous-unicorn-1528645311-DefaultNodeGroup-NodeSecurityGroup-1OC66QBNRBY0J
- default は不要なので、外して良い
- EFS を設定したときと同じ
- こんな感じのやつ:
- rds-launch-wizard という名前のセキュリティグループがウィザードによって新規に作成されるが、これらは不要なので削除してよい
- Cluster Endpoint をメモしておく
- StackStormで使う DB, user を作成する
kubectl run -it psql --image=postgres sh
RDS_CLUSTER_ENDPOINT=your.cluster.us-west-2.rds.amazonaws.com
RDS_ADMIN_USER=your_admin_user
psql -h $RDS_CLUSTER_ENDPOINT -U $RDS_ADMIN_USER postgres
create database st2_mistral;
create role st2 with login password 'changeme';
alter database st2_mistral owner to st2;
\q
exit
kubectl delete deployment/psql
Amazon ElastiCache Redis
- ElastiCache のメニューからウィザードに従って新規に Redis インスタンスを作成する
- "Cluster Mode enabled" のチェックは外す。これを使うためにはクライアント側でクラスターモードに対応した接続をする必要がある
- Node type は t2 family 以外から選択する
- t2 だと下記 Multi-AZ Auto Failover を有効に出来ない
- Multi-AZ with Auto Failover にチェックを入れる
- Subnet group は Create new にする
- VPC:
eksctl
によって作成されたVPCを選択する - Subnets: 3つ全てにチェックを入れる
- Security Groups を
eksctl
によって作成された ノード 用のセキュリティグループに変更する- こんな感じのやつ:
EKS-fabulous-unicorn-1528645311-DefaultNodeGroup-NodeSecurityGroup-1OC66QBNRBY0J
- default は不要なので、外して良い
- EFS を設定したときと同じ
- こんな感じのやつ:
- Primary Endpoint をメモしておく
StackStorm
- MongoDBのHA接続を実現するため、本家マスターにまだマージされていない機能が実装されたカスタムイメージを使う
- マニフェストファイルも上記に合わせて変更したものを使う
git clone https://github.com/shusugmt/st2-docker -b k8s/aws-eks
cd st2-docker
cd runtime/k8s-deployment-examples/aws-eks
vim configmaps.yml
git diff
- MongoDB, RabbitMQ, PostgreSQL, Redis の URL を、それぞれ自身の環境に合わせて書き換える
- MongoDB に関しては helm chart をインストールする際にリリース名を変更していなければ、特に手を加える必要はない
- パスワードに特殊文字が含まれる場合は URL エンコードしたものを使う
diff --git a/runtime/k8s-deployment-examples/aws-eks/configmaps.yml b/runtime/k8s-deployment-examples/aws-eks/configmaps.yml
index a8542c3..511e8c6 100644
--- a/runtime/k8s-deployment-examples/aws-eks/configmaps.yml
+++ b/runtime/k8s-deployment-examples/aws-eks/configmaps.yml
@@ -18,7 +18,7 @@ metadata:
name: st2-externals
data:
ST2_MONGODB_URL: mongodb://st2-mongodb-mongodb-replicaset-0.st2-mongodb-mongodb-replicaset:27017,st2-mongodb-mongodb-replicaset-1.st2-mongodb-mongodb-replicaset:27017,st2-mongodb-mongodb-replicaset-2.st2-mongodb-mongodb-replicaset:27017/st2?replicaSet=rs0
- ST2_RABBITMQ_URL: amqp://st2:changeme@st2-rabbitmq-rabbitmq-ha:5672/
- ST2_COORDINATION_BACKEND_URL: redis://:@your.redis.cache.amazonaws.com:6379/
- ST2MISTRAL_RABBITMQ_URL: rabbit://st2:changeme@st2-rabbitmq-rabbitmq-ha:5672/
- ST2MISTRAL_DB_URL: postgresql+psycopg2://st2:changeme@your.cluster.us-west-2.rds.amazonaws.com:5432/st2_mistral
+ ST2_RABBITMQ_URL: amqp://guest:PP%2Bp24R%3BD%2CR3r%3DF%3F%25x%5D%5D%60%2C.K@st2-rabbitmq-rabbitmq-ha:5672/
+ ST2_COORDINATION_BACKEND_URL: redis://:@st2-redis.mfq0jh.ng.0001.usw2.cache.amazonaws.com:6379/
+ ST2MISTRAL_RABBITMQ_URL: rabbit://guest:PP%2Bp24R%3BD%2CR3r%3DF%3F%25x%5D%5D%60%2C.K@st2-rabbitmq-rabbitmq-ha:5672/
+ ST2MISTRAL_DB_URL: postgresql+psycopg2://st2:changeme@st2-postgres-cluster.cluster-cxjltt8mheoy.us-west-2.rds.amazonaws.com/st2_mistral
kubectl apply -f configmaps.yml
kubectl apply -f st2.yml
kubectl apply -f init-st2.yml
kubectl get svc
kubectl port-forward svc/st2web 8443:443
ブラウザで https://localhost:8443
を開くと st2web の画面が表示される。ロードバランサー経由でアクセスしたい場合は kubectl edit svc/st2web
して type: LoadBalancer
に変更してあげればよい。暫く待つと EXTERNAL IP に FQDN がアサインされるので kubectl describe svc/st2web
でアドレスを確認出来る。
クリーンアップ
- StackStorm のリソースを全て
kubectl delete
する - MongoDB, RabbitMQ を
helm delete --purge
する- PVC, PV は消えないので
kubectl delete
を使って削除する
- PVC, PV は消えないので
- MongoDB, RabbitMQ の PV として使用されていた EBS ボリュームを削除する
- efs-provisionerを
kubectl delete
する - RDS, ElastiCache インスタンスを削除する
- Subnet Group の削除も忘れずに
- EFS インスタンスを削除する
eksctl delete cluster
- 複製した Launch Configuration を削除する
Notes
- Amazon MQ を RabbitMQ の代わりに使えるか: No
- kombuがAMQP 1.0を喋れるクライアントに対応していないため