【问题标题】:K8S - livenessProbe - Restart pod if another pod is not ready / working ( MySql)K8S - livenessProbe - 如果另一个 pod 未准备好/工作(MySql),则重新启动 pod
【发布时间】:2022-03-03 17:14:25
【问题描述】:

新年快乐,我有 2 个部署,MySQL 和应用程序,我的应用程序依赖于 MySQL pod,我有 initContainers 确保应用程序在 MySQL pod 完全应用程序并准备好之后运行,但我正在尝试使下一个场景发挥作用。

我希望 Application pod 检查 MySQL pod,如果端口 3306 不可用,则 Application pod 本身将重新启动,这将一直发生,直到 MySQL pod 完全准备好。

我在应用程序部署/pod中使用它

livenessProbe:
  httpGet:
    host: ???
    path: /
    port: 3306

但不是“???”我不知道我需要写什么,因为我知道我不能写他们的 DNS 名称,我被告知 livenessProbe 不适用于 DNS,所以我尝试为 ENV 输入此 IP 地址,但仍然无法正常工作。

我该怎么做?

SQL 部署 yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.deployment.mysql.name }}
  namespace: {{ .Values.namespace }}
spec:
  selector:
    matchLabels:
      app: {{ .Values.deployment.mysql.name }}
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: {{ .Values.deployment.mysql.name }}
    spec:
      containers:
      - image: {{ .Values.deployment.mysql.image }}
        name: {{ .Values.deployment.mysql.name }}
        env:
         - name: MYSQL_ROOT_PASSWORD
           valueFrom: 
             secretKeyRef:
              name: mysql-secret
              key: mysql-root-password   
        ports:
        - containerPort: {{ .Values.deployment.mysql.port }}
          name: {{ .Values.deployment.mysql.name }} 
        volumeMounts:
        - name: sqlvol
          mountPath: /var/lib/mysql/
          readOnly: false
        # - name: db
        #   mountPath: /etc/notebook-db/
        # command:
        #   - mysql < /etc/notebook-db/crud.sql
        livenessProbe:
          tcpSocket:
            port: 3306
          initialDelaySeconds: 15
          periodSeconds: 20
      initContainers:
      - name: init-myservice
        image: busybox:1.28
        command: ['sh', '-c', "sleep 10"]
      volumes:
      - name: sqlvol
        persistentVolumeClaim:
          claimName: mysqlvolume
          readOnly: false

应用部署 yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.deployment.nodejs.name }}
  namespace: {{ .Values.namespace }}
  labels:
    app: {{ .Values.deployment.nodejs.name }}
    name: {{ .Values.deployment.nodejs.name }}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: {{ .Values.deployment.nodejs.name }}
  template:
    metadata:
      labels:
        app: {{ .Values.deployment.nodejs.name }}
    spec:
      containers:
      - name: {{ .Values.deployment.nodejs.name }}
        image: {{ .Values.deployment.nodejs.image }}:{{ .Values.deployment.nodejs.tag }}
        ports:
        - containerPort: {{ .Values.deployment.nodejs.targetPort }}
         livenessProbe:
           httpGet:
             host: $MYSQL_CLUSTERIP_SERVICE_HOST
             path: /
             port: 3306
      initContainers:
        - name: init-myservice
          image: busybox:1.28
          command: ['sh', '-c', "sleep 60"]

$MYSQL_CLUSTERIP_SERVICE_HOST - 这是 ENV(它对我不起作用)。

如果 pod mysql 未准备好,我该如何重启 pod 应用程序?

【问题讨论】:

  • 您使用的是哪个版本的 Kubernetes,您是如何设置集群的?您是否使用裸机安装或某些云提供商?重现您的问题很重要。

标签: kubernetes deployment livenessprobe


【解决方案1】:
  • 为 MySQL Deployment 创建一个服务,这样可以解决两个问题
    • 服务 IP 不变
    • dns 查找和反向查找可以很好地与服务配合使用
Example: 
kubectl get svc -n default
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
nginx        ClusterIP   10.104.97.252   <none>        8080/TCP   33m

FQDN of the above service (in the fomat : <nameoftheservice>.<namespace>.cluster.local ):
nginx.default.svc.cluster.local

  • 然后在应用程序部署中的livenessProbe 中将服务的FQDN 用作host
liveness probe for with respect above service: 

livenessProbe:
  httpGet:
    host: nginx.default.svc.cluster.local
    path: /
    port: 8080

【讨论】:

  • 不,没用,pod 的描述错误我 --> Liveness probe failed: Get "mysql-clusterip.app.svc.cluster.local:3306": dial tcp:lookup mysql-clusterip.app.svc.cluster.local : 没有这样的主机
  • 服务是用名称 mysql-clusterip 创建的吗?并且您可以使用 curl 访问该服务吗?它在命名空间应用程序中?
  • 是的,是的,是的
【解决方案2】:

如果 MySQL 还没有准备好,你的应用程序会崩溃吗?如果您的应用程序是 Deployment,则 Kubernetes 将应用自我修复,因此您的 Pod 将重新启动,直到重新启动正常(实际上您可以配置最大重试次数)。

【讨论】:

    【解决方案3】:

    TL;DR

    DNS 不适用于 liveness 探测,kubelet 网络空间基本上无法解析任何集群内 DNS。

    您可以考虑将两个服务作为 sidecar 放在一个 pod 中。这样一来,如果一个容器发生故障,它们将共享相同的地址空间,然后重新启动整个 pod。

    另一种选择是为您的 pod/应用程序创建一个 operator ?,基本上让它通过集群内 DNS 分别检查两个 pod 的活跃度,并通过 Kubernetes API 重新启动这些 pod。

    您也可以在 pod 中创建自己的脚本,调用 curl 来检查 200 OK 和 kubectl 来重新启动您的 pod,如果您得到其他东西。

    请注意,对于上述 2 个选项,您需要确保 Coredns 稳定可靠,否则您的运行状况检查可能无法使您的服务出现潜在的停机时间。

    来自:Liveness-Probe of one pod via another

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2019-08-03
      • 2018-12-30
      • 2020-07-27
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      相关资源
      最近更新 更多