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.path 和 readinessProbe.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. LDAP:如何在windows系统下安装LDAP及连接测试

    1.LDAP介绍 LDAP是一个基于X.500标准的轻量目录访问协议,与X.500不同,LDAP协议支持TCP/IP连接.全称为Lightweight Directory Access Protoco ...

  2. [ABC145E] All-you-can-eat

    2023-02-25 题目 题目传送门 翻译 翻译 难度&重要性(1~10):5 题目来源 AtCoder 题目算法 背包dp 解题思路 设 \(dp_i\) 为最后一道菜在第 \(i\) 时 ...

  3. Vue3 中 keepAlive 如何搭配 VueRouter 来更自由的控制页面的状态缓存?

    在 vue 中,默认情况下,一个组件实例在被替换掉后会被销毁.这会导致它丢失其中所有已变化的状态--当这个组件再一次被显示时,会创建一个只带有初始状态的新实例.但是 vue 提供了 keep-aliv ...

  4. 【Hexo】插件推荐以及使用小技巧

    目录 插件推荐 hexo-deployer-git hexo-word-counter hexo-abbrlink hexo-generator-sitemap 小技巧 自定义提交信息 参考资料 He ...

  5. 《SQL与数据库基础》23. 读写分离

    目录 读写分离 一主一从 准备 配置 双主双从 准备 配置 主库配置 从库配置 从库关联主库 主库相互复制 双主双从读写分离 本文以 MySQL 为例.以 MyCat 数据库中间件为例,通过 MyCa ...

  6. ECharts图表动态修改series显示隐藏

    目录 1.前言 2.思路 3.实现 1.前言 最近做的大数据平台,里面很多地方用到了ECharts,其中有个功能,要求将图表分组,根据用户选择的组,来确定ECharts要显示那些线条和柱子,也就是动态 ...

  7. 如何使用关键词搜索API接口获取到快手的商品

    如果您想使用关键词搜索API接口获取到快手的商品,可以通过以下步骤实现: 1. 首先注册账号.根据文档申请相应的接口权限. 2. 确定需要使用的API接口.对于商品搜索,您可以查看相关的API文档以获 ...

  8. H.265+SRS6.0服务器部署

    H.265+SRS6.0服务器部署 SRS从6.0开始,全面支持H.265,包括RTMP.FLV.HLS.GB28181.WebRTC等等.具体的服务器部署及H.265推流步骤如下. 1. SRS 要 ...

  9. 给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

    之前有写过一篇有关maven插件的文章:spring-boot-maven-plugin插件详解 一.需求背景 我们知道Spring Boot项目,是可以通过java -jar 包名 启动的. 那为什 ...

  10. 「codeforces - 1720」

    壹 最近 cq 情况很急急,昨天出去排核酸整了两个半小时,十分无语.提前放假自然是一大好事,但是一个人在家也蛮无聊.不要再涨体重了为好,这一年间他妈 delta 了 10 kilos,算了下 BMI ...