使用kubernetes的必要性
对于打包好的一个个镜像,Docker可以运行镜像形成容器。Docker里的容器之间有强隔离性,并且非常轻量级,这是Docker盛行的主要原因。
但是镜像和容器只能解决单一应用的打包和测试问题。而要运行企业级应用的多个微服务,就需要容器调度管理系统。在这里,Docker 技术就仿佛运送系统零件的集装箱,把云原生应用的各个标准化零件交付到各个企业的不同码头,而容器调度管理系统就是企业应用的运行车间,把不同的零件组装、运行、维护起来。
Kubernetes的系统架构
一个k8s集群由分布式存储(ETCD)、一个 Master 节点和一群 Node 节点构成。
kubernetes 核心组件
控制面组件
控制面组件只部署在 master 节点。
kube-apiserver:k8s 的 API 服务器,可理解为 k8s 控制面的前端。API 服务器为 REST 操作提供服务,所有其他组件都通过该前端进行交互。
ETCD:键值数据库,可作为保存 k8s 所有集群数据的后台数据库,比如各种对象的状态。
kube Scheduler:负责监视新创建的、未指定运行节点的 Pod ,选择节点让 Pod 在上面运行。
kube Controller Manager:包含多个控制器,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。
- 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应
- 任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
- 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(Service 或 Pod)
- 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌
Cloud Controller Manager:嵌入到特定云的控制组件,该组件可以让我们的集群连接到云服务商的 API 上。
元数据存储和集群维护
为了集群系统的高可用性,集群中往往存在多个 master,总要选举出一个 leader。
在集群中,统一的存储使用 etcd 来保存,leader 的选举也是通过 etcd 进行。所以 apiserver 有参数--etcd-servers。
etcd 高可用的三种思路:
- 使用独立的 etcd 集群,使用 3 台或 5 台服务器只运行 etcd,独立维护和升级。
- 在 master 上用 static pod 的方式运行 etcd,并将多台 master 上的 etcd 组成集群。
- 使用 centos 提出的 self-hosted etcd 方案,将本应在底层为 k8s 提供服务的 etcd 运行在 k8s 之上。
manager 和 scheduler 都有参数指向 apiserver,并且有参数--leader-elect选举出 leader,以此保证 manager 和 scheduler 的高可用性。所有实例都会尝试拿 leader 锁,只有当拿到 leader 锁的实例无法正常工作时,别的实例才会拿到锁,成为新的 leader。
Node 及其组件
节点可以是虚拟机或物理机器(不是进程),维护运行的 Pod 并提供 Kubernetes 运行环境。
kubelet:集群运行在每个节点上的代理,它保证容器都运行在 Pod 中。(相当于一个进程,对节点里的 Pod 进行管理和监控)
容器运行时:负责运行容器,如Docker,containerd等。
kube-proxy:集群中每个节点上运行的网络代理,为 Service 提供集群内部的服务发现和负载均衡。
kubernetes 对象
对象是持久化的实体,k8s 通过这些实体去表示整个集群的状态。
Pod:Pod 是集群中最小的部署单元,由一个或多个容器组成,这些容器共享存储和网络。同一个Pod中的容器能够通过 localhost 互相通信。
Pod 是 K8s 集群中所有业务类型的基础,可以看作运行在 K8 集群中的小机器人,不同类型的业务就需要不同类型的小机器人去执行。目前 K8s 中的业务主要可以分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-daemon)和有状态应用型(stateful application);分别对应的小机器人类型为 Deployment、Job、DaemonSet 和 Replica Set。
Service:一个 Pod 只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的 IP 启动一个新的 Pod,因此不能以确定的 IP 和端口号提供服务。稳定地提供服务需要服务发现和负载均衡能力。
在 K8 集群中,客户端需要访问的服务就是 Service 对象,Service 是应用服务的抽象,代理 Pod 集合。每个 Service 会对应一个集群内部有效的虚拟 IP,集群内部通过虚拟 IP 访问一个服务。
ReplicaSet:维护 Pod 集合,用来保证一定数量的、完全相同的 Pod 集合的可用性。
Deployment:创建 Deployment 以将 ReplicaSet 上线,以自动创建 Pod。利用 Deployment,可以创建、更新、滚动升级一个服务。滚动升级,实际就是创建一个新的 RS,逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减小到 0。
Job/CronJob:仅执行一次的任务,Cronjob:周期性任务。
DaemonSet:保证全部节点上运行一个 Pod 的副本。常用场景:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
PetSet: RS 主要是控制提供无状态服务的,其所控制的 Pod 的名字是随机设置的,一个 Pod 出故障了就被丢弃掉,在另一个地方重启一个新的 Pod,名字变了、名字和启动在哪儿都不重要,重要的只是 Pod 总数;而 PetSet 是用来控制有状态服务,PetSet 中的每个 Pod 的名字都是事先确定的,不能更改。
对于 RC 和 RS 中的 Pod,一般不挂载存储或者挂载共享存储,保存的是所有 Pod 共享的状态,Pod 像牲畜一样没有分别;对于 PetSet 中的 Pod,每个 Pod 挂载自己独立的存储,如果一个 Pod 出现故障,从其他节点启动一个同样名字的 Pod,要挂在上原来 Pod 的存储继续以它的状态提供服务。PetSet 做的只是将确定的 Pod 与确定的存储关联起来保证状态的连续性。