我们用docker制作了一个容器镜像,使用docker命令就可以跑起来。但是当容器成千上万时,用docker命令来管理肯定是不够的。而且生产上的自动发布、容器监控、接口鉴权等工作,传统的工具已经不能支持。这时kubernete的作用就突显出来。
kubernete架构体系如下图:
从上面这张图可以看出,kubernete分为master节点和node节点。master节点是空值节点,而node节点是计算节点。
master节点有3个重要的组件组成,controller manager、api server、scheduler组成。其中controller manager负责容器编排,api server提供api服务,scheduler负责任务调度。整个集群的状态保存在etcd中。
在node节点中,最重要的组件是kubelete,负责跟容器运行时进行交互,这个交互通过CRI(Container Runtime Interface)远程调用接口,这个接口定义了容器启动时的各种参数。而真正容器在运行时,是通过OCI(容器运行时规范)跟底层操作系统交互。如下图。可以看出,只要容器能够通过CRI接入kubernete,不管是不是docker容器,都是可以被kubernete集群管理的。
kubelete还可以用来管理宿主机、网络设备、存储设备,具体如下图:
使用gRPC跟devidevice plugin交互,device plugin是kubernete管理宿主机物理设备的主要组件,使用CNI(Container Networking Interface)跟网络插件进行交互,使用CSI(Container Storage Interface)跟存储插件进行交互。
在kubernete中,最小的调度单位是pod,关联密切的容器可以被调度在一个pod中,共享network namespace、数据卷,从而可以高效进行通信。kubernete为每一个pod绑定一个service服务,service服务作为pod的代理访问入口,配置的IP等地址信息是固定不变的,这样即使pod重启后IP地址发生了变化,调用方也可以通过service服务直接访问pod。
在有些情况下,访问pod需要授权,比如访问数据库pod,这时kubernete提供了secret对象,这个对象是保存在etcd里面的键值对,存储了被访问pod的授权信息。当应用pod需要访问数据库时,只需要在pod启动时把secret对象挂载在pod里,就可以访问授权pod了。
总之,kubernete通过编排对象来管理应用,比如通过pod来管理应用容器,通过job来管理一次性运行任务,通过daemonset来管理宿主机上唯一的守护进程,通过cronjob来管理定时任务。除此之外,kubernete还定义了一些服务对象,比如service、secret等。
顺便提一下,kubeadm是部署kubernete的重要工具,使用kubeadm,只需要kubeadmin init;kuberadm join两个命令就可以部署和qido启动kubernete集群了。上面讲到kubelet是跟容器运行时交互的重要组件,所以kubeadm的部署方式选择把kubelet部署在宿主机上,而kubernete的其他组件部署在容器里,这样更方便kubelet跟宿主机打交道。
master组件的yaml文件放在/etc/kubernetes/manifests目录下,kubernete启动时,kubelet会检查到这些yaml文件,为master节点创建对应的pod。