k8s 使用 Init Container 确保依赖的服务启动顺序

一个 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: wh/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

init-mysql

通过 init container 的配置终于可以解决依赖的服务还没有 ready 应用就启动从而导致应用多次重启之后才能正常工作的问题

posted @ 2023-01-06 16:48  車輪の唄  阅读(257)  评论(0编辑  收藏  举报  来源