はじめに
お疲れ様です。yuki_inkです。
初心者がコンテナを触ってみるシリーズ4回目です。
前回の結びで「次回は満を持してDockerfileを触ってみようかなと思います」とか書いておきながら、諸般の事情により、数段飛ばしでEKSを触ってみたいと思います。
Dockerfileは後でやります!!
※最終的にはCodePipelineでDockerfileをビルドして、ECRに格納⇒EKS上でデプロイまでやりたい
やったこと
「Introduction to Amazon EKS」のハンズオンをやってみました。
このハンズオンでは Amazon Elastic Kubernetes Service (Amazon EKS) と eksctl を使用して、マネージドな Kubernetes クラスターを実行します。サンプル Web アプリケーションをビルドして Kuberneres クラスターにデプロイし、kubectl コマンドによる Kubernetes の操作と、Amazon EKS 上でのアプリケーションの実行を体験していただきます。
ステップは下記の通り。
- AWS Cloud9 環境の作成
- クラスターの作成
- クラスターの確認
本ハンズオンについては、クラメソ様の記事も参考にしました。
Cloud9 環境の作成
Cloud9 環境の作成
Cloud9はクラウドベースの統合開発環境(IDE)。
k8sを操作するコマンドライン「cubectl」などを、Cloud9上から実行したい。
ハンズオンの指示に従ってCloud9環境を作成する。
こうして見ると、クラウドベースのIDEと言いつつ、実態はEC2で、Systems Manager(あるいはSSH)で接続して処理をさせていることがわかる。
EC2の画面から、新規作成されたEC2が確認できる。
将来的にサーバレスで動かせるようにしてほしいなあ。。
この時点でEC2インスタンスには「AWSCloud9SSMAccessRole」がアタッチされている。
IAM ロールの作成・割り当て
AdministratorAccess
権限を持たせたIAMロールを作成し、先ほど作ったEC2にアタッチする。
公式のハンズオンでAdministratorAccess
権限をIAMロールに持たせるのはちょっと意外。
IAMロールの設定が完了したら、Cloud9の画面に戻り、右上の歯車から AWS Settings > Credentials の「AWS managed temporary credentials」を無効化して、EC2に割り当てたIAMロールを利用するように設定する。
AWS CLI の初期設定
まずはクレデンシャルの削除。
EC2 インスタンスに割り当てた IAM ロールが使用されることを確実にするため、クレデンシャルファイルを削除します。 ここまで手順通りに実行していればクレデンシャルファイルは存在していないはずですので、これは念のための作業です。
続いてAWS CLI のアップデートを行い、デフォルトリージョンの設定を行う。
クラスターの作成
eksctl と kubectl の導入
この節では、Kubernetes クラスター自体の作成に使用する eksctl コマンドと、作成した Kubernetes クラスターの操作に使用する kubectl コマンドをインストールします。
まずは eksctl コマンドをインストール。
$ curl -L "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 31.4M 100 31.4M 0 0 14.9M 0 0:00:02 0:00:02 --:--:-- 24.9M
$ sudo mv /tmp/eksctl /usr/local/bin
$ eksctl version
0.150.0-dev
続いて kubectl コマンドをインストール。
導入するコマンドのバージョンに注意が必要とのこと。
kubectl コマンドは EKS クラスターの Kubernetes バージョンに合わせたバージョンを使用します。各バージョンのダウンロード URL は以下のリンク先を確認して下さい。
kubectl のインストール
このハンズオンでは Kubernetes のバージョンは 1.24 を使用しますので、同じバージョンの kubectl コマンドをインストールします。
$ sudo curl -L -o /usr/local/bin/kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.24.9/2023-01-11/bin/linux/amd64/kubectl
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 43.6M 100 43.6M 0 0 9146k 0 0:00:04 0:00:04 --:--:-- 9.9M
$ sudo chmod +x /usr/local/bin/kubectl
$ kubectl version --short --client
Flag --short has been deprecated, and will be removed in the future. The --short output will become the default.
Client Version: v1.24.9-eks-49d8fe8
Kustomize Version: v4.5.4
クラスターの作成
eksctl create cluster
コマンドでクラスターを作る。
$ eksctl create cluster --name=ekshandson --version 1.24 --nodes=3 --managed --region ${AWS_REGION} --zones ${AWS_REGION}a,${AWS_REGION}c
2023-07-25 07:02:47 [ℹ] eksctl version 0.150.0-dev
2023-07-25 07:02:47 [ℹ] using region ap-northeast-1
2023-07-25 07:02:47 [ℹ] subnets for ap-northeast-1a - public:192.168.0.0/19 private:192.168.64.0/19
2023-07-25 07:02:47 [ℹ] subnets for ap-northeast-1c - public:192.168.32.0/19 private:192.168.96.0/19
2023-07-25 07:02:47 [ℹ] nodegroup "ng-042cd4a7" will use "" [AmazonLinux2/1.24]
2023-07-25 07:02:47 [ℹ] using Kubernetes version 1.24
2023-07-25 07:02:47 [ℹ] creating EKS cluster "ekshandson" in "ap-northeast-1" region with managed nodes
2023-07-25 07:02:47 [ℹ] will create 2 separate CloudFormation stacks for cluster itself and the initial managed nodegroup
2023-07-25 07:02:47 [ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-1 --cluster=ekshandson'
2023-07-25 07:02:47 [ℹ] Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "ekshandson" in "ap-northeast-1"
2023-07-25 07:02:47 [ℹ] CloudWatch logging will not be enabled for cluster "ekshandson" in "ap-northeast-1"
2023-07-25 07:02:47 [ℹ] you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=ap-northeast-1 --cluster=ekshandson'
2023-07-25 07:02:47 [ℹ]
2 sequential tasks: { create cluster control plane "ekshandson",
2 sequential sub-tasks: {
wait for control plane to become ready,
create managed nodegroup "ng-042cd4a7",
}
}
2023-07-25 07:02:47 [ℹ] building cluster stack "eksctl-ekshandson-cluster"
2023-07-25 07:02:47 [ℹ] deploying stack "eksctl-ekshandson-cluster"
2023-07-25 07:03:17 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:03:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:04:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:05:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:06:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:07:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:08:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:09:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:10:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:11:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-cluster"
2023-07-25 07:13:49 [ℹ] building managed nodegroup stack "eksctl-ekshandson-nodegroup-ng-042cd4a7"
2023-07-25 07:13:49 [ℹ] deploying stack "eksctl-ekshandson-nodegroup-ng-042cd4a7"
2023-07-25 07:13:49 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-nodegroup-ng-042cd4a7"
2023-07-25 07:14:19 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-nodegroup-ng-042cd4a7"
2023-07-25 07:15:03 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-nodegroup-ng-042cd4a7"
2023-07-25 07:16:47 [ℹ] waiting for CloudFormation stack "eksctl-ekshandson-nodegroup-ng-042cd4a7"
2023-07-25 07:16:47 [ℹ] waiting for the control plane to become ready
2023-07-25 07:16:49 [✔] saved kubeconfig as "/home/ec2-user/.kube/config"
2023-07-25 07:16:49 [ℹ] no tasks
2023-07-25 07:16:49 [✔] all EKS cluster resources for "ekshandson" have been created
2023-07-25 07:16:49 [ℹ] nodegroup "ng-042cd4a7" has 3 node(s)
2023-07-25 07:16:49 [ℹ] node "ip-192-168-52-233.ap-northeast-1.compute.internal" is ready
2023-07-25 07:16:49 [ℹ] node "ip-192-168-53-185.ap-northeast-1.compute.internal" is ready
2023-07-25 07:16:49 [ℹ] node "ip-192-168-8-90.ap-northeast-1.compute.internal" is ready
2023-07-25 07:16:49 [ℹ] waiting for at least 3 node(s) to become ready in "ng-042cd4a7"
2023-07-25 07:16:49 [ℹ] nodegroup "ng-042cd4a7" has 3 node(s)
2023-07-25 07:16:49 [ℹ] node "ip-192-168-52-233.ap-northeast-1.compute.internal" is ready
2023-07-25 07:16:49 [ℹ] node "ip-192-168-53-185.ap-northeast-1.compute.internal" is ready
2023-07-25 07:16:49 [ℹ] node "ip-192-168-8-90.ap-northeast-1.compute.internal" is ready
2023-07-25 07:16:51 [ℹ] kubectl command should work with "/home/ec2-user/.kube/config", try 'kubectl get nodes'
2023-07-25 07:16:51 [✔] EKS cluster "ekshandson" in "ap-northeast-1" region is ready
コマンド実行後に気づいたが、裏でCloudFormationが動いており、クラスター以外にも、VPCやInternet GW、NAT GW、ElasticIPなどが作成されている。
eks create cluster
コマンドで作成されるものは、以下の記事が参考になった。
https://dev.classmethod.jp/articles/getting-started-amazon-eks-with-eksctl/#toc-5
※余談※
実務でEKSを利用するときは、あらかじめ用意したNWにクラスターを作成したいとか、パブリックサブネットなんて絶対に作りたくない、という要件もありそうだなと思いつつ。。
参考になりそうなリンクだけ貼っておく。
便利なツールと設定
クラスターが作成されるのを待つ間、Kubernetes の利用の際によく使われるいくつかの便利なツールの導入と、コマンド補完の設定をしておきましょう。
ということで、別Terminalで便利ツールの導入や設定の追加を行う。
# jq, bash-completionインストール
$ sudo yum -y install jq bash-completion
# dockerのコマンド補完設定
$ sudo curl -L -o /etc/bash_completion.d/docker https://raw.githubusercontent.com/docker/cli/master/contrib/completion/bash/docker
# docker-compose導入/補完設定
$ sudo curl -L -o /usr/local/bin/docker-compose "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)"
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo curl -L -o /etc/bash_completion.d/docker-compose https://raw.githubusercontent.com/docker/compose/1.26.2/contrib/completion/bash/docker-compose
# kubectlとeksctlのコマンド補完設定
$ kubectl completion bash > kubectl_completion
$ sudo mv kubectl_completion /etc/bash_completion.d/kubectl
$ eksctl completion bash > eksctl_completion
$ sudo mv eksctl_completion /etc/bash_completion.d/eksctl
# "k"=kubectlのエイリアス設定
$ cat <<"EOT" >> ${HOME}/.bashrc
alias k="kubectl"
complete -o default -F __start_kubectl k
EOT
# kube-ps1導入
$ git clone https://github.com/jonmosco/kube-ps1.git ~/.kube-ps1
$ cat <<"EOT" >> ~/.bashrc
source ~/.kube-ps1/kube-ps1.sh
function get_cluster_short() {
echo "$1" | cut -d . -f1
}
KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short
KUBE_PS1_SUFFIX=') '
PS1='$(kube_ps1)'$PS1
EOT
# kubectx / kubens導入
$ git clone https://github.com/ahmetb/kubectx.git ~/.kubectx
$ sudo ln -sf ~/.kubectx/completion/kubens.bash /etc/bash_completion.d/kubens
$ sudo ln -sf ~/.kubectx/completion/kubectx.bash /etc/bash_completion.d/kubectx
$ cat <<"EOT" >> ~/.bashrc
export PATH=~/.kubectx:$PATH
EOT
# stern導入
$ sudo curl -L -o /usr/local/bin/stern https://github.com/wercker/stern/releases/download/1.11.0/stern_linux_amd64
$ sudo chmod +x /usr/local/bin/stern
# 設定の読み込み
$ . ~/.bashrc
$ . /etc/profile.d/bash_completion.sh
$ . /etc/bash_completion.d/kubectl
$ . /etc/bash_completion.d/eksctl
クラスターの確認
え、ENI経由で通信するなら、IGWとかいらんかったやん!!??と思ったが、
ワーカーノード⇒コントロールプレーンへの通信があるんですね。。
これもVPCエンドポイント経由でできそうだけど。。
それはまた今度やりたい。
まずはeksctl get cluster
コマンドでクラスターの存在を確認する。
kubectl cluster-info
コマンドでクラスターの情報を確認する。
ノードの確認
kubectl get node
コマンドでワーカーノードを確認。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
ip-192-168-52-233.ap-northeast-1.compute.internal Ready <none> 58m v1.24.15-eks-a5565ad
ip-192-168-53-185.ap-northeast-1.compute.internal Ready <none> 58m v1.24.15-eks-a5565ad
ip-192-168-8-90.ap-northeast-1.compute.internal Ready <none> 58m v1.24.15-eks-a5565ad
ノードグループに紐づくAutoScalingグループの配下にいるインスタンスがリストされる。
Namespace の確認
Kubernetes では、Namespace を使うことで Pod や Service といった Kubernetes リソースをグルーピングすることができます。
アプリケーション毎、プロジェクト毎、チーム毎、環境毎といった単位で Namepspace を分けて使用することで Kubernetes クラスターを効率的に使用することができます。
kubectl get namespace
コマンドで Namespace を確認。
$ kubectl get namespace
NAME STATUS AGE
default Active 70m
kube-node-lease Active 70m
kube-public Active 70m
kube-system Active 70m
default はその名の通りデフォルトの Namespace です。kube-system は Kubernetes のシステムコンポーネントが稼働する Namespace です。
kubectl get pod
コマンドで Namespace で稼働している Pod を確認する。
-n
オプションで明示的に Namespace を指定することもできるが、kubens kube-system
コマンドでデフォルトの Namespace を kube-system に変更しておけば、その手間もなくなる。
この状態でkubectl get pod
コマンドを実行すると、kube-system で稼働しているPodが確認できる。
※せっかくなので"k"エイリアスを使ってみる
$ k get pod
NAME READY STATUS RESTARTS AGE
aws-node-f2fjd 1/1 Running 0 67m
aws-node-hhr56 1/1 Running 0 67m
aws-node-zjtzg 1/1 Running 0 67m
coredns-5fc8d4cdcf-qgdhm 1/1 Running 0 73m
coredns-5fc8d4cdcf-w49zw 1/1 Running 0 73m
kube-proxy-jswfl 1/1 Running 0 67m
kube-proxy-kv894 1/1 Running 0 67m
kube-proxy-nvkgk 1/1 Running 0 67m
aws-node は Pod にネットワーク機能を提供する Amazon VPC CNI Plugin for Kubernetes です
coredns は Kubernetes クラスター内の名前解決を提供する DNS サーバーです
kube-proxy は Kubernetes Service の機能を提供する Kubernetes のコンポーネントです
-A
オプションで全ての Namespace を対象として情報を取得。
$ kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-f2fjd 1/1 Running 0 79m
kube-system aws-node-hhr56 1/1 Running 0 79m
kube-system aws-node-zjtzg 1/1 Running 0 79m
kube-system coredns-5fc8d4cdcf-qgdhm 1/1 Running 0 85m
kube-system coredns-5fc8d4cdcf-w49zw 1/1 Running 0 85m
kube-system kube-proxy-jswfl 1/1 Running 0 79m
kube-system kube-proxy-kv894 1/1 Running 0 79m
kube-system kube-proxy-nvkgk 1/1 Running 0 79m
現在は kube-system 以外の Namespace で稼働している Pod はいない。
-o wide
オプションでより詳細な情報を取得。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
aws-node-f2fjd 1/1 Running 0 84m 192.168.8.90 ip-192-168-8-90.ap-northeast-1.compute.internal <none> <none>
aws-node-hhr56 1/1 Running 0 84m 192.168.52.233 ip-192-168-52-233.ap-northeast-1.compute.internal <none> <none>
aws-node-zjtzg 1/1 Running 0 84m 192.168.53.185 ip-192-168-53-185.ap-northeast-1.compute.internal <none> <none>
coredns-5fc8d4cdcf-qgdhm 1/1 Running 0 89m 192.168.3.250 ip-192-168-8-90.ap-northeast-1.compute.internal <none> <none>
coredns-5fc8d4cdcf-w49zw 1/1 Running 0 89m 192.168.17.111 ip-192-168-8-90.ap-northeast-1.compute.internal <none> <none>
kube-proxy-jswfl 1/1 Running 0 84m 192.168.8.90 ip-192-168-8-90.ap-northeast-1.compute.internal <none> <none>
kube-proxy-kv894 1/1 Running 0 84m 192.168.53.185 ip-192-168-53-185.ap-northeast-1.compute.internal <none> <none>
kube-proxy-nvkgk 1/1 Running 0 84m 192.168.52.233 ip-192-168-52-233.ap-northeast-1.compute.internal <none> <none>
PodごとにIPが振られていることを発見。
k8sのネットワークについては後で詳しく勉強したい。
終わりに
k8sの知識が全くない状態でハンズオンをやってみました。
ネットワーク構成はどうなっているのか / どこで設定しているのかといった点や、具体的にコンテナをデプロイするためにはどうすればいいのかといったところは、これから勉強していきたいと思います。