やたらControl Planeの作成にハマったので備忘録
環境
使うのはMacとDocker。
あとローカルのAWS CLIのクレデンシャル
- mac OS Sierra
- 10.12.5
- docker 18.03
Docker version 18.03.1-ce, build 9ee9f40
- aws-cli 1.15.30
- EKS対応は
1.15.32
から - 18/06/06時点では brewのstableだと1.15.30で、
$ aws eks
は使えない。 - // あとで
$ brew install awscli --HEAD
とかやったら1.15.33
が落ちてきたのでこれでいいのでは
- EKS対応は
ローカルの作業環境にDockerを使う。
先述したとおり、awscliのEKS対応は1.15.32から。
別途GKEも触っていてkubectlのバージョン合わせるのめんどうだったりとかで、ならば脳死でDocker内でawscliとkubectlを動かす戦法。
作ったEKS触るためのDocker環境はDockerHubへ上げたのでよしなに
yohgi/eks-cli - Docker Hub
$ docker run -v /Users/`whoami`/.aws:/root/.aws -it yohgi/eks-cli ash # ~/.aws を投げ込む # aws --version aws-cli/1.15.33 Python/3.6.5 Linux/4.9.87-linuxkit-aufs botocore/1.10.33 # kubectl version Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.3", GitCommit:"2bba0127d85d5a46ab4b778548be28623b32d0b0", GitTreeState:"clean", BuildDate:"2018-05-28T20:16:17Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
Dockerfileは以下
FROM python:3-alpine RUN pip install awscli && \ apk add --update curl jq && \ cd /usr/local/bin && \ curl -LO https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/bin/linux/amd64/heptio-authenticator-aws && \ chmod +x ./heptio-authenticator-aws && \ curl -LO https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/bin/linux/amd64/kubectl && \ chmod +x ./kubectl && \ mkdir /root/.kube && { \ echo 'apiVersion: v1'; \ echo 'clusters:'; \ echo '- cluster:'; \ echo ' server: <endpoint-url>'; \ echo ' certificate-authority-data: <base64-encoded-ca-cert>'; \ echo ' name: kubernetes'; \ echo 'contexts:'; \ echo '- context:'; \ echo ' cluster: kubernetes'; \ echo ' user: aws'; \ echo ' name: aws'; \ echo 'current-context: aws'; \ echo 'kind: Config'; \ echo 'preferences: {}'; \ echo 'users:'; \ echo '- name: aws'; \ echo ' user:'; \ echo ' exec:'; \ echo ' apiVersion: client.authentication.k8s.io/v1alpha1'; \ echo ' command: heptio-authenticator-aws'; \ echo ' args:'; \ echo ' - "token"'; \ echo ' - "-i"'; \ echo ' - "<cluster-name>"'; \ echo ' # - "-r"'; \ echo ' # - "<role-arn>"'; \ } | tee /root/.kube/config ENV KUBECONFIG "/root/.kube/config"
https://hub.docker.com/r/yohgi/eks-cli/
ローカルでAWS CLIを使っていない場合。
- IAMでAdminポリシーを持ったIAMユーザーを作成し、アクセスキーを取得。
- dockerに入り
$ docker run -it yohgi/eks-cli ash
、aws cliの認証を実行$ aws configure
する。認証後は$ aws s3 ls
などで動作確認すると良いと思われ。
EKSを触る
公式の Getting Started を参考に作成
また、今回作る各種リソース名は「test-cluster」と命名。
EKSはオレゴンとバージニアしか対応してないので、オレゴンでゴニョる。バージニアで作成する場合はAMIだけ注意
やること
できるもの
あとセキュリティグループがわちゃわちゃと
1. クラスター用IAM Roleの作成
# cat <<EOL > policy.json { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "eks.amazonaws.com" } } ] } # aws iam create-role --role-name test-cluster --assume-role-policy-document file://policy.json # aws iam attach-role-policy --role-name test-cluster --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy # aws iam attach-role-policy --role-name test-cluster --policy-arn arn:aws:iam::aws:policy/AmazonEKSServicePolicy
roleが作成されたか確認
# aws iam list-attached-role-policies --role-name test-cluster { "AttachedPolicies": [ { "PolicyName": "AmazonEKSClusterPolicy", "PolicyArn": "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" }, { "PolicyName": "AmazonEKSServicePolicy", "PolicyArn": "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" } ] }
2. EKS用VPCの作成
公式で提供されているCloudFormationを使用してネットワークを作成。
VPCを1つとSubnet3つ、そしてCluster用セキュリティーグループを作成してくれる。Subnetは3つともPublic Subnet。
# aws cloudformation create-stack --stack-name test-cluster --template-url https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/amazon-eks-vpc-sample.yaml
Getting Started with Amazon EKS - Amazon EKS
3. クラスターの作成
先程作成したCloudFormationのスタック作成完了後、クラスターの作成を行う。
# export EKS_SUBNETS=$(aws cloudformation describe-stacks --stack-name test-cluster --query 'Stacks[0].Outputs[?OutputKey==`SubnetIds`][].OutputValue' --output text) # export EKS_CLUSTER_SG=$(aws cloudformation describe-stacks --stack-name test-cluster --query 'Stacks[0].Outputs[?OutputKey==`SecurityGroups`][].OutputValue' --output text) # export EKS_CLUSTER_ROLE=$(aws iam get-role --role-name test-cluster --query 'Role.Arn' --output text) # aws eks create-cluster --name test-cluster --role-arn ${EKS_CLUSTER_ROLE} --resources-vpc-config subnetIds=${EKS_SUBNETS},securityGroupIds=${EKS_CLUSTER_SG}
クラスターの作成にはそこそこ時間かかる模様。
2018/06/06: オレゴンリージョンのGUIで作成した場合
kubectlがKubernetesへ接続できず動かない模様。18年6月6日現在ではまだGUIからの作成は非対応っぽい。
# kubectl get all The connection to the server localhost:8080 was refused - did you specify the right host or port?
4. kubectlの設定
/root/.kube/config
へKubernetesの認証情報を記述する。
# export EKS_CLUSTER_NAME=$(aws eks describe-cluster --name test-cluster --query 'cluster.name' --output text) # export EKS_CLUSTER_ENDPINT_URL=$(aws eks describe-cluster --name test-cluster --query 'cluster.endpoint' --output text) # export EKS_CLUSTER_CREDENTIAL=$(aws eks describe-cluster --name test-cluster --query 'cluster.certificateAuthority.data' --output text) # sed -i -e "s|server: <endpoint-url>|server: $EKS_CLUSTER_ENDPINT_URL|g" .kube/config # sed -i -e "s|certificate-authority-data: <base64-encoded-ca-cert>|certificate-authority-data: $EKS_CLUSTER_CREDENTIAL|g" .kube/config # sed -i -e "s|- \"<cluster-name>\"|- \"$EKS_CLUSTER_NAME\"|g" .kube/config
Control Planeへ接続できることを確認。
# kubectl get all NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 2h
5. Nodeの作成
Node用キーペアの作成
念の為作っておく。
# aws ec2 create-key-pair --key-name test-cluster --query 'KeyMaterial' --output text > /tmp/test-cluster.pem
作成しただけだとコンテナ内にしか秘密鍵がないので、ローカルからコンテナへcpコマンドを打ち、秘密鍵を退避させる。
$ docker cp $(docker ps | grep yohgi/eks-cli | awk '{print $1}'):/tmp/test-cluster.pem ~/.ssh/test-cluster.pem
CloudFormationでNodeの作成
公式のCloudFormationを用いて作成。
セキュリティグループの作成と、AutoScalingGroupを用いてWorkerNode用のEC2を3つ立てるテンプレート。
バージニア北部の場合は NodeImageId
を変更する必要あり。
export EKS_NODE_KEYPAIR=test-cluster # さっき作ったキーペア export EKS_NODE_AMI=ami-73a6e20b # 使用するリージョンのAMIを指定 export EKS_CLUSTER_NAME=$(aws eks describe-cluster --name test-cluster --query 'cluster.name' --output text) export EKS_CLUSTER_SG=$(aws cloudformation describe-stacks --stack-name test-cluster --query 'Stacks[0].Outputs[?OutputKey==`SecurityGroups`][].OutputValue' --output text) export EKS_VPCID=$(aws cloudformation describe-stacks --stack-name test-cluster --query 'Stacks[0].Outputs[?OutputKey==`VpcId`][].OutputValue' --output text) export EKS_SUBNETS=$(aws cloudformation describe-stacks --stack-name test-cluster --query 'Stacks[0].Outputs[?OutputKey==`SubnetIds`][].OutputValue' --output text) aws cloudformation create-stack \ --stack-name test-cluster-nodegroup \ --template-url https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/amazon-eks-nodegroup.yaml \ --capabilities CAPABILITY_NAMED_IAM \ --parameters \ ParameterKey=ClusterName,ParameterValue=$EKS_CLUSTER_NAME \ ParameterKey=ClusterControlPlaneSecurityGroup,ParameterValue=$EKS_CLUSTER_SG \ ParameterKey=NodeGroupName,ParameterValue=${EKS_CLUSTER_NAME}-nodegroup \ ParameterKey=NodeImageId,ParameterValue=$EKS_NODE_AMI \ ParameterKey=KeyName,ParameterValue=$EKS_NODE_KEYPAIR \ ParameterKey=VpcId,ParameterValue=$EKS_VPCID \ ParameterKey=Subnets,ParameterValue=\"$EKS_SUBNETS\"
あとあとコピペするのがめんどうになるので今回は先頭の #
は排除した。
上記コマンドもコンテナ内から実行。
EC2をEKS Clusterへ参加させる
# export EKS_NODE_ROLE=$(aws cloudformation describe-stacks --stack-name test-cluster-nodegroup --query 'Stacks[0].Outputs[?OutputKey==`NodeInstanceRole`].OutputValue' --output text) # curl -sSL https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/aws-auth-cm.yaml | sed -e "s|rolearn: <ARN of instance role (not instance profile)>|rolearn: $EKS_NODE_ROLE|g" | kubectl apply -f -
Control PlaneがWorker NodeとしてEC2を認識したかの確認
# kubectl get configmap -n kube-system NAME DATA AGE aws-auth 1 57s kube-dns 0 2h kube-proxy 1 2h # kubectl get nodes --watch NAME STATUS ROLES AGE VERSION ip-192-168-140-149.us-west-2.compute.internal Ready <none> 1m v1.10.3 ip-192-168-232-3.us-west-2.compute.internal Ready <none> 1m v1.10.3 ip-192-168-83-147.us-west-2.compute.internal Ready <none> 1m v1.10.3
Control Planeの作成完了 🎉
6. 適当にコンテナを走らせる
nginxを雑に走らせて port forwardで動作確認
# kubectl run nginx --image=nginx --port 80 # kubectl port-forward `kubectl get pod | grep nginx | awk '{print $1}'` 8080:80 & # curl -D - -o /dev/null -s localhost:8080 Handling connection for 8080 HTTP/1.1 200 OK Server: nginx/1.15.0 Date: Wed, 06 Jun 2018 18:53:47 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 05 Jun 2018 12:00:18 GMT Connection: keep-alive ETag: "5b167b52-264" Accept-Ranges: bytes
ヘッダーにnginxを確認して満足。
雑記
後発だけどGKEほど抽象化してくれていないので、コンテナを走らせるまでが泥臭いなぁと
ネットワーク周りをControl Plane含め自分で定義していくあたりココらへんをしっかり学びたい