Kubernetes是当今最流行的开源容器管理平台,来自Google Borg的开源版本,2014年推出。Kubernetes源于希腊语,意为舵手,K8S是一个简称,因为首尾字母中间正好有8个字母。
基于容器技术,Kubernetes可以方便的进行集群应用的部署、扩容、缩容、自愈机制、服务发现、负载均衡、日志、监控等功能,大大减少日常运维的工作量。
从两个维度来看k8s。
Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。
APIServer 负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd。
controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。
etcd 保存了整个集群的状态。etcd是一个高可用的键/值存储系统,Kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。
Node 可以是一个物理机也可以是虚拟机,每个节点上都运行了可以运行 Pods 的服务。通过Master节点来进行管理。
- 反向代理: 将客户端流量转发到与service对应的一组后端pod
Pod 是Kubernetes中可以创建和部署的最小单位。Pod包含了应用容器、存储资源、唯一的网络IP地址以及容器运行的参数。Pod内部的容器共享的网络、存储资源。Docker是Pod中最常用的容器运行环境,但仍允许用户使用其他的容器环境。
Pod使用有两种方式:
- 一个Pod中运行多个容器 containers (这些容器联系必须 非常紧密,而且需要 直接共享资源。 web-db模式不行)
在Docker中,容器是最小的处理单元,增删改查的对象是容器,容器是一种虚拟化技术,容器之间是隔离的,隔离是基于Linux Namespace实现的。而在Kubernetes中,Pod包含一个或者多个相关的容器,Pod可以认为是容器的一种延伸扩展,一个Pod也是一个隔离体,而Pod内部包含的一组容器又是共享的(包括PID、Network、IPC、UTS)。除此之外,Pod中的容器可以访问共同的数据卷来实现文件系统的共享。
在kubernetes中,镜像的下载策略为:
Always:每次都下载最新的镜像
Never:只使用本地镜像,从不下载
IfNotPresent:只有当本地没有的时候才下载镜像
Pod被分配到Node之后会根据镜像下载策略进行镜像下载,可以根据自身集群的特点来决定采用何种下载策略。无论何种策略,都要确保Node上有正确的镜像可用。
通过yaml文件,可以在Pod中设置:
Host网络,一些特殊场景下,容器必须要以host方式进行网络设置(如接收物理机网络才能够接收到的组播流),在Pod中也支持host网络的设置,如:spec-->hostNetwork=true;
重启策略,当Pod中的容器终止退出后,重启容器的策略。这里的所谓Pod的重启,实际上的做法是容器的重建,之前容器中的数据将会丢失,如果需要持久化数据,那么需要使用数据卷进行持久化设置。Pod支持三种重启策略:Always(默认策略,当容器终止退出后,总是重启容器)、OnFailure(当容器终止且异常退出时,重启)、Never(从不重启);
工作类容器,一次性任务。通过Job运行一个容器,当其任务执行完以后,就自动退出,集群也不再重新将其唤醒。
执行定时任务的控制器。
k8s旧版,通过它实现了 Pod 的多副本管理(现在不建议用)
Kubernetes进行垃圾回收管理的控制器,Kubernetes的垃圾回收由kubelet进行管理,每分钟会查询清理一次容器,每五分钟查询清理一次镜像。在kubelet刚启动时并不会立即进行GC,即第一次进行容器回收为kubelet启动一分钟后,第一次进行镜像回收为kubelet启动五分钟后。(了解一下)
客户端只需要访问 Service 的 IP,Kubernetes 则负责建立和维护 Service 与 Pod 的映射关系。无论后端 Pod 如何变化,对客户端不会有任何影响,因为 Service 没有变。
service可以将pod ip封装起来,即使pod发生重建,依然可以通过service来访问pod提供的服务,service还解决了负载均衡的问题. 运行在每个node上的kube-proxy进程其实就是一个智能的软件负载均衡器,它负责把service的请求转发到后端的某个pod实例。
Kubernetes创建Pod时会自动添加所有可用的service环境变量到该Pod中,如有需要.这些环境变量就被注入Pod内的容器里。需要注意的是,环境变量的注入只发送在Pod创建时,且不会被自动更新。这个特点暗含了service和访问该service的Pod的创建时间的先后顺序,即任何想要访问service的pod都需要在service已经存在后创建,否则与service相关的环境变量就无法注入该Pod的容器中,这样先创建的容器就无法发现后创建的service。
Kubernetes集群现在支持增加一个可选的组件——DNS服务器。这个DNS服务器使用Kubernetes的watchAPI,不间断的监测新的service的创建并为每个service新建一个DNS记录。如果DNS在整个集群范围内都可用,那么所有的Pod都能够自动解析service的域名。
Kubernetes使用iptables和kube-proxy解析service的人口地址,在中小规模的集群中运行良好,但是当service的数量超过一定规模时,仍然有一些小问题。首当其冲的便是service环境变量泛滥,以及service与使用service的pod两者创建时间先后的制约关系。目前来看,很多使用者在使用Kubernetes时往往会开发一套自己的Router组件来替代service,以便更好地掌控和定制这部分功能。
容器中的文件系统是临时的,一旦容器重新启动,所有运行时对文件的操作都会丢失。Kubernetes使用Volumes来解决这个问题。不同于Docker自身的Volume,Kubernetes提供了Volume的生命周期管理,另外还提供了多种存储形式的支持。在Pod的spec中指定volume的类型以及挂载的位置。
实际使用中,存储选择优先顺序: