k8s 使用 Init Container 確保依賴的服務已經啟動
Intro
最近 helm 3 正式發布了,dotnetcore 3.1 也正式發布了,最近打算把我的活動室預約項目做一個升級,項目已經升級到了 dotnetcore 3.1,最近幾天則在準備把項目打包一個 helm 包,使得想要在 k8s 上部署的童鞋可以更方便的部署,目前已經基本完成,本來打算發布到阿里云的 AppHub 上,但是前幾天更新的 angular client 的 chart 還沒有更新,不知道最近是不更新了還是怎么回事,所以現在暫時還沒發布到阿里云的 AppHub。你如果想要現在體驗,可以直接拉取 Github 上的 chart 配置,自己打包安裝。
一個 Pod 中可以有多個 container,也可以有多個 init container,init container 會在應用啟動之前啟動,并且如果有多個應用會依次啟動,只有一個運行成功了,才會啟動下一個,所有 init container 都運行結束了,應用才會啟動,因此,我們可以借助 init container 來檢查應用的依賴(如:db/redis/es...)是否已經可用。
Init Container 使用示例
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: reservation-server
image: weihanli/activityreservation:dev
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/notice
port: http
initialDelaySeconds: 60
periodSeconds: 10
initContainers:
- name: init-redis
image: busybox:1.31
command: ['sh', '-c', 'until nslookup redis-server; do echo waiting for redis; sleep 2; done;']
- name: init-mysql
image: busybox:1.31
command: ['sh', '-c', 'until nslookup mysql-server; do echo waiting for mysql; sleep 2; done;']
上面這一示例定義了兩個 init container,一個用來檢查 redis 是否啟動成功,另外一個用來檢查 mysql 是否啟動成功,開始部署的時候,首先會通過 nslookup
檢查 redis 是否成功啟動,檢測到 redis 啟動了之后,域名解析也就會成功,然后會檢查 mysql 的狀態,mysql 也成功啟動之后才會開始啟動 reservation-server
container
查看 pod 信息:
kubectl describe po reservation-server-59fb5447f7-gb5jg
從上面的信息可以看到結果是符合預期的,首先是創建并啟動 init-redis
的容器,然后創建并啟動 init-mysql
容器,最后創建并啟動 reservation-server
容器,從 pod 狀態來看,redis 和 mysql 還未 ready
時,resrvation-server
容器也不會啟動
查看 init-redis 的日志
kubectl logs reservation-server-59fb5447f7-gb5jg -c init-redis
查看 init-mysql 的日志:
kubectl logs reservation-server-59fb5447f7-gb5jg -c init-mysql
Memo
通過 init container 的配置終于可以解決依賴的服務還沒有 ready 應用就啟動從而導致應用多次重啟之后才能正常工作的問題~~