EKSでCalicoを使ってみた[1.インストール編]
『IT自動化の力でビジネス加速を全ての企業に』
”IT自動化の専門会社”、リアルグローブ・オートメーティッド(RGA)の技術ブログ編集部の馬塚です。本日もRGAの技師がまとめた技術情報を読者の皆様にお届けしていきます!
前回、コンテナ技術を使うと「アプリケーションごとに環境を分離できる」ため、"より効率的で機動的なシステム運用が可能"になることをお伝えしましたが、その他に「環境を統一できる(開発環境・テスト環境・本番環境での差異を軽減できる)」ことや「軽量である(オーバーヘッドが少なく、起動も高速)」であることも、運用の効率化やスピードアップに寄与しています。
ビジネス加速には欠かせない、大変便利なコンテナ技術ですが、運用するコンテナの数が増えるとその管理が大変になるため、kubernetes等のコンテナオーケストレーションツールが必要になって来るわけですが、今回の記事はコンテナの増加に伴い増えるPodの運用に関わるネットワークモデルの構築に関してご案内いたします。
ディープな内容になっているので、複数編に分けてお届けいたします!
――――――――――――――――――――――――――――――――――
EKSでCalicoを使ってみた
今回は、Amazon EKS(Amazon Elastic Kubernetes Service、以下EKS)のCNIプラグインを、デフォルトの amazon-vpc-cni-k8s から calico に変更した際の手順とその検証結果について書きたいと思います。
※編集部注:CNI(Container Networking Interface)は、コンテナへのネットワーク接続を実現するための仕様です。
なぜCNIプラグインをCalicoに変更したかったのか
Kubernetesのネットワークモデルの実装方法は複数ありますが、EKSではEKSに特化したCNIプラグイン amazon-vpc-cni-k8s がデフォルトで採用されています。(Kubernetesのネットワークモデルについては公式ドキュメントを参照して下さい)
EKSで amazon-vpc-cni-k8s を使うと次のようなメリット・デメリットがあります。
メリット
デメリット
メリット・デメリットについては、以下の記事により詳細な情報が書かれています。
https://www.weave.works/blog/aws-and-kubernetes-networking-options-and-trade-offs-part-3
基本的には amazon-vpc-cni-k8s を使うのが良いですが、上記のPod数の制約が問題となる環境では他のネットワークモデルに変更する必要があります。今回は、AWSのサイトで「amazon-vpc-cni-k8s でどうしてもダメな場合はcalicoとかいいんじゃない?」と紹介されていましたので、calicoを試してみることにしました。
Calicoのインストール方法
基本的には公式サイトのインストール方法通りにやりましたが、少しクラスタの設定に気をつける必要がありました。
(amazon-vpc-cni-k8sを使いながらCalico network policyを使う方法も書いてありますが、今回はAmazon VPC Networking を Calico Networking に変更したいので、"Install EKS with Calico networking"の手順を参考にしました。)
クラスタを作成
ノードグループなしでクラスタを作成します。
$ eksctl create cluster \
--name calico-cluster \
--without-nodegroup
”aws-node” DaemonSetを削除
クラスタが作成できたら、コンテキストが正しいことを確認して次のコマンドを実行します。
$ kubectl delete daemonset -n kube-system aws-node
Calicoの設定をインストール
Calicoを導入するためのマニフェストファイルを適用します。
$ kubectl apply -f https://docs.projectcalico.org/manifests/calico-vxlan.yaml
ノードグループを作成
クラスタにノードグループを追加します。
このときに、--max-pods-per-node を十分に大きな値に設定することが重要です。amazon-vpc-cni-k8sプラグイン由来のPod数制限がなくなっても、eksctlのデフォルト設定でノードグループを作成すると、各ノードの割当制限としてamazon-vpc-cni-k8sプラグインを使用している場合の制限値が設定されてしまうため、この値を明示的に変更する必要があります。今回は1ノードあたりのPod数上限を「10」に設定してみました。
$ eksctl create nodegroup \
--cluster calico-cluster \
--node-type t3.nano \
--nodes 2 \
--node-ami auto \
--max-pods-per-node 10
以上でcalicoのインストールは完了です。
動作確認
次に、本当に1ノードあたりのPod数制限が変更されているのか確認します。t3.nano のノードを2つ作ったので、デフォルトCNIでは {2 * (2-1) + 2} * 2 = 8個のPodしかデプロイできないノードグループになるはずです。
しかし、Calico Networking を採用し、--max-pods-per-node を「10」に設定したので、クラスタ全体で20個のPodが動かせるようになっているはずです。
Node情報の確認
Node情報を確認して、Nodeに割当可能なPod数が「10」になっているか確認します。
$ kubectl get nodes -o json | jq '.items[].status.allocatable'
{
"attachable-volumes-aws-ebs": "25",
"cpu": "1930m",
"ephemeral-storage": "18242267924",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "106612Ki",
"pods": "10"
}
{
"attachable-volumes-aws-ebs": "25",
"cpu": "1930m",
"ephemeral-storage": "18242267924",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "106612Ki",
"pods": "10"
}
ちゃんと各ノードの pods の値が「10」になっています。
サンプルPodをデプロイする
予め、すでに立ち上がっているPodの数を確認しておきます。
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-77d6cbc65f-wjl7b 1/1 Running 0 9m14s
kube-system calico-node-lxpl8 1/1 Running 0 10m
kube-system calico-node-zjlql 1/1 Running 0 10m
kube-system coredns-cdd78ff87-6p6lj 1/1 Running 0 9m14s
kube-system coredns-cdd78ff87-sv97r 1/1 Running 0 9m13s
kube-system kube-proxy-c8v2z 1/1 Running 0 10m
kube-system kube-proxy-vtwhv 1/1 Running 0 10m
すでに7個のPodが立ち上がっているため、サンプルPodを14個立ち上げて1個だけ Pending になるか確認します。
まず1個デプロイしてみます。
$ kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx
image: nginx:latest
EOF
次にレプリカ数を「14」にします。
$ kubectl scale deployment sample --replicas=14
Podの状況を確認します。
$ kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
sample-74996797fd-6z2h7 0/1 Pending 0 14m
sample-74996797fd-84b7p 1/1 Running 0 14m
sample-74996797fd-8s4jg 1/1 Running 0 14m
sample-74996797fd-frbbq 1/1 Running 0 14m
sample-74996797fd-gv9s8 1/1 Running 0 14m
sample-74996797fd-hx27n 1/1 Running 0 14m
sample-74996797fd-jczhq 1/1 Running 0 14m
sample-74996797fd-pt97j 1/1 Running 0 14m
sample-74996797fd-r2bk5 1/1 Running 1 34m
sample-74996797fd-sxzrr 1/1 Running 0 14m
sample-74996797fd-ts2sl 1/1 Running 1 48m
sample-74996797fd-v7zpg 1/1 Running 0 14m
sample-74996797fd-wz582 1/1 Running 0 14m
sample-74996797fd-zx7zr 1/1 Running 0 14m
想定通り、20個のPodが Runnnig になり、余った1個が Pending になったので成功です。
追加検証
amazon-vpc-cni-k8sを使用しながら --max-pods-per-node の値だけ大きくしたらどうなるのか?
試しにやってみました。
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default sample-74996797fd-2pmff 0/1 ContainerCreating 0 35m
default sample-74996797fd-jsl8h 0/1 ContainerCreating 0 35m
default sample-74996797fd-l58qt 1/1 Running 3 90m
kube-system aws-node-dhw2q 1/1 Running 0 27m
kube-system aws-node-g6rxl 1/1 Running 0 27m
kube-system coredns-cdd78ff87-hmqpk 1/1 Running 0 35m
kube-system coredns-cdd78ff87-w8wv8 1/1 Running 0 35m
kube-system kube-proxy-kc5gd 1/1 Running 0 27m
kube-system kube-proxy-tjg2p 1/1 Running 0 27m
STATUSは Pending ではなく ContainerCreating になります。そして待っていても Running にはなりません。
ContainerCreating になっているPodのEventsを確認してみます。
$ kubectl describe pods sample-74996797fd-2pmff -n default
(省略)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 33m (x4 over 34m) default-scheduler 0/2 nodes are available: 2 node(s) were unschedulable.
Warning FailedScheduling 33m (x3 over 33m) default-scheduler 0/1 nodes are available: 1 node(s) were unschedulable.
Warning FailedScheduling 27m (x6 over 32m) default-scheduler no nodes available to schedule pods
Warning FailedScheduling 26m default-scheduler 0/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate.
Warning FailedScheduling 26m (x2 over 26m) default-scheduler 0/2 nodes are available: 2 node(s) had taints that the pod didn't tolerate.
Normal Scheduled 25m default-scheduler Successfully assigned default/sample-74996797fd-2pmff to ip-192-168-68-97.ap-northeast-1.comp
ute.internal
Warning FailedCreatePodSandBox 25m kubelet, ip-192-168-68-97.ap-northeast-1.compute.internal Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox containe
r "926c546742d4e2c199cb0b57a06b48a45d8b1bd7f4b34929a9de2a9ed276ba1a" network for pod "sample-74996797fd-2pmff": networkPlugin cni failed to set up pod "sample-74996797fd-2pmff_default" network: add cmd: failed
to assign an IP address to container
(...一部省略)
Warning FailedCreatePodSandBox 24m kubelet, ip-192-168-68-97.ap-northeast-1.compute.internal Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox containe
r "2b83c2e58d35536007d8216c82ecb6a2b239700f95032f87f46285e8b715093a" network for pod "sample-74996797fd-2pmff": networkPlugin cni failed to set up pod "sample-74996797fd-2pmff_default" network: add cmd: failed
to assign an IP address to container
Normal SandboxChanged 15m (x86 over 25m) kubelet, ip-192-168-68-97.ap-northeast-1.compute.internal Pod sandbox changed, it will be killed and re-created.
Warning FailedCreatePodSandBox 5m36s (x118 over 24m) kubelet, ip-192-168-68-97.ap-northeast-1.compute.internal (combined from similar events): Failed create pod sandbox: rpc error: code = Unknown desc = f
ailed to set up sandbox container "23277d1da24d3c2757c39c61a69dfa08f7bee6a9de7cb7df21c78b7939d1eacd" network for pod "sample-74996797fd-2pmff": networkPlugin cni failed to set up pod "sample-74996797fd-2pmff_de
fault" network: add cmd: failed to assign an IP address to container
予想通りCNIプラグインがエラーを吐いてます。そして、理由はわかりませんがNodeが NotReady になってしまいました。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-45-205.ap-northeast-1.compute.internal NotReady <none> 32m v1.16.8-eks-e16311
ip-192-168-68-97.ap-northeast-1.compute.internal NotReady <none> 32m v1.16.8-eks-e16311
結果
amazon-vpc-cni-k8sを使っているときは、--max-pods-per-node の値を変えただけでは1ノード辺りのPod数の上限値は増えないことがわかりました。
そしておそらくこの設定が原因で、Nodeも NotReady になってしまいました。
CNIプラグインもちゃんと別のものに変えないといけないということですね。
Calico独自の機能や動作検証の結果については、またの機会に書こうと思います。
執筆者:株式会社リアルグローブ・オートメーティッド技師 青島――――――――――――――――――――――――――――――――――
【ご案内】
ITシステム開発やITインフラ運用の効率化、高速化、品質向上、その他、情シス部門の働き方改革など、IT自動化導入がもたらすメリットは様々ございます。
IT業務の自動化にご興味・ご関心ございましたら、まずは一度、IT自動化の専門家リアルグローブ・オートメーティッド(RGA)にご相談ください!
お問合せは以下の窓口までお願いいたします。
【お問い合わせ窓口】
株式会社リアルグローブ・オートメーティッド
代表窓口:info@rg-automated.jp
URL: https://rg-automated.jp
(編集:馬塚勇介/校正:水谷裕一)