この記事はKMCアドベントカレンダー2023の24日目です。
この記事ではインフラ初心者がkubernetesクラスタを立ててみたときに詰まった点をまとめてみました。
はじめに
最近、VPS上で公開していたポートフォリオや歌枠データベースをDocker上で立てられるようにし、自宅サーバーへと完全移行しました。
(自宅サーバーへサーバーを移行した話はこの辺りの記事にまとめました。)
しかし、自宅サーバーは諸々の理由で頻繁に電源が落ちるため、kubernetesを使って冗長構成にしたいと思うようになりました。また、毎回sshでログインしてデプロイをするのが手間だったので自動デプロイの基盤をkubernetesで作りたいと思うようになり、意を決してkubernetesのお勉強を始めました!
というわけで、これから先「お家Kubernetes環境を作ろう」シリーズとしてk8sのお勉強記録をつけていこうと思います。
今回はその第一段階として、VPS上にkubernetesのマルチノードクラスタを構成してみました。
環境
- lemon: Kagoya Cloud VPS 2コア 2GB
- lime: Kagoya Cloud VPS 2コア 2GB
(lemonやlimeはマシン名です)
- デプロイツール: kubeadm
- CRI: cri-dockerd
- CNI: Calico(で上手くいかなかったためWeave netにした(後述))
ネタバレ
細かいことは置いといてとりあえず結論を知りたい!と言う方へ
マルチノードクラスタ上でpodを作成し、port-forwardしてpodにアクセスしようとしたのですが、表題の通りpodにアクセスできないという問題が生じました。
$ kubectl port-forward hello-node-7c97b7fcf5-rj259 8080:8080
error: error upgrading connection: unable to upgrade connection: pod does not exist
結論から言うと、Calicoに必要なポートが使えないことが原因でした。VPSをローカルネットで繋いだりしたものの179番が通らなかったため、Calicoは諦めてWeaveworksを使うことにしました。
問題発生までの流れ
ざっくり言うと:
- kubeadm init
- Calicoのインストール
- kubeadm join
- hello-nodeのデプロイ・サービス作成
です。詳細に興味がない方は次章まで飛ばして大丈夫です。
Docker・コンテナランタイムのインストール
ドキュメントを眺めて、雑に馴染みのあるDocker Engineを選んでインストールしました。
(強いお友達はCRI-Oとかを勧めていた気がするが初心者の私には違いが分からないため一旦このまま進めます。)
kubeadm-config.yamlを記述
CRIにcri-dockerdを選んだため、kubeadm initするときに読み込むconfigファイルに次のように記述しました。後でCalicoを使うためにClusterConfigurationのnetworking.podSubnetもついでに設定しておきます。
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
  criSocket: unix:///run/cri-dockerd.sock
===
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: stable
networking:
  podSubnet: "192.168.0.0/16"
criSocketはunix://をつけないとエラーで怒られたので注意が必要です。
kubeadm init
マスターノードにしたいVPS上で
$ sudo kubeadm init --config=kubeadm-config.yaml
としました。表示されるコマンド(mkdir ...とか)をコピーして実行します。また、kubeadm joinコマンドは後で使うためコピーしてどこかにメモっておきます。
Calicoをインストール
Install Calicoのコマンドを順に実行しました。
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/custom-resources.yaml
kubeadm join
ワーカーノードにしたいVPS上にもdockerやcri-dockerdなどをインストールし、さっきメモったコマンドを実行します。
$ sudo kubeadm join ...(略) --cri-socket=unix:///var/run/cri-dockerd.sock
ワーカーノードでもCRIにcri-dockerdを使用しているため、kubeadm join ...にオプションで--cri-socket=unix:///var/run/cri-dockerd.sockを指定する必要があります。これを忘れるとCRIが複数あって云々と怒られました。
マスターノードに戻ってnodeを確認してみると、正常に追加できていそうです。
$ kubectl get nodes
NAME    STATUS   ROLES           AGE   VERSION
lemon   Ready    control-plane   27m   v1.28.2
lime    Ready    <none>          19m   v1.28.2
hello-nodeをデプロイ
チュートリアルに従って、hello-nodeのデプロイメント・サービスを作成します。
$ kubectl create deployment hello-node --image=registry.k8s.io/echoserver:1.4
$ kubectl expose deployment hello-node --port=8080
チュートリアルから単純にコピペするとserviceのtypeはLoadBalancerになっていますが、これを正しく使うにはMetalLbなどを入れる必要があるため、--type=LoadBalancerは消して実行します。
問題の内容
前章でマルチノードクラスタ上にhello-nodeのpod・serviceを作成することができました。
get podsやらをすると、確かにpodやserviceが作成できていそうです。
$ kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
hello-node-7c97b7fcf5-rj259   1/1     Running   0          21m
$ kubectl get deployment
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
hello-node   1/1     1            1           21m
$ kubectl get svc/hello-node
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
hello-node   ClusterIP   10.111.221.203   <pending>     8080:31781/TCP   18m
そこで、実際にpodに対してport-forwardしようとすると、
$ kubectl port-forward hello-node-7c97b7fcf5-rj259 8080:8080
error: error upgrading connection: unable to upgrade connection: pod does not exist
pod does not existと言われてしまいました。
試したこと
- namespaceがdefaultになっているか確認→なっている。
$ kubectl get pod -A -o wide
NAMESPACE          NAME                                      READY   STATUS    RESTARTS        AGE   IP                NODE    NOMINATED NODE   READINESS GATES
calico-apiserver   calico-apiserver-68644496f8-4w6wp         1/1     Running   0               46m   192.168.232.6     lemon   <none>           <none>
calico-apiserver   calico-apiserver-68644496f8-h5v4r         1/1     Running   0               46m   192.168.232.5     lemon   <none>           <none>
calico-system      calico-kube-controllers-69bbc55b7-d5slw   1/1     Running   0               46m   192.168.232.4     lemon   <none>           <none>
calico-system      calico-node-4vwxs                         0/1     Running   0               46m   10.150.11.1       lemon   <none>           <none>
calico-system      calico-node-hrhhl                         0/1     Running   1 (8m43s ago)   40m   10.150.11.1       lime    <none>           <none>
calico-system      calico-typha-6c4fc595ff-kdqwn             1/1     Running   0               46m   10.150.11.1       lemon   <none>           <none>
calico-system      csi-node-driver-d2fzq                     2/2     Running   0               46m   192.168.232.2     lemon   <none>           <none>
calico-system      csi-node-driver-z9xm7                     2/2     Running   0               40m   192.168.124.129   lime    <none>           <none>
default            hello-node-7c97b7fcf5-rj259               1/1     Running   0               39m   192.168.124.130   lime    <none>           <none>
kube-system        coredns-5dd5756b68-6twqb                  1/1     Running   0               48m   192.168.232.3     lemon   <none>           <none>
kube-system        coredns-5dd5756b68-rkwdv                  1/1     Running   0               48m   192.168.232.1     lemon   <none>           <none>
kube-system        etcd-lemon                                1/1     Running   0               48m   10.150.11.1       lemon   <none>           <none>
kube-system        kube-apiserver-lemon                      1/1     Running   0               48m   10.150.11.1       lemon   <none>           <none>
kube-system        kube-controller-manager-lemon             1/1     Running   0               48m   10.150.11.1       lemon   <none>           <none>
kube-system        kube-proxy-8n2r9                          1/1     Running   0               48m   10.150.11.1       lemon   <none>           <none>
kube-system        kube-proxy-m8qlt                          1/1     Running   0               40m   10.150.11.1       lime    <none>           <none>
kube-system        kube-scheduler-lemon                      1/1     Running   0               48m   10.150.11.1       lemon   <none>           <none>
tigera-operator    tigera-operator-7f8cd97876-pm4hz          1/1     Running   0               46m   10.150.11.1       lemon   <none>           <none>
- serviceで指定すると?→できない。
$ kubectl port-forward svc/hello-node 8080:8080
error: error upgrading connection: unable to upgrade connection: pod does not exist
- podSubnetが被っている説?を検証
 kubeadm-config.yamlのpodSubnetを次のように修正。
networking:
  podSubnet: 10.244.0.0/16
この変更を加えてkubeadm reset、kubeadm initをしたところ、色々と苦戦したのですが結局上手くいきませんでした。
この部分で詰まった点は記事1つ分くらいになりそうなのでここでは省略することにします。
- Calicoの必須ポートを確認
 CalicoのNetwork requirementsに記載のポートが公開されていないことに気づきました。
 179番を公開するのはあまり良くないと考え、Kagoya Cloud VPSのローカルネットワークを使ってVPSを同一ネットワーク上に配置しました。
Kagoyaのマニュアルに従ってIPを10.0.0.1/16, 10.0.0.2/16にしました。
しかし、同一ネットワークに配置しても179番が使えず、Calicoの使用を断念しました。
- Weave netをいれてみる
 すぐには上手くいきませんでした。
ログを見てみたところ、設定したIPで通信されていませんでした。
- localAPIEndpointを設定する
 kubeadm-config.yamlのInitConfigurationを次のように修正しました。
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
  criSocket: unix:///run/cri-dockerd.sock
localAPIEndpoint:
  advertiseAddress: 10.0.0.1
  bindPort: 6443
...
これでkubeadm reset + kubeadm initを再度行ったのですが、なお上手くいきませんでした。
- Calicoの設定を抹消
 /etc/cni/net.d、/opt/cni/binにcalicoの設定が残っていたためすべて削除して再起動したところ、上手くいきました!!
教訓
- インストールするパッケージ等のrequirementsはちゃんと確認する!
 必須ポートが開いていることを確認できていなかったのが最大の原因
- エラーが起きたらちゃんとログを読もう!
最後に
今回エラーを解消するに当たり、WalnutsとSouthball、他KMCの先輩方にたくさん助けていただきました。ありがとうございます!!
この次は手元のminikube上でnextサーバー構築に挑戦していきたいと思います。