5.2 kubernetes runtime部署及维护
目录
01.介绍
kubernetes runtime一般是指容器生命周期的管理, 早起kubelet在创建容器的时候直接调用docker daemon, docker daemon调用自己的libcontainer就可以把容器启动起来, 但是随着后续rkt的加入出现了很多兼容性的问题, Container Runtime Interface(CRI)即程序运行时接口就这样出生了, 后续接入的runtime按照CRI的接口实现就可以了, 启动容器的过程中需要根据Open Container Initiative(OCI)即开放容器标准中的有关规定进行启动, 目前比较稳定的还是Docker并且Dockershim 核心代码依然保留在 kubelet 内部是最稳定和特性支持最好的运行时
目前官方文档中支持的如下:
OCI
OCI的runtime spec标准中对于容器的状态描述,以及对于容器的创建、删除、查看等操作进行了定义。 目前包括两个标准容器运行时标准和容器镜像标准, 简单的来说就是创建镜像的标准和运行容器的标准,
-
容器镜像标准
文件系统: 以layer保存的文件系统,每个layer保存了和上层之间变化的部分,layer应该保存哪些文件,怎么表示增加、修改和删除的文件等
config文件: 保存了文件系统的层级信息(每个层级的hash值,以及历史信息)以及容器运行时需要的一些信息(比如环境变量、工作目录、命令参数、mount 列表)
manifest文件: 镜像的config文件索引,有哪些layer,额外的annotation信息,manifest文件中保存了很多和当前平台有关的信息
index文件: 可选的文件,指向不同平台的manifest文件,这个文件能保证一个镜像可以跨平台使用,每个平台拥有不同的manifest文件,使用index作为索引
-
容器运行时标准
ociVersion: OCI版本
id: 容器的ID,在宿主机唯一
status: 容器运行时状态,生命周期
- creating: 使用 create 命令创建容器,这个过程称为创建中,创建包括文件系统、namespaces、cgroups、用户权限在内的各项内容
- created: 容器创建出来,但是还没有运行,表示镜像和配置没有错误,容器能够运行在当前平台
- running: 容器的运行状态,里面的进程处于up状态,正在执行用户设定的任务
- stopped: 容器运行完成,或者运行出错或者stop命令之后,容器处于暂停状态,这个状态,容器还有很多信息保存在平台中,并没有完全被删除
pid: 容器进程在宿主机的进程ID
bundle: 容器文件目录,存放容器rootfs及相应配置的目录
annotations: 与容器相关的注释
CRI
容器运行时插件(Container Runtime Interface,简称 CRI)容器运行时接口, 其中包括容器运行时和镜像的管理两个grpc接口, Kubelet 作为 CRI 的客户端,而容器运行时则需要实现 CRI 的服务端(即 gRPC server,通常称为 CRI shim)。容器运行时在启动 gRPC server 时需要监听在本地的 Unix Socket, 具体请看下图:
简单的来说就是容器的编排API调用CRI, CRI调用OCI启动容器
02.使用docker作为k8s runtime 时的启动流程
当kubelet要创建一个容器时,需要以下几步:
- Kubelet 通过 CRI 接口(gRPC)调用 dockershim,请求创建一个容器。CRI 即容器运行时接口(Container Runtime Interface),这一步中,Kubelet 可以视作一个简单的 CRI Client,而 dockershim 就是接收请求的 Server。目前 dockershim 的代码其实是内嵌在 Kubelet 中的,所以接收调用的凑巧就是 Kubelet 进程;
- dockershim 收到请求后,转化成 Docker Daemon 能听懂的请求,发到 Docker Daemon 上请求创建一个容器。
- Docker Daemon 请求 containerd 创建一个容器;
- containerd 收到请求后,并不会自己直接去操作容器,而是创建一个叫做 containerd-shim 的进程,让 containerd-shim 去操作容器。这是因为容器进程需要一个父进程来做诸如收集状态,维持 stdin 等 fd 打开等工作。而假如这个父进程就是 containerd,那每次 containerd 挂掉或升级,整个宿主机上所有的容器都得退出了。而引入了 containerd-shim 就规避了这个问题(containerd 和 shim 并不是父子进程关系);
- containerd-shim 在这一步需要调用 runC 这个命令行工具,来启动容器;
- runC 启动完容器后本身会直接退出,containerd-shim 则会成为容器进程的父进程,负责收集容器进程的状态,上报给 containerd,并在容器中 pid 为 1 的进程退出后接管容器中的子进程进行清理,确保不会出现僵尸进程。
03.Docker 安装
卸载旧版本docker
$ yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
$ rm -rf /var/lib/docker #删除旧版本数据
安装依赖包
$ yum install -y yum-utils \
device-mapper-persistent-data \
lvm2yum
添加源,使用了阿里云镜像
$ yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
$ yum makecache fast #配置元数据缓存
安装最新稳定版docker
$ yum install -y docker-ce
04.配置docker使用flannel网络
修改docker的配置文件/usr/lib/systemd/system/docker.service
,增加如下几条环境变量配置:
EnvironmentFile=-/run/docker_opts.env
EnvironmentFile=-/run/flannel/subnet.env
systemd 维护
$ systemctl daemon-reload
$ systemctl start docker #启动docker引擎
$ systemctl enable docker #设置开机启动
番外篇配置加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF
05.Q&A
Q:
没有配置flannel之前启动了docker, 已经默认分配了网络, docker0使用bip分配的地址
"Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address"
A:
查看/lib/systemd/system/docker.service
文件发现启动命令没有调用/run/docker_opts.env
中的${DOCKER_OPTS}
, 需要将启动命令从ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
修改为
/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock $DOCKER_OPTS
Q:
修改docker的默认网段
A:
编辑/etc/docker/daemon.json
添加如下内容{ "bip": "172.26.0.1/16" }
重启docker服务
systemctl restart docker.service