Kubernetes,从官方网站上可以看到,它是一个工业级的容器编排平台。 Kubernetes
这个单词是希腊语,它的中文翻译是“舵手”或者“飞行员”。在一些常见的资料中也会看到“ks”这个词,也就是“k8s”,它是通过将8个字母“ubernete
”替换为“8”而导致的一个缩写。
Kubernetes 为什么要用“舵手”来命名呢?大家可以看一下这张图:
这是一艘载着一堆集装箱的轮船,轮船在大海上运着集装箱奔波,把集装箱送到它们该去的地方。我们之前其实介绍过一个概念叫做
container,container 这个英文单词也有另外的一个意思就是“集装箱”。Kubernetes
也就借着这个寓意,希望成为运送集装箱的一个轮船,来帮助我们管理这些集装箱,也就是管理这些容器。
这个就是为什么会选用 Kubernetes 这个词来代表这个项目的原因。
更具体一点地来说:Kubernetes 是一个自动化的容器编排平台,它负责应用的部署、应用的弹性以及应用的管理,这些都是基于容器的。
Kubernetes(分布式资源管理框架),用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。
提供简单的负载均衡、服务部署与弹性伸缩、服务拆分与服务发现。 Pod是Kubernetes管理的最小单位。
Etcd 是一种分布式 kv 存储设施, 他具有一定的一致性,高性能,高可用的方案. 类似的 zookeeper, 但没有 zookeeper 那么重型,功能也没有覆盖那么多. 简单直接的应用就是配置中心。
架构设计总览:
clients 为多个需要 配置的服务, 中间层为 多个 grpc-proxy 做均衡负载, 以免一个 proxy 挂了之后 导致单点问题.
grpc-proxy 可以 同时访问多个 etcd 服务器,进行 kv 的操作. 如果某一个 server 挂了,会自动访问别的
集群中的其他 server 以保证高可用。
Etcd cluster 至少为 3 台, 如果小于 3 台则无法进行选举,造成集群
不可用. (这里需要用 promethus 进行监控预警)
推荐在Kubernetes集群中使用Etch v3,v2版本已在Kubernetes
v1.11中弃用。
APIserver:所有服务访问的统一入口。
CrontrollerManager:维持副本期望数目。
Scheduler:负责介绍任务,选择合适的节点进行分配任务。
ETCD:键值对数据库,存储K8S集群所有重要信息(持久化)。
Kubelet:直接跟容器引擎交互实现容器的生命周期管理。
Kube-proxy:负责写入规则至IPTables、IPVS(负载均衡)实现服务映射访问的。
Coredns:可以为集群中的SVC创建一个域名IP的的对应关系解析。
DashBoard:给K8S集群提供一个B/S结构访问体系。
Ingress controller:官方只能实现4层代理,Ingress可以实现7层代理。
Federation:提供一个可以跨集群中心多K8S统一管理功能。
Prometheus:提供K8S集群的监控能力。
ELK:提供K8S集群日志统一分析接入平台。
Kubernetes kubelet
为每个Kubernetes节点(Node)实现Pod和容器操作。
它们作为每个节点上的代理运行,无论该节点是物理服务器还是虚拟机,并在该节点上处理Pod/容器操作。kubelets将名为PodSpec的配置作为输入,并确保PodSpec中指定的容器正在运行且运行正常。
自主式Pod:
Pod退出了,此类型的Pod不会被创建。
控制器管理的Pod:
在控制器的生命周期里,始终要维持Pod的副本数目。
Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平网络空间中,这在GCE(Google Compute
Engine)里面是现成的网络模型,Kubernetes假定这个网络已经存在。而在私有云里搭建Kubernetes集群,就不能假定这个网络已经存在了。我们需要自己实现这个网络假设,将不同节点上的Docker容器之间的互相访问先打通,然后运行Kubernetes。
同一个Pod内的多个容器之间:lo
各Pod之间的通讯:Overlay Network
Pod与Service之间的通讯:各节点的Iptables规则。
网络解决方案Kubernetes+Flannel:
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。而且它还能在这些IP地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动的传递到目标容器内。
ETCD之Flannel提供说明:
1、存储管理Flannel可分配的IP地址段资源。
2、监控ETCD中每个Pod的实际地址,并在内存中建立维护Pod节点路由器。
不同情况下网络通信方式:
同一个Pod内部通讯:同一个Pod共享同一个网络命名空间,共享同一个Linux协议栈。
Pod1至Pod2:
1、Pod1与Pod2不在同一台主机,Pod的地址是与docker0在同一个网段的,但docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行。将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问。
2、Pod1与Pod2在同一台机器,由Docker0网桥直接转发请求至Pod2,不需要经过Flannel
Pod至Service的网络:
目前基于性能考虑,全部为iptables维护和转发。
Pod至外网:
Pod向外网发送请求,查找路由器,转发数据包到宿主机的网卡,宿主网卡完成路由选择后,iptables执行Masquerade,把源IP更改为宿主网卡的IP,然后向外网服务器发送请求。
外网访问Pod:
Servcei
做集群最少需要三台虚拟机。 一个kubernetes对应一个集群
集群资源分类:
什么是资源:
K8S中所有的内容都抽象为资源。资源实例化之后,叫做对象。
名称空间级别:
集群级别资源:Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBingding
元数据类型资源:HPA、PodTemplate、LimitRange
在K8S中,一般使用yaml格式的文件来创建符合我们预期的Pod,这样的yaml文件我们一般称为资源清单。
简单说明:
是一个可读性高、用来标识数据序列的的格式。YAML的意思其实是:仍是一种标记语言,当为了强调这种语言以数据做为中心,而不是以标记语言为重点。
基本语法:
YAML支持的数据结构:
对象类型:对象的一组键值对,使用冒号结构表示
name:Steve
age:18
Yaml也允许另一种写法,将键值对写成一个行内对象。
hash:{name:Steve,age:18}
数组类型:一组连词线开头的行,构成一个数组
数组也可以采用行内表示法:
animal{Cat,Dog}
纯量:纯量是最基本的、不可再分的值。以下类型都属于纯量:
Init容器:
Pod能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的Init容器。
Init容器与普通的容器非常像,除了如下两点:
如果Pod的Init容器失败,Kubernetes会不断的重启改Pod,直到Init容器成功为止。如果Pod对应的restartPolicy为Never,它不会重新启动。
Init容器的作用:
因为Init容器具有与应用程序容器分离的单独镜像,所以它们的启动相关代码具有以下优势:
特殊说明:
探针是由Kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler。
有三种类型的处理程序:
每次探测都将会获得以下三种结果之一:
探测方式:
挂起(Pending):
Pod已被Kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间。
运行中(Running):
该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
成功(Succeeded):
Pod中的所有容器都被成功终止,并且不会再重启。
失败(Failed):
Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
未知(Unknown):
因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败。
什么是控制器:
Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为。
控制器又被称为工作负载,pod通过控制器实现应用的运维,比如伸缩、升级等。
控制器类型:
主要职责是为了保证Pod资源的健康运行,其不同于replicaset(副本集、容器副本)的功能:
Deployment为Pod和ResplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。典型的应用场景包括:
Deployment更新策略:
Deployment可以保证在升级时只有一定数量的Pod是down的。默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)。
Deployment同时也可以确保只创建出超出期望数量的一定数量的Pod。默认的,它会确保最多比期望的Pod数量多一个的Pod是up的(最多一个surge)
未来的Kubernetes版本中,将从1-1变成25%-25%
Rollover(多个rollout并行):
假如您创建了一个有5个nignx:1.7.9 replica的Deployment,但是当还要3个的nignx:1.7.9
replica创建出来的时候您就会开始更新含有5个nignx:1.9.1replica的Deployment。在这种情况下,Deployment会立即杀掉已创建的3个nignx:1.7.9的Pod,并开始创建nignx:1.9.1的Pod。它不会等到所有的5个nignx:1.7.9的Pod都创建完成后才开始改变航道。
清理Policy(方针、政策):
您可以通过设置.spec.revisonHistoryLimit项来指定deployment最多保留多少revision历史记录。默认的会保留所有的revision;如果将该项设置为0,Deployment就不允许回退了。
用于在集群中的全部节点(Node)上同时运行一份指定的Pod资源副本,后续新加入集群的节点也会自动创建一个相关的Pod对象,当从集群中移除节点时,此类Pod对象也将被自动回收而无需重建,管理员可使用节点标签进行定义节点相关属性,然后使用节点标签选择器在特定节点上运行Pod对象。删除DaemonSet将会删除它创建的所有Pod。
应用场景:
StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:
负责批量处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
用户调配Pod对象执行一次性任务,容器中的进程完成任务后容器不会进行重启,而是将其置于completed(完成)状态,若容器中的进程因错误而终止,则需要依据重启策略判断是否需要重启,未运行完成的Pod若节点故障,则其会被调度至其他节点进行处理。
运行方式:
Cron Job:管理基于时间的Job,即:
用于管理Job控制器资源的运行时间,job控制器定义的作业做任务在执行控制器资源创建之后便会立即执行,但cronjob可以以类似Linux系统的周期性任务计划的方式控制器运行的时间点击重复运行的方式,具体如下:
crpnjob控制器在指定的时间点时,"" 和 "*"意义相同,都表示任何可用的有效值。
应用的资源使用率通常都有高峰和低谷的时候,如何肖峰填谷,提高集群的整体资源利用率,让service中的Pod个数自动调整呢?这就有赖于Horizontal
Pod Autoscaling了,顾名思义,使Pod水平自动缩放。
RC(ReplicationController)主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数。即如果有容器异常退出,会自动创建新的Pod来代替;而如果异常多出来的容器也会自动回收。
Kubernetes官方建议使用RS(ReplicaSet)替代RC(ReplicationController)进行部署,RS跟RC没有本质的不同,只是名字不一样,并且RS支持集合式的selector。
Kubernetes service定义了这样一种抽象:一个Pod的逻辑分组,一种可以访问它们的策略—通常称为微服务。这一组Pod能够被Service访问到,通常是通过Label Selector。
Service能够提供负载均衡的能力,但是在使用上有以下权限:
Service在K8S中有4中类型
在Kubernetes集群中,每个Node运行一个kube-proxy进程。Kube-proxy负责为Service实现了一种VIP(虚拟IP)的形式,而不是ExternalName的形式。在Kubernetes
v1.0版本,代理完全在userspace。在Kubernetes
v1.1版本,新增了iptables代理,但并不是默认的运行模式。从Kubernetes
v1.2起,默认就是iptables代理。在Kubernetes v1.8.0-beta.0中,添加了ipvs代理。 在Kubernetes
1.14版本开始默认使用ipvs代理, 在Kubernetes v1.0版本,Service是4层(TCP/UDP over IP)概念。在Kubernetes v1.1版本,新增了Ingress API(beta版),用来表示”7层”(HTTP)服务。
ClusterIP主要在每个Node节点使用iptables,将发向clusterIP对应端口的数据,转发到kube-proxy中。然后kube-proxy自己内部实现有负载均衡的方法,并可以查询到这个service下对应的Pod的地址和端口,进而把数据转发给对应的Pod的地址和端口。
为了实现图上的功能,主要需要以下几个组件的协同工作:
有时不需要或不想要负载均衡,以及单独的Service IP。遇到这种情况,可以通过指定的Cluster
IP(spec.clusterIP)的值为 “None”来创建Headless
Service。这类Service并不会分配ClusterIP,kube-proxy不会处理它们,而且平台也不会为它们进行负载均衡和路由。
NodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由kube-proxy进一步到给对应的pod。
Loadbalancer和nodePort其实是同一种方式, 区别在于loadbalancer比nodePort多一步,就是可以调用cloud
provider去创建LB来向节点导流。
这种类型的Service通过返回cname和它的值,可以将服务映射到externalName字段的内容(例如:hub.atguigu.com)。ExternalName
Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式提供服务。
概述
kubernetes 提供了两种内建的负载均衡机制,一种是位于传输层的TCP/IP
service资源,其实现的是TCP负载均衡器,另一种是ingress资源,其实现的是HTTP(S)负载均衡器。
TCP负载均衡器
iptables 和 ipvs均实现的是四层调度,其不能基于URL 的请求调度机制,其也不支持为此类负载均衡配置任何类型的健康检查机制。
ingress 是kubernetes API
的标准资源类型之一,其其实是一组基于DNS名称或URL路径把请求转发至service资源的规则,用于将集群外部的请求流量转发至集群内部完成服务发布,ingress
资源自身并不能进行"流量穿透" ,其仅仅是一组路由规则的集合,这些规则要发挥相应的作用,则需要ingress
controller,其可监听套接字,然后给据这些规则的匹配机制路由请求流量。
注意 :
ingress 不同于deployment,其不是直接运行与kube-controller-manager的一部分,其是kubernetes集群的一个重要附件,需要单独安装才能使用。
ingress
控制器可以由任何具有反向代理(http/https)功能的服务器程序实现,如nginx、envoy、haproxy、vulcand和traefik等,ingress控制器自身也是运行与集群中的POD资源对象,其与北代理的运行的POD资源的应用运行于同一网络中。另外:
ingress控制器可基于ingress资源定义的规则将客户端请求流量直接转发到service对应的后端POD资源上,其会绕过service资源,省去了kube-proxy实现的端口代理开销。
ConfigMap功能在Kubernetes1.2版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap
API给我们提供了向容器中注入配置信息的机制,ConfigMap可以用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod
Spec中。Secret可以以Volume或者环境变量的方式使用。
Secret有三种类型:
Service Account用来访问Kubernetes
API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secret/kubernetes.io/serviceaccount目录中。
Opaque类型的数据是一个map类型,要求value是base64编码格式;
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器奔溃时,
Kubelet会重启它,但是容器中的文件将丢失—容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中的volume抽象就很好的解决了这些问题。
背景:
Kubernetes中的卷有明确的寿命—与封装它的Pod相同。所以,卷的生命比Pod中的所有容器都长,当这个容器重启时数据仍然得以保存。当然,当Pod不再存在时,卷也将不复存在。也许更重要的是,kubernetes支持多种类型的卷,Pod可以同时使用任意数量的卷。
当Pod被分配给节点时,首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上,当出于任何原因从节点中删除Pod时,empty中的数据将被永久删除。
emptyDir的用法有:
hostPath卷将主机节点的文件系统中的文件或目录挂载到集群中。
hostPath的用法如下:
使用这种卷类型时请注意,因为:
是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV是Volume之类的卷插件,但具有独立于使用PV的Pod的生命周期。此API对象包含存储实现的细节,即NFS、iSCSI或特定于云供应商的存储系统。
是用户存储的请求。它与Pod相似,Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或
只读多次模式挂载)
静态pv:
集群管理员创建一些pv。它们带有可供群集用户使用的实际存储的细节。它们存在于Kubernetes API中,可用于消费。
动态:
当管理员创建的静态PV都不匹配的PersistentVolumeClaim时,集群可能会尝试动态地为PVC创建卷。此配置基于storageClasses:PVC必须请求[存储类],并且管理员必修创建并配置该类才能进行动态创建,声明该类为“”可以有效地禁用其动态配置。
要启用基于存储级别的动态存储配置,集群管理员需要启用API
Service上的DefaultStorageClass[准入控制器]。例如,通过确保DefaultStoragClass 位于API
Service组件的–admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作。
绑定:
Master中的控制环路监视新的PVC,寻找匹配的PV(如果可能),并将它们绑定在一起。如果为新的PVC动态调配PV,则该环路将始终该PV绑定到PVC。否则,用户总会得到它们所请求的存储,但是容量可能超出要求的数量。一旦PV和PVC绑定后,PersistentVolumeClaim绑定是排他性的,不管它们是如何绑定的。PVC跟PV绑定是一对一的映射。
PVC保护的目的是确保由pod正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失
当启用PVC保护alpha功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,直到PVC不再被任何pod使用。
PersistentVolume可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个PV的访问模式都将被设置为该卷支持的特定模式。例如,NFS可以支持多个读/写客户端。但特定的NFS PV可能以只读方式导出到服务器上。每个PV都有一套自己的用来描述特定功能的访问模式。
在命令行中,访问模式缩写为:
卷可以处于以下的某种状态:
命令行会显示绑定到PV到PVC的名称
StatefulSet使用场景:
Scheduler是Kubernetes的调度器,主要任务是把定义的pod分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:
Scheduler是作为单独的程序运行的,启动之后会一监听API
Service,获取PodSpec.NodeName(节点名称)为空的Pod,对每个pod都会创建一个binding,表明该pod应该放到哪个节点上。
调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为predicate;然后对通过的节点按照顺序优先级排序,这个是priority;最后从中选择优先级最高的节点。如果中间任何一步有错误,就直接返回错误。
如果predicate过程中没有合适的节点,pod会一直在pending状态,不断重试调度,直到节点满足条件。经过这个步骤,如果有多个节点满足条件,就继续priorities(优先事项)过程,按照优先级大小对节点排序。
优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。
这些优先选项包括:
除了Kubernetes自带的调度器,你也可以编写自己的调度器。通过spec:schedulername参数指定调度器的名字,可以为pod选择某个调度器进行调度。比如下面的pod选择my-scheduler进行调度,而不是默认的default-scheduler:
pod.spec.nodeAffinity
几点亲和性,是pod的一种属性(偏好或硬性要求),它使pod被吸引到类特定的节点。Taint则相反,它使节点能够排斥一类特定的pod。
Taint额Toleration相互配合,可以用来避免pod被分配到不合适的节点上,每个节点都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的pod,是不会被该节点接受的。如果亮toleration应用于pod上,则表示这些pod可以(但不要求)被调度到具有匹配的taint的节点上。
污点的组成:
使用Kubectl
taint命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去。
每个污点的组成如下:
Key-value:effect
每个污点有一个key和value作为污点的标签,其中value可以为空,effect(影响)描述污点的作用。当前taint
effect支持如下三个选项: ·NoSchedule:表示K8S将不会将Pod调度到具有该污点的Node上
·PreferNoSchedule:表示K8S将尽量避免将Pod调度到具有该污点的Node上。
·NoExecute:表示K8S将不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐出去。
设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到Node上。但我们可以在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。
当不指定key值时,表示可以容忍所有的污点key:
当不指定effect值时,表示容忍所有的污点作用:
有多个Master存在时,防止资源浪费,可以如下设置:
Kubectl taint nodes Node-Name node-role.kubernetes.io/master=:PerferNoSchedule
Pod.spec.nodeName将Pod直接调度到指定的Node节点上,会跳过Scheduler的调度策略,该匹配规则是强制匹配。
Pod.spec.nodeSelector:通过kubernetes的label-selector机制选择节点,由调度器调度策略匹配label,而后调度Pod到目标节点,该匹配规则属于强制约束。
Kubernetes作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。API Service是集群内部各个组件通信的中介,也是外部控制的入口。所以Kubernetes的安全机制基本就是围绕保护API Service来设计的。Kubernetes使用了认证(Authentication)、鉴权(Authorization)、准入机制(AdmissionControl)三步来保证API Service的安全。
HTTP
Token的认证是用一个很长的特殊编码方式的并且难以被模拟的字符串。Token来表达客户的一种方式。Token是一个很长的很复杂的字符串,每一个Token对应一个用户名存储在API
Service能访问的文件中,当客户端发起API调用请求时,需要在HTTP Header里放入Token
用户名+:+密码 用BASE64算法进行编码后的字符串放在HTTP Request中的Heather
Authorization域里发送给服务端,服务端收到后进行编码,获取用户名及密码。
两种类型:
安全性说明:
证书颁发:
kubeconfig文件包含集群参数(CA证书、API
Server),客户端参数(上面生成的证书和私钥),集群context信息(集群名称、用户名)。Kubernetes组件通过启动时指定不同的kubeconfig文件可以切换到不用的集群。
Pod中的容器访问API
Server。因为Pod的创建,销毁是动态的,所以要为它手动生成证书就不可行了。kubernetes使用了Server
Account解决Pod访问API Server的认证问题。
Kubernetes设计了一种资源对象叫做Secret,分为两类,一种是用于ServerAccount的service-account-token,另一种是用于保存用户自定义保密信息的Opoque。ServerAccount中用到包含三个部分:Token、ca.crt、namespace
默认情况下,每个namespace都会有一个ServiceAccount,如果Pod在创建期间没有指定的ServiceAccount,就会使用Pod所属的namespace的ServiceAccount
上面认证过程,只是确认通信的双方都确认了对方是可信的,可以相互通信。而鉴权是确定请求方有哪些资源的权限。API Server目前支持以下几种授权策略(通过API Server的启动参数”–authorization-mode”设置)
RBAC(Role-Based-Access-Control)基于角色的访问控制,在Kubernetes1.5中引入,现行版本成为默认标准。相对其他访问控制,拥有以下优势:
需要注意的是Kubernetes并不会提供用户管理,那么User、Group、ServerAccount指定的用户又是从哪里来的呢?Kubernetes组件(kubectl、kube-proxy)或是其他自定义的用户在想CA申请证书时,需要提供一个证书请求文件。
API Server会把客户端证书的CN字段作为User,把names.0字段作为Group。 Kubelet使用TLS
Bootstaping认证时,API Server可以使用Bootstrap Token或者Token。 authentication
file验证=token,无论哪一种,kubernetes都会为token绑定一个默认的User和Group。
Pod使用ServiceAccount认证时,service-account-token中的JWT会保存User信息。
有了用户信息,再创建一对角色/角色绑定(集群角色/集群角色绑定)资源对象,就可以完成权限绑定了。
在RBAC
API中,Role表示一组规则权限,权限只会增加(累加权限),不存在一个资源一开始就有很多权限而通过RBAC对其进行减少的操作;Role可以定义在一个namespace中,如果想要跨namespace则可以创建ClusterRole
ClusterRole具有与Role相同的权限角色控制能力,不同的是ClusterRole是集群级别的,ClusterRole可以用于:
RoleBinding可以将角色中定义的权限授权用户或用户组,RoleBinding包含一组权限列表(subjects),权限列表中包含有不同形式的待授予权限资源类型(users,groups,or
service
accounts);RoleBinding同样包含对被Bind的Role引用;RoleBinding适用于某个命名空间内授权,而ClusterRoleBinding适用于某个命名空间内授权,而ClusterRoleBinding适用于集群范围内的授权。
将default命名空间的pod-reader
Role授予jane用户,此后jane用户在default命名空间中将具有pod-reader的权限。
RoleBinding同样可以引用ClusterRole来对当前namespace内用户、用户组或ServiceAccount进行授权,这种操作允许集群管理员在整个集群内定义一些通用的ClusterRole,然后在不同的namespace中使用RoleBinding。
例如,以下RoleBinding引用了一个ClusterRole。这个ClusterRole具有整个集群内对secrets的访问权限;但是其授权用户dave只能访问development空间中的secrets(因为RoleBinding定义在development命名空间)
使用ClusterRoleBinding可以对整个集群中的所有命名空间资源权限进行授权;以下ClusterRoleBinding样例展示了授权manager组内所有用户在全部命名空间中对secrets进行访问。
Kubernetes集群内一些资源一般以其名称字符串来表示,这些字符串一般会在API的URL地址中出现;同时某些资源也会包含子资源。例如logs资源就属于pods的子资源,API中样例如下:
如果要在RBAC授权模型中控制这些子资源的访问权限,可以通过/分隔符来实现。以下是一个定义pods资源logs访问权限的Role定义样例:
RoleBinding和ClusterRoleBinding可以将Role绑定到Subjects可以是groups、users或者service
accounts。
Subject中Users使用字符串表示,它可以是一个普通的名字字符串,如”alice”;也可以是email格式的邮箱地址,如”[email protected]”;甚至是一组字符串形式的数字ID。但是Users的前缀system:是系统保留的,集群管理员应该确保普通用户不会使用这个前缀格式。
Groups书写格式与Users相同,都为一个字符串,并且没有特定的格式要求:同样ststem前缀为系统保留。
准入控制是API Service的插件集合,通过添加 不同的插件,实现额外的准入控制规则。甚至API Server的一些主要功能都需要通过Admission Controller实现,比如ServiceAccount
官方文档上有一份针对不同版本的准入控制器推荐列表,其中最新的1.14的推荐列表是:
列举几个插件的功能:
在没使用helm之前,向kubernetes部署应用,我们要依次部署deployment、svc等,步骤较繁琐。况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm通过打包的方式,支持发布的版本管理和控制,很大程度上简化了kubernetes应用的部署和管理。
Helm本质就是让K8S的应用管理(Deployment、Service等)可配置,能动态生成。通过动态生成k8s资源清单文件(deployment.yaml、service.yaml)。然后调用kubectl自动执行k8s资源部署。
Helm是官方提供的类似于YUM的包管理器,是部署环境的流程封装。Helm有两个重要的概念:chart和release
·chart是创建一个应用的信息集合,包括各种Kubernetes对象的配置模板、参数定义、依赖关系、文档说明等。Chart是应用 部署的自包含逻辑单元。可以将chart想象成apt、yum中的软件包。
·release是chart的运行实例,代表了一个正在运行的应用。当chart被安装到kubernetes集群,就生成一个release。Chart 能够多次安装到同一个集群,每次安装都是一个release。
Helm包含两个组件:Helm客户端和Tiller服务器,如下图所示:
Helm客户端负责chart和release的创建和管理以及和Tiller的交互。Tiller服务器运行在kubernetes集群中,它会处理Helm客户端的请求,与kuberestes API Server交互。
越来越多的公司和团队开始使用Helm这个Kubernetes的包管理器,我们也将使用Helm安装Kubernetes的常用组件。Helm由客户端helm令行工具和服务端tiller组成,Helm的安装十分简单。下载helm命令行工具到moster节点node1 的/usr/locai/bin下,这里下载的2.13.1版本:
为了安装服务端tiller,还需要在这台机器上配置好kubectl工具和kubeconfig文件,确保kubectl工具可以在这台机器上访问apiserver且正常使用。这里的node1节点以及配置好了kubectl
因为kubernetes API Server开启了RBAC访问控制,所以需要创建tiller使用的service account:tiller并分配合适的角色给它。这里简单直接分配cluster-admin这个集群内置的ClusterRole给它,创建rbac-config.yaml文件:
Tiller默认被部署在K8S集群中的kue-system这个namespace下:
Kubernetes对资源的限制实际上是通过cgroup来控制的,cgroup是容器的一组用来控制内核如何运行进程的相关属性集合,针对内核、CPU和各种设备都有对应的cgroup
默认情况下,Pod运行没有CPU和内存的限额。这意味着系统中的任何Pod将能够像执行该Pod所在的节点一样,消耗足够多的CPU和内存。一般会针对某些应用的pod资源进行资源限制,这个资源限值是通过resources的requests和limits来实现。
Requests要分配的资源,limits为最高请求的资源值。可以简单理解为初始值和最大值。
计算资源配额
配置对象数量配额限制
配置CPU和内存LimitRange
部署Elasticsearch
部署Fluentd
部署kibana
Go环境部署
下载源码
修改kubeadm源码包更新证书策略
更新kubeadm
更新各节点证书至Master节点