クラスタがどんどんアップグレードされちゃうので、node pool のバージョンが古くなってきました。
ちなくみ、サービスを 1秒も切らすことなく、node pool をアップグレードしたいです。
実験ですが、このページどおりにやってみます。
https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer?hl=ja
以下を追加します。これで、ReplicaSetができることになります。
replicas: 3
適用します。
$ gcloud container clusters get-credentials cluster-1 --region=asia-northeast1-a
$ kubectl apply -f web-deployment.yaml
確認します。
$ kubectl get pod,replicaset,deployment
NAME READY STATUS RESTARTS AGE
pod/web-xxxx-xxxx 1/1 Running 0 6m7sZZ
pod/web-xxxx-yyyy 1/1 Running 0 6m7s
pod/web-xxxx-zzzz 1/1 Running 0 6m7s
NAME DESIRED CURRENT READY AGE
replicaset.apps/web-xxxx 3 3 3 6m7s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/web 3/3 3 3 6m8s
サービスを開始します。
$ kubectl apply -f web-service.yaml
確認します。
$ kubectl get service web
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web NodePort 10.56.2.xxx <none> 8080:32758/TCP 12h
HTTP(S) ウェブサーバー アプリケーションを公開するには、Ingress リソースを作成する必要があります。
$ kubectl apply -f basic-ingress.yaml
EXTERNAL-IPがしばらくしたら取れます。
アプリケーションに対応するロードバランサの外部 IP アドレスを調べます。
$ kubectl get ingress basic-ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
basic-ingress <none> * 34.xxx.xxx.xxx 80 72s
では、この外部IPをcurlコマンドで5秒毎に監視してみます。
#!/bin/bash
EXTERNAL_IP="34.xxx.xxx.xxx"
NOW=$(date '+%Y-%m-%d-%H-%M-%S')
#echo "${NOW}"
#exit 1
FILE="check_web_ingress_${NOW}.txt"
function check_web()
{
echo "========" >> "${FILE}"
date '+%Y-%m-%d-%H-%M-%S' >> "${FILE}"
curl -s "${EXTERNAL_IP}" >> "${FILE}"
sleep 5
}
while :
do
check_web
done
tail -f で目視確認します。
リソース確認用のスクリプトです。
デフォルトラベル(cloud.google.com/gke-nodepool=default-pool)を利用します。
#/bin/bash
NOW=$(date '+%Y-%m-%d-%H-%M-%S')
OUTFILE="blue_green_ingress_"${NOW}".txt"
function get_resource_info()
{
echo "========" >> $OUTFILE
date >> $OUTFILE
#echo "---vm---" >> $OUTFILE
#gcloud compute instances list >> $OUTFILE
#echo "---node-pools---" >> $OUTFILE
#gcloud container node-pools list --cluster cluster-1 --zone=asia-northeast1-a >> $OUTFILE
echo "---nodes default-pool---" >> $OUTFILE
kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool >> $OUTFILE
sleep 5
}
while :
do
get_resource_info
done
これも、tail -f で目視確認します。
PodDistrubtionBudgetも設定します。
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web
namespace: default
spec:
maxUnavailable: 1
selector:
matchLabels:
app: web
設定します。
$ kubectl apply -f web-pdb.yaml
poddisruptionbudget.policy/web created
確認します。
$ kubectl get pdb
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
web N/A 1 0 16s
これで、まず、クラスターをアップグレードして、終わったら、 node pool を blue/green でアップグレードします。
外形監視の方で、サービスが切れないか見ていましたけど、うーん、やっぱり切れちゃうのか。
考え直して、Nodepool soak duration の値を 3600 にし、readynessgateも作成しておきました。
また、Batch node count: 1 of 3 nodes (33%) にしてみました。
これで、なんとかサービスを切らすことなくアップグレード出来たようだ。
ただし、アップグレードがなかなか終わらなくて、次のコマンドを実行する必要がありました。
gcloud container node-pools complete-upgrade [NODE_POOL] --cluster [CLUSTER] --zone=[ZONE]
なお、現在の node pool に nodepool=old というラベルを追加して、新しいバージョンの node pool を作っておき、old を condorn, drain, delete を手動で実行することでも、web サービスの tail -f の外形監視で切れないのが確認出来ました。
cordon と drain のコマンドを参考に書いておきます。
$ kubectl cordon -l "nodepool=old"
$ kubectl drain --ignore-daemonsets --delete-emptydir-data -l "nodepool=old"
とりあえず、1秒もサービスを切らすことなくアップグレードすることは、blue/greenアップグレードの方法で、Nodepool soak duration の値を 3600 にし、readynessgateも作成してアップグレードする方法と、移行の方法でできました。Nodepool soad duration の値を 3600 にするのは長いので、確認していいと思ったら、そこで、アップグレードが終了したという指示を出しています。
なお、経費節減のために、クラスタ、node pool ともに、"e2-small", "pd-standard", --spot に直して、コマンドラインから作成しています。
(参考)
https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer?hl=ja
https://kubernetes.io/docs/tasks/run-application/configure-pdb/
https://qiita.com/toshihirock/items/5adaece0206127121551
https://cloud.google.com/kubernetes-engine/docs/tutorials/migrating-node-pool?hl=ja