1.Kubernetes基础架构
Kubernetes是一个跨主机集群的开源容器调度平台,可以管理各种不同的底层容器(不仅限于Docker);与Openstack类似,OpenStack通过管理底层大量的虚拟化节点构成一个庞大的集群,提供云服务,而Kubernetes通过管理底层的容器节点,自动化应用容器的部署、扩展和操作,提供以容器为中心的基础架构。
Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用;kubeadm用于快速启动 和运行一个最小可用的Kubernetes集群,通过kubeadm init来快速初始化安装Master节点组件(Kubernetes集群的基础组件),通过kubeadm join来快速将Node节点加入到集群当中。
一个Kubernetes集群包含一个或多个Master节点和多个Node节点。
1.1 Master节点组件
Master是Cluster的主控节点,主要职责是为用户和客户端暴露API ,跟踪其他服务器的健康状态、以最优方式调度工作负载, 及编排其他组件之间的通信等;Master节点运行Linux操作系统上,可以是物理机或者虚拟机;为了实现高可用,可以部署多个Master节点以主备方式运行。
通常,Master节点上不运行用户容器。
- API Server(kube-apiserver)
API Server是Kubernetes Cluster的前端接口,各种客户端工具(CLI或UI)以及Kubernetes其他组件可以通过它管理Cluster的各种资源;负责接收、校验并响应所有的REST请求,结果状态被持久存储于 etcd。
- Scheduler(kube-scheduler)
Scheduler负责决定将Pod放在哪个Node上运行,Scheduler在调度时会充分考虑Cluster的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。
- Controller Manager(kube-controller-manager)
Controller Manager负责管理各种控制器,保证控制器处于预期的状态,是处理集群中常规任务的后台线程;不同的controller控制器管理不同的资源。例如,replication controller管理Deployment、StatefulSet、DaemonSet的生命周期,namespace controller管理Namespace资源。
- etcd
etcd负责保存Kubernetes Cluster的配置信息和各种资源的状态信息;基于监听watch机制,当数据发生变化时,etcd会快速地通知Kubernetes相关组件;etcd 是独立的服务组件,并不属于Kubernetes 集群自身,在生产环境中应该以 etcd 集群的方式运行以确保其服务可用性。
- Pod网络
主要用于实现Pod之间相互通信,使用集成flannel插件来实现Pod网络。
1.2 Node节点组件
Node的职责是运行容器应用;由Master管理,Node负责监控并汇报容器的状态,同时根据Master的要求管理容器的生命周期;Node运行在Linux操作系统上,可以是物理机或者是虚拟机。
- kubelet
kubelet是Node的agent,当Scheduler确定在某个Node上运行Pod后,会将Pod的具体配置信息(image、volume等)发送给该节点的kubelet,kubelet根据这些信息(调用相关的容器引擎,如docker engine)来创建和运行容器、挂载数据卷,并向Master报告运行状态。
注:kubelet是唯一一个没有运行在Pod中的组件,是以服务进程的方式运行在Linux系统中,因为Kubernetes的核心组件(kube-apiserver、kube-scheduler、kube-controller-manager、etcd)都是以Pod的方式运行,需要kubelet拉起。
- kube-proxy
每个Node都会运行kube-proxy服务,它负责按需为 Service 资源对象生成 iptables或ipvs 规则,将访问service的TCP/UPD数据流转发到后端的容器。如果有多个副本,kube-proxy会实现负载均衡。
- Pod网络
主要用于实现Pod之间相互通信,使用集成flannel插件来实现Pod网络。
1.3 添加节点到集群
kubeadm join 把新增节点注册到 Master 的过程需要新加节点和集群 Master 之间建立互信。
1、首先需要master节点创建一个key-value键值对,其中value是当前集群的基本信息;将key作为bootstrap token,通过可信赖的途径上传至新节点(人工方式);
#在master节点上生成token
kubeadm token create --print-join-command
2、一方面,新加节点获取到 bootstrap token后,将使用这个 bootstrap token 连接 Master,Master 则可通过验证这个 bootstrap token 来建立对新加节点的信任;
#在新加节点上执行加入集群命令
kubeadm join <MASTER_IP:PORTAL> --token .. --discovery-token-ca-cert-hash ..
3、另一方面,新加节点以匿名身份从 Master kube-public 命名空间中获取集群 cluster-info,cluster-info 包括集群 CA 证书和使用集群 bootstrap token 对这个 CA 做的签名(hash值);新加节点使用 bootstrap token,对 CA 生成新的签名,然后将此签名与 cluster-info 内签名做对比,如果两个签名一致,则说明cluster-info 和 bootstrap token 来自同一集群,来实现新加入节点对master的信任。
#查看集群的cluster-info详细信息
kubectl cluster-nifo dump --namespace kube-public
#不带dump参数,则只显示控制平面的地址
注:所谓管控,其实可以理解为专门用于管理token的第三方,在小规模的集群中一般由Master代管。
1.4 组件交互
①、用户通过kubectl 或者 webUI 向api-server提交需要运行的pod描述:例如副本描述,Kubernetes通过ReplicaSet 控制器监视集群中的容器并保持数量;例如service描述,通过kube-proxy负责将访问应用的工作流量转发,这些不同的操作都是由不同的controller控制器来完成;
②、api-server接收请求并将相关描述存储到etcd;
③、scheduler 监控api-server拿到相关描述信息,开始扫描node节点,找到满足条件的node节点,将Pod与node的对应关系写入etcd;
④、Kubelet定时请求api-server,拿到需要在本机运行的Pod信息,运行起来;
⑤、当通过kubectl获取pod信息时,API Server会从etcd中读取这些数据并返回。
2. 资源对象
2.1 资源对象类型
Kubemetes API 对象大体可分为工作负载( Workload )、 发现和负载均衡( Discovery & LB )、 配置和存储 (Config & Storage )、 集群( Cluster )以及元数据 Metadat )五个类型。
- 工作负载
Pod 是工作负载型资源中的基 资源,它负责运行容器,并为其解决环境性的依赖,但是对Pod的管理是通过工作负载型控制器来完成;控制器又分为有状态和无状态两种,ReplicaSet、Deployment 负责管理无状态应用, StatefulSet 用于管控有状态类应用。
- 发现和负载均衡
如果Pod需要与外界通信,则需要先将其暴露到集群外部,并且要为同一种工作负载的访问流量进行负载均衡,Kubernetes通过用于为工作负载添加发现机制及负载均衡功能的 Service 资源和 Endpoint 资源,以及通过七层代理实现请求流量负载均衡的 Ingress 资源来实现。
- 配置与存储
Kubernetes通过Volume资源来支持多种类型的存储设备或存储系统,如Glusterfs、Ceph RBD等;ConfigMap 资源能够以环境变量或存储卷的方式接入到 Pod 资源的容器中,并且可被多个同类的 Pod 共享引用,从而实现“一次修改,多处生效” ;但是对于存储敏感数据,如私钥、密码等,则需要使用另一个资源类型Secret 。
- 集群级
Pod、Deployment、Service、ConfigMap 等资源属于命名空间级别,可由相应的项目管理员所管理;另外还存在一些集群级别的资源,用于定义集群自身配置信息的对象,它们仅应该由集群管理员进行操作,如要包括以下几种类型:
①、Namespace:命名空间,资源对象名称的作用范围,绝大多数对象都隶属于某个名称空间,默认时隶属于“default”;
②、Node:集群工作节点,其标识符(默认为主机名)在当前集群中必须是唯一的;
③、Role:角色,命名空间级别的权限集合,可以被RoleBinding引用;
④、ClusterRole:集群角色,集群级别的权限集合,可被 RoleBinding和ClusterRoleBinding 引用;
⑤、RoleBinding:将 Role 中的权限绑定在一个或一组用户之上,它隶属于且仅能用于一个命名空间;绑定时,可以引用同一命名空间中的 Role ,也可以引用全局命名空间的ClusterRole;
⑥、ClusterRoleBinding:将 ClusterRole 中定义的权限绑定在一个或一组用户之上,它能够引用全局命名空间中的 ClusterRole ,并能通过 Subject 子项目添加相关信息。
- 元数据型
主要用于为集群内部的其他资源配置其行为或特性,HorizontalPodAutoscaler 资源可用于自动伸缩工作负载类型的资源对象的规模, Pod 模板资源可用于为 pod 资源的创建预制模板,而 LimitRange 则可为命名空间的资源设置其 CPU 和内存等系统级资源的数量限制
2.2 资源对象格式
对几乎所有的资源来说, apiVersion、kind、metadata 字段的功能基本上都是相同的,但 spec 则用于资源的期望状态,而资源之所以存在类型上的不同,也在于它们的嵌套属性存在显著差别,它由用户定义和维护。
- metadata嵌套字段
metadata 字段描述对象的属性信息,其内嵌多个字段用于定义资源的元数据,其中必选字段包括namespace、name(对象名字,同一命名空间内必须唯一)、uid(对象标识符);用户通过配置清单创建资源时,通常仅需要给出必选字段。
- spec和status字段
Kubernetes中的spec 字段来描述所期望的对象应该具有的状态,是必须定义的,用来描述对象的目标状态(如设定3副本等);用 status字段来记录对象在系统上的当前状态,有Kubernetes自动填充,用户不能指定。所以当资源当前的状态与spec不同时(status字段发生变化),Kubernetes会根据spec和status字段的差异做出相应的动作,如副本数不足3时会补足副本数等。
在定义资源对象时可以自己编写,也可以将已存在的资源导出后修改。
①、当手动编写资源对象时,尽管 apiVersion、kind、metadata 有规律可循,但 spec 字段对不同的资源来说却是千差万别的,所以需要查询参考文档来了解可用的属性;
kubectl explain pod #以pod资源为例
...
FIELDS:
apiVersion <string>
...
kind <string>
...
metadata <Object>
...
spec <Object>
...
status <Object>
...
#如果要查看spec字段配置
kubectl explain pod.spec
②、当使用已经存在的同类资源作为模板来创建资源时,可以更快的生成目标资源的配置文件;
kubectl get <RESOURCE_TYPE> <NAME> -o yaml --export
# --export选项表示输出将省略出系统生成的信息
# NAME是当前存在的同类资源的名字
2.3 命名空间Namespace
Namespace可以将一个物理的Cluster逻辑上划分成多个虚拟Cluster,每个Cluster就是一个Namespace,在创建Pod时必须指定namespace;
不同Namespace里的资源是完全隔离的,可以用来区分不同的项目、不同的用户等;同一命名空间内的同一类型资源名必须是唯一的,但跨命名空间时并无此限制。
通过在 yml 配置文件中 metadata 项指定,如 namespace:kube-public。
注:区别于Linux内核提供的Namespace技术,Kubernetes提供的Namespace仅仅是逻辑上的概念,只是单纯将不同用户区分开的一种方式,本质上并没有使用Linux的NS技术。
#查询当前集群中所有的namespace
kubectl get ns
#描述指定的命名空间
kubectl describe namespace <NAMESPACE_NAME>
Kubernetes默认创建了两个Namespace:
①、default:创建资源时如果不指定,将被放到这个Namespace中。
②、kube-system:Kubernetes自己创建的系统资源将放到这个Namespace中。
注:Namespace 对象仅用于资源对象名称的隔离,它自身并不能隔绝跨命名空间的 Pod 间通信,那是网络策略( network policy )资源的功能。
3. Kubectl管理工具
kubectl是Kubemetes 系统的命令行客户端工具,常用的子命令列表如下。