本記事はFIXERが提供する「cloud.config Tech Blog」に掲載された「AWS EC2でkubeadmを用いたKubernetesクラスターを作ってみたのでメモ」を再編集したものです。
はじめに
Kubernetesって動かすと楽しいじゃないですか。
でも、Kubernetesで遊ぼうと思ったら普段はローカルでRancher Desktopからシングルノードのクラスターをワンボタンで作ったりEKSやAKSでマネージドなクラスターを作ったりするのですが、それではちょっと物足りないこともあります。
例えば最新のバージョンのKubernetesを使ってみようとしたら、前述の方法だとどれもすぐには対応していなくて、最新バージョンに対応するのを待つ必要があります。
そのためいつでも最新のバージョンのKubernetesを試せるように、ついでにマルチノードの構成で立ち上げるようにするためにAWS EC2の中にkubeadmでKubernetesを立ち上げ、クラスターを構成する方法を確立しておこうと試みたので今のところ確立できている方法をメモしておきます。
そのうちもっといい方法が確立できるかもしれないのでその時はその時で別途記事にしようと思います。
今回の構成
今回作成した構成は以下のような形です。
Control Plane Nodeが1台、Worker Nodeの数は2台にしましたが実際はお好みで。
コンテナランタイム: runc
CNI: Cilium
作成したリソース
EC2
- name: kubernetestest-dev-app-controlplane
image: Canonical, Ubuntu, 24.04 LTS, amd64 noble image build on 2024-04-23
instanceType: t3.small
keyPair: 新規作成
VPC: kubernetestest-dev-pvc
サブネット: kubernetes-dev-subnet
NSG: kubernetestest-dev-nsg
パブリックIPの自動割り当て: 有効化
- name: kubernetestest-dev-app-worker
image: Canonical, Ubuntu, 24.04 LTS, amd64 noble image build on 2024-04-23
instanceType: t3.micro
keyPair: 新規作成
VPC: kubernetestest-dev-pvc
サブネット: kubernetes-dev-subnet
NSG: kubernetestest-dev-nsg
パブリックIPの自動割り当て: 有効化
インスタンスサイズは、Control Plane用のインスタンスではメモリとCPUがそれぞれ2GiBと2v必要なためt3.smallとしています。
Worker Node用では最低限で構わないのでt3.microにしています。
また、今回は学習用リソースとして作成しているため、インスタンスにローカルから直接sshするためにパブリックIPの自動割り当てを有効にいています。
VPC
- name: kubernetestest-dev-vpc
IPv4 CIDR: 10.0.0.0/16
Subnet
- name:
VPC: kubernetestest-dev-vpc
IPv4 Subnet CIDR: 10.0.0.0/16
Route Table
- name: kubernetes-dev-rtb
VPC: kubernetestest-dev-vpc
routes:
- to: 10.0.0.0/16
target: local
- to: 0.0.0.0/16
target: kubernetestest-dev-igw
IGW
- name: kubernetestest-dev-igw
VPC: kubernetestest-dev-vpc
NSG
- type: ssh
source: 0.0.0.0/0
- type: customTCP
source: 0.0.0.0/0
port: 6443
- type: customTCP
source: 10.0.0.0/16
port: 10250
NSGではこちらを参考に許可する通信を規定しています。
本当はControl PlaneとWorker Nodeで要件は異なりますが、今回はひとまとめにしています。
ssh用の22番、API Serverへのアクセス用の6443番、Kubernetes Nodeのkubelet間のやりとりのための10250番ポートを開放してあります。
特に10250番はクラスター内部の通信であるため、通信元は同じVPC内部に限定しています。
実行したコマンド
リソースが一通り作成できれば、EC2 Instance Connect等を用いてインスタンスにssh接続します。
Control Plane NodeとなるEC2インスタンスでは起動後に以下のコマンドを実行してコンテナランタイム、Kubernetes、CNIをインストールしています。
実行時は先にControl Plane Nodeのコマンドから実行してください。
# Dockerのインストール sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl sudo apt-get update sudo apt-get install -y docker.io # Dockerの開始 sudo systemctl start docker sudo systemctl enable docker # Kubernetesのインストール curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl # Kubernetesの起動 sudo kubeadm init --pod-network-cidr=10.0.0.0/16 # kubeconfigのコピー mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # CNIのインストール CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt) CLI_ARCH=amd64 if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum} sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum} cilium install
Worker NodeとなるEC2インスタンスでは以下のコマンドを実行しています。KubernetesのインストールコマンドまではControl Plane Nodeと同様です。
クラスターに加入するコマンドは、Control Plane Nodeの立ち上げ時に最後のほうでkubeadm join ~~~といった形で表示されるのでそれをそのままWorker Nodeで打ち込んでください。
# Dockerのインストール sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl sudo apt-get update sudo apt-get install -y docker.io # Dockerの開始 sudo systemctl start docker sudo systemctl enable docker # Kubernetesのインストール curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl # Kubernetesクラスターに加入 sudo kubeadm join <Control PlaneノードのプライベートIP>:6443 --token <トークン> --discovery-token-ca-cert-hash sha256:<hash値>
# 動作確認
各ノードでコマンドを実行し、成功していれば以下のような出力が得られるかと思います。
Control Plane Nodeでkubectl get nodeを実行
どこのノードでもsudo docker infoコマンドを実行すると現在使用しているDockerのバージョンやコンテナランタイムが表示されるかと思います。
Todo
このクラスターではまだメトリクスサーバーがインストールされていません。
そのため`kubectl top`コマンドやHPAが使えません。
スケーリングの動きを確かめようと思ったらこのあたりの機能が使える必要があるので、また今度インストールも試してみます。
今回動作確認が取れたコンテナランタイムはruncで、しかもそのためにインストールしたパッケージは少し古めのdocker.ioでした。
推奨されるコンテナランタイムはcotainerdかcri-oなのですが、今回は動作確認が取れなかったので今度動作することを確認したいと思います。
また、今回はEC2やネットワーク系のリソース、Kubernetesのインストール等を手動で行っていますが、1コマンドでできたほうが楽なので今度Terraform化を試してみます。
おわりに
今回は勉強がてらEC2でKubernetesクラスターをkubeadmベースで作成してみました。
この方法が確立できていれば後でいろいろ検証するのに役立ちそうに思います。
ただ、今回はそれなりに苦労した割に妥協した点も多くあるので、これからもっと構成を洗練させていければと考えています。
自分と同様にKubernetesクラスターをkubeadmベースで作ってみたいという方の助けになれば幸いです。
なむゆ/FIXER
Kubestronautになりました。
たぶん社内Kubernetes最強です。
この連載の記事
-
TECH
Amazon CloudFrontで特定の国からのアクセスを制限する方法 -
TECH
Azure Kubernetes Service(AKS)のちょっとした運用ノウハウ -
TECH
AWS CDKでECSの環境変数を管理する際に気をつけるべきこと -
TECH
初心者向け:RDSスナップショットを別のAWSアカウントで復元する手順 -
TECH
AWS CDKとGitHubを使ったIaC=インフラ構成管理の基本 -
TECH
同世代エンジニアに刺激を受けた!JAWS-UG「若手エンジニア応援LT会」参加レポート -
TECH
AWS CDKでGuardDutyのRDS保護を有効化しよう(として詰みかけた話) -
TECH
ノーコードで生成AI連携! SlackからAmazon Bedrockのエージェントに質問 -
TECH
Terraform:変数の値が未代入でもインタラクティブな入力を回避する方法 -
TECH
Amazon SESでEメールの送信機能/受信機能を作る手順 -
TECH
Amazon BedrockからWeb上のコンテンツを参照する新機能「Web Crawler」 - この連載の一覧へ