NUC上にk8sクラスタを構築する

しばらく放置していたNUC上にk8sをインストールして、おうちクラスタを運用していこうと思います。 今回はkubeadmを使ってk8sをインストールしようと思います。 前提 ベアメタル(Intel NUC11PAHi5)上に構築 Control Planex1台とWorkerx3台の4台構成 OSはRocky Linux9.3 ルーター側の設定で固定IPを割り当て 各ノードのスペックは以下 CPU メモリ ストレージ 4コア 16GB 500GB kubeadmのインストール 以下の手順を参考にします。 kubeadmのインストール 「始める前に」にSwapがオフであること、と記載がありますが、swapがオフになっていなかったので無効化します。 sudo swapoff -a ポートの開放 kubernetesのコンポーネントが互いに通信するために、これらのポートを開く必要があります。 RockyはRHEL系なのでfirewall-cmdを使って、Control Planeノードのポートを開放します。 sudo firewall-cmd --add-port=6443/tcp --permanent sudo firewall-cmd --add-port=2379-2380/tcp --permanent sudo firewall-cmd --add-port=10250/tcp --permanent sudo firewall-cmd --add-port=10257/tcp --permanent sudo firewall-cmd --add-port=10259/tcp --permanent ポートが開放されたことを確認します。 sudo firewall-cmd --reload sudo firewall-cmd --list-ports 続いて各Workerノードのポートを開放します。 sudo firewall-cmd --add-port=30000-32767/tcp --permanent sudo firewall-cmd --add-port=10250/tcp --permanent ポートが開放されたことを確認します。 sudo firewall-cmd --reload sudo firewall-cmd --list-ports コンテナランタイムのインストール コンテナランタイムの手順を参考に、各ノードに設定をしていきます。...

June 5, 2024 · Ken Kato

Alertmanagerのwebhookを試してみる

Kubernetes上でAlertmanagerがちゃんと通知できるか、どんな内容が通知されているのか確認してみようとすると、連携するためのSlackが必要であったり、Emailを送信するにもメールサーバが必要だったりと、意外と気軽に試せないということがありました。 なので、今回はwebhookの機能を使ってNginxにリクエストを飛ばし、リクエストの内容をログから確認してみようと思います。 webhookとは? Alertmanagerのreceiverには以下が指定できます。 Email Opesgenie PagerDuty Pushover Slack AWS SNS VictorOps Webhook Wechat Telegram Webex Webhookとは特定のエンドポイントに対してHTTP POSTリクエストでアラートの情報を送信するというものです。 外部サービスではないので、自分自身でエンドポイントを用意し、自分自身で後続の処理を実装する必要があります。 例えば、以下のように設定します。 receivers: - name: "nginx" webhook_configs: - url: 'http://nginx-svc.default:8080/' webhookの連携先としてnginxを使う 今回はwebhookの連携先としてnginxを使用します。 nginxを使って実現したいことは以下のとおりです。 エンドポイントを用意する リクエスト内容を確認する nginx.confの初期設定をベースにしていますが、そのままだとリクエスト内容を確認することができないので、設定を追加しました。 log_formatで$request_bodyを指定し、/にアクセスした時に$request_bodyがログとして標準出力に出るように設定しています。 しかし、$request_bodyを有効化するにはproxy_passなどの後続処理が必要になります。なので、proxy_passで/trashというエンドポイントにリクエストを転送し、/trashで特に意味のない処理(1x1ピクセルのgifを返す)をしています。 The variable’s value is made available in locations processed by the proxy_pass, fastcgi_pass, uwsgi_pass, and scgi_pass directives when the request body was read to a memory buffer. http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx....

August 13, 2023 · Ken Kato

KubernetesのCronJobが失敗したときにアラートをあげる

CronJobは、指定したcronフォーマットに基づいて定期的にJobを実行するという機能です。 主にバックアップの取得やメール送信など、定期的な処理を実行する際に便利です。 一方で、CronJobが失敗した際にどのように検知すべきかについては、あまり情報がありませんでした。 なので、今回はそちらについて考えてみたいと思います。 kube-state-metricsを活用する kube-state-metricsとはKubernetesクラスタ内のリソースの状態をメトリクスとして提供してくれるというものです。 kube-state-metricsではCronJobやJobの状態をメトリクスとして取得することができます。 この方式採用している記事が多かったので、こちらで検討を進めてみたいと思います。 ※記事 https://medium.com/@tristan_96324/prometheus-k8s-cronjob-alerts-94bee7b90511 https://www.giffgaff.io/tech/monitoring-kubernetes-jobs どのメトリクスを使い監視するか CronJobはcronフォーマットで指定された時刻にJobを生成し、そのJobがPodを生成するという3層の親子構造になっています。 また、CronJobとJobの関係は1対多で、JobとPodの関係は1対多になります。 Jobが完了するのはcompletions個のPodが正常終了した場合、もしくはbackoffLimit個のPodが異常終了した場合に限ります。 completions completions個のPodが成功すると、Jobが完了したとみなされる デフォルトは1 backoffLimit 失敗したと判断するまでの再試行回数で、この回数を超えるとJobは失敗とみなされる デフォルトは6 そして、アラートを上げたいのはJobが失敗した時です。言い換えると、backoffLimit個のPodが異常終了したときにアラートを上げるということになります。 何個のPodが異常終了したのか監視することも可能だと思いますが、ここではJobのステータスを監視するのが適切かと思います。 メトリクス 対応する項目 説明 kube_job_status_succeeded .status.succeeded Jobの管理下で正常終了したPodの数 kube_job_status_failed .status.failed Jobの管理下で異常終了したPodの数 kube_job_complete .status.conditions.type Jobが成功したかどうか kube_job_failed .status.conditions.type Jobが失敗したかどうか 参考: https://github.com/kubernetes/kube-state-metrics/blob/main/docs/job-metrics.md Jobに関するメトリクスは複数ありますが、この中でも特にkube_job_failedを使ってアラートを上げるのが良さそうです。 以下の設定だと、Jobが失敗したときにアラートが上がります。 kube_job_failed > 0 アラートが発火し続けてしまう問題 失敗したJobは削除されずに残り続けるので、アラートが発火し続けてしまいます。 なので、JobのttlSecondsAfterFinishedを設定し、数分後にJobが削除されるようにします。 ttlSecondsAfterFinished 指定秒後にJobを削除できる CronJobのfailedJobsHistoryLimitを設定するという方法も思いつきましたが、0にしてしまうとそもそもアラートが上がらないと思うので、こちらは1のままにしておきました。 failedJobsHistoryLimit 失敗したJobを指定個数分残しておける デフォルトは1 まとめ 今回はkube-state-metricsを活用して、CronJobが失敗した時のアラートを設定しました。他にもっといい方法をご存知の方は教えていただけるとありがたいです。

August 8, 2023 · Ken Kato

kubesprayでk8sクラスタを構築する

k8s構築ツールはいろいろありますが、公式ドキュメントでは以下が紹介されています。 学習環境 Minikube Kind プロダクション環境 kubeadm kops kubespray ※各ツールの違いについてはこちら 今回はその中でもkubesprayというツールを使ってk8sクラスタを構築してみようと思います。kubeadmは1台ずつインストールを実施するのに対し、kubesprayはAnsibleを使い、各ノードで一斉にインストールを実施します。なので、kubesprayは台数が多いときに便利です。 ちなみに、kubesprayは内部でkubeadmを使っているので、kubespray = kubeadm + Ansibleという感じです。また、kubesprayを使うと、コンテナランタイム(デフォルトはcontainerd)やPod間通信のネットワークプラグイン(デフォルトはcalico)などが自動でインストールされるので、非常に便利です。 構築 前提: ベアメタル(Intel NUC11PAHi5)上に構築 Control Planex1台とWorkerx3台の4台構成 OSはRocky Linux9.1 ルーター側の設定で固定IPを割り当て 各ノードのスペックは以下 CPU メモリ ストレージ 4コア 16GB 500GB ssh公開認証の設定 手元のPCからパスワードなしでssh接続できるように公開鍵認証の設定をします。 ssh-keygenのパスワードには空文字を指定します。 kkato@bastion:~$ ssh-keygen kkato@bastion:~$ scp ~/.ssh/id_rsa.pub 192.168.10.xxx:~/ 公開鍵の情報を各ノードのauthorized_keysに追記します。 kkato@nuc01:~$ mkdir ~/.ssh kkato@nuc01:~$ chmod 700 /.ssh kkato@nuc01:~$ cat id_rsa.pub >> ~/.ssh/authorized_keys kkato@nuc01:~$ chmod 600 ~/.ssh/authorized_keys /etc/hostsの編集 手元のPCから各ノードへホスト名で接続できるように、/etc/hostsを編集します。 kkato@bastion:~$ cat /etc/hosts --- 192.168.10.121 nuc01 192.168.10.122 nuc02 192.168.10.123 nuc03 192.168.10.124 nuc04 ユーザーの設定 各ノードのユーザーがパスワードなしでsudo実行できるよう設定します。...

May 1, 2023 · Ken Kato

Raspberry Pi上にk8sクラスタを構築する

最近ラズパイを手に入れたので、kubeadmを使ってk8sクラスタを組んでみたいと思います。 Control Planeノードx1 Workerノードx3の構成です。 準備 準備したものは以下のとおりです。 アイテム 個数 Raspberry Pi 4 Model B / 4GB 4 Raspberry Pi PoE+ HAT 4 ケース 1 microSD 64GB 4 スイッチングハブ 1 LANケーブル 0.15m 4 LANケーブル 1m 1 SDカードリーダー 1 HDMI変換アダプター 1 PoE(Power over Ethernet)+ HATを使うと、LANケーブルから電源供給できるのでとても便利です。今回はPoE+ HATを使っているので、スイッチングハブもPoE対応のものを購入しています。ラズパイのOSをSDカードにインストールする必要があるので、SDカードリーダーも購入しました。あとは、ディスプレイと繋ぐときにmicro HDMIに変換するためのアダプタも購入しました。 OSの設定 OSのインストール 手元のPCはUbuntu 22.04 LTSなので、以下のコマンドでRaspberry Pi Imagerをインストールします。 $ sudo apt install rpi-imager そして、microSDカード4枚全てにUbuntu Server 22.10 (64-bit)を焼きます。 $ rpi-imager microSDカードを差し込み、ディスプレイ(micro HDMI)とキーボード(USB)を接続し、OSの初期設定を行います。初期ユーザー名とパスワードはubuntuです。パッケージを最新にしておきます。 $ sudo spy update $ sudo apt upgrade -y 新しくユーザを作成し、ユーザにsudo権限を付与します。sudoをパスワードなしでできるように追加の設定もします。...

April 23, 2023 · Ken Kato