1. 开篇

米娜桑,宝子们,ladies and 砖头们…… 总之,我回来了!

你看这标题,没错,K8s 的。兜转两载,我还是决定从“DevOps 工程师”变回“机器学习平台研发工程师”。直观一点讲,就是“云平台开发”那点事配上 GPU 那点料,是不是很好理解?

Anyway,以后又有机会玩 K8s 了,所以接下来我会继续更新和 K8s 或者“机器学习平台”相关的内容。总之总之,你们蹲了那么久的更新,来了!

2. 聊啥

今天有个同事问我:在1个 Pod 中跑多个 Container,如果其中一个挂了,另外一个会怎样?

嗯…… 我记得大概,不过没有确切的结论,这个取决于 probes 是怎么工作的,于是我实测了一下,发现和预期不是完全一致。

于是乎,今天和大伙分享下这个知识点。

3. 结论(TL;DR)

对,结论在开头。毕竟,我知道你们都很忙。


一番操作猛如虎,然后我发现:

当1个 Pod 中包含2个 Containers 的时候,如果2个 Containers 分别对外暴露不同的端口(http 服务为例),当其中有1个 Container 的:

  1. Liveness probe 失败,则该 Container 会被 Kubelet 干掉,然后该 Container 重启/重建(当然,你的重启策略得是 Always),另外一个 Container 不会重启(也就是不会发生 Pod 级别的重启/重建,因此 Pod IP 也不会变化);
  2. Readiness probe 失败,这时候 Pod 状态里的 Ready 列自然是1/2,关键是 Service 会怎样工作呢?
    1. 当使用1个 Service 负载流量到这个 Pod 的2个端口时,Service 对应的 Endpoint 会变成 NotReady,导致 Pod 中 ready 的那个 Container 也不能通过 Service 地址访问到;
    2. 当使用2个不同的 Service 分别负载流量到这个 Pod 的2个端口时,很遗憾,对应的2个 Endpoint 均会变成 NotReady,而不是1个 Ready,一个 NotReady。(这是和我最开始的猜测不相符的)

4. 测试过程

你居然看到了这里,宝子,你是个求知欲很强的孩子啊!

4.1 准备测试用镜像

我想用 NGINX 镜像来完成这次 probes 特性测试,但是要让2个 containers 在1个 Pod 里监听不同的端口,那就得重新打下镜像,包一层了。

1. 首先,准备一个配置文件

  • default.conf
server {
listen 8080; location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}

2. 然后准备一个 Dockerfile

  • Dockerfile
FROM nginx

RUN rm /etc/nginx/conf.d/default.conf

COPY default.conf /etc/nginx/conf.d/

EXPOSE 8080

注意到这里我们将端口号指定成了8080。

3. 接着 build 一下

docker build -t my-nginx-8080:1.0 .

很酷,第一个镜像有了。然后咱需要继续搞一个监听8081端口的新镜像。

4. 更新配置文件

  • default.conf
server {
listen 8081; location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}

5. 更新 Dockerfile

FROM nginx

RUN rm /etc/nginx/conf.d/default.conf

COPY default.conf /etc/nginx/conf.d/

EXPOSE 8081

6. build 第二个镜像

docker build -t my-nginx-8081:1.0 .

OK,到这里2个镜像就准备完成了。接着如何将镜像丢到 K8s worker 节点,大家就各显神通吧,通过镜像仓库也行,手动拷贝也罢。

4.2 准备 Deployment YAML

首先跑一个 probe 能过的版本,确保“1 Pod 2 Container”启起来。

  • deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-container1
image: my-nginx-8080:1.0
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
- name: nginx-container2
image: my-nginx-8081:1.0
ports:
- containerPort: 8081
livenessProbe:
httpGet:
path: /
port: 8081
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: /
port: 8081
initialDelaySeconds: 5
periodSeconds: 5

4.3 准备 Service YAML

然后准备一个 Service,用来测试 readinessProbe 相关行为。

  • svc.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx-service
spec:
selector:
app: nginx
ports:
- name: port1
protocol: TCP
port: 8080
targetPort: 8080
- name: port2
protocol: TCP
port: 8081
targetPort: 8081

4.4 准备第二个 Service YAML

如果是分开的2个 Services 去转发流量到 Pod 内的2个 Containers 呢?也试一下:

  • svc-2.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx-service-1
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 8080
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx-service-2
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 8081
targetPort: 8081

4.5 测试过程

Apply YAML 后,依次将 Deployment 配置里的 livenessProbe.httpGet.pathreadinessProbe.httpGet.path 从正确的 / 改成会引发404的 /hehe,然后观察 Pod 的状态变化,Service/Endpoint 的状态变化,就可以啦。

(对,不放截图,显得冗长,不是懒,真的不是懒!)

5. 结论

前面贴过结论了,复制粘贴一波:

当1个 Pod 中包含2个 Containers 的时候,如果2个 Containers 分别对外暴露不同的端口(http 服务为例),当其中有1个 Container 的:

  1. Liveness probe 失败,则该 Container 会被 Kubelet 干掉,然后该 Container 重启/重建(当然,你的重启策略得是 Always),另外一个 Container 不会重启(也就是不会发生 Pod 级别的重启/重建,因此 Pod IP 也不会变化);
  2. Readiness probe 失败,这时候 Pod 状态里的 Ready 列自然是1/2,关键是 Service 会怎样工作呢?
    1. 当使用1个 Service 负载流量到这个 Pod 的2个端口时,Service 对应的 Endpoint 会变成 NotReady,导致 Pod 中 ready 的那个 Container 也不能通过 Service 地址访问到;
    2. 当使用2个不同的 Service 分别负载流量到这个 Pod 的2个端口时,很遗憾,对应的2个 Endpoint 均会变成 NotReady,而不是1个 Ready,一个 NotReady。(这是和我最开始的猜测不相符的)

6. 结尾

没看够?别急嘛,关注微信公众号“胡说云原生”,来日方长,see you tomorrow。

K8s 里多容器 Pod 的健康检查探针工作机制分析的更多相关文章

  1. 十一、Pod的健康检查-探针

    Pod 的健康检查-探针 一.Pod 的健康检查-探针 1.1.探针基本概念 ​探针是由 kubelet 对容器执行的定期诊断.要执行诊断,kubelet 调用由容器实现的 Handler 有三种类型 ...

  2. idou老师教你学Istio 14:如何用K8S对Istio Service进行流量健康检查

    Istio利用k8s的探针对service进行流量健康检查,有两种探针可供选择,分别是liveness和readiness: liveness探针用来侦测什么时候需要重启容器.比如说当liveness ...

  3. Kubernetes中Pod的健康检查

    本文介绍 Pod 中容器健康检查相关的内容.配置方法以及实验测试,实验环境为 Kubernetes 1.11,搭建方法参考kubeadm安装kubernetes V1.11.1 集群 0. 什么是 C ...

  4. 为你的docker容器增加一个健康检查机制

    1.健康检查 在分布式系统中,经常需要利用健康检查机制来检查服务的可用性,防止其他服务调用时出现异常.自 1.12 版本之后,Docker 引入了原生的健康检查实现. 如何给Docke配置原生健康检查 ...

  5. k8s之ingress-nginx部署一直提示健康检查10254端口不通过问题就处理

    之前部署了一套k8s集群,但是到部署ingress-nginx的时候,一直提示10254端口拒绝不通:如下图. 这是因为我之前装的是docker1.17.默认的驱动是systemd.因为systemd ...

  6. nginx健康检查模块源码分析

    nginx健康检查模块 本文所说的nginx健康检查模块是指nginx_upstream_check_module模块.nginx_upstream_check_module模块是Taobao定制的用 ...

  7. nginx 健康检查和负载均衡机制分析

    nginx 是优秀的反向代理服务器,这里主要讲它的健康检查和负载均衡机制,以及这种机制带来的问题.所谓健康检查,就是当后端出现问题(具体什么叫出现问题,依赖 于具体实现,各个实现定义不一样),不再往这 ...

  8. 附: K8S入门系列之集群健康检查

    Kubernetes的kubectl常用命令 1. pod操作 # 获取所有的pod kubectl get pods --all-namespaces -o wide # 使用yaml文件创建pod ...

  9. oracle 容灾库日常维护 ,健康检查脚本 以及常见问题分析

    select DEST_ID, APPLIED_SCN FROM v$archive_dest select * from v$dataguard_status; SELECT gvi.thread# ...

  10. pod资源的健康检查-liveness探针的exec使用

    使用探针的方式对pod资源健康检查 探针的种类 livenessProbe:健康状态检查,周期性检查服务是否存活,检查结果失败,将重启容器 readinessProbe:可用性检查,周期性检查服务是否 ...

随机推荐

  1. 如何使用API接口获取Lazada商品详情数据

    随着电商市场的不断发展壮大,越来越多的人开始选择在网上购买商品.其中,东南亚地区的Lazada电商平台备受欢迎.如果您是一名电商从业者,或者打算在Lazada上开店,那么获取商品详情信息将是一个非常重 ...

  2. springboot集成seata1.5.2+nacos2.1.1

    一.前言 Seata出现前,大部分公司使用的都是TCC或者MQ(RocketMq)等来解决分布式事务的问题,TCC代码编写复杂,每个业务均需要实现三个入口,侵入性强,RocketMQ保证的是最终一致性 ...

  3. Solution -「洛谷 P5048」「YunoOI 2019 模拟赛」Yuno loves sqrt technology III

    Description Link. 区间众数出现次数强制在线. Solution 三个 YLST 中比较清新的一个分块. 比较重点的地方在于询问散块的处理. 先离散化一下序列. 我们首先预处理出来一个 ...

  4. Java 21 新特性:Record Patterns

    Record Patterns 第一次发布预览是在JDK 19.随后又在JDK 20中进行了完善.现在,Java 21开始正式推出该特性优化.下面我们通过一个例子来理解这个新特性. record Po ...

  5. MPI转以太网模块连接300PLC与DCS modbus通信

    MPI转以太网模块连接300PLC与DCS modbus通信 由300PLC通过MPI转以太网Plus模块作为modbus从站与DCS主站通信实现MPI转RTU与DCS通信 打开兴达易控提供的MPI转 ...

  6. SpringBoot进阶教程(七十七)WebSocket

    WebSocket是一种在单个TCP连接上进行全双工通信的协议.WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebSocket API中,浏览器和 ...

  7. 其它——python操作kafka实践

    文章目录 1.先看最简单的场景,生产者生产消息,消费者接收消息,下面是生产者的简单代码. ------------------------------------------------------- ...

  8. MySQL系列之——MySQL体系结构、基础管理(用户、权限管理、连接管理、多种启动方式介绍、初始化配置、多实例的应用)

    文章目录 一 体系结构 1.1 C/S(客户端/服务端)模型介绍 1.2 实例介绍 1.3 mysqld程序运行原理 1.3.1 mysqld程序结构 1.3.2 一条SQL语句的执行过程 1.3.2 ...

  9. Python面向对象——封装

    文章目录 内容回顾 封装 为何要隐藏? 作业 内容回顾 上节课复习: 1.编程范式/思想 面向过程 介绍: 核心是"过程"二字 过程就是"流水线" 过程终极奥义 ...

  10. ELK-日志收集-Kibana WEB安全认证

    1.ELK收集MYSQL日志实战: 日志收集存放目录位置: /usr/local/logstash/config/etc/   1)日志采集-存入redis缓存数据库:mysql-redis.conf ...