文章目录

  • Init模式
  • 什么InitContainer?
  • Init容器“Request”和“Limits”行为
  • 应用场景01:为数据库做种
    • 如果我们没有使用 InitContainers会发生什么?
  • 场景 02:延迟应用程序启动,直到依赖项准备就绪
  • 结论:

Init模式

init逻辑在一般的编程语言中是通用的。在面向对象的编程语言中,有构造函数的概念。构造函数是一个函数(或方法),每当对象被实例化时就会调用它。构造函数的目的是为它应该做的工作“准备”对象。例如,它设置变量的默认值、创建数据库连接对象、确保存在对象正确运行的必要先决条件。例如,如果创建了一个用户对象,它至少需要用户的用户名、名字和姓氏才能正常运行。不同语言的构造函数实现不同。然而,所有这些都只被调用一次,并且只在对象实例化时调用。

初始化模式的目的是将对象与其初始化逻辑解耦。因此,如果一个对象需要将一些种子数据送入数据库,这属于构造函数逻辑而不是应用程序逻辑。这允许更改对象“启动”的方式,而不会影响它的“工作”方式。

Kubernetes 使用相同的模式。对象是面向对象语言的原子单元,而 Kubernetes 有 Pod。因此,如果应用程序在需要一些初始化逻辑的容器上运行,最好将这项工作交给另一个容器。Kubernetes 为该特定作业提供了一种容器类型:init 容器。

什么InitContainer?

在 Kubernetes 中,init 容器是在同一个 Pod 中的其他容器之前启动和执行的容器。它旨在为 Pod 上托管的主应用程序执行初始化逻辑。例如,创建必要的用户帐户、执行数据库迁移、创建数据库模式等。

initcontainer容器设计注意事项 在创建 init 容器时,应该考虑一些注意事项:

「它们总是在 Pod 中的其他容器之前执行。因此,它们不应包含需要很长时间才能完成的复杂逻辑。启动脚本通常小而简洁。如果发现向 init 容器添加了太多逻辑,则应考虑将其中的一部分移至应用程序容器本身。」

「Init 容器按顺序启动和执行。除非成功完成其前任容器,否则不会调用 init 容器。因此,如果启动任务很长,可以考虑将其分解为多个步骤,每个步骤由一个 init 容器处理,以便知道哪些步骤失败。」

「如果任何 init 容器失败,整个 Pod 将重新启动(除非将 restartPolicy 设置为 Never)。重新启动 Pod 意味着再次重新执行所有容器,包括任何 init 容器。因此,可能需要确保启动逻辑可以容忍多次执行而不会导致重复。例如,如果数据库迁移已经完成,再次执行迁移命令应该被忽略。」

「init 容器是延迟应用程序初始化直到一个或多个依赖项可用的良好候选者。例如,如果应用程序依赖于强加 API 请求速率限制的 API,可能需要等待特定时间段才能接收来自该 API 的响应。在应用程序容器中实现这个逻辑可能很复杂;因为它需要与健康和准备探测器相结合。一个更简单的方法是创建一个 init 容器,它会等待 API 准备就绪后再成功退出。只有在 init 容器成功完成其工作后,应用程序容器才会启动。」

「Init 容器不能像应用程序容器那样使用健康和就绪探测。原因是它们旨在成功启动和退出,就像 Jobs 和 CronJobs 的行为方式一样。」

「同一个 Pod 上的所有容器共享相同的 Volumes 和网络。可以利用此功能在应用程序及其初始化容器之间共享数据。」

Init容器“Request”和“Limits”行为

如以上话术,init 容器总是在同一个 Pod 上的其他应用程序容器之前启动。因此,调度程序对 init 容器的资源和限制给予更高的优先级。必须彻底考虑此类行为,因为它可能会导致不希望的结果。例如,如果你有一个 init 容器和一个应用程序容器,并且你将 init 容器的资源和限制设置为高于应用程序容器的资源和限制,那么只有在有一个满足 init 的可用节点时,整个 Pod 才会被调度容器要求。换句话说,即使有一个未使用的节点可以运行应用程序容器,如果 init 容器具有该节点可以处理的更高资源先决条件,Pod 也不会部署到该节点。因此,在定义 init 容器的请求和限制时,应该尽可能严格。作为最佳实践,除非绝对需要,否则不要将这些参数设置为高于应用程序容器的值。

应用场景01:为数据库做种

在这个场景中,我们为 MySQL 数据库提供服务。该数据库用于测试应用程序。它不必包含真实数据,但必须填充足够的数据,以便我们可以测试应用程序的查询速度。使用 init 容器来处理 SQL 转储文件的下载并将其恢复到托管在另一个容器中的数据库。这个场景可以用下图来说明:

定义Pod资源如下:

apiVersion: v1
kind: Pod
metadata:name: mydblabels:app: db
spec:initContainers:- name: fetchimage: mwendler/wgetcommand: ["wget","--no-check-certificate","https://sample-videos.com/sql/Sample-SQL-File-1000rows.sql","-O","/docker-entrypoint-initdb.d/dump.sql"]volumeMounts:- mountPath: /docker-entrypoint-initdb.dname: dumpcontainers:- name: mysqlimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "example"volumeMounts:- mountPath: /docker-entrypoint-initdb.dname: dumpvolumes:- emptyDir: {}name: dump

上面的定义创建了一个 Pod,它托管着两个容器:init 容器和应用程序容器。让我们来看看这个定义的有趣方面:

「init 容器负责下载包含数据库转储的 SQL 文件。使用 mwendler/wget 镜像,因为我们只需要 wget 命令。」

「下载的 SQL 的目标目录是 MySQL 镜像用来执行 SQL 文件的目录(/docker-entrypoint-initdb.d)。此行为内置于我们在应用程序容器中使用的 MySQL 镜像中。」

「init 容器将/docker-entrypoint-initdb.d挂载到emptyDir卷。因为两个容器都托管在同一个 Pod 上,所以它们共享相同的卷。因此,数据库容器可以访问放置在 emptyDir 卷上的 SQL 文件。」

如果我们没有使用 InitContainers会发生什么?

在这个例子中,我们使用初始化模式来建立关注点分离的最佳实践。如果我们在不使用 init 模式的情况下实现相同的逻辑,我们必须基于 mysql 基础镜像创建一个新镜像,安装 wget,并使用它来下载 SQL 文件。这种方法的缺点是:

如果需要对下载逻辑进行任何更改,我们需要创建一个新镜像,推送它并更改其在定义文件中的引用。这增加了必须维护自定义镜像的负担。
它在 DB 容器与其启动逻辑之间创建了紧密耦合的关系,这使得应用程序更难管理并增加了引入错误和错误的可能性。

场景 02:延迟应用程序启动,直到依赖项准备就绪

init 容器的另一个常见用例是当需要应用程序等待另一个服务完全运行(响应请求)时。以下定义演示了这种情况:

apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels:app: myapp
spec:initContainers:- name: init-myserviceimage: busybox:1.28command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']containers:- name: myapp-containerimage: busybox:1.28command: ['sh', '-c', 'echo The app is running! && sleep 3600']

因此,假设我们的应用程序在 myapp-container 上运行时无法正常运行,除非 myservice 应用程序正在运行。我们需要延迟 myapp 启动,直到 myservice 准备就绪。为此,我们使用一个简单的 nslookup 命令(第 11 行)不断检查“myservice”的名称解析是否成功。如果 nslookup 能够解析“myservice”,则服务将启动。使用成功退出代码,init 容器终止,让应用程序容器启动。否则,容器在再次尝试之前会休眠两秒钟,从而延迟应用程序容器的启动。

为了完整起见,这是 myservice 的定义文件:

apiVersion: v1
kind: Service
metadata:name: myservice
spec:ports:- protocol: TCPport: 80targetPort: 9376

结论:

初始化模式是设计需要启动逻辑的应用程序时要遵循的重要实践。

Kubernetes 提供 init 容器作为将应用程序逻辑与其启动过程分离的一种手段。

将应用程序初始化逻辑放在 init 容器中具有许多优点:

将强加关注点分离原则。一个应用程序可以有它的工程师团队,而它的初始化逻辑是由另一个团队编写的。

当涉及到授权和访问控制时,拥有一个单独的团队来处理应用程序的初始化步骤可以使公司更加灵活。例如,如果启动应用程序需要使用需要安全许可的资源(例如,修改防火墙规则),则可以由具有合适凭据的人员完成。应用团队不参与操作。

如果涉及的初始化步骤太多,可以将它们分解成多个 init 容器依次执行。如果一个步骤失败,init 容器会报告错误,这可以让你更好地了解逻辑的哪一部分不成功。

使用 init 容器时应考虑以下几点:

  • 初始化容器在失败时重新启动。因此,他们的代码必须是幂等的。
  • 初始化容器是请求和限制首先由调度程序检查。不正确的值可能会对调度程序关于放置整个 Pod(包括应用程序容器)的位置的决定产生负面影响。

参考:
https://www.magalix.com/blog/kubernetes-patterns-the-init-container-pattern

Kubernetes InitContainers模式相关推荐

  1. Kubernetes operator 模式开发实践

    0. 前言 近日我们在开发符合我们业务自身需求的微服务平台时,使用了 Kubernetes 的 Operator Pattern 来实现其中的运维系统,在本文,我们将实现过程中积累的主要知识点和技术细 ...

  2. 云原生 | Kubernetes - Webhook 模式

    目录 配置文件格式 请求载荷 WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求:通过 HTTP POST 发送的简单事件通知.一个基于 web 应用实现的 WebHo ...

  3. 阿里云云效技术专家:一文详解kubernetes下5种常见发布模式如何选择

    简介:Kubernetes下5场场景应用发布方式的选择,每种发布模式适合什么样的场景,以及如何在阿里云云效上高效落地. 作者:郑云龙,阿里云云效技术专家 Kubernetes面向通用场景提供了非常灵活 ...

  4. 云重磅|中西合璧 联想凌拓瓜熟蒂落;5G实锤 华为推出首部5G折叠手机;​IBM打造Kubernetes无处不在”的模式...

    戳蓝字"CSDN云计算"关注我们哦! 嗨,大家好,重磅君带来的[云重磅]特别栏目,如期而至,每周二第一时间为大家带来重磅新闻.把握技术风向标,了解行业应用与实践,就交给我重磅君吧! ...

  5. kubernetes 部署_用于Kubernetes部署的10种反模式

    kubernetes 部署 As container adoption and usage continues to rise, Kubernetes (K8s) has become the lea ...

  6. kubernetes k8s 云原生技术

    云原生 [整理总结自 CNCF × Alibaba 云原生技术公开课] [非全部内容] [图片看不到,可以去gitee上看] 文章目录 云原生 相关定义和概念 技术范畴 两个理论 云原生关键技术点 容 ...

  7. 实战4节点Centos7.3 安装Kubernetes集群

    Kubernetes集群安装部署 Kubernetes集群组件: -Master节点 - etcd 一个高可用的K/V键值对存储和服务发现系统 - kube-apiserver 提供kubernete ...

  8. 【译】A Kubernetes quick start for people who know just enough about Docker to get by

    如果你住在我们太阳系的这一侧,你可以保证以前听说过Kubernetes. 你可能不知道究竟是什么. 但那没关系. 即使你以前没有听说过,也要坚持下去并找出答案. 它会达到你的期望. 我保证Kubern ...

  9. Kubernetes的三种集群外部访问方式及使用场景说明:NodePort、LoadBalancer和Ingress

    Kubernetes的三种外部访问方式:NodePort.LoadBalancer和Ingress 最近有些同学问我 NodePort,LoadBalancer 和 Ingress 之间的区别.它们都 ...

  10. 微服务下分布式事务模式的详细对比

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 作为 Red H ...

最新文章

  1. 搭建android开发环境注意事项1
  2. springboot 源码_springboot框架源码分享
  3. cscope使用命令
  4. Hive集成HBase详解
  5. 详解log4j2(下) - 按日志级别区分文件输出
  6. 【Scala谜题】继承
  7. 一些Setup Factory 教程的链接
  8. js删除两个集合中共同元素_多个集合中的共同和独特元素
  9. 纽交所决定将蛋壳公寓ADS摘牌
  10. nginx绑定IP的坑
  11. java题1_java面试题1
  12. Linux中last的用法及参数,查看登陆系统用户的信息
  13. 如何搭建一套业务、数据一体化的数据指标体系
  14. MADlib——基于SQL的数据挖掘解决方案(24)——分类之决策树
  15. 事关男女的三十二个绝妙比喻——男女关系
  16. 仿企查查、天眼查关系图以及架构图(双向树,集团图谱,组织架构图谱,企业图谱,网络拓扑,人物关系网络)
  17. 关于Wasserstein GAN的理解
  18. 【Python】sorted函数的使用
  19. Linux 不能命令补全,Linux 命令未自动提示补全
  20. 如何排查CPU占用100%

热门文章

  1. requests使用案例 爬取信用中国
  2. coldfusion php,coldfusion在php中解密
  3. 当供应链金融遇到区块链会擦出怎样的火花?
  4. postgresql立式版本下载_【PostgreSQL下载】PostgreSQL官方版下载_多特软件站
  5. 帝国cms系统使用初级教程二(较全面)
  6. Error writing to process file pid.nbf问题
  7. Ubuntu20.04微信安装 简单 使用方便
  8. 【转载】JavaWeb之ssm框架搭建中遇到的问题
  9. 桌面点击:右键点击-显示设置,提示“该文件没有与之关联的程序来执行该操作“解决方法总结
  10. RedHat认证介绍