自己研鑽で学んだことのメモです。
準備事項
- kubectlをインストールする
- AWS CLIをインストールする
- aws-iam-authenticator をインストールする
- キーペアを作成する
- サービスロールを作成する
- クラスタVPCを作成する
インストールするものから、先に進めていきます。EKSは、日本から一番近いオレゴンのリージョンを利用しました。
1.kubectlコマンドのインストール
筆者が試したところ、CNCFからダウンロードした kubectl コマンドでも、利用できたので、特別にビルドされたものではないようです。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/configure-kubectl.html
ホームディレクトリに、ディレクトリ aws-eks を作成して、ダウンロードした kubectl を保存します。
2.AWS CLIをイントール
awsコマンドは、IaaS部分の操作のために必要なので、インストールしておきます。
-
ダウンロード
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/installing.html -
認証情報の設定
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-command-line.html
$ aws configure
AWS Access Key ID []: ****************ADMA
AWS Secret Access Key []: ****************pXoq
Default region name []: us-west-2
Default output format []: text
AWS Access Key ID と Secret Access ID の取得は、https://console.aws.amazon.com/iam/home#/security_credential で、「新しいアクセスキーの作成」をクリックする。
アクセスキーを表示して、コピーして、上記の asw configure コマンドのプロンプトへペーストする。
3.aws-iam-authenticator をインストール
このaws-iam-authenticator kubectl コマンドの中から呼び出して利用します。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started.html Amazon EKS の 「aws-iam-authenticator をインストールするには」に従ってインストールする。
ホームディレクトリに、ディレクトリ aws-eks を作成して、ダウンロードした このファイルを保存します。
4.キーペアを作成する
後に、ワーカーノードを作成する時に、必要となるので、キーペアを作成しておきます。
コンソールのリンク
https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#KeyPairs:sort=keyName
5.サービスロールの作成
EKSクラスタのために、サービスロールを作成します。
https://console.aws.amazon.com/iam/home#/home をクリックして、Web画面を開いてロールを選択する。そして、「ロールの作成」ボタンをクリックする。次に遷移した画面で、"EKS" のリンクをクリックする。 「次のステップ:アクセス権限」をクリック、「次のステップ:確認」をクリックする。次の画面のロール名*にロール名を入れて、「ロールの作成」ボタンをクリックする。
クリックにより、ロールのリストが表示されたら、今作った「eksRole」をクリックする。そして、「ポリシーをアタッチします」をクリックする。
ロール名のリストの中から、「AmazonEC2FullAccess」を探して、アタッチする。
6.クラスタVPCを作成する
EKSクラスタのために、VPCを作成します。
CloudFormationマネジメント https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks?filter=active をクリックして開くいて、「新しいスタックの作成」をクリック
テンプレートが登録されたURLをペーストして、「次へ」をクリックする。
https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2018-08-30/amazon-eks-vpc-sample.yaml
以下は、S3のURLをペーストしたところ
Amazon S3テンプレートによって、次の画面の表示が変わる。 スタックの名前に eks-vpc をセットして、「次へ」をクリックする。
オプション画面は入力なしで、「次へ」をクリック。確認画面が表示されるので「作成」をクリックする。
スタック作成の進行中画面が表示されるので、「状況」に「CREATE_COMPLETE」が表示されたら、作成成功です。
以上で、EKSクラスタを作成するための準備が整いました。これから、EKSクラスタのマスターノードとワーカーノードを作成していきます。
EKS (Kubernetes) クラスタの構築
EKSでは、クラスタを一歩づつ構成していく必要があるので、GKE/IKSと同じような環境をつくるために、次の 1〜7 の作業をおこないます。
- k8sクラスタの作成
- KUBECONFIGの設定
- アクセス資格情報の取得
- ワーカーノードの起動
- ワーカーノードとクラスタ結合
- Calicoのデーモンセット起動
- ストレージクラスの設定
1.k8sクラスタの作成
EKSではマスターノードとワーカーノードは別々に作成します。 ここでは、まず、マスターノードのデプロイです。
マスターノードだけの作成時間
開始 14:52 完了 15:02
2.KUBECONFIGの設定
macOSのケースですが、ホームディレクトリにaws-eksに作っておき、以下のファイルを置いておきます。
export KUBECONFIG=/Users/maho/aws-eks/.kube/config.yml:$KUBECONFIG
export PATH=/Users/maho/aws-eks/bin:/Users/maho/Library/Python/2.7/bin:$PATH
aws-eksにディレクトリとコマンドを、専用のディレクトリに置いて、上のパス設定で利用することにしました。
$ tree aws-eks
aws-eks
├── bin
│ ├── aws-iam-authenticator
│ └── kubectl
├── env-setup
EKSを利用する前に、source して、環境変数を設定します。
$ . env-setup
3.アクセス資格情報の取得
新しく提供されたコマンド https://aws.amazon.com/jp/about-aws/whats-new/2018/09/amazon-eks-simplifies-cluster-setup-with-update-kubeconfig-cli-command/ を利用して、前述で設定した 環境変数 KUBECONFIG のパスに設定されたコンフィグファイルに、EKSクラスタの設定を追加します。
$ aws eks update-kubeconfig --region us-west-2 --name eks1
Added new context arn:aws:eks:us-west-2:102321567306:cluster/eks1 to /Users/maho/aws-eks/.kube/config.yml
imac:aws-eks maho$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* arn:aws:eks:us-west-2:102321567306:cluster/eks1 arn:aws:eks:us-west-2:102321567306:cluster/eks1 arn:aws:eks:us-west-2:102321567306:cluster/eks1
上記のコマンドが成功すると、次のように、マスターノード上で動作するサービスが表示されます。しかし、この時点でワーカーノードが無いので、これ以上のことができません。
imac:aws-eks maho$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 5m
4.ワーカーノードの起動
ワーカーノードは、EC2インスタンスとして起動して、マスターと結合します。 CloudFormation ( https://us-west-2.console.aws.amazon.com/cloudformation/) を開いて、「スタックの作成」をクリックして、作成画面を表示します。そして、次のリンクをAmazon S3 テンプレートURLの入力フィールドにコピペします。
https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/amazon-eks-nodegroup.yaml
次の画面は、テンプレートURLをペーストしたところです。
これで「次へ」をクリックして、入力画面を表示します。スタックの名称をインプットします。
クラスタの作成パラメータをセットしていきます。この設定が正しくないと、ワーカーノードの作成に失敗したり、ネットワーク関連の動作がうまくいかないケースが発生するので、注意が必要です。
- スタックの名前: CloudFormation上の名前
- ClusterName: EKSクラスタの名前で、前述で作成した名前と一致させます。
- ClusterControlPlaneSecurityGroup: 前述のCloudFormationで作成したVPCの名前で始まる eks-pvc をセットします。
- NodeGroupName: ノード名に付与される目印です。
- NodeAutoScalingGroupMinSize: オートスケール利用時の最小ノード数
- NodeAutoScalingGroupMaxSize: オートスケール利用時の最大ノード数
- NodeInstanceType: EC2インスタンスのタイプ
- NodeImageId: イメージID データセンターによってセットするべきIdが決まっています。
- KeyName: 前述で作成したキーペアの名前です。
- Vpcid: 前述で作成したVPCのIDです。
- Subnets: サブネットはVPCのもとに作られたサブネットを全て選択します。
以下は、入力画面です。
入力後に「作成」ボタンをクリックした後に、EC2インスタンスのリストを表示したところです。 インスタンスが作成されていきます。
5.ワーカーノードとクラスタ結合
次のYAMLファイルを作成して、キー rolearn の値に、NodeInstanceRole の値をセットします。
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: (ここに CloudFormation の NodeInstanceRole の値を入れる)
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
この NodeInstanceRole は、CloudFormationの画面から参照できます。
YAMLを適用して、ノードがクラスタに追加される様子です。約40秒で追加が完了しています。
$ kubectl apply -f aws-auth-cm.yaml
configmap "aws-auth" created
$ kubectl get no --watch
NAME STATUS ROLES AGE VERSION
ip-192-168-112-136.us-west-2.compute.internal NotReady <none> 3s v1.10.3
ip-192-168-142-69.us-west-2.compute.internal NotReady <none> 3s v1.10.3
ip-192-168-248-229.us-west-2.compute.internal NotReady <none> 5s v1.10.3
ip-192-168-248-229.us-west-2.compute.internal NotReady <none> 11s v1.10.3
ip-192-168-142-69.us-west-2.compute.internal NotReady <none> 11s v1.10.3
ip-192-168-112-136.us-west-2.compute.internal NotReady <none> 11s v1.10.3
ip-192-168-248-229.us-west-2.compute.internal Ready <none> 21s v1.10.3
ip-192-168-142-69.us-west-2.compute.internal Ready <none> 21s v1.10.3
ip-192-168-112-136.us-west-2.compute.internal NotReady <none> 21s v1.10.3
ip-192-168-248-229.us-west-2.compute.internal Ready <none> 31s v1.10.3
ip-192-168-142-69.us-west-2.compute.internal Ready <none> 31s v1.10.3
ip-192-168-112-136.us-west-2.compute.internal Ready <none> 31s v1.10.3
ip-192-168-248-229.us-west-2.compute.internal Ready <none> 41s v1.10.3
ip-192-168-142-69.us-west-2.compute.internal Ready <none> 41s v1.10.3
次は追加されたノードのリストです。
$ kubectl get no
NAME STATUS ROLES AGE VERSION
ip-192-168-112-136.us-west-2.compute.internal Ready <none> 5m v1.10.3
ip-192-168-142-69.us-west-2.compute.internal Ready <none> 5m v1.10.3
ip-192-168-248-229.us-west-2.compute.internal Ready <none> 5m v1.10.3
6.Calicoの設定
次のネットワークのポリシー設定が有効となるように、Calicoを導入します。
$ kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/v1.2/calico.yaml
daemonset.extensions "calico-node" created
customresourcedefinition.apiextensions.k8s.io "felixconfigurations.crd.projectcalico.org" created
customresourcedefinition.apiextensions.k8s.io "bgpconfigurations.crd.projectcalico.org" created
customresourcedefinition.apiextensions.k8s.io "ippools.crd.projectcalico.org" created
customresourcedefinition.apiextensions.k8s.io "hostendpoints.crd.projectcalico.org" created
customresourcedefinition.apiextensions.k8s.io "clusterinformations.crd.projectcalico.org" created
customresourcedefinition.apiextensions.k8s.io "globalnetworkpolicies.crd.projectcalico.org" created
customresourcedefinition.apiextensions.k8s.io "globalnetworksets.crd.projectcalico.org" created
customresourcedefinition.apiextensions.k8s.io "networkpolicies.crd.projectcalico.org" created
serviceaccount "calico-node" created
clusterrole.rbac.authorization.k8s.io "calico-node" created
clusterrolebinding.rbac.authorization.k8s.io "calico-node" created
deployment.extensions "calico-typha" created
clusterrolebinding.rbac.authorization.k8s.io "typha-cpha" created
clusterrole.rbac.authorization.k8s.io "typha-cpha" created
configmap "calico-typha-horizontal-autoscaler" created
deployment.extensions "calico-typha-horizontal-autoscaler" created
role.rbac.authorization.k8s.io "typha-cpha" created
serviceaccount "typha-cpha" created
rolebinding.rbac.authorization.k8s.io "typha-cpha" created
service "calico-typha" created
calicoの導入と稼働は、デーモンセットによって行われますから、ノードを追加した場合でも、自動的にインストールされます。 calico-nodeがノードで動作することで、機能が働くようになります。
$ kubectl get daemonset calico-node --namespace=kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
calico-node 3 3 3 3 3 <none> 1m
$ kubectl get po --namespace=kube-system
NAME READY STATUS RESTARTS AGE
aws-node-lktrj 1/1 Running 0 12m
aws-node-m745d 1/1 Running 0 12m
aws-node-x2vr2 1/1 Running 1 12m
calico-node-hcw6s 1/1 Running 0 1m
calico-node-nchg5 1/1 Running 0 1m
calico-node-p8d2l 1/1 Running 0 1m
calico-typha-75667d89cb-ftvbf 1/1 Running 0 1m
calico-typha-horizontal-autoscaler-78f747b679-8k2jm 1/1 Running 0 1m
kube-dns-7cc87d595-zfmf5 3/3 Running 0 6h
kube-proxy-9vc2m 1/1 Running 0 12m
kube-proxy-m584p 1/1 Running 0 12m
kube-proxy-xlp7r 1/1 Running 0 12m
7.ストレージクラスの設定
EKSでは、デフォルトでストレージクラスが入っていないので、AWSのブロックストレージ EBS が利用できるように、ストレージクラスを設定します。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: ebs-gp2
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
mountOptions:
- debug
上記のストレージクラスのマニフェストを設定する様子が次の実行結果です。
$ kubectl apply -f ebs-storage-class.yml
storageclass.storage.k8s.io "ebs-gp2" created
$ kubectl get sc
NAME PROVISIONER AGE
ebs-gp2 (default) kubernetes.io/aws-ebs 7s
以上で、EKSのセットアップが完了しました。
アプリケーションのデプロイ
EKSの中でも、ネットワークとストレージの基本的な部分を以下の3つのケースで確認しました。
- ノードポート EC2インスタンスに対応づけたパブリックIPアドレスでアクセスします。
- ロードバランサー ELBを起動してパブリックIPでアクセスします。
- 永続ボリューム EBSをマウントします。ブロックストレージなので、1PVは1ポッド接続になります。
1.ノードポート
マニフェストを適用した結果です。
$ kubectl apply -f apl-1.yml
deployment.apps "web-apl1" created
service "web-apl1" created
$ kubectl get -f apl-1.yml
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/web-apl1 1 1 1 0 7s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/web-apl1 NodePort 10.100.97.17 <none> 80:31467/TCP 7s
EC2インスタンスのリストを表示したところです。 このIPアドレスに対して、curlでアクセスして、動作を確認します。
$ aws ec2 describe-instances --query 'Reservations[].Instances[].[PublicIpAddress,Tags[?Key==`Name`].Value|[0]]'
18.***.***.*** eks1-ng1-Node
35.***.***.** eks1-ng1-Node
34.***.***.*** eks1-ng1-Node
セキュリティ・グループへのNodePortをアクセスするためのルールの追加します。
次は curlのテスト結果です。 ポッドが1個なので、どのノード(EC2インスタンス)から、同じポッドにアクセスしていることがわかります。
$ curl http://18.***.***.***:31467/
Hostname: web-apl1-74cb4d5959-tk6qp
$ curl http://35.***.***.**:31467/
Hostname: web-apl1-74cb4d5959-tk6qp
$ curl http://34.***.***.***:31467/
Hostname: web-apl1-74cb4d5959-tk6qp
ここで利用したマニフェストです。
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: web-apl1
spec:
replicas: 1
template:
metadata:
labels:
web: web-apl1
spec:
containers:
- image: maho/webapl3
name: web-server-c
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-apl1
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
selector:
web: web-apl1
2.ロードバランサー
EKSからELBを利用して、外部からアクセスするケースです。
$ kubectl apply -f apl-3.yml
deployment.apps "web-apl3" created
service "web-apl3" created
$ kubectl get -f apl-3.yml
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/web-apl3 3 3 3 0 8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/web-apl3 LoadBalancer 10.100.162.235 a4538c834d465... 80:32641/TCP 8s
起動状態の確認です。
$ kubectl get svc web-apl3 -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
web-apl3 LoadBalancer 10.100.248.65 acfbaa466d46611e8baaa02a2ba37abf-1173102834.us-west-2.elb.amazonaws.com 80:31152/TCP 4m apl=web-apl3
ELBのDNS名でアクセスした結果です。 同様にポッドが一個なので、一つのポッドへしかアクセスしていません。
imac:yaml maho$ curl http://acfbaa466d46611e8baaa02a2ba37abf-1173102834.us-west-2.elb.amazonaws.com/
Hostname: web-apl3-dc7dcbfdf-rmkz9
imac:yaml maho$ curl http://acfbaa466d46611e8baaa02a2ba37abf-1173102834.us-west-2.elb.amazonaws.com/
Hostname: web-apl3-dc7dcbfdf-rmkz9
imac:yaml maho$ curl http://acfbaa466d46611e8baaa02a2ba37abf-1173102834.us-west-2.elb.amazonaws.com/
Hostname: web-apl3-dc7dcbfdf-rmkz9
ここで利用したマニフェストです。 この設定でELBが起動して外部公開されます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-apl3
spec:
replicas: 1
selector:
matchLabels:
apl: web-apl3
template:
metadata:
labels:
apl: web-apl3
spec:
containers:
- image: maho/webapl3
name: web-server-c
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-apl3
spec:
selector:
apl: web-apl3
ports:
- name: http
protocol: TCP
port: 80
type: LoadBalancer
3.永続ボリューム
EBSを利用するケースです。
最初に、PVC(永続ボリューム要求)を作成しておきます。 EBSはブロックストレージなので、1ボリュームは、1ポッドからのみアクセスできます。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data1
spec:
accessModes:
#- ReadWriteMany
- ReadWriteOnce
# storageClassName: standard
resources:
requests:
storage: 2Gi
永続ボリュームにマウントするポッドのマニフェストです。
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
volumes:
- name: pvc1
persistentVolumeClaim:
claimName: data1
containers:
- name: ubuntu
image: ubuntu:16.04
volumeMounts:
- name: pvc1
mountPath: /mnt
#command: [”tail”, “-f”, “/d
command: [ 'tail' ]
args:
- -f
- /dev/null
デプロイと結果です。
$ kubectl apply -f pvc.yml
persistentvolumeclaim "data1" created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data1 Bound pvc-4ce26c73-d476-11e8-baaa-02a2ba37abf8 2Gi RWO ebs-gp2 20s
$ kubectl apply -f pod.yml
pod "pod1" created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 15s
デプロイしたポッドに入って、永続ボリュームをマウントしている状態を確認したものです。
$ kubectl exec -it pod1 -- bash
root@pod1:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 20G 2.3G 18G 12% /
tmpfs 997M 0 997M 0% /dev
tmpfs 997M 0 997M 0% /sys/fs/cgroup
/dev/xvdbj 2.0G 6.0M 1.8G 1% /mnt
/dev/xvda1 20G 2.3G 18G 12% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 997M 12K 997M 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 997M 0 997M 0% /sys/firmware
クリーンアップ
EKSクラスタを削除しただけでは、ワーカーノードのEC2インスタンスなどを削除しないので、注意が必要です。想定外の課金が発生しないように、それぞれ削除しなければなりません。
- EKSクラスタの削除
- Cloud Formation のワーカーノードのスタックを削除
- ELBの削除 k8sから作成したPVを消去する必要がある。
- EBSの削除 k8sから作成したLoadBalancerは削除されないケースがあった。
感想
EKSは、GKEやIKSとは違った設定方法だけど、解ってしまえば、同じように使えるということが解った。
参考資料
[1] Amazon EKS の使用開始、https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started.html