2-1 了解kubernetes
核心目标:为了自动化、应用部署、扩缩容自动化、管理、容器化的应用。
建立在Google 15年的生产积累,大量时间实践过的,优秀的社区实践经验。
使用经验来自ber,非常老的系统了。以ber的容器实践基础。
不用关心服务的运行环境细节。
K8S部署的系统可以独立运行在物理机、虚拟机、私有云,在什么地方运行都是无差别的。
另外特征,自动化,自动扩缩容、升级、更新、部署。
比如K8S在收到一个指令之后,会触发调动流程,选中目标节点,部署或停止相关的服务。
如果有一个新的POD启动,会自动的加入负载均衡器,自动生效,在服务自动运行中,K8S会自动的定期检查它们的实例数、实例状态是否正常,某个实例不可用,自动销毁这个不可用实例,而会重新调度新的实例。以上所有过程,不需要人工参与,全部自动化完成的。
Kubernetes VS Docker
二者关系。
K8S可以看成是docker的上层架构,以docker的技术标准为基础,打造一个全新的分布式架构系统,K8S并不一定要依赖于docker,docker只是一个产品,docker技术本质是一系列的标准,只要实现这个标准的产品都可以替代docker。
K8S所以在底层可以支持自己的容器技术,并且经过了Google的某些优化,声称在某些方面做的比docker更加优秀。
2-2 kubernetes的核心概念
一个容器是由一个镜像起来的。通过一个镜像运行了一个容器。容器外面就是POD。
一个容器Container都是由一个镜像起来的。
容器外面一层是K8S中的POD
POD中可以有一个或多个容器。
POD特征:
里面的所有容器都是运行在一台机器中;
里面的所有容器的共享网络,有一个唯一的IP;
每一个POD中都会有一个容器是PAUSE容器(一般有一个特有的固定镜像,eg:pause-v1.0);
这个PAUSE镜像的作用是作为跟容器把其他容器link到一起,类似于docker与pause。
比如POD的另外一个容器,镜像是user-image:v1,这个pause容器就会把每个容器link一下,把大家关联到一起。
PAUSE容器的另外功能,负责整个POD的健康检查汇报给K8S。
当业务里面有两个容器或多个容器,关系非常紧密,可以考虑把它们放在同一个POD里面。
POD的上一层是RS:ReplicaSet,副本集。
在同一个应用下,要运行几个实例,就是管这个的。
比如同一个应用负责运行两个POD,RS把这俩一模一样的POD关联起来。
如果有一个POD运行异常/退出,RS就会保证这个副本始终为2,在另一个机器重启调度起一个。
在RS的上一层,Deployment部署。
当一个旧的应用运行了两个实例,要更新这个应用,会发生什么?
比如旧的两个应用就是左边两个POD,当更新应用的时候,就是更新的这个Deployment,Deployment会自动的帮我们创建一个RS副本集,并且会自动的申请一个新版本的POD,POD容器是一样的,第一个服务没有改变,改变了login-image:v1变成login-image:v2,进行了升级,这个副本集RS就会先启动一个实例POD,那么此时Deployment管理的就是三个实例,正在对外提供服务的就是这三个实例。
新的POD启动完成, 健康检查之后 ,控制旧的RS会先停掉最左边的POD,并删掉。
那么现在就有一个新版本和一个旧版本。
旧版本下掉一个。
通过新的RS再创建一个POD,新的POD也会被新的RS管理起来,新启动的这个POD 健康检查之后 ,同样请求旧的RS把另一个POD停掉,停掉之后会把旧RS也清理掉,此时服务更新的过程也就完成了。
这就是一个滚动部署的过程。
真正使用的过程中,RS的使用和POD的创建都是不需要我们去管理的,管理的层面只在Deployment,Deployment会自动的帮创建和销毁RS,和整个POD的过程。
服务Service也是K8S的一个重要概念。
要了解Service,首先要了解Label标签,标签是K8S中非常多的东西,许多组件都可以进行打标签,起到了一个标识作用,Deployment、POD也都可以打标签。
比如一个单点登录服务的标签是app:login
Service中的Selector(app=login)表示,这个Service管理的POD要有app=login的标签,那么会自动找到这两个POD。
Service对外会有一个ClusterIP。
Client通过ClusterIP就会访问到最底层的POD服务。
2-3 kubernetes的架构设计
服务器分为两种角色
一种master主节点,负责管理这些worker节点。
一种worker。
1、应用一般都有自己的存储:文件存储、数据库、存储中间件。
K8S也需要自己的存储,因为要管理节点与服务。
这些信息要放在一个地方,如果不进行持久化,那么出现问题导致机器的重启,数据的丢失,导致服务无法恢复。
K8S选择存储的组件是ETCD(集群)。
2、存储有了,如何访问集群?创建一个服务,如何跟K8S交互?
那么K8S的Master上有一个服务:ApiServer,操作K8S的唯一入口。对外提供http/https的API,ApiServer接收到了客户端的请求之后,比如创建Deployment的请求,首先要选择一个节点,把POD调度上去。如何选择?K8S的另一个组件,scheduler调度器。
3、Scheduler会收集每一个worker的详细信息,包括资源、内存、CPU、节点上运行的什么服务等,经过一系列的算法,算法有两大类,一个是预选策略,一个是优选策略,最终选择出最优的节点,把节点和POD建立出关系,告诉ApiServer,说这个POD可以运行在某一个节点上。
4、ApiServer会把这个消息存在ETCD中做持久化。
POD的NODE节点做一个绑定关系之后,接下来需要真正的启动POD,用另一个模块ControllerManager,它是集群内部的控制中心和维护各种各样的K8S对象,比如有ServiceController可以管理服务的,PodController管理POD列表的,ReplicationController管理副本的,ResourceCallerController管理资源配额的,它会时刻关注这些内容的状态,时刻会保证它们处于一个正确的状态。
5、接着上述调度过程,
ControllerManager会通过APISERVER从获取ETCD节点的变化,比如POD跟节点的绑定关系内容,就会被ControllerManager监听到,会通过一些目录发现POD当前处于等待调度的状态,完成这个调度,让POD运行起来。
6、POD怎么在worker运行起来的?那么需要在每个worker事先装好一个服务Kubelet,Kubelet在每一个worker都存在,Kubelet负责维护POD的生命周期,包括容器的wallm和网络管理,最终Kubelet会调用本地的docker,运行起来容器,运行起来一个个的POD。
2-4 kubernetes认证的密码学原理
原生K8S搭建非常复杂,一半原因归功于认证和授权的机制。
操作和理解都麻烦。
所以这里一定要搞清楚。
K8S的所有资源都是通过ApiServer组件来实现的。
所以集群关键的点在于ApiServer。
在于其如何实现客户端的身份以及随后通过ApiServer访问权限的授权资源。
认证解决的是什么问题?要防止什么事情发生?
网络安全是解决某些假设的成立下,应该如何防范的问题。
这是在任何需要在网络上访问的服务都需要面临的问题。
肯定已经被解决掉了。
业内是如何解决这类问题发生的?
要了解一下密码学的两个概念。
比如这里举个例子:
对称加密。加解密秘钥一样。
非对称加密。加解密秘钥不一样。公钥和私钥。
最后,简单总结一下,
非对称加密复杂。性能损耗高。
对称加密性能高。
两种方法结合到一起。
为了提高安全性,这里引入CA证书:
HTTPS基于SSL/TLS协议。
2-5 kubernetes的认证与授权 (非常重要)
----非常重要,特别是认证和授权的过程。
2、5、1认证(访问APISERVER的第一关)
认证是访问APISERVER的第一关。
====认证方式一(集群的外部进行认证):
1、Kuberctl访问ApiServer的时候,ApiServer是集群的唯一入口。
集群中的各个组件都是通过ApiServer建立起联系的。
2、TLS双向认证。
Kuberctl访问ApiServer的时候,第一步要认证,ApiServer要知道,访问的人是谁。
这里要讲的是客户端证书认证方式去跟APISERVER进行认证。
TLS是一种协议,双向协议。
Kubectl在访问ApiServer的时候,要认证ApiServer的证书是否是合法的,也要验证ApiServer是否是真正的ApiServer。
ApiServer被Kuberctl访问的时候,也要验证Kuberctl客户端是否合法。
所以说它们之间的认证是一个双向认证。
3、在验证的时候,它们之间需要做什么事情。
它们之间需要先有一个CA,判断证书的合法性,K8S并不是用的网站共有机构,K8S用的是自己的认证中心。K8S用的是自己的认证机构中心CA,而不是网站使用的CA。K8S在自定义的CA中去给每一个组件颁发证书,(组件:scheduler、controllerManager、etcd)只要需要证书,CA就会给每个组件颁发证书。
4、当Kuberctl访问ApiServer的时候,Kuberctl会把自己的证书发给ApiServer,ApiServer会把自己的证书发给Kuberctl,二者之间互相验证对方的证书是否是K8S自己的CA颁发的,是就可以通过认证来进行加密的通信。这个通信过程就是客户端证书认证。
====认证方式二(集群的外部进行认证):
非常复杂的密码。预先定义在APISERVER中,把密码告诉自定义客户端,客户端再跟APISERVER通信的时候,把这个BEARERTOKEN带上,APISERVER验证没问题就可以通信了。
在开发基于K8S的容器管理平台时,可以通过BEARERTOKEN方式来访问APISERVER。
====认证方式三(集群的内部进行认证)::
SERVICEACCOUNT是用于在K8S的内部运行的POD运行的容器,这个容器POD要跟APISERVER打交道时,就要使用SERVICEACCOUNT的方式。
SERVICEACCOUNT跟K8S的其他资源都是一样的,可以创建自己的SERVICEACCOUNT????
SERVICEACCOUNT主要包含三个内容:namespace命名空间、token密码、ca验证APIserver的证书。
SERVICEACCOUNT中的这些信息都会通过目录挂载的方式挂载到POD的文件系统里,应用就可以通过读取指定目录的文件来获取上述三个信息,之后就可以跟APISERVER进行通信。
2、5、2授权(访问APISERVER的第二关)
认证是访问APISERVER的第一关,那么授权是访问APISERVER的第二关。
认证身份没问题,那么要知道这个身份的这个人能干什么事情。
1、K8S中有一系列的鉴权机制:
ABAC
WebHook
RBAC(Role Based Access Control):RBAC是K8S的1.6版本引入的最新的授权策略,社区投入相比其他两种更丰富,RBAC更好的选择。基于角色的访问控制。
2、一般的权限系统设计结构,这种三层结构(role和authority会因不同的系统设计而不同):
用户user
角色role
权限Authority
K8S权限系统设计方式
3、看一下K8S是怎么设计这个权限系统的?
3、1首先用户的设计:两种用户,在用户层面区分。
普通用户User:客户端或者通过XXController访问APISERVER
另一种用户ServiceAccount:专门用于在集群内部访问APISERVER
3、2权限Authority的设计:权限层面。K8S有很多类型的资源和对象(pod、deployment、service)
资源维度Resource的权限(要把资源和对象区分开,什么样的资源是可以访问的,什么样的资源是不可以访问的)。
资源控制的方式Verbs(动作:列表list、create新增、UPDATE更新、PATCH部分更新、DELETE删除)。
3、3角色ROLE的设计:
名称name、资源权限resource、操作动作verbs
K8S权限系统授权方式
====授权方式一:
====授权方式2:
命名空间namespace,对K8S资源起到了一个隔离的作用。
一种情况:一个人只能访问某一个或某几个命名空间下的资源,这样的设计并不能解决问题。
这里整个命名空间并不包含命名空间的任何东西。
于是K8S想到了一个办法,可以把这些角色放在namespace下面。
比如一个命名空间叫做test,那么这个role就属于这个Test命名空间下面,
如果拥有了这个Role角色,那么只能拥有这个当前命名空间test下的角色对应的权限。
那么这个命名空间的问题就解决了。
====授权方式3:
1、一种需求,跨namespace,如果一个人拥有所有的权限呢。
K8S提出了另外一种角色,ClusterRole集群角色、ClusterRoleBinding集群角色绑定。这个集群的角色除了可以定义跟普通角色一样的resource和verbs以外,还可以定义集群范围内的资源。
并不是所有资源都属于一个namespace,比如node的K8S的nodes返回集群的机器列表,node节点这个资源,就不属于namespace,但也属于一个资源。
这种情况如果要给一个人node的操作权限,就需要定义一个clusterrole,就需要把node资源加入到角色clusterrole中,那么此角色的控制就比较灵活了,可以满足各种各样的需求了。
2、如果一个人需要某一个或某几个namespace下的权限,就可以定义对应的几个role,再把它对应的rolebinding关联起来。
3、如果用户需要整个集群的PODS SERVER 的访问权限,可以定义ClusterRole,可以在这个ClusterRole中的resource中指定pods和service,建立ClusterRoleBinding,绑定用户到ClusterRole上,就可以访问集群范围内的service和pod了,不受命名空间namespace的制约了。
4、再说下User中的user,
RoleBinding和ClusterRoleBinding都是同时支持普通User和ServiceAccount的,可以认为在权限设计中,这二者是对等的概念。此时第二步授权就通过了。
----虽然现在授权过了,但是此时还不能通过请求。
====还有一关:准入控制AdmisionControl:
准入控制AdmisionControl可以理解为,一个个的小插件,一个个的小插件之间独立存在,没之间的联系。
请求会一个一个的会从准入控制的代码段中执行一遍,都走完,就通了。具体执行哪些,顺序是啥样的,在配置APISERVER的时候指定的。
可以理解成java中的一个个的filter,在K8S中的AdmisionControl默认有二十种左右。
简单提几个准入控制插件:
AlwaysAdmit总是允许所有的请求通过。
AlwaysDeny用于测试,所有的请求都会被拒绝。
ServiceAccount(跟User中的ServiceAccount不是同一个概念)是把User中的ServiceAccount提供自动化,辅助User中的ServiceAccount做一些事情。比如某些pod没有ServiceAccount,它会添加一个当前命名空间的默认的ServiceAccount,确保ServiceAccount在每个pod中都存在。
DenyEscolatingExec用于拒绝所有的exec和tech?到一些具有特权的pod上。用来限制登录到容器里面,去执行命令的安全层面的插件。
标题:Kubernetes(二)Kubernetes学习前的了解
作者:yazong
地址:https://blog.llyweb.com/articles/2022/10/27/1666853025422.html