今回はラズベリーパイ上に構築したおうちk8sにnginxをhelmを使って入れてみようとした話。
今回もエラーと格闘することになり、案の定k8sが上手くいかない。
そんな記録を残しておこうと思います。
helm インストール前にエラー対応
😇【エラー】couldn’t get current server API group list: Get “http://localhost:8080/api?timeout=32s”: dial tcp [::1]:8080: connect: connection refused
workerノードで「kubectl get nodes」を実行すると以下のようなエラーが発生した。
k8s-worker1:~ $ kubectl get nodes
E0511 20:39:46.437696 1849037 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0511 20:39:46.439524 1849037 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0511 20:39:46.441167 1849037 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0511 20:39:46.442839 1849037 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0511 20:39:46.444581 1849037 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
The connection to the server localhost:8080 was refused - did you specify the right host or port?
解決法
k8s-worker1:~ $ sudo cp -i /etc/kubernetes/kubelet.conf $HOME/.kube/config
k8s-worker1:~ $ sudo chown $(id -u):$(id -g) $HOME/.kube/config
「~/.bashrc」に以下を追記
k8s-worker1:~ $ vi ~/.bashrc
## これ👇を追記
alias k='kubectl --kubeconfig $HOME/.kube/config
「~/.bashrc」の設定を反映するとコマンドが機能している
k8s-worker1:~ $ source ~/.bashrc
k8s-worker1:~ $ k get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 8d v1.30.0
k8s-worker1 Ready worker 5d v1.30.0
helmを触る
やっと本題。(案の定、k8sが上手くいかないなぁ)
helmとは
そもそもhelmとは何かを簡単に書いておきます。
HelmはKubernetes のパッケージマネージャーです。
Kubernetesには以下のようなデメリットがあります。
- 学習コストが高い事
- 大量のyamlファイルを書く必要がある事
- 変化が非常に速い事
これに対して、Helmが必要になってきます。
Helmのメリットは以下です。
- 複雑なyamlファイルを書く必要がない(コマンド1つでkubernetes上に展開が可能)
- パラメータを変えることで、オンプレやパブリッククラウドに合わせたり、映像化の有無を選択できる
- Chartからアプリケーションのyamlファイルを取得することが可能
- Chartを自作しておくことで、自作アプリのデプロイもコマンド1つで可能
だから、Helmを使っていきたいと思います。
helmを導入する前に注意点
これはk8s初心者の僕がハマったことなんだけど、当初、helmはworker node実行するものだと思っていた。
でも、実際はmaster nodeで実行するみたい。
ネットを探すとラズパイのworker nodeで実行するのか、master nodeで実行するのか明記されている記事がほぼ見つからないので、どっちで実行するのかわからなかった。
workerでhelmを入れてnginxを動かそうとすると以下のようなエラーでハマることになる。
$ helm install sample-nginx ingress-nginx/ingress-nginx
Error: INSTALLATION FAILED: Unable to continue with install: could not get information about the resource ServiceAccount "sample-nginx-ingress-nginx" in namespace "default": serviceaccounts "sample-nginx-ingress-nginx" is forbidden: User "system:node:k8s-worker1" cannot get resource "serviceaccounts" in API group "" in the namespace "default": can only create tokens for individual service accounts
helmの導入とnginxを動かす
参考にしたサイトは以下です。
参考:Rasberry Piクラスターに helm を導入してみた
$ sudo apt update
$ sudo apt install snapd
$ sudo reboot
$ sudo snap install helm --classic
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
$ helm repo add stable https://charts.helm.sh/stable
$ helm repo update
$ helm install sample-nginx ingress-nginx/ingress-nginx
worker nodeからもmaster nodeで立てたpodを確認できる。
k8s-worker1:~ $ k get pods
NAME READY STATUS RESTARTS AGE
sample-nginx-ingress-nginx-controller-644fd9f778-v9krt 1/1 Running 0 10m
やはりnginxならブラウザから確認したい。
でも、このままだと、ブラウザから確認ができません。
以下のように「sample-nginx-ingress-nginx-controller」は「LoadBalancer」というTYPEになっていますが、
k8s-master:~ $ kubectl get services -o wide -w
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25d <none>
sample-nginx-ingress-nginx-controller LoadBalancer 10.100.18.41 <pending> 80:31299/TCP,443:32285/TCP 14h app.kubernetes.io/component=controller,app.kubernetes.io/instance=sample-nginx,app.kubernetes.io/name=ingress-nginx
sample-nginx-ingress-nginx-controller-admission ClusterIP 10.109.156.142 <none> 443/TCP 14h app.kubernetes.io/component=controller,app.kubernetes.io/instance=sample-nginx,app.kubernetes.io/name=ingress-nginx
EXTERNAL-IPがpendingになっています。
クラウド環境だとEXTERNAL-IPが割り当てられるのですが、オンプレ環境やラズベリーパイ上だとLoadBalancerは今の状態だとできないっぽいです。(おそらくMetal LBを導入すればLoadBalanerでもアクセスできるはず)
このため、今回はNodePortタイプで設定します。
k8s-master:~$ helm upgrade sample-nginx ingress-nginx/ingress-nginx --set controller.service.type=NodePort
IPが割り当てられました。
k8s-master:~ $ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25d
sample-nginx-ingress-nginx-controller NodePort 10.100.18.41 <none> 80:31299/TCP,443:32285/TCP 14h
sample-nginx-ingress-nginx-controller-admission ClusterIP 10.109.156.142 <none> 443/TCP 14h
ラズベリーパイのIPでブラウザからアクセスすると、Not Foundだけど、nginxのNot Foundが表示されたのが分かります。