おはこんばんにちは
zerobillbank株式会社のインフラエンジニアtomatoことtomatoです。
今回はkubernetesシリーズの最終回ということで、
構築時のトラブルシューティングから運用・監視についてお話していきたいと思いまうす
ちなみに前回の記事はこちらです
「おじいちゃん kubernetesってなに?」「...それはコスモスじゃよ」(1) -概要編-
「おじいちゃん kubernetesってなに?」「...それはコスモスじゃよ」(2) -構築編-
構築のトラブルシューティング
構築時のエラーに対応として、まずPodで起こっているエラーか、
それ以外で起こっているエラーかを分類するといいと思います。
Podのエラー
Podでエラーが起こっているかを確認するのは簡単です。
kubectl get po
でPod
を確認した時に、正常時の場合はSTATUS
がRunnning
、STATUS
が1/1
のように分母と分子が等しくなっているはずです。
$ kubectl get po
NAME READY STATUS RESTARTS AGE
sample-775487cf8-d5czn 0/1 ImagePullBackOff 2 15m
それ以外の場合はエラーが出ていますので、
describe
コマンドを使ってエラーの原因を確認します。
$ kubectl describe po sample-775487cf8-d5czn
---省略
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal BackOff 28s (x4 over 1m) kubelet, ip-xxx.internal Back-off pulling image "nginx:1.123"
Warning Failed 28s (x4 over 1m) kubelet, ip-xxx.internal Error: ImagePullBackOff
describe
コマンドで対象のPod
を調べると、Events
の欄にエラーイベントが出力されます。
上記の例では存在しないnginx
のバージョンを指定したため、イメージがpullできないエラーが出ていました。
調査系コマンド
上記のdescribe
コマンドでも調査は可能ですが、
多くのケースでは下記の2つのコマンドのどちらかを打てば
エラー原因を見つけることができます。
logsコマンド
kubectl logs [deployment名]
get events
kubetctl get events | grep [deployment名]
アクセスできないエラー
上記以外でPod
は正常に稼働しているにも関わらず
Webページなどが上手くアクセスできない場合についての対処方法についてです。
この場合、どこでアクセスが途切れているかを下記のステップで特定します。
- Podでのアクセス確認
- Service経由でのアクセス確認
- Ingress経由でのアクセス確認
Podでのアクセス確認
$ kubectl exec -it [Pod名] -- /bin/sh
alpineなどは操作系のツールが入っていないことが多いため、
その場合は下記のコマンドでインストールします。
# update
apt update
# curlのインストール
apt install -y curl
# netstatのインストール
apt install -y net-tools
# aptがない場合
apk -U add curl
apk add net-tools
動いているプロセスの確認
$ netstat -pant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN 1/nginx: master pro
上記コマンドで、対象のアプリケーションが動作している事と
動いているPort番号を確認します。
$ curl http://localhost:3000
welcome nginx!!
これで表示されれば 1. Podでのアクセス確認
は問題なしです。
Service経由でのアクセス確認
$ curl http://nginx:3000
welcome nginx!!
これで表示されれば 2. Service経由でのアクセス確認
は問題なしです。
よくあるミスとしては、service.yaml
の中のports
の項目の
port
とtargetPort
の記載ミスです。
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: sample
labels:
app: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80 # Default port for image
targetPort: 80
port
... image内でのPort番号。上記のPod内でnetstat
した場合のPort番号になる。
targetPort
... kubernetes上のPort番号。Service
に紐付く。
この場合、image内でのPort番号は3000
なので、port
は80
ではなく3000
と記載します。
またdeployment.yaml
内にもcontainerPort
という項目があり
こちらはservice.yaml
のtargetPort
と合わせる必要があります。
Ingress経由でのアクセス確認
上記までで問題がなくてアクセスできない場合は、ドメイン周りの問題が考えられます。
実際にページにアクセスした際のエラーメッセージを基に
ドメインやSSL証明書周りを確認してみてください。
運用
kubernetesではyaml
で管理することで冪等性を担保していますが
運用に置いてyamlの取り扱いで気をつけたほうがいいなーと思う点をあげてみます。
applyの前にはdiffを取る
apply
コマンドで適用をする前に、必ずdiff
コマンドで差分確認をしましょう。
想定外のyaml
を当ててしまう事故を防げます。
# 想定の差分が出ることを確認
$ kubectl diff -f nginx/deployment.yaml
# 適用
$ kubectl apply -f nginx/deployment.yaml
# 差分が出ないことを確認
$ kubectl diff -f nginx/deployment.yaml
更新の際にはrolloutコマンドを用いる
Pod
の更新の際はdelete
コマンドではなく、rollout restart
コマンドを使用します。
delete
コマンドでPod
を削除しても、deployment
が存在していればPod
は再起動されますが
削除してから再起動する間にサービスダウンが発生します。
rollout restart
コマンドであれば、古いPod
を残しつつ、新しいPod
に順次移行してくれるため、サービスダウンなく再起動をすることができます。
config
やsecret
などのリソースのみを更新する場合、Pod
が再起動されないと
新しい定義が読み込まれませんので、その際もrollout restart
コマンドを忘れずに実行しましょう。
$ kubectl rollout restart deploy/nginx
deployment.apps/nginx restarted
おまけ
kubectl api-resources
と打つと、利用できるリソースの一覧を表示できます。
さらにリソースごとのショートカットの名前と、yaml
に記載するapiVersion
も確認できるので
何かあった時に覚えておくと便利なコマンドです。
$ kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings true Binding
componentstatuses cs false ComponentStatus
configmaps cm true ConfigMap
endpoints ep true Endpoints
events ev true Event
limitranges limits true LimitRange
namespaces ns false Namespace
nodes no false Node
persistentvolumeclaims pvc true PersistentVolumeClaim
persistentvolumes pv false PersistentVolume
pods po true Pod
...
監視
監視については色々なツールがあると思いますが、
まず手軽にやるのなら下記のツールと相性が良いと思います。
無料でUIによるログ表示から、アラート発報まで一通り必要なことができちゃいます
またhelm
(パッケージ管理ツール)が3系になり、とても導入が楽になりました。
ただし、デフォルト設定のまま適用すると、どんな値なのかの認識や管理ができないため
一旦ローカルにfetch
してからinstall
するのが良いのではと思います。
各設定値についてはvalues.yaml
に記載されてますので
変更したい項目を見つけて値をいじるとinstall
もしくはupgrade
の際に適用されます。
インストール
helmのインストールについては下記を参照してください。
https://helm.sh/ja/docs/intro/install/
fetchする
$ helm repo update
$ helm fetch stable/filebeat
$ helm fetch stable/logstash
$ helm fetch stable/elasticsearch
$ helm fetch stable/kibana
$ helm fetch grafana/grafana
$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update
$ helm fetch prometheus-community/kube-prometheus-stack
installする
$ helm install -name filebeat -n monitoring -f filebeat/values.yaml stable/filebeat
$ helm install -name logstash -n monitoring -f logstash/values.yaml stable/logstash
$ helm install -name elasticsearch -n monitoring -f elasticsearch/values.yaml stable/elasticsearch
$ helm install -name kibana -n monitoring -f kibana/values.yaml stable/kibana
$ helm install -name grafana -n monitoring -f grafana/values.yaml grafana/grafana
$ helm install -name prometheus -n monitoring -f kube-prometheus-stack/values.yaml prometheus-community/kube-prometheus-stack
インストールはこれだけですのでとても簡単!
ちなみに更新したいときはinstall
の部分をupgrade
に変えるだけです。
Grafanaは設定周りがちょっとややこしいので、以前に書いた下記の記事を参考にしていただければと。
helm3を使用して超簡単にkubernetesにGrafanaをデプロイする方法がまるでtomato
おわり
というわけで全3回に渡ってkubernetesについて解説していきました。
気づいた点があれば随時加筆していきたいと思います。
一人でも多くkubernetes沼にハマってくれるエンジニアが増えてくれればいいなと思っております。
みなさま良いkubernetesライフを!!
ではまた🙋♂️
さいごに
ZEROBILLBANKでは一緒に働く仲間を募集中です。
なんとかjsとか、ブロックチェーンとか、kubernetesとかでいろんなAPIを作るお仕事。
今のところエンジニアは5人くらい。スタートアップだけど、結構ホワイトで働きやすいです。