k8s 主要由以下核心组件组成:
以下是 K8s 架构图。
Master控制节点
Master节点是Kubernetes集群的控制节点,每个Kubernetes集群里至少有一个Master节点,它负责整个集群的决策(如调度),发现和响应集群的事件。一个集群通常运行多个Master控制节点,提供容错性和高可用性。Master节点可以运行在集群中的任意一个节点上,但是最好将Master节点作为一个独立节点,不在该节点上创建容器,因为如果该节点出现问题导致宕机或不可用,整个集群的管理就会失效。
在Master节点上,会运行以下服务:
在Master节点上,还会运行以下服务:
“
kube-apiserver
此服务负责公开K8s API并处理请求,可以通过K8s API查询和操纵K8s中对象的状态。
“
etcd
一致且高度可用的Key-Value键值存储,用作Kubernetes的所有群集数据的后备存储,在K8s中有两个服务需要用到etcd来协同和配置,分别如下
网络插件 flannel、对于其它网络插件也需要用到 etcd 存储网络的配置信息
Kubernetes 本身,包括各种对象的状态和元信息配置
注意:flannel 操作 etcd 使用的是 v2 的 API,而 Kubernetes 操作 etcd 使用的 v3 的 API,所以在下面我们执行 etcdctl 的时候需要设置 ETCDCTL_API 环境变量,该变量默认值为 2。
etcd实现原理:http://jolestar.com/etcd-architecture/
“
kube-scheduler
调度器,运行在Master上,用于监控节点中的容器运行情况,并挑选节点来创建新的容器。调度决策所考虑的因素包括资源需求,硬件/软件/策略约束,亲和性和排斥性规范,数据位置,工作负载间干扰和最后期限。
“
kube-controller-manager
控制和管理器,运行在Master上,每个控制器都是独立的进程,但为了降低复杂性,这些控制器都被编译成单一的二进制文件,并以单独的进程运行。
Node工作节点
Node 节点是 Kubernetes 集群的工作节点,每个集群中至少需要一台Node节点,它负责真正的运行Pod,当某个Node节点出现问题而导致宕机时,Master会自动将该节点上的Pod调度到其他节点。Node节点可以运行在物理机上,也可以运行在虚拟机中。
Node节点可以在集群运行期间动态增加,只要整个节点已经正确安装配置和启动了上面的进程。在默认情况下,kubelet会向Master自动注册。一旦Node被接入到集群管理中,kubelet会定时向Master节点汇报自身的情况(操作系统,Docker版本,CPU内存使用情况等),这样Master便可以在知道每个节点的详细情况的同时,还能知道该节点是否是正常运行。当Node节点心跳超时时,Master节点会自动判断该节点处于不可用状态,并会对该Node节点上的Pod进行迁移。
在Node节点上,通常会运行以下服务:
Pod
Pod是K8s中最小的调度资源单位,是容器或容器的集合,一个Pod中可以有多个容器 ,彼此共享网络和存储等。Pod中的容器都是统一进行调度,并且运行在共享上下文中。一个Pod被定义为一个逻辑的host,它包括一个或多个相对耦合的容器。
Pod的共享上下文,实际上是一组由namespace、cgroups和其他资源的隔离的集合,意味着Pod中的资源已经是被隔离过了的,而在Pod中的每一个独立的container又对Pod中的资源进行了二次隔离。
一个 Pod 总是运行在工作节点。工作节点可以有多个 Pod 。控制节点会根据每个工作节点上可用资源的情况,自动调度 Pod(容器组)到最佳的工作节点上。如果运行实例的工作节点关机或被删除,则 Kubernetes Deployment Controller 将在群集中资源最优的另一个工作节点上重新创建一个新的实例。这提供了一种自我修复机制来解决机器故障或维护问题。
Replication Controller
Replication Controller为Kubernetes的一个核心内容,应用托管到Kubernetes之后,需要保证应用能够持续的运行,Replication Controller就是这个保证的key,主要的功能如下:
Deploment
在kubernetes中,Pod是最小的控制单元,但是kubernetes很少直接控制Pod,一般都是通过Pod控制器来完成的。Pod控制器用于Pod的管理,确保Pod资源符合预期的状态,当pod的资源出现故障时,会尝试进行重启或重建Pod。在kubernetes中Pod控制器的种类有很多,Deployment 是最常用的那种。Deployment是K8s用于管理Pod的资源对象,用来保证K8s中Pod的多实例、高可用与滚动更新、灰度部署等。可以说,Deployment是K8s中最常用最有用的一个对象,多用来发布无状态的应用。
单独创建pod的时候就不会有deployment出现,但是创建deployment的时候一定会创建pod,因为pod是一个基础的单位。任何的控制器单位的具体实现必须落到pod去实现。
Deployment是比Replication Controller更高级的一种资源,它不但可以控制Pod的副本数,同时还可以控制Pod的版本,所以这么高级的资源并不是时时刻刻都需要的,比如你就想暂时性的部署一个小程序,用完就不要了,那么你就没有必要使用RS或者RC,更没有必要去用Deploment。
从开发者角度看,deployment顾明思意,既部署,对于完整的应用部署流程,除了运行代码(既pod)之外,需要考虑更新策略,副本数量,回滚,重启等步骤,而运行代码的方式有很多种,例如有一次性的也就是job,有定时执行的也就是crontabjob,有排号的也就是sts,为了复用运行代码的功能所以抽象为pod,从而进行复用。
从用户角度看,我们操作时也会根据不同的代码副本进行查看,例如日志,资源占用都是实例级别的也需要这么一个抽象。
Deployment同样为Kubernetes的一个核心内容,主要职责同样是为了保证pod的数量和健康,90%的功能与Replication Controller完全一样,可以看做新一代的Replication Controller。但是,它又具备了Replication Controller之外的新特性:
“
Replication Set
前面提到,Deployment是Pod的其中一个管理者,这其实也不准确,Deployment控制器也不直接操纵Pod。应用存在副本、版本,如果直接Deployment控制器直接管理Pod,对于版本管理、灰度部署、滚动更新等功能就比较麻烦,因此在Deployment和Pod直接还存在一个ReplicaSet的对象,它是对对应着不同不Pod版本,是Pod直接管理者。Deployment通过操纵ReplicaSet间接的管理Pod:
如图所示描述了在 replicas=5 的设置下,灰度部署(滚动更新)2/5的时候,Deployment的状态。我们不用直接创建ReplicaSet,在创建Deployment的时候,K8s会默认创建ReplicaSet,并由Deployment控制器进行管理。K8s也不建议人工管理ReplicaSet。
“
创建deployment
执行如下命令输出一个yaml模板
kubectl create deploy nginx-deploy --image=nginx:alpine --dry-run=client -o yaml
我们将这个yaml模板spec下的replicas参数修改为3,然后保存为1.yml文件,执行如下命令在指定test命名空间下进行部署。
#使用yml文件在指定test命名空间下创建部署
kubectl apply -f 1.yml -n test
#查看部署
kubectl get deploy nginx-deploy -n test
#查看指定命名空间下的pod
kubectl get pods -n test
#查看 Deployment 创建的 ReplicaSet
kubectl get replicaSet -A
#使用yam文件在指定test命名空间下删除部署
kubectl delete -f 1.yml -n test
#在指定test命名空间下创建一个名为nginx的deployment部署
kubectl create deployment nginx-deploy2 --image=nginx:alpine --port=8080 -n test
#使用名字删除部署
kubectl delete deployments.apps nginx-deploy2 -n test
如图所示,因为spec下的replicas参数为3,所以创建了3个pod。
此时删除指定的pod,可以看到,指定的pod确实删除了,但是又新生成了重新的pod。因为spec下的replicas参数值为3,所以这个deployment需要3个pod。
Namespace
K8s使用命名空间实现集群内部的逻辑隔离,Namespace可实现容器隔离及一些权限控制等。Namespace用于对k8s中资源对象的分组。namespace之间没有嵌套或层级关系。一个资源对象只能属于一个namespace。不同组之间的对象是隔离的,互相不可见。
以下是K8s安装完成后默认的一些namespace。
注意:namespace无法保证网络的隔离性,比如说service可以跨namespace访问。
“
kube-system
K8s系统自己运行所需的资源对象所在的namespace。
“
kube-public
k8s自动创建的namespace,对所有用户可见。适合放置集群范围都可见的服务。kube-public 含有一个单一的 ConfigMap 对象 cluster-info,它有助于发现和安全引导。该命名空间默认不允许被删除。
kube-node-lease
kube-node-lease 这个命名空间含有与每个节点关联的 Lease 对象。节点 lease 允许 kubelet 发送 heartbeat(心跳),以便控制平面(节点控制器)可以检测节点故障。那么,如果删除了 kube-node-lease,会发生什么?Kubernetes 通常会为每个节点创建另一个带有 Lease 对象的对象,但有时命名空间移除操作会在终止状态卡住。到那时我们会有一个节点 Lease,过时的 heartbeat 可能会告诉节点控制器:该节点访问不了,从而影响节点之间的整体通信。
default
K8s默认的namespace,如果操作不指明namespace,默认会操作名为default的namespace。
kubernetes-dashboard
如果安装了dashboard,那么该命名空间为dashboard所在的namespace。
参考:k8s 资源管理之 deployment:
https://mp.weixin.qq.com/s/p-yaDl_PtT2LJVcHSYJnzw
K8s学习笔记——Deployment:
https://mp.weixin.qq.com/s/nDnjlm3A-KdpbUCMBQzKrw