一.系统环境

服务器版本 docker软件版本 Kubernetes(k8s)集群版本 CPU架构
CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 x86_64

Kubernetes集群架构:k8scloude1作为master节点,k8scloude2,k8scloude3作为worker节点

服务器 操作系统版本 CPU架构 进程 功能描述
k8scloude1/192.168.110.130 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master节点
k8scloude2/192.168.110.129 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点
k8scloude3/192.168.110.128 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点

二.前言

本文介绍初始化容器Init Containers,初始化容器Init Containers是一种特殊容器,在 Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。你可以在 Pod 的规约中与用来描述应用容器的 containers 数组平行的位置指定 Init 容器。

创建pod的前提是已经有一套可以正常运行的Kubernetes集群,关于Kubernetes(k8s)集群的安装部署,可以查看博客《Centos7 安装部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/16686769.html

三.初始化容器Init Containers

3.1 何为初始化容器Init Containers

每个 Pod 中可以包含多个容器, 应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。Init 容器与普通的容器非常像,除了如下两点:

  • 它们总是运行到完成。
  • 每个都必须在下一个启动之前成功完成。

如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 然而,如果 Pod 对应的 restartPolicy 值为 "Never",并且 Pod 的 Init 容器失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。

为 Pod 设置 Init 容器需要在 Pod 规约中添加 initContainers 字段, 该字段以 Container 类型对象数组的形式组织,和应用的 containers 数组同级相邻。 Init 容器的状态在 status.initContainerStatuses 字段中以容器状态数组的格式返回 (类似 status.containerStatuses 字段)。

3.2 Init Containers与普通容器的不同之处

Init 容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。 然而,Init 容器对资源请求和限制的处理稍有不同,同时 Init 容器不支持 lifecycle、livenessProbe、readinessProbe 和 startupProbe, 因为它们必须在 Pod 就绪之前运行完成。

如果为一个 Pod 指定了多个 Init 容器,这些容器会按顺序逐个运行。 每个 Init 容器必须运行成功,下一个才能够运行。当所有的 Init 容器运行完成时, Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。

3.3 Init 容器优点

因为 Init 容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:

  • Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。 例如,没有必要仅为了在安装过程中使用类似 sed、awk、python 或 dig 这样的工具而去 FROM 一个镜像来生成一个新的镜像。

  • 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。

  • 与同一 Pod 中的多个应用容器相比,Init 容器能以不同的文件系统视图运行。因此,Init 容器可以被赋予访问应用容器不能访问的 Secret 的权限。

  • 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。 一旦前置条件满足,Pod 内的所有的应用容器会并行启动。

  • Init 容器可以安全地运行实用程序或自定义代码,而在其他方式下运行这些实用程序或自定义代码可能会降低应用容器镜像的安全性。 通过将不必要的工具分开,你可以限制应用容器镜像的被攻击范围。

3.4 创建初始化容器Init Containers

创建一个pod,initContainers指定初始化容器,command: ["sh","-c","sleep 15"]表示初始化容器需要休眠15秒

[root@k8scloude1 pod]# vim initcontainer.yaml 

[root@k8scloude1 pod]# cat initcontainer.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: initc
name: initc
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: n1
resources: {}
initContainers:
- name: initc
image: nginx
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 15"]
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {} [root@k8scloude1 pod]# kubectl apply -f initcontainer.yaml
pod/initc created

查看pod可以发现,初始化容器休眠了15秒之后,才执行应用容器。

[root@k8scloude1 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
initc 0/1 Init:0/1 0 1s [root@k8scloude1 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
initc 0/1 Init:0/1 0 15s [root@k8scloude1 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
initc 0/1 PodInitializing 0 17s [root@k8scloude1 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
initc 1/1 Running 0 18s

3.5 使用初始化容器,修改内核参数

在容器里修改内核参数,实际上修改的就是物理机的内核参数,为了安全性,一般不允许在容器里修改内核参数,seccom控制了容器能做哪些操作,添加securityContext参数之后就可以修改内核参数了。

创建一个pod,initContainers初始化容器里的securityContext:privileged: true表示该容器具有特权,可以执行命令"sh","-c","/sbin/sysctl -w vm.swappiness=0",vm.swappiness设置为0表示尽量少使用swap内存。

[root@k8scloude1 pod]# vim initcontainer2.yaml 

[root@k8scloude1 pod]# cat initcontainer2.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: initc
name: initc
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: n1
resources: {}
initContainers:
- name: initc
image: alpine
imagePullPolicy: IfNotPresent
command: ["sh","-c","/sbin/sysctl -w vm.swappiness=0"]
securityContext:
privileged: true
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {} [root@k8scloude1 pod]# kubectl apply -f initcontainer2.yaml
pod/initc created [root@k8scloude1 pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
initc 1/1 Running 0 7s #可以看到pod运行在k8scloude2节点
[root@k8scloude1 pod]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
initc 1/1 Running 0 22s 10.244.112.147 k8scloude2 <none> <none>

查看k8scloude2机器的swappiness ,此时k8scloude2机器上的swappiness变为了0,swappiness修改为0之后,nginx容器才可以运行

[root@k8scloude2 ~]# cat /proc/sys/vm/swappiness
0

注意:在k8s中,每一个pod都会有一个掩藏的初始化容器pause

创建一个普通的Nginx pod

[root@k8scloude1 pod]# vim nginx.yaml 

#kind: Pod表示资源类型为Pod   labels指定pod标签   metadata下面的name指定pod名字   containers下面全是容器的定义
#image指定镜像名字 imagePullPolicy指定镜像下载策略 containers下面的name指定容器名
#resources指定容器资源(CPU,内存等) env指定容器里的环境变量 dnsPolicy指定DNS策略
#restartPolicy容器重启策略 ports指定容器端口
[root@k8scloude1 pod]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: xx
value: "12"
- name: yy
value: "21"
- name: zz
value: hello
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {} [root@k8scloude1 pod]# kubectl apply -f nginx.yaml
pod/nginx created #pod运行在k8scloude2机器
[root@k8scloude1 pod]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 10s 10.244.112.148 k8scloude2 <none> <none>

通过在k8scloude2机器上执行docker ps | grep nginx,可以看到初始化容器pause

#这是pause镜像
[root@k8scloude2 ~]# docker images | grep pause
registry.aliyuncs.com/google_containers/pause 3.4.1 0f8457a4c2ec 12 months ago 683kB [root@k8scloude2 ~]# docker ps | grep nginx
d00a5991dd5b 605c77e624dd "/docker-entrypoint.…" 27 seconds ago Up 27 seconds k8s_nginx_nginx_pod_8aaab455-5e27-4c65-815d-2a23f76e758b_0
595918a44478 registry.aliyuncs.com/google_containers/pause:3.4.1 "/pause" 28 seconds ago Up 27 seconds k8s_POD_nginx_pod_8aaab455-5e27-4c65-815d-2a23f76e758b_0

pod(六):初始化容器Init Containers的更多相关文章

  1. k8s中初始化容器(init container)的作用及其使用方法

    概述 在容器的部署过程中,有的时候需要在容器运行之前进行一些预配置的工作,比如下载配置,判断某些服务是否启动,修改配置等一些准备的工作,想要实现这些功能,在k8s中可以使用初始化容器,在应用容器运行之 ...

  2. 十、Pod的init containers

    Pod 的 init Containers Pod 我们可以分为两类,一种属于自主式 Pod ,还有一种属于控制器管理的 Pod . 一.Pod 的 initContainers 基本概念: ​Pod ...

  3. k8s家族Pod辅助小能手Init容器认知答疑?

    k8s家族Pod辅助小能手Init容器认知答疑? k8s集群Init 容器是一种特殊容器,职责是在Pod的生命周期中作为应用容器的前置启动容器. 在很多应用场景中,在 Pod 内的应用容器正式启动之前 ...

  4. Init Container(初始化容器)

    在很多应用场景中,应用在启动之前都需要进行如下初始化操作. ◎ 等待其他关联组件正确运行(例如数据库或某个后台服务). ◎ 基于环境变量或配置模板生成配置文件. ◎ 从远程数据库获取本地所需配置,或者 ...

  5. kubernetes之初始容器(init container)

    系列目录 理解初始容器 一个pod里可以运行多个容器,它也可以运行一个或者多个初始容器,初始容器先于应用容器运行,除了以下两点外,初始容器和普通容器没有什么两样: 它们总是run to complet ...

  6. kubernetes 健康检查和初始化容器

    Pod-hook:postStart:1.$ $ vim preStart-hook.yaml---apiVersion: v1kind: Podmetadata:  name: hook-demo1 ...

  7. Kubernetes的初始化容器initContainers

    initContainers是一种专用的容器,在应用程序容器启动之前运行,可以包括一些应用程序镜像中不存在的实用工具和安装脚本,可以完成应用的必要数据初始化等工作.总的来说就是在正式的容器启动之前做一 ...

  8. 【三】Kubernetes学习笔记-Pod 生命周期与 Init C 介绍

    一.容器生命周期 Init C(初始化容器)只是用于 Pod 初始化的,不会一直随着 Pod 生命周期存在,Init C 在初始化完成之后就会死亡. 一个 Pod 可以有多个 Init C,也可以不需 ...

  9. Docker入门(三):容器(Containers)

    这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...

  10. 一个容器多个进程,一个pod多个容器

    一个容器多个进程:在Docker的镜像编译脚本Dockerfile中带起多个进程,如下可以在contivNet.sh中启动多个进程 FROM 10.37.210.125:5001/suning/cen ...

随机推荐

  1. Pandas选择与索引

    Series和DataFrame对象与Numpy数组和标准Python字典的数据索引和选择模式一样. 字典形式选择和索引 Series In [1]: import pandas as pd In [ ...

  2. js实现电子白板

    功能:使用画笔绘制笔迹(线条).橡皮檫 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  3. idea无法解析目录@/xxx

    显示错误如下 解决办法 vite.config.js 中添加配置,配置'@'的别名 import { fileURLToPath, URL } from 'node:url' // https://v ...

  4. CentOS 防火墙配置实战精要

    防火墙是服务器最重要的安全屏障,正确的操作对应用也是非常非常关键,本文参考了一些实战经验并经过实验验证,集众家之长做了简单的归纳整理,希望能帮助你更好地操作防火墙. 设置CentOS防火墙开放端口 在 ...

  5. 混合app 解决常见bug弹出键盘返回出现闪屏

    前言 在我们开发混合app中,我们会发现一个问题,那就是比如我们正在输入信息的时候,然后我们按导航的返回键返回,因为切页面和回收键盘是同时的,给人一种闪屏的感觉,那么怎么解决呢? 方案 以ionic为 ...

  6. 争论不休的一个话题:金额到底是用Long还是BigDecimal?

    在网上一直流传着一个争论不休的话题:金额到底是用Long还是用BigDecimal?这个话题一出在哪都会引起异常无比激烈的讨论.... 比如说这个观点:算钱用BigDecimal是常识 有支持用Lon ...

  7. node统计指定文件夹内代码行数

    1. 来源 想对于自己接触前端日常学习与思考的代码行数进行一个统计,看自己大约敲了多少代码 2.代码 const fs = require('fs') const path = require('pa ...

  8. 阿里云原生应用安全防护实践与 OpenKruise 的新领域

    简介: 得益于 Kubernetes 面向终态的理念,云原生架构天然具备高度自动化的能力.然而,面向终态的自动化是一把"双刃剑",它既为应用带来了声明式的部署能力,同时也潜在地会将 ...

  9. 作业帮基于 DeltaLake 的数据湖建设最佳实践

    ​简介:作业帮是一家以科技为载体的在线教育公司,其大数据中台作为基础系统中台,主要负责建设公司级数仓,向各个产品线提供面向业务主题的数据信息.本文主要分享了作业帮基于 DeltaLake 的数据湖建设 ...

  10. Flow vs Jenkins 实操对比,如何将Java应用快速发布至ECS

    ​简介:Jenkins 由于其开源特性以及丰富插件能力,长久以来都是中小企业搭建 CICD 流程的首选.不过 Jenkins 存在维护成本高.配置复杂等缺点,云效 Flow 较好地解决了这些问题. 本 ...