kubeadmによるKubernetesクラスタ構築 on AWS


Kubernetes公式のセットアップツールkubeadmを利用してのシングルマスター構成をAWS上に構築できるかのトライ。動作は確認、実働に耐えうるかについては未調査。

  • Amazon Linux 2
  • Nitro Systemベースのインスタンス

での動作の確認が目的

kubeadm

公式のk8sクラスタ作成ツール。Kopsと違い一つノードの中からプロビジョニングしていくボトムアップなスタイルで、カスタマイズ性が高いのも特徴。

Amazon Linux 2

K8Sが理想的に動作するのであれば、基本はベースOSはなんでもいいはずで、AWSで動作させるのであればメンテが便利なAmazon Linuxがベストのはず。EKS optimized AMIもAmazon Linux 2ベース。

Nitro System

C5, M5, T3などのインスタンスの元のシステム。諸々すごいのだけれど、NW帯域幅が増大しているので積極的に利用したいインスタンス。
Kopsでは2018/10現在デフォルトで、ストレージアクセス速度を気にしてインスタンスストアを持つはM3インスタンスを利用しているのだけれど、もうM5dでいい気がする(mediumサイズはないけれど)

手順

下準備

  • VPC
  • Subnet
  • Internet gateway
  • RouteTable

については作成、設定しておく。めんどくさかったらDefaultVPCを利用すれば良い。
VPCについてはAction>Edit DNS Hostnameを「Yes」にしておく。こうすることでインスタンスのホストネーム(ip-xxx..)でプライベートIPを解決してくれるので、/etc/hostsを編集しなくてもノード間が通信できる。

ベースAMIの作成

あらかじめ作成したサブネットに
- Amazon Linux 2
- t3.small (なるべく安く、かつ要求スペックがメモリ2GB以上のため)
を選択してEC2を起動する。ストレージは8GBあれば十分。T3 Unlimitedは時間さして変わらないと思うので外しておく。
セキュリティグループはまず22番SSHをMy IPにのみ開けたものを作成して付与したのち、このセキュリティ内からのAll traficを自己で許可するように設定。

sshでログインしたのち

# ともあれアップデート
sudo yum update -y
# docker インストール
sudo amazon-linux-extras install docker -y
# インスタンス起動時に自動でON
sudo systemctl enable docker && sudo systemctl start docker
# 公式ドキュメント通りだと2018/10現在キーの検証に失敗するので個別に入れる
sudo rpm --import https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
# リポジトリを登録
sudo bash -c "cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
EOF"
# kubelet, kubeadm, kubectlのインストール
sudo yum install -y kubelet kubeadm kubectl
# kubeletは自動起動するようにしておく
sudo systemctl enable kubelet && sudo systemctl start kubelet
# クラスタ構築・動作に必要なdocker imageについてあらかじめpullしておく
sudo kubeadm config images pull

ここまできたらインスタンスをstop, AMIを作成しておく。

マスターノード

kubeadmでの初期化

先ほどstopしたインスタンスを再起動しマスターノードとする(AMIから改めて起こしても良い)
sshログインしkubeadmを実行。

# マスターとして起動、cidrはVPCのレンジに揃える
sudo kubeadm init --pod-network-cidr=10.0.0.0/16

うまくいけばしばらくすると
kubeadm join a.b.c.d --token xxx... --discovery-token-ca-cert-hash sha256:yyy...
のようなメッセージが出るので、これを控えておく(この後のノードの参加で利用する)

kubectlの設定

下記を打てと表示が出ているはずなので実行

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

これでkubectlコマンドが打てるようになる。

ネットワークの設定

こちらにあるように、各Podが通信できるように仮想的なネットワークを敷く必要がある。と言ってもコマンド打つだけ。どれを選んだらいいのか分かりかねたのでKopsで使われてるWeaveを利用する。

# v1.2 は現在validation error が発生
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

ワーカー

保存したAMIから起動して、マスターでinitした際に表示されたコマンドを打つ

sudo kubeadm join a.b.c.d --token xxx... --discovery-token-ca-cert-hash sha256:yyy...

うまくいけばマスターでkubectl get nodeを打てばワーカーが見えるようになっているはず。


  • あらかじめネットワーク用のコンテナもpullしておけば制限があるNW上でも使えそう。
  • Amazon VPC CNIも使えたら良かったのだけど、ECRからイメージ落とす必要あったり、結局 CoreDNSがうまく動かず一旦断念。