kops を使って AWS 上に Kubernetes クラスタを立ててみた

Posted on

これまで Kubernetes を触ったことがなかったのですが(概念はざっくり知っている程度)、freee で使いそうな雰囲気になってきたので空き時間を見つけてキャッチアップしています。

AWS は Kubernetes のマネージドサービスを出していないので、自前でクラスタを構築する必要があります。ツールはいろいろありますが、今回は AWS Compute Blog で紹介されている kops を使って AWS 上に Kubernetes クラスタを立ててみます。

kops とは

kops は Kubernetes Operations の略で、Kubernetes クラスタをマネージメントするコマンドラインツールです。 Golang で書かれているので macOS と Linux をサポートしています。

kops helps you create, destroy, upgrade and maintain production-grade, highly available, Kubernetes clusters from the command line. AWS (Amazon Web Services) is currently officially supported, with GCE and VMware vSphere in alpha and other platforms planned.

現在は AWS のみサポートされていますが、ほかのプラットフォームもサポートする計画があるみたいです。

kops のインストール

macOS だと Homebrew でインストールできます。

$ brew update && brew install kops

$ kops version
Version 1.7.1

state store の S3 バケット作成

クラスタのノード数、インスタンスタイプ、Kubernetes のバージョンなど、クラスタの構成情報を保存するための S3 バケットを作成します。これを state store と呼びます。

$ aws s3 mb s3://k8s-xxxxxxxxxxxx --region ap-northeast-1

以前のバージョンに戻したり、オペレーションミスに備えて S3 のバージョニング機能を有効にします。

$ aws s3api put-bucket-versioning --bucket k8s-xxxxxxxxxxxx --versioning-configuration Status=Enabled

作成したバケット名を環境変数で定義しておきます。

$ export KOPS_STATE_STORE=s3://k8s-xxxxxxxxxxxx

DNS の設定

クラスターを作成するにはトップレベルのドメインまたはサブドメインが必要です。今回は k8s.manabusakai.com というサブドメインで進めます。

$ aws route53 create-hosted-zone \
--name k8s.manabusakai.com \
--caller-reference $(uuidgen) \
| jq .DelegationSet.NameServers
[
  "ns-1990.awsdns-56.co.uk",
  "ns-244.awsdns-30.com",
  "ns-1339.awsdns-39.org",
  "ns-992.awsdns-60.net"
]

manabusakai.com の Hosted Zone に NS レコードを追加して名前解決できるようにします。

$ dig +short k8s.manabusakai.com ns
ns-992.awsdns-60.net.
ns-1339.awsdns-39.org.
ns-1990.awsdns-56.co.uk.
ns-244.awsdns-30.com.

Kubernetes クラスタを立ち上げる

kops create cluster で Kubernetes クラスタを立ち上げます。今回は東京リージョンの AZ 2 つを指定します。

$ kops create cluster \
--name k8s.manabusakai.com \
--zones ap-northeast-1a,ap-northeast-1c \
--state $KOPS_STATE_STORE \
--yes

実行すると起動のログが出力されます。

I1011 17:22:45.560860   27275 create_cluster.go:659] Inferred --cloud=aws from zone "ap-northeast-1a"
I1011 17:22:45.561621   27275 create_cluster.go:845] Using SSH public key: /Users/xxxxxx/.ssh/id_rsa.pub
I1011 17:22:46.434526   27275 subnets.go:183] Assigned CIDR 172.20.32.0/19 to subnet ap-northeast-1a
I1011 17:22:46.434560   27275 subnets.go:183] Assigned CIDR 172.20.64.0/19 to subnet ap-northeast-1c
I1011 17:22:50.267811   27275 executor.go:91] Tasks: 0 done / 65 total; 34 can run
I1011 17:22:51.166706   27275 vfs_castore.go:422] Issuing new certificate: "kubecfg"
I1011 17:22:51.263897   27275 vfs_castore.go:422] Issuing new certificate: "kube-scheduler"
I1011 17:22:51.331760   27275 vfs_castore.go:422] Issuing new certificate: "kubelet"
I1011 17:22:51.507162   27275 vfs_castore.go:422] Issuing new certificate: "kops"
I1011 17:22:51.516900   27275 vfs_castore.go:422] Issuing new certificate: "kube-controller-manager"
I1011 17:22:51.574221   27275 vfs_castore.go:422] Issuing new certificate: "master"
I1011 17:22:51.579946   27275 vfs_castore.go:422] Issuing new certificate: "kube-proxy"
I1011 17:22:52.100617   27275 executor.go:91] Tasks: 34 done / 65 total; 13 can run
I1011 17:22:52.995148   27275 executor.go:91] Tasks: 47 done / 65 total; 16 can run
I1011 17:22:53.385889   27275 launchconfiguration.go:327] waiting for IAM instance profile "masters.k8s.manabusakai.com" to be ready
I1011 17:22:53.553967   27275 launchconfiguration.go:327] waiting for IAM instance profile "nodes.k8s.manabusakai.com" to be ready
I1011 17:23:03.790475   27275 executor.go:91] Tasks: 63 done / 65 total; 2 can run
I1011 17:23:04.317998   27275 executor.go:91] Tasks: 65 done / 65 total; 0 can run
I1011 17:23:04.318062   27275 dns.go:152] Pre-creating DNS records
I1011 17:23:06.150327   27275 update_cluster.go:247] Exporting kubecfg for cluster
Kops has set your kubectl context to k8s.manabusakai.com

Cluster is starting.  It should be ready in a few minutes.

Suggestions:
 * validate cluster: kops validate cluster
 * list nodes: kubectl get nodes --show-labels
 * ssh to the master: ssh -i ~/.ssh/id_rsa admin@api.k8s.manabusakai.com
The admin user is specific to Debian. If not using Debian please use the appropriate user based on your OS.
 * read about installing addons: https://github.com/kubernetes/kops/blob/master/docs/addons.md

数分待つとクラスタが起動します。 kops validate cluster でクラスタの検証をしてみます。

$ kops validate cluster --state=$KOPS_STATE_STORE
Using cluster from kubectl context: k8s.manabusakai.com

Validating cluster k8s.manabusakai.com

INSTANCE GROUPS
NAME                    ROLE    MACHINETYPE     MIN     MAX     SUBNETS
master-ap-northeast-1a  Master  m3.medium       1       1       ap-northeast-1a
nodes                   Node    t2.medium       2       2       ap-northeast-1a,ap-northeast-1c

NODE STATUS
NAME                                                    ROLE    READY
ip-172-20-32-125.ap-northeast-1.compute.internal        master  True
ip-172-20-34-23.ap-northeast-1.compute.internal         node    True
ip-172-20-76-37.ap-northeast-1.compute.internal         node    True

Your cluster k8s.manabusakai.com is ready

ノードサーバは 2 つの AZ にまたがっていることがわかります。 kubectl get nodes で各ノードの詳細情報を調べられます。

$ kubectl get nodes
NAME                                               STATUS    ROLES     AGE       VERSION
ip-172-20-32-125.ap-northeast-1.compute.internal   Ready     master    16m       v1.7.4
ip-172-20-34-23.ap-northeast-1.compute.internal    Ready     node      14m       v1.7.4
ip-172-20-76-37.ap-northeast-1.compute.internal    Ready     node      14m       v1.7.4

ノード数を増やしてみる

デフォルトで 2 台のノードが起動していますが、試しに 4 台に増やしてみます。 kops edit ig nodes を実行するとエディタが起動するので maxSizeminSize を 4 にします(ig は instancegroup の略)。

$ kops edit ig nodes
apiVersion: kops/v1alpha2
kind: InstanceGroup
metadata:
  creationTimestamp: 2017-10-11T08:22:47Z
  labels:
    kops.k8s.io/cluster: k8s.manabusakai.com
  name: nodes
spec:
  image: kope.io/k8s-1.7-debian-jessie-amd64-hvm-ebs-2017-07-28
  machineType: t2.medium
  maxSize: 4
  minSize: 4
  role: Node
  subnets:
  - ap-northeast-1a
  - ap-northeast-1c

まだ設定変更しただけで適用されていません。 kops update cluster で変更をプレビュー、 --yes オプションを付けると適用されます。

$ kops update cluster k8s.manabusakai.com
I1011 17:57:45.509970   28655 executor.go:91] Tasks: 0 done / 65 total; 34 can run
I1011 17:57:46.495537   28655 executor.go:91] Tasks: 34 done / 65 total; 13 can run
I1011 17:57:47.101685   28655 executor.go:91] Tasks: 47 done / 65 total; 16 can run
I1011 17:57:47.646531   28655 executor.go:91] Tasks: 63 done / 65 total; 2 can run
I1011 17:57:47.706182   28655 executor.go:91] Tasks: 65 done / 65 total; 0 can run
Will modify resources:
  AutoscalingGroup/nodes.k8s.manabusakai.com
        MinSize                  2 -> 4
        MaxSize                  2 -> 4

Must specify --yes to apply changes

$ kops update cluster k8s.manabusakai.com --yes
I1011 18:00:09.681858   28733 executor.go:91] Tasks: 0 done / 65 total; 34 can run
I1011 18:00:10.646050   28733 executor.go:91] Tasks: 34 done / 65 total; 13 can run
I1011 18:00:11.243637   28733 executor.go:91] Tasks: 47 done / 65 total; 16 can run
I1011 18:00:12.128070   28733 executor.go:91] Tasks: 63 done / 65 total; 2 can run
I1011 18:00:12.295319   28733 executor.go:91] Tasks: 65 done / 65 total; 0 can run
I1011 18:00:12.295408   28733 dns.go:152] Pre-creating DNS records
I1011 18:00:12.781403   28733 update_cluster.go:247] Exporting kubecfg for cluster
Kops has set your kubectl context to k8s.manabusakai.com

Cluster changes have been applied to the cloud.

Changes may require instances to restart: kops rolling-update cluster

kubectl get nodes で確認するとたしかに 2 台増えています(AGE が若いノードが追加された分)。

$ kubectl get nodes
NAME                                               STATUS    ROLES     AGE       VERSION
ip-172-20-32-125.ap-northeast-1.compute.internal   Ready     master    37m       v1.7.4
ip-172-20-34-23.ap-northeast-1.compute.internal    Ready     node      35m       v1.7.4
ip-172-20-59-77.ap-northeast-1.compute.internal    Ready     node      2m        v1.7.4
ip-172-20-76-37.ap-northeast-1.compute.internal    Ready     node      35m       v1.7.4
ip-172-20-84-148.ap-northeast-1.compute.internal   Ready     node      2m        v1.7.4

どういう仕組みでノードを増やしているのかというと、Auto Scaling Group の Desired capacity を変更しているだけです。 Activity History に変更内容が残っていました。

At 2017-10-11T09:00:07Z a user request update of AutoScalingGroup constraints to min: 4, max: 4, desired: 4 changing the desired capacity from 2 to 4. At 2017-10-11T09:00:19Z an instance was started in response to a difference between desired and actual capacity, increasing the capacity from 2 to 4.

このあたりは AWS とうまくインテグレートされていますね。

Kubernetes クラスタを削除する

最後にクラスタを削除してみます。 kops delete cluster で関連するリソースも含めてきれいに削除してくれます。

$ kops delete cluster --state=$KOPS_STATE_STORE --name k8s.manabusakai.com --yes

(snip)

Deleted cluster: "k8s.manabusakai.com"

まとめ

Kubernetes は初めてでしたが、kops を使えば簡単にクラスタを構築できました。イメージとしては Terraform とよく似ている印象です。本番環境を構築するにはもっとじっくり学ぶ必要がありますが、開発環境ならサクッと準備できそうです。

こういうニュースもあるので、今後 AWS から Kubernetes のマネージドサービスが出てくるかもしれません。