暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kubernetes的轻量级CRI

ProdanLabs 2019-12-12
1256

  01.


我们在提到容器运行时(Container Runtime)时就会想到Docker,即使用于制作容器的LXC工具早于Docker,但Docker以其简单性将容器技术带入了主流,在过去的五年Docker也成为了运行容器的事实上的标准。

容器技术成为主流之后,容器圈进行了一系列政治斗争,感兴趣的读者可以网上查查,本文不再赘述。最终DockerSwarm不敌Kubernetes,Docker公司把 containerd 项目捐给 CNCF社区,专心做Docker企业版。

最终由Kubernetes统治了容器圈,并制定了相关的标准

Container Runtime Interface:即容器运行时接口(CRI),Kubernetes v1.5版本推出,无论是docker、rkt或cri-o,只要能实现这个接口,谁都可以做 Runtime。

Open Container Initiative开放容器标准(OCI),Docker公司把libcontainer封装变成Runc捐献出来,作为 OCI 的参考实现,因为Runc能按照标准将符合标准的容器镜像运行起来


当CRI标准提出后,Red Hat开始想构建一个更简单的运行时,且这个运行时仅为 Kubernetes所用,最初称为CRID,最后改为CRI-O,它实现了一个最小的 CRI 接口,由CNCF社区孵化CRI-O设计比其他的方案都要小,遵循久经考验的Unix模块化编程哲学,实现组件重用

  02.

为什么选择CRI-O?

真正开放的项目CRI-O是Kubernetes生态的一部分,成为其子项目,由CNCF社区孵化Red Hat,SUSE,Intel ,Google,IBM等公司提供了大量的贡献者。

轻量 CRI-O由许多小型组件组成,每个组件都有特定的角色,并与其他组件一起工作,以提供完整的容器体验,相比之下,Docker引擎是一个重量级的守护程序。

更加安全每个使用Docker CLI运行的容器都是该大型Docker Daemon的“子级”,这使得使用cgroup和安全约束等工具来为容器提供额外的保护层变得复杂或彻底受阻。由于CRI-O容器是产生它的进程(而不是守护进程)的子进程,因此它们与这些工具完全兼容,而不会产生复杂问题。对Kubernetes来说很完美,在Podman中使用也很“因吹斯汀”。

与Kubernetes保持一致作为一个正式的Kubernetes项目,CRI-O与Kubernetes同步发布。



  • 当创建一个POD时,kubelet通过kubernetes CRI将请求转发给CRI-O守护进程,以启动新的POD

  • CRI-O从镜像仓库(docker仓库、私有仓库等)拉取镜像

  • 下载好的镜像被解压,通过UnionFS挂载到容器的根文件系统中

  • 为容器创建rootfs之后,CRI-O会生成OCI运行时规范config.jsonn文件,该文件描述了如何使用OCI Generate工具运行容器。(Runc通过读取这个json文件,获取该如何启动容器的信息)

  • 然后,CRI-O按OCI标准通过Runc将镜像运行起来

  • 每个容器都由一个独立的 conmon 进程监控,conmon 为容器中 pid 为 1 的进程提供一个 pty,同时它还负责处理容器的日志记录并记录容器进程的退出代码

  03.

注:Kubernetes安装过程略,本文只讲CRI-O替代Docker


初始化环境

内核参数优化

[root@kube-master01 ~]# modprobe overlay
[root@kube-master01 ~]# modprobe br_netfilter
[root@kube-master01 ~]# cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
[root@kube-master01 ~]# sysctl --system

安装依赖包

[root@kube-master01 ~]# yum install btrfs-progs-devel container-selinux device-mapper-devel gcc git glib2-devel glibc-devel glibc-static gpgme-devel json-glib-devel libassuan-devel libgpg-error-devel libseccomp-devel make pkgconfig skopeo-containers tar wget -y
[root@kube-master01 ~]# yum install golang-github-cpuguy83-go-md2man golang -y


编译安装runc

[root@kube-master01 ~]#  git clone https://github.com/opencontainers/runc /root/src/github.com/opencontainers/runc
[root@kube-master01 ~]# cd /root/src/github.com/opencontainers/runc
[root@kube-master01 runc]# export GOPATH=/root
[root@kube-master01 runc]# make BUILDTAGS="seccomp selinux"
[root@kube-master01 runc]# make install
[root@kube-master01 runc]#  ln -sf /usr/local/sbin/runc /usr/bin/runc
[root@kube-master01 runc]


编译安装cri-o

[root@kube-master01 ~]# git clone https://github.com/cri-o/cri-o /root/src/github.com/cri-o/cri-o
[root@kube-master01 ~]# cd /root/src/github.com/cri-o/cri-o
[root@kube-master01 cri-o]# git checkout master
[root@kube-master01 cri-o]# make
[root@kube-master01 cri-o]# make  install
[root@kube-master01 cri-o]# make install.systemd
[root@kube-master01 cri-o]# make install.config


编译安装conmon

[root@kube-master01 ~]# git clone http://github.com/containers/conmon /root/src/github.com/conmon
[root@kube-master01 ~]# cd /root/src/github.com/conmon
[root@kube-master01 conmon]# make
[root@kube-master01 conmon]# make install


安装crictl工具

[root@kube-master01 ~]# wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.16.1/crictl-v1.16.1-linux-amd64.tar.gz
[root@kube-master01 ~]# tar -zxvf crictl-v1.16.1-linux-amd64.tar.gz
[root@kube-master01 conmon]# chown root.root crictl
[root@kube-master01 conmon]# mv crictl /usr/local/sbin/crictl


修改cri-o配置

[root@kube-master01 ~]# cd /etc/crio/
[root@kube-master01 crio]# vim crio.conf 
cgroup_manager = "systemd"
storage_driver = "overlay2"
storage_option = [ "overlay2.override_kernel_check=1" ]
registries = ['registry.access.redhat.com''docker.io']
#pause_image默认镜像为"k8s.gcr.io/pause:3.1",因为国内网络原因,需要修改
pause_image = "gcr.azk8s.cn/google_containers/pause-amd64:3.1"
[root@kube-master01 ~]# mkdir -p /usr/share/containers/oci/hooks.d


修改kubelet配置

#kubelet添加以下参数
  --network-plugin=cni \
  --container-runtime=remote \
  --container-runtime-endpoint=/var/run/crio/crio.sock \
  --runtime-request-timeout=5m \
  --image-service-endpoint=/var/run/crio/crio.sock \
  --runtime-cgroups=/systemd/system.slice \
  --kubelet-cgroups=/systemd/system.slice \


启动cri-o、kubelet

[root@kube-master01 ~]# systemctl daemon-reload
[root@kube-master01 ~]# systemctl enable crio
[root@kube-master01 ~]# systemctl start crio
[root@kube-master01 ~]# systemctl status crio
[root@kube-master01 ~]# systemctl enable kubelet
[root@kube-master01 ~]# systemctl start kubelet
[root@kube-master01 ~]# systemctl status kubelet


查看节点

[root@kube-master01 ~]# crictl --runtime-endpoint unix:///var/run/crio/crio.sock version
Version:  0.1.0
RuntimeName:  cri-o
RuntimeVersion:  1.17.0-dev
RuntimeApiVersion:  v1alpha1
[root@kube-master01 ~]
[root@kube-master01 ~]# kubectl get nodes -o wide
NAME            STATUS   ROLES    AGE     VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION   CONTAINER-RUNTIME
kube-master01   Ready    master   3h26m   v1.17.0   172.20.143.102   <none>        CentOS Linux 7 (Core)   4.19.88          cri-o://1.17.0-dev
[root@kube-master01 ~]


安装calico

[root@kube-master01 ~]# curl https://docs.projectcalico.org/v3.10/manifests/calico.yaml -O
#POD的网络默认为192.168.0.0/16,需要改为你定义的网段
[root@kube-master01 ~]# POD_CIDR="<your-pod-cidr>"
[root@kube-master01 ~]# sed -i -e "s?192.168.0.0/16?$POD_CIDR?g" calico.yaml
[root@kube-master01 ~]# kubectl apply -f calico.yaml

查看calico

[root@kube-master01 ~]# kubectl get pod -n kube-system -o wide     
NAME                                       READY   STATUS    RESTARTS   AGE    IP               NODE            NOMINATED NODE   READINESS GATES
calico-kube-controllers-68649775ff-5hn5v   1/1     Running   0          164m   192.168.237.65   kube-master01   <none>           <none>
calico-node-fbxhf                          1/1     Running   0          164m   172.20.143.102   kube-master01   <none>           <none>
coredns-585ccc4656-gmcrc                   1/1     Running   0          164m   192.168.237.66   kube-master01   <none>           <none>
[root@kube-master01 ~]# 


至此,CRI-O代替docker成为Kubernetes Runtime安装完毕。

即使有了CRI-O、containerd-plugin精简轻量的Runtime架构,但Docker仍是Kubernetes 默认的 Runtime 实现,因为它受了最多生产环境考验

大势所趋,相信不久的将来,CRI-O会替代Docker成为Kubernetes默认的Runtime。


有空再更新Kubernetes 1.17版本功能。

华为KubeEdge在边缘计算的实践




文章转载自ProdanLabs,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论