初识K8s集群

作者:yang.yanan

        Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,它的目标是让部署容器化的应用简单并且高效,提供了应用部署,规划,更新,维护的一种机制。Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着(比如用户想让apache一直运行,用户不需要关心怎么去做,Kubernetes会自动去监控,然后去重启,新建,总之,让apache一直提供服务)。

        接下来就带大家熟悉kubernetes中的常见的资源对象以及涉及操作命令。kubernetes中的大部分概念如note、pod、replication controller、service等都可以看作一种“资源对象”。

一、master

        master是集群控制节点,每个kuberneters集群里需要有一个master节点来负责整个集群的管理和控制,基本上kuberneters所有的控制命令都是发给他,它来负责具体的执行过程,如果它宕机或者不可用,那么所有的控制命令都将失效。

        其上运行着以下一组关键进程:

        1、kube-apiserver:是所有资源的增删改查等操作的唯一入口,也是集群控制的入口进程。

        2、kube-controlerr-manager:所有资源对象的自动化控制中心,可理解为资源对象的“大总管”。

        3、kube-scheduler:负责资源调度(pod调度)的进程。

        4、etcd server:进程,所有资源对象的数据全部是保存在etcd中。

二、node

        node可为物理主机或虚拟主机,工作负载节点,每个node都会被master分配一些工作负载(docker容器)。当某个node宕机,其上的工作负载会被master自动转移到其他节点上去。每个node节点上都运行着以下一组关键进程:

        1、kubelet:负责pod对应的容器的创建、启停等任务,同时与master节点密切合作,实现集群管理的基本功能。

        2、kube-proxy:实现kuberneters service的通信与负载均衡机制的重要组件;

        3、docker engine:docker引擎,负责本机的容器创建和管理工作。

        举例说明如下:

        1、查看集群中有多少个node的命令:kubectl get nodes

        2、查看某个node的详细信息的命令:kubectl describe node node名称

 

 

  • node基本信息:名称name、标签labels、创建时间CreationTimestamp等。

  • node当前的运行状态,node启动以后会做一系列的自检工作,比如:检查内存是否不足(memoryPressure=true),最后一切正常,就切换为Ready状态(ready=true),这种情况表示node处于健康状态,可以在其上创建新pod.

  • node的主机地址与主机名(Addresses);

  • node 上的资源总量(Capacity):描述node可用的系统资源,包括CPU、内存数量、最大可调度Pod数量等。

  • node可分配资源量(Allocatable):描述node当前可用于分配的资源量;

  • 主机系统信息(System Info):包括主机的唯一标识UUID、Linux kernel版本号、操作系统类型与版本、kubelnetes版本号、kubelet与kube-proxy的版本号等。

  • 当前正在运行的Pod列表概要信息(Non-terminates Pods)

  • 已分配的资源使用概要信息(Allocatable resources),例如资源申请的最低、最大允许使用量占系统总量的百分比。

  • node相关的event信息

        event是一个事件的记录,记录来了事件的最早产生时间、最后重现时间、重复次数、发起者、类型、以及导致此事件的原因等众多信息。event通常会关联到某个具体的资源对象上,

        例如:

        查看某个pod的描述信息:kubectl describe pod ,如下展示的event信息

三、Pod

        每个pod都有一个特殊的被称为“跟容器”的Pause容器,Pause容器对应的镜像属于kubernetes平台的一部分,除了Pause容器,每个pod还包含一个或多个紧密相关的用户业务容器user container .为每一个pod都分配了唯一的IP地址,称podIP,一个pod里的多个容器共享podIP。

        所有资源对象都可以采用yaml或者JSON格式的文件来定义或描述。

        举例说明:下面的例子为一个pod定义文件:

  • kind:pod,表明这是一个pod的定义;

  • metadata:name为pod名称,labels声明pod有一个标签;

  • container:名称name、image镜像;

  • env:该容器注入了MYSQL_SERVICE_HOST=mysql和MYSQL_SERVICE_PORT=3306两个环境变量;

  • ports:podIP加上这个容器端口,组成一个Endpoint,代表此Pod里的一个服务进程的对外通信地址。

        每个pod都可以对其能使用服务器上的计算资源设置限额,目前可以设置限额的计算资源有:CPUMemory两种:CPU的资源单位为CPU(Core)的数量,是一个绝对值,通常一个容器的的CPU配额被定义为100~300m,即占用0.1~0.3个CPU。Memory配额也是一个绝对值,单位是内存字节数。

        在kubernetes里,一个计算资源进行配额限定需要设定2个参数:request:该资源的最小申请量,系统必须满足要求。limits:该资源最大允许使用的量,不能被突破,当容器试图使用超过这个量的资源时,可能会被kubernetes kill并重启。

        举例说明:下面定义标明该容器申请最少0.25个CPU及64MiB,在执行过程中容器所能使用的资源配额为0.5个CPU及128MiB内存,

四、Label

        label是一个key=value的键值对,key和value由用户自己指定。label可以附加到各种资源对象上,如node、pod、service、rc等;一个资源对象可以定义任意数量的label,同一个label也可以添加到任意数量的资源对象上去。可通过给指定的资源对象捆绑一个或多个不同的label来实现多维度的资源分组管理功能,以便灵活进行资源分配、调度、配置、部署等管理工作。

        可通过label selector(标签选择器)查询和筛选拥有某些label的资源对象,当前有两种表达式:基于等式和基于集合,

        例如

        1、name=redis-slave:匹配所有具有标签name=redis-slave的资源对象;

        2、env!=redis-slave: 匹配所有不具有标签env!=redis-slave的资源对象,比如env=test满足此条件;

        3、name in**(redis-master,redis-slave)**:匹配所有具有标签name=redis-slave或者name=redis-master的资源对象;

        4、name not in(name=redis-slave):匹配所有不具有标签name=redis-slave的资源对象。

        多个表达式之间用“,”分隔,几个条件是“AND”的关系:

五、Replication Controller(RC)

        Replication Controller(RC):声明某种pod的副本数量在任意时刻都符合某个预期值。

        RC的定义包括:

        1、pod期待的副本数(replicas);

        2、用于筛选目标pod的label selector;

        当pod的副本数量小于预期数量时,用于创建新pod的pod模板(template)。

 

        举例说明:下面RC的例子即确保拥有tier=frontend标签的pod,在整个kubernetes集群中始终只有一个副本

        删除RC并不会影响通过RC已创建好的pod。为了删除所有pod,可以设置replicas=0,然后更新RC。还可以stop 和delete命令来一次性删除RC和RC控制的全部pod。

        RC的特性和作用:

        1、在大多数情况下,通过定义一个RC实现pod的创建过程及副本数量的自动控制;

        2、RC里包括完整的pod定义模板;

        3、RC通过label selector机制实现对pod副本的自动控制;

        4、通过改变RC里的pod副本数量,可以实现pod的扩容或缩容功能;

        5、通过改变RC里pod模板中的镜像版本,可实现pod的滚动升级功能。

六、Deployment

        Deployment:解决pod编排问题,相对于RC的升级。

        使用场景:

        1、创建一个deployment对象来生成对应的replica set并完成pod副本的创建过程。

        2、检查deployment的状态来看部署动作是否完成(pod副本的数量是否达到预期的值)。

        3、更新deployment以创建新的pod(比如镜像升级)。

        4、如果当前deployment不稳定,则回滚到一个早先的deployment版本。

        5、挂起或恢复一个deployment。

        举例说明:首先创建一个yaml文件,内容如下:

        运行kubectl create -f 文件名命令创建Deployment:

        运行kubectl get deployment命令查看信息:

  • DESIRED:pod副本数量的期望值,即deployment里定义的replicas。

  • CURRENT:当前replics的值,这个值不断增加直到达到DESIRED为止,表明整个部署过程完成

  • UP-TO-DATE:最新版本的pod的副本数量,用于指示在滚动升级的过程中,有多少个pod副本已经成功升级。

  • AVAILABLE:当前集群中可用的pod副本数量,即集群中当前存活的pod数量。

七、service

        运行在每个node上的kube-proxy进程其实就是一个智能的软件负载均衡器,它负责把对service的请求转发到后端的某个pod实例上,并在内部实现服务的负载均衡与会话保持机制。每个service分配了一个全局唯一的虚拟地址,称cluster IP。

        举例说明:

        1、首先创建一个yaml定义文件,内容如下,定义了一个名为thinkweb-svc的service,服务端口为8088,拥有app=thinkweb这个label的所有pod实例都属于它:

        2、运行kubectl create -f 文件名命令进行创建service:

        3、运行kubectl get svc命令查看service的列表,其中10.68.188.116是服务的IP地址,端口8088是服务端口:

        4、运行kubectl get svc 服务名 -o -yaml命令可查看service被分配的cluster IP及更多信息:

        在spec.ports的定义中,target Port属性来确定提供该服务的容器所暴露的端口,即具体业务进程在容器内的targetPort上提供TCP/IP介入,而port属性则定义了service的虚端口。没有指定时,默认targetPort与port相同。

        nodeport:外部机器可访问的端口,

        targetport:容器的端口,与dockerfile中的expose端口一致。

        port:服务之间访问的端口

服务发现机制:外部系统访问service的问题

  • node IP是集群中每个节点的物理网卡的IP地址,这是一个真实存在的物理网络,所有属于这个网络的服务器之间都能通过这个网络直接通信,不管它们中是否有部分节点不属于这个kubernetes集群,这也表明了集群之外的节点访问集群之内的某个节点或者TCP/IP服务时,必须通过node IP进行通信。

  • pod IP是每个pod的IP地址,是docker engine根据docker0网桥的IP地址段进行分配的,通常是一个虚拟的二层网络,kubernetes要求位于不同的node上的pod能够彼此直接通信,所以一个pod里的容器访问另外一个pod里的容器,就是通过pod IP所在的虚拟二层网络进行通信的,而真实的TCP/IP流量则是通过nodeIP所在的物理网卡流出的。

  • service的cluster IP,也是一个虚拟的IP,更像是一个“伪造”的IP网络。cluster IP仅仅作用于kubernetes service这个对象,并由kubernetes管理和分配IP地址;cluster IP无法被ping,因为没有一个“实体网络对象”来响应;cluster IP只能结合service port组成一个具体的通信端口,单独的cluster IP不具备TCP/IP通信的基础,并且他们属于kubernetes集群这样一个封闭的空间,集群之外的节点若要访问这个通信端口,则需要做一些额外的工作。

        当一部分服务需要提供给kubernetes集群外部的应用或用户来使用时,采用NodePort方式解决,如下黑体加粗部分:

        NodePort是在kubernetes集群里的每个node上为需要外部访问的service开启一个对应的TCP监听端口,外部系统只要用任意一个Node的IP地址+具体的NodePort端口号即可访问此服务;在任意node上运行netstat -tlp | grep 端口号命令,就可看到有nodeport端口被监听。

八、volume(存储卷)

        volume(存储卷):是pod中能够被对各容器访问的共享目录。

        kubernetes中的volume定义在pod上,然后被一个pod里的多个容器挂载到具体的文件目录下;volume与pod的生命周期相同,但与容器的生命周期不相关,当容器终止或重启时,volume中的数据也不会丢失。

九、namespace(命名空间)

        在很多情况下用于实现多租户的资源隔离。通过将集群内部的资源对象分配给不同namespace中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享使用整个集群的资源的同时还能被分别管理。

        集群在启动后,会创建一个名为default的namespace,通过kubectl get namespace可以查看:

        用户创建的pod、rc、service、deployment时,如果不特别指明namespace,都将被系统创建到这个默认的名为default的namespace中。kubectl get命令不加参数时将仅显示属于”default“命名空间的资源对象,可在kubectl命令中加入--namespace参数来查看某个命名空间的对象。

        kubectl get 资源对象 --namespace=Name 

原文地址:https://www.cnblogs.com/ustcinfo-qc/p/12098064.html