
📅 2021-06-29
容器运行时在调用CNI插件创建容器网络时,CNI插件需要为容器网络接口分配和维护一个IP地址,并配置该网络接口所需要的路由,着给了CNI插件很大的灵活性,但也给它们带来了很大负担。
许多CNI插件需要重复编写相同的代码来支持用户可能需求的集中IP管理方案(如:dhcp, host-local)。为了减轻第三方CNI插件的编写负担,将IP管理功能独立出来,CNI规范定义了第二种插件类型
IP Address Management插件(IPAM插件)
。这样,CNI插件就可以在执行过程中需要的时候直接调用相应的IPAM插件,由IPAM插件负责确定IP/子网、网关、路由并将这些信息返回到主CNI插件中。
IPAM插件可以从协议(例如DHCP)、本地文件系统存储的数据、网络配置文件中的ipam
,或者以上这些方式的组合中来获取IP/子网、网关、路由等信息。
...📅 2021-06-27
本节来学习CNI的网络配置。
CNI网络配置(Network Configuration)
#
CNI的网络配置是JSON格式的,可以是存储在磁盘中的文件,也可以由容器运行时以其他方式生成。
下面是cni json配置文件中的一些重要字段:
cniVersion
(string): 描述cni配置遵循的cni规范版本(版本号为语义化版本,如0.4.0)name
(string): 表示network name,在主机(或其他管理域)上的所有容器中应该是唯一的type
(string): 表示cni插件的可执行文件名args
(dictionary, optional): 由容器运行时提供的可选参数。例如,可以通过将标签添加到args下的标签字段,将标签字典传递给CNI插件ipMasq
(boolean, optional): 如果插件支持此字段,将为这个网络上的主机设置一个ip伪装(ip masquerade)。如果主机将充当分配给容器的子网的网管,那么这个配置字段是必须的ipam
(boolean, optional): 包含具体IPAM(IP地址管理)值的键值对type
(string) 表示ipam插件的可执行文件名,如dhscp
, host-local
, static
dns
(dictionary, optional): 包含具体DNS配置的键值对nameservers
(list of strings, optional): 一个对配置网络可见的按优先级顺序排列的dns服务器列表,列表中的每个值是一个IPV4或IPV6的字符串domain
(string, optional): 用于短主机名查找的本地域名search
(list of strings, optional): 用于短主机名查找的优先级排序搜索域列表,被大多数解析器(resolver)在解析时优先于domain
options
(list of strings, optional): 一组可以传递给解析器(resolver)的选项值
cni网络的JSON配置除了上面这些标准字段外,某个具体的插件还可以定义自己的附加字段,但如果配置了插件未定义的字段将会报错。args
中配置的附加字段可以用来传递任意数据,如果插件不认识args中传递的字段,将会直接忽略而不会报错。
...📅 2021-06-25
kubeadm是Kubernetes官方提供的用于快速安部署Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,kubeadm会对集群配置方面的一些实践做调整,通过实验kubeadm可以学习到Kubernetes官方在集群配置上一些新的最佳实践。
...📅 2021-06-23
CNI(容器网络接口)是云原生计算基金会(CNCF)的一个项目,它定义了一个规范,同时提供了一个Go语言的库(Library),用于开发在Linux容器中配置网络接口的插件,CNI项目还内置提供了一系列受支持的插件。
CNI只关心容器创建时的网络分配,以及当容器被删除时已经分配网络资源的释放。 CNI作为容器网络的标准,使得各个容器管理平台可以通过相同的接口调用各种各样的网络插件来为容器配置网络。
...📅 2021-06-13
通过上节内容的学习,nerdctl在启动容器时连接的网络默认是bridge,除此之外还可以使用--net
选项指定其他网络模式。
1--network value, --net value Connect a container to a network ("bridge"|"host"|"none") (default: "bridge")
从nerdctl命令的帮助中给出了使用--net
选项指定启动容器时连接的网络,默认是brdige
,另外还可以选择none
和host
。
因为容器连接的网络是由CNI插件实现的,所以除了bridge
, host
, none
这3个选项外,还可以指定手动添加的CNI配置。
下面分别看一下这几种不同的网络。
...📅 2021-06-12
从本节开始学习容器网络,根据前面已经学习过的内容,单机模式下使用容器的最佳组合是nerdctl+containerd+buildkit,这套组合已经可以在本地开发、测试和单机容器部署方面替代docker了。关于容器网络的学习,就先从nerdctl启动容器的创建的brdige网络开始吧。
...📅 2021-06-11
前面已经完成了rootless模式下buildkitd的二进制部署,本节将buildkitd部署到k8s集群中。
具体的环境信息k8s集群版本1.20.7,服务器系统CentOS 7.9,Jenkins Master通过使用kubernetes-plugin使运行job的jenkins slave(pod)在k8s集群上的jenkins namespace内动态创建。
...📅 2021-06-10
本节做一个实战的练习,使用buildkit完成容器镜像的远程构建,即实现本地的buildctl客户端远程请求服务器上的buildkitd完成一个容器镜像的构建并推送到镜像仓库中。
部署buildkitd服务端, 暴露为TCP服务
#
下面将在服务器上以二进制的形式部署服务端buildkitd,并将其gRPC API以TCP服务的形式暴露出来。
此处在部署buildkitd的时候是以具备生产环境可用为目的,为了安全性会以rootless的形式启动buildkitd,同时为gRPC Server和Client生成TLS证书,开启TLS认证以保障服务的安全。
...📅 2021-06-09
本节一起看一下都有哪些可用于构建容器镜像的工具和方案。可能你会疑问,构建镜像不就是使用docker build
就可以吗,即使将来docker真的退出历史舞台,不还有containerd吗,前面第5节的时候也介绍了在containerd下可以使用nerdctl+buildkit构建容器镜像。
如果你只是在单机本地构建镜像的话,使用docker build
或nerdctl+containerd+buildkit
确实没有问题,但实际中由于不同场景和技术背景下的限制,如docker build
依赖于docker daemon
,这些限制使得在一些特殊的场景下本机构建镜像的方式不再可用。
...📅 2021-06-03
前面学习了容器运行时containerd的基本使用,containerd的架构,namespace, cgroup, rootfs等容器背后的技术。
本节做一个阶段性的小节。此时,如果有人问"容器是什么?",我们可能会给出以下的回答:
- 容器实际上是一种特殊的进程。它使用namespace进行隔离,使用cgroup进行资源限制,并且它还以联合文件系统的形式挂载了单独的rootfs。
- 为了更方便的准备运行容器所需的资源和管理容器的生命周期,还需要容器引擎如containerd。
- 容器镜像实际上就是一种特殊的文件系统,它包含容器运行所需的程序、库、资源配置等所有内容,构建后内容保持不变。在启动容器时镜像会挂载为容器的rootfs。
既然容器仅仅是一种特殊的进程,下面我们实际去探索一下它的存在。继续前面启动的redis容器为例,可以使用nerdctl inspect <container id>
和ctr c info <container id>
查看一下容器的信息。
下面的命令可以打印出容器在宿主机上的进程id:
...