はじめに
EKSがGAになったので、早速 Getting Started with Amazon EKS をやってみました。
EKSの構築が完了してアプリケーションをデプロイできるようになるまでには、IAMロールを作成して、VPCを作成して、Masterを起動して、Workerを起動して、ConfigMapを作成して...と、たくさんのステップが必要で非常に面倒です。
今後は勉強用に気軽にEKSを起動できるよう、AWS CLIを使ったシェルスクリプトでEKSの構築を自動化しました。
前提
事前準備
以下の3つは Getting Started with Amazon EKS に従ってインストール済みとします。
- kubectl
- AWS CLI
- heptio-authenticator-aws
環境
動作確認した環境は以下の通りです。
- OS
- macOS High Sierra バージョン 10.13.3
- Bash
- GNU bash version 3.2.57(1)-release (x86_64-apple-darwin17)
- kubectl
- v1.10.2
- AWS CLI
- 1.15.351
- heptio-authenticator-aws
- 1.10.3
自動化した内容
以下、ソースコードの抜粋です。
IAMロールの作成
AWS CLIで作成するようにしました。
aws iam create-role \
--role-name $EKS_ROLE_NAME \
--assume-role-policy-document file://$POLICY_FILE
aws iam attach-role-policy \
--role-name $EKS_ROLE_NAME \
--policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
aws iam attach-role-policy \
--role-name $EKS_ROLE_NAME \
--policy-arn arn:aws:iam::aws:policy/AmazonEKSServicePolicy
SSHキーペアの作成
AWS CLIで作成するようにしました。
aws ec2 create-key-pair \
--key-name $EKS_KEY_NAME \
--query 'KeyMaterial' \
--output text \
> $EKS_KEY_FILE
chmod 600 $EKS_KEY_FILE
VPCの作成
Getting Started with Amazon EKS に記載されているCloudFormationテンプレートをAWS CLIから呼び出すようにしました。
aws cloudformation create-stack \
--stack-name $EKS_VPC_STACK_NAME \
--template-body https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/amazon-eks-vpc-sample.yaml \
--parameters \
ParameterKey=VpcBlock,ParameterValue=$VPC_BLOCK \
ParameterKey=Subnet01Block,ParameterValue=$SUBNET_01_BLOCK \
ParameterKey=Subnet02Block,ParameterValue=$SUBNET_02_BLOCK \
ParameterKey=Subnet03Block,ParameterValue=$SUBNET_03_BLOCK
Masterの作成
こちらも Getting Started with Amazon EKS に記載されているCloudFormationテンプレートをAWS CLIから呼び出すようにしました。
パラメータはVPC構築時のOutputsを使うようにしました。
ROLE_ARN=$(aws iam get-role \
--role-name $EKS_ROLE_NAME \
--query 'Role.Arn' \
| sed -E 's/.(.*)./\1/')
SUBNET_IDS=$(aws cloudformation describe-stacks \
--stack-name $EKS_VPC_STACK_NAME \
--query 'Stacks[0].Outputs[?OutputKey==`SubnetIds`].[OutputValue][0][0]' \
| sed -E 's/.(.*)./\1/')
SECURITY_GROUP_IDS=$(aws cloudformation describe-stacks \
--stack-name $EKS_VPC_STACK_NAME \
--query 'Stacks[0].Outputs[?OutputKey==`SecurityGroups`].[OutputValue][0][0]' \
| sed -E 's/.(.*)./\1/')
aws eks create-cluster \
--name $EKS_CLUSTER_NAME \
--role-arn $ROLE_ARN \
--resources-vpc-config subnetIds=$SUBNET_IDS,securityGroupIds=$SECURITY_GROUP_IDS
Workerの作成
こちらも Getting Started with Amazon EKS に記載されているCloudFormationテンプレートをAWS CLIから呼び出すようにしました。
パラメータはVPC構築時とMaster構築時のOutputsを使うようにしました。
CLUSTER_CONTROL_PLANE_SECURITY_GROUP=$(aws cloudformation describe-stacks \
--stack-name $EKS_VPC_STACK_NAME \
--query 'Stacks[0].Outputs[?OutputKey==`SecurityGroups`].[OutputValue][0][0]' \
| sed -E 's/.(.*)./\1/')
VPC_ID=$(aws cloudformation describe-stacks \
--stack-name $EKS_VPC_STACK_NAME \
--query 'Stacks[0].Outputs[?OutputKey==`VpcId`].[OutputValue][0][0]' \
| sed -E 's/.(.*)./\1/')
SUBNETS=$(aws cloudformation describe-stacks \
--stack-name $EKS_VPC_STACK_NAME \
--query 'Stacks[0].Outputs[?OutputKey==`SubnetIds`].[OutputValue][0][0]')
aws cloudformation create-stack \
--stack-name $EKS_WORKER_STACK_NAME \
--template-body https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/amazon-eks-nodegroup.yaml \
--parameters \
ParameterKey=ClusterName,ParameterValue=$EKS_CLUSTER_NAME \
ParameterKey=ClusterControlPlaneSecurityGroup,ParameterValue=$CLUSTER_CONTROL_PLANE_SECURITY_GROUP \
ParameterKey=NodeGroupName,ParameterValue=$NODE_GROUP_NAME \
ParameterKey=NodeAutoScalingGroupMinSize,ParameterValue=$NODE_AUTO_SCALING_GROUP_MIN_SIZE \
ParameterKey=NodeAutoScalingGroupMaxSize,ParameterValue=$NODE_AUTO_SCALING_GROUP_MAX_SIZE \
ParameterKey=NodeInstanceType,ParameterValue=$NODE_INSTANCE_TYPE \
ParameterKey=NodeImageId,ParameterValue=$NODE_IMAGE_ID \
ParameterKey=KeyName,ParameterValue=$EKS_KEY_NAME \
ParameterKey=VpcId,ParameterValue=$VPC_ID \
ParameterKey=Subnets,ParameterValue=$SUBNETS \
--capabilities CAPABILITY_IAM
kubectlの設定
Master構築時のOutputsから設定ファイルを作るようにしました。
ENDPOINT_URL=`aws eks describe-cluster \
--name $EKS_CLUSTER_NAME \
--query cluster.endpoint`
BASE64_ENCODED_CA_CERT=`aws eks describe-cluster \
--name $EKS_CLUSTER_NAME \
--query cluster.certificateAuthority.data`
mkdir -p ~/.kube
cat << EOT > $EKS_KUBE_CONFIG_FILE
apiVersion: v1
clusters:
- cluster:
server: $ENDPOINT_URL
certificate-authority-data: $BASE64_ENCODED_CA_CERT
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: aws
name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: heptio-authenticator-aws
args:
- "token"
- "-i"
- "$EKS_CLUSTER_NAME"
# - "-r"
# - "<role-arn>"
EOT
ConfigMapの作成
Worker構築時のOutputsから設定ファイルを作るようにしました。
ROLE_ARN=$(aws cloudformation describe-stacks \
--stack-name $EKS_WORKER_STACK_NAME \
--query 'Stacks[0].Outputs[0].OutputValue' \
| sed -E 's/.(.*)./\1/')
cat << EOT | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: $ROLE_ARN
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
EOT
まとめ
以上をまとめて、以下のコマンドでEKSの構築が完了するようになりました。
$ source set-env.sh
$ ./launch.sh
15分ほど待てば、Workerの設定まで完了します。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
ip-192-168-111-33.us-west-2.compute.internal Ready <none> 7m v1.10.3
ip-192-168-152-30.us-west-2.compute.internal Ready <none> 7m v1.10.3
ip-192-168-250-1.us-west-2.compute.internal Ready <none> 7m v1.10.3
ついでに廃棄も1コマンドにしました。
./cleanup.sh
ソースコードの全容は以下です。
https://github.com/os1ma/eks-sample/tree/master/getting-started-with-amazon-eks
課題
ひとまず動くように作った程度なので、課題がいくつもあります。
- 例外処理やロールバックがない
- Serviceのtype LoadBalancerを削除せずにEKSを削除してしまうと、ELBとSecurity Groupが残ってしまい、VPCの削除がうまくいかない
- EKSを削除する前に関連するリソースを削除する処理を入れたい
- 命名にランダムな文字列などをつけていないので、名前が競合してしまう可能性がある
- 特に、
~/.kube/config-$EKS_CLUSTER_NAME
は既存のファイルを上書きしないよう注意が必要
- 特に、
-
2018/06/09の時点ではHomebrewでEKSに対応しているバージョンをインストールできなかったので、pipでインストールしました ↩