如何忽略多容器容器中容器的故障?

时间:2019-08-21 14:04:37

标签: kubernetes pod

我有一个多容器应用程序:app + sidecar。这两个容器都应该一直存在,但是挎斗并不是那么重要。 如果此资源不可用,Sidecar取决于外部资源-Sidecar崩溃。并且它使整个吊舱下降。 Kubernetes尝试重新创建Pod并失败,因为Sidecar现在无法启动。 但是从我的业务逻辑角度来看,Sidecar的崩溃绝对是正常的。拥有同伴是很好的,但不是强制性的。 我不希望Sidecar在崩溃时随身携带主应用程序。 什么是实现这一目标的最佳kubernets本地方法? 是否有可能告诉kubernetes忽略Sidecar的失败是绝对正确的“误报”事件?

我在pod规范中找不到任何能控制该行为的东西。

我的Yaml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myapp
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: myapp
    spec:
      volumes:
      - name: logs-dir
        emptyDir: {}
      containers:
      - name: myapp
        image: ${IMAGE}
        ports:
        - containerPort: 9009
        volumeMounts:
        - name: logs-dir
          mountPath: /usr/src/app/logs
        resources:
          limits:
            cpu: "1"
            memory: "512Mi"
        readinessProbe:
          initialDelaySeconds: 60 
          failureThreshold: 8 
          timeoutSeconds: 1
          periodSeconds: 8 
          httpGet:
            scheme: HTTP
            path: /myapp/v1/admin-service/git-info
            port: 9009
      - name: graylog-sidecar
        image: digiapulssi/graylog-sidecar:latest
        volumeMounts:
        - name: logs-dir
          mountPath: /log
        env:
        - name: GS_TAGS
          value: "[\"myapp\"]"
        - name: GS_NODE_ID
          value: "nodeid"
        - name: GS_SERVER_URL
          value: "${GRAYLOG_URL}"
        - name: GS_LIST_LOG_FILES
          value: "[\"/ctwf\"]"
        - name: GS_UPDATE_INTERVAL
          value: "10"
        resources:
          limits:
            memory: "128Mi"
            cpu: "0.1"

4 个答案:

答案 0 :(得分:1)

自定义的livenessProbe应该会有所帮助,但对于您的情况,我将为您的主应用程序容器myapp使用liveness。
考虑到您实际上并不在乎侧面护理(如上所述)。我将广告连播restartPolicy设置为Never,然后为主要myapp定义自定义livelinessProbe。这样,不管哪个容器发生故障,Pod都不会重启,但是当您的myapp容器的活动性失败时,kubelet会重新启动容器!参考以下link

  

Pod正在运行,并且有两个容器。容器1退出失败。

     

记录失败事件。如果restartPolicy为:始终:重新启动容器;荚   阶段保持运行状态。 OnFailure:重新启动容器;豆荚阶段停留   跑步从不:不要重新启动容器; Pod阶段保持运行状态。

所以更新的(伪)yaml应该如下所示

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myapp
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    ...
    spec:
      ...
      restartPolicy: Never
      containers:
      - name: myapp
        ...
        livenessProbe:
          exec:
            command:
            - /bin/sh
            - -c
            - {{ your custom liveliness check command goes }}
          failureThreshold: 3
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        readinessProbe:
          ...
      - name: graylog-sidecar
        ...

注意:由于我不知道您的应用程序,因此无法编写命令,但是对于我的jboss服务器,我使用了此命令(为您提供示例)

livenessProbe:
          exec:
            command:
            - /bin/sh
            - -c
            - /opt/jboss/wildfly/bin/jboss-cli.sh --connect --commands="read-attribute
              server-state"
          failureThreshold: 3
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1

答案 1 :(得分:1)

警告:被标记为“正确”的答案似乎无效。

在应用程序容器中添加活动探针并将“重新启动策略”设置为“从不”,将导致Pod停止并且从不重新启动。未能通过“活力调查”。这是一个问题,因为您确实希望重新启动应用程序容器。

该问题应按以下方法解决:

  • 在启动命令中调整sidecar容器,以在应用程序进程失败时保持主进程运行。这可以通过额外的脚本来完成,例如通过将| tail -f /dev/null附加到启动命令。
  • 向应用程序容器添加活动探测器通常是一个好主意。请记住,尽管这样做仅能保护您免受应用程序进程持续运行而应用程序未处于正确状态的情况。它当然不会覆盖restartPolicy:

livenessProbe:指示容器是否正在运行。如果活动性探针失败,则kubelet将杀死该容器,并且该容器将接受其重新启动策略。如果容器未提供活动性探针,则默认状态为“成功”。 Container Probes

答案 2 :(得分:0)

您可以为边车定义一个自定义livenessProbe,以使其具有更大的故障阈值/周期秒数,以适应环境中可接受的故障率,或者只是忽略所有故障。

文档:

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#probe-v1-core

kubectl explain deployment.spec.template.spec.containers.livenessProbe

答案 3 :(得分:0)

对我有用的最佳解决方案不是在 sidecar 容器内失败,而只是记录错误并重新运行。

#!/usr/bin/env bash

set -e
# do some stuff which can fail on start

set +e # needed to not exit if command fails

while ! command; do
    echo "command failed - rerun"
done

如果失败,这将始终重新运行 command,但如果 command 成功完成,则退出。