K8S Container解析

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 今天,我们聊一下Kubernetes Container相关话题,什么是Container?

      今天,我们聊一下Kubernetes Container相关话题,什么是Container?

      容器和虚拟机器一样,可以让我们将应用程序与依赖库及其他依附元件封装在一起,提供隔离的环境来执行软件服务。但是,对比VM而言,容器提供的是一种逻辑封装机制,能够将应用程序从实际执行所在环境中抽取出来。无论目标环境是私有云、公用云端还是我们自己的本地环境,这种分离的方式让我们可以轻松、一致地部署容器型应用程序。

      容器化提供了一种便利的分工模式,当我们开发人员专注于应用程序逻辑与依附元件时,IT 运维团队可将注意力集中到部署与管理上,而不用担心诸如特定软体版本与应用程式特定设定之类的应用程式细节。

      本文主要针对K8S生态栈中(注:我的环境为Kubernetes-1.18.15)所支持的容器类型进行解析,以及详细介绍一下不同类型容器的特性以及其使用场景。具体我们先了解下当前所支持的容器类型,具体如下所示:

      基于上述图中,我们可以看出,目前在Kubernetes 1.18 version中,已经支持4种不同类型的容器,分别为:标准容器(主容器)、Sidecar容器、Init 容器以及Ephemeral 容器等。

      下面我们针对此4种类型的容器进行简要的解析,在解析之前,我们简要了解下Pod的生命周期,毕竟,Container与Pod息息相关,相互关联,一个Pod的生命活动涉及到Container相关活动事件,具体如下所示:

      上图展示了一个Pod的完整生命周期,其中包含Init Container、Pod Hook、健康检查等 三个核心组成部分,整个Pod生命周期围绕 “ 挂起 (Pending) ”、“ 运行中 (Running) ”、“ 成功(Succeeded) ”、“ 失败(Failed) ”以及“ 未知 (Unknown) ”等状态运行,具体细节后续将会解析。我们注意到有个被称为“Pod Hook”的事件,由Kubelet发起,其在容器中的进程启动前或者容器的进程终止之前执行,我们可以同时为Pod 中的所有容器都配置Hook(钩子)。

       K8S中生态为我们提供了2种Hook函数:

       PostStart:此函数在容器创建后立即执行。主要用于资源部署、环境准备等。但是,并不能保证钩子将在容器ENTRYPOINT之前运行,因为没有参数传递给处理程序。不过需要注意的是如果钩子花费太长时间以至于不能运行或者挂起,容器将不能达到Running状态。

       PreStop:此函数在容器终止之前立即被调用。主要用于优雅关闭应用程序、通知其他系统等。其基于阻塞模型, 因此必须在删除容器的调用发出之前完成。如果钩子在执行期间挂起,Pod阶段将停留在Running状态并且永不会达到Failed状态。

      了解了Pod状态后,首先来了解下Pod中最新启动的Init Container,也就是我们平时常说的初始化容器。

Init Container-初始化容器

      Init Container是一种特殊容器,在 Pod 内的应用容器启动之前运行。Init Container 可以包括一些应用镜像中不存在的实用工具及脚本。

      Init Container作为预先型容器,主要做容器运行前的初始化工作,其可以为一个或者多个,若为多个的话,这些容器会按依据定义的规则顺序依次执行。我们知道一个Pod里面的所有容器是共享数据卷和Network Namespace的,所以Init Container里面产生的数据可以被主容器使用到。从上面的Pod生命周期的图中可以看出初始化容器是独立于主容器之外的,只有所有的初始化容器执行完之后,主容器才会被启动。

      以下为简单的示例,本例中我们将创建一个包含一个应用容器和一个 Init 容器的 Pod。Init 容器在应用容器启动前运行完成。其配置文件init-container-demo.yaml如下所示:


apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  # These containers are run during pod initialization
  initContainers:
  - name: install
    image: busybox
    command:
    - wget
    - "-O"
    - "/work-dir/index.html"
    - http://info.cern.ch
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  dnsPolicy: Default
  volumes:
  - name: workdir
    emptyDir: {}


Init 容器能做什么?

       Init 容器作为一个与应用容器分离的单独容器镜像,其天生具有如下优势:

       1、Init 容器可以包含一些安装过程中应用容器不存在的实用工具。例如,在容器运行过程中需要使用类似 sed、awk、lsof、netstat或 dig 这样的工具,以便我们能够在容器内进行各种Debug操作,那么我们可以将其放到Init容器去安装这些工具;除此之外,针对应用容器需要一些必要的目录或者配置文件甚至涉及敏感信息,就需要放到Init容器去执行,而不是在主容器执行。

       2、Init 容器可以安全地运行指定的工具,从而避免因此类工具的运行使得应用镜像的安全性降低。

       3、应用镜像的创建者和部署者可以各自独立工作,减少不必要的应用镜像的制作。

       4、Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,相对于应用容器,Init容器能够访问 Secrets 。

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

Ephemeral Container-临时容器

      临时容器,顾名思义,在当前的Pod中临时运行,完成使命后自动销毁。由于缺少对资源或执行的保证,且永远不会自动重启,因此不适用于构建应用程序,通常可借助其进行调试、问题排查等。临时容器虽然使用与常规容器相同的 ContainerSpec 节进行描述,但许多字段是不兼容且不允许。

  • 临时容器没有端口配置选项,类似Ports,LivenessProbe,ReadinessProbe 字段是不

允许的。

  • Pod 资源分配不可变,因此无法进行Resources 。
  • 允许字段的信息,可参考EphemeralContainer文档

      临时容器是使用 API 中的一种特殊的Ephemeral Containers处理器进行创建的, 而不是直接添加到 Pod.spec 段,因此无法使用 Kubectl edit 来添加一个临时容器。具体可参考:


{
    "apiVersion": "v1",
    "kind": "EphemeralContainers",
    "metadata": {
            "name": "demo-pod"
    },
    "ephemeralContainers": [{
        "command": [
            "sh"
        ],
        "image": "busybox",
        "imagePullPolicy": "IfNotPresent",
        "name": "debugger",
        "stdin": true,
        "tty": true,
        "terminationMessagePolicy": "File"
    }]
}


      我们可借助如下命令来更新已运行的临时容器 demo-pod:


[administrator@JavaLangOutOfMemory ~ ]% kubectl replace --raw /api/v1/namespaces/default/pods/demo-pod/ephemeralcontainers  -f ec.json

      基于返回临时容器的新列表,我们执行以下命令可查看新创建的临时容器的状态,具体如下所示:


[administrator@JavaLangOutOfMemory ~ ]% kubectl describe pod demo-pod


Ephemeral 容器能做什么?

      1、故障排除,若容器崩溃或镜像中未安装调试工具而导致 Kubectl Exec失效时,此时Ephemeral 器派上用场。

      2、Debug功能,借助Ephemeral 容器,我们可以对自己构建的镜像文件或者基于当前容器的需求进行调试,以帮助我们能够更快的进行监测与部署。

Sidecar Container-边车容器

      作为K8S 1.8版本内置支持SideCar容器,其所有问题都与容器生命周期相关性有关。由于Pod中的标准容器之间没有区别,因此无法控制哪个容器首先启动或最后终止,但是先正确运行Sidecar容器通常是应用程序容器正确运行的前提。

      让我们看一个Istio服务网格场景。Envoy边车负责将所有传入和传出流量代理到应用程序容器。因此,在代理启动并运行之前,应用程序应该无法发送或接收流量。此时,如果应用程序尝试出站访问,则K8S的就绪性探针便形同虚设。如果应用容器先启动,您会在日志中看到很多莫名的错误消息,明明应用已启动了,为什么还报503呢?但如果代理容器正常启动,但业务容器遭遇CrashLoopBackoffs时,应用容器根本启动失败,此时代理容器该何去何从?具体可参考如下示图:

      为了彻底解决上述痛点,从K8S 1.18版本开始,K8S内置的Sidecar功能将确保边车在正常业务流程开始之前就启动并运行,即通过更改Pod的启动生命周期,在Init容器完成后启动Sidecar容器,在Sidecar容器就绪后启动业务容器,基于启动流程保证其顺序性。具体可参考如下:

      关于Sidecar  Container使用规范,可参考以下:


apiVersion: v1
kind: Pod
metadata:
  name: bookings-v1-b54bc7c9c-v42f6
  labels:
    app: demoapp
spec:
  containers:
  - name: bookings
    image: banzaicloud/allspark:0.1.1
    ...
  - name: istio-proxy
    image: docker.io/istio/proxyv2:1.4.3
    lifecycle:
      type: Sidecar
    ...

      基于上述配置,我们需要将Pod规范中的container.lifecycle.type将容器标记为边车类型:Sidecar,默认为Standard。目前,在K8S的1.18版本,Sidecar模式仅仅作为支撑功能,故需要通过Api Server显示启用。

Sidecar容器能做什么呢?

      1、加速应用开发,基于敏捷模式。

      2、关注点分离,并专注于特定功能。

      对于Sidecar Container,目前主要应用于“完全的微服务”服务网格体系中,其主要体现在以下4种角色,具体如下图所示:

  • 代理,以Istio中的Envoy组件为例。

      通过这种Sidercar 模式,代理可以拦截进出主容器的流量从而Istio可以提取有关流量行为的大量信号作为属性。Istio可以使用这些属性来执行策略决策,并将其发送到监视系统以提供有关整个网格行为的信息。

  • 适配器。适配器容器对输出进行标准化。考虑监视N个不同应用程序的任务。可以使用

不同的导出监视数据的方式来构建每个应用程序。

  • 增强主容器功能。Sidecar容器扩展并增强了“主”容器,它们可以使用现有的容器并使

它们变得更好。

  • 实现辅助功能 。这种场景一般出现在DevOps中。比如将收集日志的组件以Sidecar的

方式部署,实现收集日志的用途,或是部署一个Sidecar组件从配置中心监听配置变化,实时更新本地配置。

Standard Container-标准容器

      在K8S生态系统1.18版本之前,这两种容器从管理角度来讲,并没有本质区别,只不过基于不同的场景而定义相关属性及行为。具体可参考如下所示:


      至此,关于Kubernetes 1.8版本中的4种类型的Container解析到此为止,大家有什么问题或者建议,欢迎随时留言沟通。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
24天前
|
弹性计算 Kubernetes 安全
Kubernetes 的架构问题之在Serverless Container中保障应用的安全防护如何解决
Kubernetes 的架构问题之在Serverless Container中保障应用的安全防护如何解决
143 8
|
9天前
|
Kubernetes API 调度
Kubernetes 架构解析:理解其核心组件
【8月更文第29天】Kubernetes(简称 K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用。它提供了一个可移植、可扩展的环境来运行分布式系统。本文将深入探讨 Kubernetes 的架构设计,包括其核心组件如何协同工作以实现这些功能。
26 0
|
15天前
|
存储 Kubernetes 调度
在K8S中,⼀个pod的不同container能够分开被调动到不同的节点上吗?
在K8S中,⼀个pod的不同container能够分开被调动到不同的节点上吗?
|
24天前
|
弹性计算 Kubernetes Serverless
Kubernetes 的架构问题之ACK/ASK支持ECI的Serverless Container如何解决
Kubernetes 的架构问题之ACK/ASK支持ECI的Serverless Container如何解决
68 7
|
24天前
|
弹性计算 Kubernetes Serverless
Kubernetes 的架构问题之Serverless Container中不支持特权模式的问题如何解决
Kubernetes 的架构问题之Serverless Container中不支持特权模式的问题如何解决
66 6
|
24天前
|
Kubernetes 安全 Serverless
Kubernetes 的架构问题之Serverless Container中提供对外服务如何解决
Kubernetes 的架构问题之Serverless Container中提供对外服务如何解决
61 5
|
24天前
|
运维 Kubernetes 大数据
Kubernetes 的架构问题之在Serverless Container场景下尚不支持资源超售如何解决
Kubernetes 的架构问题之在Serverless Container场景下尚不支持资源超售如何解决
52 0
|
15天前
|
Kubernetes 负载均衡 网络协议
在K8S中,DNS组件有什么特性?
在K8S中,DNS组件有什么特性?
|
19天前
|
消息中间件 Kubernetes 数据库
在k8S中,初始化容器(init container)概念原理是什么?
在k8S中,初始化容器(init container)概念原理是什么?
|
19天前
|
存储 Kubernetes 网络协议
在K8s中,提供的DNS组件是什么?有什么特性?
在K8s中,提供的DNS组件是什么?有什么特性?

热门文章

最新文章

推荐镜像

更多
下一篇
DDNS