Istio 服务的健康检查

Kubernetes 存活和就绪探针 描述了几种配置存活和就绪探针的方法:

  1. 命令
  2. HTTP 请求
  3. TCP 探针
  4. gRPC 探针

命令方式无需更改即可工作,但 HTTP 请求、TCP 探针和 gRPC 探针需要 Istio 更改 Pod 的配置。

liveness-http 服务的健康检查请求由 kubelet 发送。当启用双向 TLS 时, 这会成为一个问题,因为 kubelet 没有 Istio 颁发的证书。 因此,健康检查请求将失败。

TCP 探针检查需要特殊处理,因为 Istio 将所有传入的流量重定向到 Sidecar, 所以所有 TCP 端口都显示为开放。kubelet 仅检查某个进程是否正在监听指定的端口, 因此只要 Sidecar 正在运行,该探针就总会成功。

Istio 通过重写应用程序 PodSpec 就绪/存活探针来解决这两个问题, 以便将探针请求发送到 Sidecar 代理

存活探针重写示例

为了演示存活探针和就绪探针如何在应用程序 PodSpec 级别进行重写, 可以使用 liveness-http-same-port 样例

首先为此样例应用创建一个命名空间并打好标签:

  1. $ kubectl create namespace istio-io-health-rewrite
  2. $ kubectl label namespace istio-io-health-rewrite istio-injection=enabled

然后部署样例应用程序:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: liveness-http
  6. namespace: istio-io-health-rewrite
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: liveness-http
  11. version: v1
  12. template:
  13. metadata:
  14. labels:
  15. app: liveness-http
  16. version: v1
  17. spec:
  18. containers:
  19. - name: liveness-http
  20. image: docker.io/istio/health:example
  21. ports:
  22. - containerPort: 8001
  23. livenessProbe:
  24. httpGet:
  25. path: /foo
  26. port: 8001
  27. initialDelaySeconds: 5
  28. periodSeconds: 5
  29. EOF

部署完成后,您可以检查 Pod 的应用容器,以查看已更改的路径:

  1. $ kubectl get pod "$LIVENESS_POD" -n istio-io-health-rewrite -o json | jq '.spec.containers[0].livenessProbe.httpGet'
  2. {
  3. "path": "/app-health/liveness-http/livez",
  4. "port": 15020,
  5. "scheme": "HTTP"
  6. }

原来的 livenessProbe 路径现在被映射到 Sidecar 容器环境变量 ISTIO_KUBE_APP_PROBERS 中的新路径:

  1. $ kubectl get pod "$LIVENESS_POD" -n istio-io-health-rewrite -o=jsonpath="{.spec.containers[1].env[?(@.name=='ISTIO_KUBE_APP_PROBERS')]}"
  2. {
  3. "name":"ISTIO_KUBE_APP_PROBERS",
  4. "value":"{\"/app-health/liveness-http/livez\":{\"httpGet\":{\"path\":\"/foo\",\"port\":8001,\"scheme\":\"HTTP\"},\"timeoutSeconds\":1}}"
  5. }

对于 HTTP 和 gRPC 请求,Sidecar 代理将请求重定向到应用程序并剥离响应体,仅返回响应代码。 对于 TCP 探针,Sidecar 代理会在避免流量重定向的同时进行端口检查。

在所有内置的 Istio 配置文件中, 有问题的探针的重写是默认启用的,但可以如下所述禁用。

使用命令方式的存活和就绪探针

Istio 提供了一个存活示例来实现这种方式。 为了演示该探针在启用双向 TLS 的情况下如何工作,本例先创建一个命名空间:

  1. $ kubectl create ns istio-io-health

要配置 STRICT 双向 TLS,请运行:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: security.istio.io/v1
  3. kind: PeerAuthentication
  4. metadata:
  5. name: "default"
  6. namespace: "istio-io-health"
  7. spec:
  8. mtls:
  9. mode: STRICT
  10. EOF

接下来,运行以下命令来部署示例服务:

Zip

  1. $ kubectl -n istio-io-health apply -f <(istioctl kube-inject -f @samples/health-check/liveness-command.yaml@)

要确认存活探针是否正常工作,请检查示例 Pod 的状态以验证它是否正在运行。

  1. $ kubectl -n istio-io-health get pod
  2. NAME READY STATUS RESTARTS AGE
  3. liveness-6857c8775f-zdv9r 2/2 Running 0 4m

使用 HTTP、TCP 和 gRPC 方式的存活和就绪探针

如上所述,Istio 默认使用探针重写来实现 HTTP、TCP 和 gRPC 探针。 您可以为特定 Pod 或全局禁用此特性。

为 Pod 禁用探针重写

您可以使用 sidecar.istio.io/rewriteAppHTTPProbers: "false"为 Pod 添加注解 以禁用探针重写选项。确保将注解添加到 Pod 资源, 因为在其他任何地方该注解会被忽略(例如,在封闭的 Deployment 资源上)。

  1. kubectl apply -f - <<EOF
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: liveness-http
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: liveness-http
  10. version: v1
  11. template:
  12. metadata:
  13. labels:
  14. app: liveness-http
  15. version: v1
  16. annotations:
  17. sidecar.istio.io/rewriteAppHTTPProbers: "false"
  18. spec:
  19. containers:
  20. - name: liveness-http
  21. image: docker.io/istio/health:example
  22. ports:
  23. - containerPort: 8001
  24. livenessProbe:
  25. httpGet:
  26. path: /foo
  27. port: 8001
  28. initialDelaySeconds: 5
  29. periodSeconds: 5
  30. EOF
  1. kubectl apply -f - <<EOF
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: liveness-grpc
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: liveness-grpc
  10. version: v1
  11. template:
  12. metadata:
  13. labels:
  14. app: liveness-grpc
  15. version: v1
  16. annotations:
  17. sidecar.istio.io/rewriteAppHTTPProbers: "false"
  18. spec:
  19. containers:
  20. - name: etcd
  21. image: registry.k8s.io/etcd:3.5.1-0
  22. command: ["--listen-client-urls", "http://0.0.0.0:2379", "--advertise-client-urls", "http://127.0.0.1:2379", "--log-level", "debug"]
  23. ports:
  24. - containerPort: 2379
  25. livenessProbe:
  26. grpc:
  27. port: 2379
  28. initialDelaySeconds: 10
  29. periodSeconds: 5
  30. EOF

这种方式允许您在单个 Deployment 上逐步禁用健康检查探针重写, 而无需重新安装 Istio。

全局禁用探针重写

安装 Istio 时使用 --set values.sidecarInjectorWebhook.rewriteAppHTTPProbe=false 全局禁用探针重写。或者更新 Istio Sidecar 注入器的配置映射:

  1. $ kubectl get cm istio-sidecar-injector -n istio-system -o yaml | sed -e 's/"rewriteAppHTTPProbe": true/"rewriteAppHTTPProbe": false/' | kubectl apply -f -

清理

移除这些示例所用的命名空间:

  1. $ kubectl delete ns istio-io-health istio-io-health-rewrite