k8s进阶3-容器

一 容器镜像

容器镜像

在 Kubernetes 的 Pod 中使用容器镜像之前,您必须将其推送到一个镜像仓库(或者使用仓库中已经有的容器镜像)。在 Kubernetes 的 Pod 定义中定义容器时,必须指定容器所使用的镜像,容器中的 image 字段支持与 docker 命令一样的语法,包括私有镜像仓库和标签。

容器镜像1.png

  • 蓝色部分:registry 地址

  • 绿色部分:registry 端口

  • 紫色部分:repository (仓库)名字

  • 红色部分:image (联合文件系统)名字

  • 棕色部分:image 标签

如果您使用 hub.dokcer.com Registry 中的镜像,可以省略 registry 地址和 registry 端口。例如:nginx:latest,eipwork/kuboard

二 Runtimeclass

参考网址:https://www.sohu.com/a/386647109_120342237

1 出现的原因:
随着越来越多的容器运行时的出现,不同的容器运行时也有不同的需求场景,于是就有了多容器运行时的需求。但是,如何来运行多容器运行时还需要解决以下几个问题:

  • 集群里有哪些可用的容器运行时?

  • 如何为 Pod 选择合适的容器运行时?

  • 如何让 Pod 调度到装有指定容器运行时的节点上?

  • 容器运行时在运行容器时会产生有一些业务运行以外的额外开销,这种「额外开销」需要怎么统计?

2 RuntimeClass 的工作流程
Runtimeclass截图1.png

下面以 v1.16 版本为例,讲解一下 RuntimeClass 的工作流程。如上图所示,左侧是它的工作流程图,右侧是一个 YAML 文件。

YAML 文件包含两个部分:上部分负责创建一个名字叫 runv 的 RuntimeClass 对象,下部分负责创建一个 Pod,该Pod 通过 spec.runtimeClassName 引用了 runv 这个 RuntimeClass。

RuntimeClass 对象中比较核心的是 handler,它表示一个接收创建容器请求的程序,同时也对应一个容器运行时。比如示例中的 Pod 最终会被 runv 容器运行时创建容器;scheduling 决定 Pod 最终会被调度到哪些节点上。

结合左图来说明一下 RuntimeClass 的工作流程:

K8s-master 接收到创建 Pod 的请求;
方格部分表示三种类型的节点。
每个节点上都有 Label 标识当前节点支持的容器运行时,节点内会有一个或多个 handler,每个 handler 对应一种容器运行时。
比如第二个方格表示节点内有支持 runcrunv两种容器运行时的 handler;第三个方格表示节点内有支持 runhcs 容器运行时的 handler;

根据 scheduling.nodeSelector, Pod 最终会调度到中间方格节点上,并最终由 runv handler 来创建 Pod。

3 RuntimeClass 功能介绍
RuntimeClass 的结构体定义
Runtimeclass截图2.png

1个 RuntimeClass 对象代表了一个容器运行时,它的结构体中主要包含 Handler、Overhead、Scheduling 三个字段。

  • Handler,它表示一个接收创建容器请求的程序,同时也对应一个容器运行时;

  • Overhead 它表示 Pod 中的业务运行所需资源以外的额外开销; 是 v1.16 中才引入的一个新的字段。

  • Scheduling 也是在 v1.16 中被引入的,该 Scheduling 配置会被自动注入到 Pod 的 nodeSelector 中。

4-RuntimeClass 资源定义例子

Runtimeclass截图3.pngRuntimeclass截图4.png

在 Pod 中引用 RuntimeClass 的用法非常简单
只要在 runtimeClassName 字段中配置好 RuntimeClass 的名字,就可以把这个 RuntimeClass 引入进来。

Scheduling 结构体的定义
顾名思义,Scheduling 表示调度,但这里的调度不是说 RuntimeClass 对象本身的调度,而是会影响到引用了 RuntimeClass 的 Pod 的调度。
Scheduling 结构体的定义4.png

5 基本原理:

  • RuntimeClass 是 Kubernetes 一种内置的集群资源,主要用来解决多个容器运行时混用的问题;

  • RuntimeClass 中配置 Scheduling 可以让 Pod 自动调度到运行了指定容器运行时的节点上。但前提是需要用户提前为这些 Node 设置好 label;

  • RuntimeClass 中配置 Overhead,可以把 Pod 中业务运行所需以外的开销统计进来,让调度、ResourceQuota、Kubelet Pod 驱逐等行为更准确

三 Runittimeclass使用

1 在节点上配置 CRI
如需通过RuntimeClass进行配置,是依赖于 Container Runtime Interface(CRI)的具体实现的。

  • 配置 CRI 时,请留意其 handler 名称(该名称是有 字符/数字 和 - 组成的字符串),RuntimeClass中将引用该名称。

通过 containerd 的配置文件 配置其 Runtime handler。

vim  /etc/containerd/config.toml 
[plugins.cri.containerd.runtimes.${HANDLER_NAME}]

通过 cri-o 的配置文件配置 Runtime handler

vim /etc/crio/crio.conf
[crio.runtime.runtimes.${HANDLER_NAME}]
  runtime_path = "${PATH_TO_BINARY}"

2 创建对应的 RuntimeClass
在前面的步骤中完成了配置之后,每个配置都会有一个 handler 名称,用来唯一地标识该 CRI 的配置。此时,我们需要为每一个 handler 创建一个对应的 RuntimeClass api 对象。

RuntimeClass 目前只有两个主要的字段:

RuntimeClass name(metadata.name) handler (handler)
该对象的定义如下所示:

apiVersion: node.k8s.io/v1beta1
kind: RuntimeClass
metadata:
  name: myclass # RuntimeClass 没有名称空间
handler: myconfiguration  # 对应 CRI 配置的 handler 名称

3-使用
为集群完成 RuntimeClass 的配置后,使用的时候会非常简单。在 Pod 的定义中指定 runtimeClassName 即可,例如:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  runtimeClassName: myclass

kubelet 将依据这个字段使用指定的 RuntimeClass 来运行该 Pod。如果指定的 RuntimeClass 不存在,或者 CRI 不能运行对应的 handler 配置,则 Pod 将进入 Failed 这个终止 阶段。此时可通过 Pod 中的 Event(事件)来查看具体的出错信息。

如果 Pod 中未指定 runtimeClassName,kubelet 将使用默认的 RuntimeHandler 运行 Pod,其效果等价于 RuntimeClass 这个特性被禁用的情况。

四 容器的网络插件背景

容器网络是容器选择连接到其他容器、主机和外部网络(如Internet)的机制。容器的Runtime提供了各种网络模式,每种模式都会产生不同的体验。

例如,Docker默认情况下可以为容器配置以下网络:

  • none:将容器添加到一个容器专门的网络堆栈中,没有对外连接。

  • host:将容器添加到主机的网络堆栈中,没有隔离。

  • default bridge:默认网络模式。每个容器可以通过IP地址相互连接。

  • 自定义网桥:用户定义的网桥,具有更多的灵活性、隔离性和其他便利功能。