kubernetes运维学习(一)

一、kubernetes运维

Kubernetes是一个全新的基于容器技术的分布式架构领先方案,它是Google再2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernetes也叫K8S。K8S是Google内部一个叫Borg的容器集群管理系统衍生出来的,Brog已经在Google大规模生产运行十年之久。K8S主要用于自动化部署、扩展和管理容器应用,提供了资源调度、部署管理、服务发现、扩容缩容、监控等一整套功能。2015年7月,Kubernetes v1.0正式发布,截至到2017年9月29日最新稳定版本是v1.8。Kubernetes目标是让部署容器化应用简单高校

Kubernetes最初源于谷歌内部的Brog,提供了面向应用的容器集群部署和管理系统。Kubernetes的目标旨在消除编排物理/虚拟计算,网络和存储基础设施的负担,并使应用程序运营商和开发人员完全将重点放在以容器为中心的原语上进行自助运营。Kubernetes也提供稳定、兼容的基础(平台),用于构建定制化的workflows和更高级的自动化任务。

Kubernetes具备完善的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建负载均衡器、故障发现和自我修复能力、服务滚动升级和在线扩容、可扩展的资源自动调度机制、多粒度的资源配额管理能力。Kubernetes还提供完善的管理工具,涵盖开发、部署测试、运维监控等各个环节。

二、Kubernetes主要功能

Kubernetes是docker容器用来编排和管理的工具,它是基于Docker构建一个容器的调度服务,提供资源调度、均衡容灾、服务注册、动态扩容等功能套件。Kubernetes提供应用部署、维护、扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用,其主要功能如下:

**数据卷:**Pod中容器之间共享数据,可以使用数据卷。

**应用程序健康检查:**容器内服务可能进程堵塞无法处理请求,可以设置监控检查策略保证应用健壮性。

**复制应用程序实例:**控制器维护者Pod副本数量,保证一个Pod或一组同类地Pod数量始终可用

**弹性伸缩:**根据设定地指标(cpu利用率)自动缩放Pod副本数。

**服务发现:**使用环境变量或DNS服务插件保证容器中程序发现Pod入口访问地址。

**负载均衡:**一组Pod副本分配一个私有地集群IP地址,负载均衡转发请求到后端容器。在集群内部其他Pod可通过这个ClusterIP访问应用。

**滚动更新:**更新服务不中断,一次更新一个Pod,而不是同事删除整个服务。

**服务编排:**通过文件描述部署服务,使得应用程序部署变得更高效。

**资源监控:**Node几点组件集成Cadvisor资源收集工具,可通过Prometheus抓取数据,存储到prometheus地数据库,再由Grafanan展示。

**提供认证和授权:**支持属性访问控制(ABAC)、角色访问控制(RBAC)认证授权策略。

除此之外,Kubernetes主要功能还体现在:

  • 使用Docker对应用程序包装(package)、实例化(instantiate)、运行(run)
  • 将多台Docker主机抽象为一个资源,以集群地方式运行、管理跨机器地容器,包括任务调度、资源管理、弹性伸缩、滚动升级等功能。
  • 使用编排系统(YAML File)快速构建容器集群,提供负载均衡,解决容器直接关联及通信问题
  • 解决Docker跨机器容器之间地通讯问题。
  • 自动管理和修复容器,简单说,比如创建一个集群,里面有是个容器,如果某个容器异常关闭,那么,会尝试重启或重新分配容器,始终保证会有十个容器在运行,反而杀死多余地。Kubernetes地自我修复机制使得容器集群总是运行在用户期望的状态,当前Kubernetes支持GCE、vShpere、CoreOS、OpenShift。

Kubernetes的集群至少有两个主机组成:master+node,即为master/node架构。master为集群的控制面板,master主机需要做冗余,一般建议为3台;而node主机不需要做冗余,因为node的主要作用是运行pod,贡献计算能力和存储能力,而pod控制器会自动管控pod资源,如果资源少,pod控制器会自动创建pod,即pod控制器会严格按照用户指定的副本来管理pod的数量。客户端的请求下发给master,即把创建和启动容器的请求发给master,master中的调度器分析各node现有的资源状态,把请求调用到对应的node启动容器。

可以理解为kubernetes把容器抽象为pod来管理,到多个彼此间有非常紧密联系的容器。但是LAMP的容器主机A,M,P只是有关联,不能说是非常紧密联系,因此A,M,P都要运行在三个不同的Pod上。在kubernetes中,要运行几个pod,是需要定义一个配置文件,在这个配置文件里定义用哪个控制器启动和控制几个pod,在每个pod里面定义那几台容器,kubernetes通过这个配置文件,去创建一个控制器,由此控制器来管控这些pod,如果这些pod的某几个down掉后,控制器会通过健康监控功能,随时监控pod,发现pod异常后,根据定义的策略进行操作,既可以进行自愈。

kubernetes内部需要5套证书,手动创建和自动生成,分别为:

  • etcd内部通信需要一套ca和对应证书。
  • etcd与外部通信也要有一套ca和对应证书。
  • APIserver间通信需要一套证书。
  • APIserver与node间通信需要一套证书。
  • node和pod间通信需要一套证书

目前来说还不能实现把所有业务迁到kubernetes上,如存储,因为这个是有状态的应用,出现错误排查很麻烦,所以目前kubernetes主要运行无状态服务应用。

所以一般而言,负载均衡运行在kubernetes之外,nginx或者tomcat这种无状态的应用运行于kubernetes集群内部,而数据库入mysql,zabbix,zookeeper等有状态的,一般运行于kubernetes外部,通过网络连接,实现kubernetes集群的pod调用这些外部的有状态应用。

三、Kubernetes架构和组件

在这里插入图片描述

kubernetes主要由以下几个核心组件组成:

  • **ectd:**集群的主数据库,保存了整个集群的状态;etcd负责节点间的服务发现和配置共享。etcd分布式键值存储系统,用于保存集群状态,比如Pod、service等对象信息。
  • **kube-apiserver:**提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;这是kubernetes API,作为集群的统一入口,各组件协调者,以HTTPAPI提供接口服务,所有对象资源的增删改查和监听操作都交给APIserver处理后在提交给Etcd存储。
  • **kube-controller-manager:**负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;它用来执行整个系统中的后台任务,包括节点状态、pod个数、Pods和Service的关联等,一个资源对应一个控制器,而ControllerManager就是负责管理这些控制器的。
  • **kube-scheduler:**资源调度,按照预定的调度策略将Pod调度到相应的机器上;它负责节点资源管理,接受来自kube-apiserver创建pods任务,并分配到某个节点。它会根据调度算法为新创建的Pod选择一个Node节点。
  • **kubectl:**客户端命令行工具,将接受的命令格式化后发送给kube-apiserver,作为整个系统的操作入口。
  • **kubelet:**负责维护容器的生命周期,负责管理pods和它们上面的容器,images镜像、volumes、etcd。同时也负责Volume(CVI)和网络(CNI)的管理;kubelet运行在每个计算节点上,作为agent,接受分配该节点的pods和任务管理容器,周期性获取容器状态,反馈给kube-apiserver;kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、pod挂载数据卷、下载secret、获取容器和节点状态等工作。kubelet将每个pod转换成一组容器。
  • **container runtime:**负责镜像管理以及Pod和容器的真正运行(CRI)
  • **kube-proxy:**负责为Service提供cluster内部的服务发现和负载均衡;它运行在每个计算节点上,负责pod网络代理。定时从etcd获取到service信息来做相应的策略。它在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作。
  • **docker或containerd:**运行容器

除了上面的几个核心组件,还有一些常用插件

  • kube-dns: 负责为整个集群提供DNS服务;
  • **Ingress Controller:**为服务提供外网入口
  • **Prometheus:**提供资源监控
  • **Dashboard:**提供GUI
  • **Metris-server:**监控node和pod资源使用率

其中:

**Master组件包括:**kube-apiserver, kube-controller-manager, kube-scheduler

**Node组件包括:**kubelet,kube-proxy,docker

**第三方服务:**etcd

3.1:Kubernetes Master控制组件,调度管理整个系统(集群),包含如下组件:

  • **Kubernetes API Server:**作为Kubernetes系统入口,其封装了核心对象的增删改查操作,以RESTful API接口方式提供给外部客户和内部组件调用,维护的REST对象持久化到Etcd中存储。
  • **Kubernetes Scheduler:**为新建立的Pod进行节点(node)选择(即分配机器),负责集群的资源调度,组件抽离,可以方便替换成其他调度器
  • **Kubernetes Controller:**负责执行各种控制器,目前已经提供了很多控制器来保证Kubernetes的正常运行。
  • **ReplicaSet:**用于管理Pod副本数量和健康状态,在spec.replicas 字段中可以定义Pod副本数量,ReplicaSet会始终保持Pod在指定数量
  • **Node Controller:**管理维护Node,定期检查Node的健康状态,标识出(失效|未失效)的Node节点
  • **Namespace Controller:**管理维护Namespace,定期清理无效的Namespace,包括Namespace下的API对象,比如Pod、Service等
  • **Service Controller:**管理维护Service,提供负载以及服务代理
  • **EndPoints Controller:**管理维护EndPoints,关联Service和Pod,创建Endpoints为Service的后端,当Pod发生变化时,实时更新Endpoints(即Pod Ip + Container Port)
  • **Servie Account Controller:**管理维护Service Account,为每个Namespace创建默认的Service Account,同时为Service Account创建Service Account Secret
  • **Persistent Volume Controller:**管理维护Persistent Volume和Persistent Volume Claim,为新的Persistent Volume Claim分配Persistent Volume 进行绑定,为释放的Persistent Volume执行清理回收。
  • **Daemon Set Controller:**管理维护Daemon Set,负责创建Daemon Pod,保证指定的Node 上正常的运行Daemon Pod。
  • **Deployment Controller:**管理维护Deployment,关联Deployment和Replication Controller,保证运行指定数量的Pod。当Deployment更新时,控制实现Replication Controller和Pod的更新。
  • **Job Controller:**管理维护Job,为Job创建一次性任务Pod,保证完成Job指定完成的任务数目
  • **Pod Autoscaler Controller:**实现Pod的自动伸缩,定时获取监控数据,进行策略匹配,当满足条件时执行Pod的伸缩动作。

在这里插入图片描述

3.2:Kubernetes Node运行节点,运行管理业务容器,包含如下组件:

  • **Kubelet:**负责管控容器,Kubelet会从Kubernetes API Server接收Pod的创建请求,启动和停止容器,监控容器运行状态并汇报给Kubernetes API Server
  • **kube-proxy:**负责为Pod创建代理服务,kube-proxy会从Kubernetes API Server获取所有的Service信息,并根据Service的信息创建代理服务,实现Service到pod的请求路由和转发,从而实现kubernetes层级的虚拟转发网络
  • **Docker:**Node上需要运行容器服务

在这里插入图片描述

3.3:kubernetes的分层设计理念

kubernetes设计理念和功能类似linux的分层架构,如下图:

在这里插入图片描述

  • **核心层:**kubernetes最核心的功能,对外提供API构架高层的应用,对内提供插件式应用执行环境;
  • **应用层:**部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等);
  • **管理层:**系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等);
  • **接口层:**kubectl命令行工具、客户端SDK以及集群联邦;
  • **生态系统:**在接口层之上的庞大容器管理调度的生态系统,可以划分为两个范畴:
    • kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、Faas、OTS应用、ChatOps等
    • Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等。

四:Kubernetes基本对象概念

Kubernetes中的大部分概念Node、Pod、Replication、Controller、Service等都可以看作一种"资源对象",几乎所有的资源对象都可以通过kubectl工具(API调用)执行增、删、改、查等操作并将其保存在etcd中持久化存储。从这个角度来看,kubernetes其实是一个高度自动化的资源控制系统,通过跟踪对比etcd库里保存的"资源期望状态"与当前环境中的"实际资源状态"的差异来实现自动控制和自动纠错的高级功能。

基本对象

  • **Pod:**Pod是最小部署单元,一个Pod有一个或多个容器组成,Pod中容器共享存储个网络,在同一台Docker主机上运行;Pod中的容器会作为一个整体被Master调度到一个Node上运行。pod是一组container,pod里面的container是共享网络栈和存储卷等资源,是一个整体。pod可以认为是容器组的概念,里面有个infra container负责pod内所有container共享namespace。docker的容器可以类比成OS的进程,而K8S的pod更像是PS中的"进程组"概念。
  • **Service:**Service一个应用服务抽象,定义 了Pod逻辑集合和访问这个Pod集合的策略。Service代理Pod集合对外表现是一个访问入口,分配一个集群IP地址,来自这个IP的请求将负载均衡转发后端pod中的容器。Service通过LabelSelector选择一组Pod提供服务。
  • **Volume:**数据卷,共享Pod中容器使用的数据。
  • **Namespace:**命名空间将对象逻辑上分配到不同Namespace,可以是不同的项目、用户等区分管理,并设定控制策略,从而实现多租户。命名空间也称为虚拟集群。
  • **Label:**标签用于区分对象(比如Pod、Service),键/值对存在;每个对象可以有多个标签,通过标签关联对象。

基于基本对象更高层次抽象:

  • **ReplicaSet:**下一代ReplicationController。确保任何给定时间的Pod飞奔数量,并提供声明式更新等功能。RC与RS唯一区别就是Lableselector支持不同,RS支持新的基于集合的标签,RC仅支持基于等式的标签。
  • **Deployment:**Deployment是一个更高层次的API对象,它管理ReplicaSets和Pod,并提供声明式更新等功能。官方建议使用Deployment管理ReplicaSets,而不是直接使用ReplicaSets,这就意味这可能永远不需要直接操作ReplicaSet对象。负责无状态应用pod控制,支持二级控制器(HPA,HorizontalPodAutoscaler水平pod自动控制器)
  • **StatefulSet:**StatefulSet适合持久性的应用程序,有唯一的网络标识符(IP),持久存储,有序的部署、扩展、删除和滚动更新。负责有状态应用pod控制
  • **DaemonSet:**DaemonSet确保所有(或一些)节点运行同一个Pod。当节点加入Kubernetes集群中,Pod会被调度到该节点运行,当节点从集群中移除时,DaemonSet的Pod会被删除。删除DaemonSet会清理它所有创建的Pod。
  • **Job:**一次性任务,运行完成后Pod销毁,不在重新启动新容器。还可以任务定时运行。Kubernetes中的Job用于结束被删除的应用。

API对象是K8S集群中管理操作单元。K8s集群系支持一项新功能,引入一项新技术,一定会引入对应的API对象,支持对该功能的管理操作。例如副本集Replica Set对应的API对象是RS。Kubernetes中所有的配置都是通过API对象的spec去设置的,也就是用户通过配置系统的理想状态来改变系统,这是k8s重要的设计理念之一,即所有的操作都是声明式(Declarative)的而不是命令式(Imperative)的。声明式操作在分布式系统中好处是稳定,不怕丢操作或运行多次,例如设置副本数为3的操作运行多次也还是一个结果,而给副本数加1的操作就不是声明式的,运行多次结果就错了。

  • **Cluster:**Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用
  • **Master:**kubernetes集群的管理节点,负责管理集群,提供集群的数据访问入口。拥有Etcd存储服务(可选),运行Api Server进程,Controller Manager服务进程及Scheduler服务进程,关联工作节点Node。Kubernetes API server提供HTTP Rest接口的关键服务进程,是kubernetes里所有资源的增、删、改、查等操作的唯一入口。也是集群控制的入口进程;Kubernetes Controller Manager是Kubernetes所有资源对象的自动化控制中心;Kubernetes Scheduler是负责资源调度(Pod调度)的进程。
  • **Node:**Node是Kubernetes集群架构中运行Pod的服务节点(亦叫agent或minion)。Node是Kubernetes集群操作的单元,用来承载被分配Pod的运行,是Pod运行的宿主机。关联Master管理节点,拥有名称和IP、系统资源信息。运行docker eninge服务,守护进程kubelet及负载均衡器kube-proxy,每个Node节点都运行着以下一组关键进程:
    • **kubelet:**负责对pod对于的容器的创建、启停等任务
    • **kube-proxy:**实现kubernetes service 的通信与负载均衡机制的重要组件
    • **Docker Engine:**Docker引擎,负责本机机器的创建和管理工作

Node节点可以在运行期间动态增加到kubernetes集群中,默认情况下,kubelet会想master注册自己,这也是kubernetes推荐的Node管理方式,kubelet进程会定时向Master汇报自身情报,如操作系统、Docker版本、CPU和内存,以及有哪些Pod在运行等等,这样Master可以获知每个Node节点的资源使用情况,实现高效均衡的资源调度策略。

  • Pod:运行于Node节点上,若干相关容器的组合。Pod内包含的容器运行在同一宿主机上,使用相同的网络命名空间、IP地址和端口,能够通过localhost进行连接。Pod是Kubernetes进行创建、调度和管理的最小单位,它提供了比容器更高层次的抽象,使得部署和管理更加灵活。一个Pod可以包含一个容器或者多个相关容器。 Pod其实有两种类型:普通Pod和静态Pod,后者比较特殊,它并不存在Kubernetes的etcd存储中,而是存放在某个具体的Node上的具体文件中,并且只在此Node上启动。普遍Pod一旦创建 ,就会被放入etcd存储中,随后会被Kubernetes Master调度到具体的Node上进行绑定,随后该Pod被对应的Node上的kubelet进程实例化成一组相关的Docker容器并启动起来。在默认情况下,当Pod里的某个容器停止时,Kubernetes会自动检测到这个Pod并且重启这个Pod(重启Pod里面的所有容器),如果Pod所在的Node宕机,则会将这个Node上的所有Pod重新调度到其他节点上。**Pod是在K8s集群中运行部署应用或服务得最小单元,**它是可以支持多容器得。Pod得设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务,比如你运行一个操作系统发行版的软件仓库,一个nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。

    kubernetes的最核心功能就是为了运行Pod,其他组件是为了pod能够正常运行而执行的。pod可以分为两类:

    1. 自主式pod
    2. 控制器管理的pod

​ 一个pod上有两类元数据,label和annotation

​ label: 标签,对数据类型和程度要求严格

​ annotation:注解,用于存储自己定义的复杂元数据,用来描述pod的属性

外部请求访问内部的pod经过了三级转发,第一级先到nodeip(宿主机IP)对应的端口,然后被转为cluster ip的service端口,然后转换为PodIP的containerPort

4.1:kubernetes引入Pod主要基于下面两个目的:

  • **客观理性:**有些容器天生就是需要紧密联系,一起工作。Pod提供了比容器更高层次的抽象,将他们封装到一个部署单元中。Kubernetes以Pod为最小单位进行调度、扩展、共享资源、管理生命周期。
  • **通信和资源共享:**Pod中的所有容器使用同一个网络namespace,即相同的IP地址和Port空间。它们可以直接用localhost通信。同样的,这些容器可以共享存储,当kubernetes挂载volume到Pod,本质上将volume挂载到Pod中的每个容器。在这里插入图片描述

File Puller会定期从外部的Content Manger中拉取最新的文件,将其存放在共享的volume中。Web server从volume读取文件,响应Consumer的请求。这两个容器是紧密协作的,他们一起为Consumer提供最新的数据;同时他们也通过volume共享数据。所以放到一个Pod是合适的。

**Controller:**Kubernetes通常不会直接创建Pod,而是通过Controller来管理Pod的。Controller中定义了Pod的部署特性,比如有几个副本,在什么样的Node上运行等。为了满足不同的业务场景,Kubernetes提供了多种Controller,包括Deployment、ReplicaSet、DaemonSet、StatefulSet、Job等

**Replica Set(副本集RS):**RS是新一代RC,提供同样的高可用能力,区别主要在于RS后来居上,能支持更过种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用。Replica Set实现了Pod的多副本管理。使用Deployment时会自动创建ReplicaSet,也就是说Deployment是通过ReplicaSet来管理pod的多个副本,我们通常不需要直接使用ReplicaSet

**Deployment(部署):**Deployment是最常用的Controller,Deployment可以管理Pod的多个副本,并确保Pod按照期望的状态运行。Deployment是一个比RS应用模式更广的API对象,支持动态扩展。可以创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的RS,然后逐渐将新的RS中副本数增加到理想状态,将旧RS中的副本数减小到0的符合操作(逐渐升级新的副本,剔除旧的副本)

总结:RS和Deployment知识保证了支撑服务的微服务Pod的数量

**DaemonSet:**DamonSet用于每个Node最多只运行一个Pod副本的场景。正如其名称所揭示的,DaemonSet通常用于运行daemon。

**StatefulSet:**StatefulSet能够保证Pod的每个副本在整个生命周期中名称是不变的。而其他Controller不提供这个功能,当某个Pod发生故障需要删除并重新启动时,Pod的名称会发生变化。同时StatefulSet会保证副本按照固定的顺序启动、更新或者删除。

**Service:**Service定义了Pod逻辑集合和访问该集合的策略,是真实服务的抽象。Service提供了同意的服务访问入口以及服务代理和发现机制,关联多个相同Label的Pod,用户不需要了解后台Pod是如何运行。

外部系统访问Service的问题:

---->>>首先需要弄明白Kubernetes的三种IP问题

  • Node IP:Node节点上的IP地址
  • Pod IP:Pod的IP地址
  • Cluster IP:Service的IP地址

---->>>首先,Node IP是Kubernetes集群中节点的物理网卡IP地址,所有属于这个网络的服务器之间都能通过这个网络直接通信。这也表明Kubernetes集群之外的节点访问Kubernetes集群之内的某个节点或者TCP/IP服务的时候,必须通过Node IP进行通信

---->>>其次,Pod IP是每个Pod的IP地址,它是Docker Engine根据docker0网桥的IP地址进行分配的,通常是一个虚拟的二层网络。

最后Cluster IP是一个虚拟的IP,但更像是一个伪造的IP网络,原因有以下几点:

—> Cluster IP仅仅作用于Kubernetes Service这个对象,并由Kubernetes管理和分配IP地址

—> cluster IP无法被ping,他没有一个"实体网络对象"来响应

—>Cluster IP只能结合Service Port组成一个具体的通信端口,单独的Cluster IP不具备通信的基础,并且他们属于Kubernetes集群这样一个封闭的空间

—>Kubernetes集群之内,Node IP网、Pod IP网和Cluster IP网之间的通信,采用的是Kubernetes自己的设计的一种编程方式的特殊路由规则。

RC、RS和Deployment只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。要稳定的提供服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的后端服务实例。在k8s集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。在k8s集群中微服务的负载均衡是由kube-proxy实现的。kube-proxy是k8s集群内部的负载均衡器。它是一个分布代理服务器,在k8s的每个节点上都有一个;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的kube-proxy就越多,高可用节点也随之增加。与之相比,我们平时在服务器端做个反向代理做负载均衡,还要进一步解决方向代理的负载均衡和高可用问题。

Kubernetes运行容器(Pod)与访问容器(Pod)这两项任务分别由Controller和Service执行。

**Namespace:**名字空间为k8s集群提供虚拟的隔离作用,k8s集群初始有两个名字空间,分别是默认名字default和系统名字空间kube-system,除此之外,管理员可以创建新的名字空间满足需要。

在这里插入图片描述

**Label:**Kubernetes中任意API对象都是通过Label进行标识,Label的实质是一系列的Key/Value键值对,其中key、value由用户自己指定。Label可以附加在各种资源对象上,如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去。Label是Replica Set和Service运行的基础,二者通过Label来进行关联Node上运行的Pod。

我们可以通过给指定的资源对象捆绑一个或者多个不同的Label来实现多维度的资源分组管理功能,以便于灵活、方便的进行资源分配、调度、配置等管理工作。

一些常用的Label如下:

版本标签:“release”:“stable”,“release”:“canary”…

环境标签:“environment”:“dev”,“environment”:“qa”

架构标签:“tier”:“frontend”,“tier”:“backend”,“tier”:“middleware”
分区标签:“partition”:“customerA”,“partition”:“customerB”
质量管控标签:“track”:“daily”,“track”:“weekly”

Label相当于我们熟悉的标签,给某个资源对象定义一个Label就相当于给它打了一个标签,随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制。

Label Selector在kubernetes中重要使用场景如下:

  • kube-Controller进程通过资源对象Deployment定义Label Selector来筛选要监控的Pod副本的数量,从而实现副本数量始终符合预期设定的全自动流程控制。
  • kube-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立起每个Service对应Pod的请求转发路由表,从而实现Service的只能负载均衡;
  • 通过对某些Node定义特定的Label,并且在pod定义文件中使用NodeSelector这种标签调度策略,kube-scheduler进程可以实现Pod"定向调度"的特性;

4.2:Master管理节点和Node工作节点的各组件关系:

在这里插入图片描述

Kubernetes工作流程:

1)通过kubectl向kubernetes Master发出指令,Master节点主要提供API Server、Scheduler、Controller组件,接收kubectl命令,从Node节点获取Node资源信息,并发出调度任务。

2)Node节点提供kubelet、kube-proxy,每个node节点都安装docker,是实际的执行者。kubernetes不负责网络,所以一般是用flannel或者calico。

3)etcd是一个键值存储仓库,etcd负责服务发现和node信息存储。不过需要注意的是:由于etcd是负责存储,所以不建议搭建单点集群,如zookeeper一样,由于存在选举策略,所以一般推荐奇数各集群,如3,5,7.只要集群半数以上的节点存活,那么集群就可以正常运行,否则集群可能无法正常使用。

**Master:**集群控制管理节点,所有的命令都经由master处理。

在这里插入图片描述

**Node:**是kubernetes集群的工作负载节点。Master为其分配工作,当某个Node宕机时,Master会将其工作负载自动转移到其他节点。

在这里插入图片描述

Node节点可动态增加到kubernetes集群中,前提是这个节点已经正确安装、配置了上述的关键进程,默认情况下,kubelet会向master注册自己,这也kubernetes推荐的node管理方式。一旦Node被纳入集群管理范围,kubelet会定时向master汇报自身的情况,以及之前有哪些Pod在运行等,这样Master可以获知每个node的资源使用情况,并实现高效均衡的资源调度策略。如果Node没有按时上报信息,则会被Master判断为失联,Node状态会被标记为Not Ready,随后Master会触发工作负载转移流程。

**Pod:**是kubernetes最重要也是最基本的概念。每个pod都会包含一个"根容器",还会包含一个或者多个紧密相连的业务容器。

在这里插入图片描述

Kubernetes为每个Pod都分配了唯一IP地址,称之为PodIP,一个Pod里多个容器共享PodIP地址,要求底层网络支持集群内任意两个Pod之间的直接通信,通常采用虚拟二层网络技术来是按(Flannel)

**Label:**是一个key=value的键值对,其中key与value由用户指定,可以附加到各种资源对象上,一个资源对象可以定义任意数量的Label。可以通过LabelSelector(标签选择器)查询和筛选资源对象。

在这里插入图片描述

**Deployment:**声明某个Pod的副本数在任意时刻都符合某个预期值。定义包含如下:

  • Pod期待的副本数(replicas);
  • 用于筛选目标Pod的Label Selector;
  • 当Pod副本数小于期望时,用于新的创建Pod的模板template。

需要注意:

  • 通过改变Deployment里的Pod副本数量,可以实现Pod的扩容或缩容功能
  • 通过改变Deployment里Pod模板中的镜像版本,可以实现Pod的滚动升级功能

在这里插入图片描述

Service:“微服务”,kubernetes中的核心。通过分析、识别并建模系统中的所有服务为微服务,最终系统有多个提供不同业务能力而又彼此独立的微服务单元所组成,服务之间通过TCP/IP进行通信。每个Pod都会被分配一个单独的IP地址,而且每个Pod都提供了一个独立的Endpoint被客户端访问。

客户端如何访问:
部署负载均衡器,为Pod开启对外服务端口,将Pod的Endpoint列表加入转发列表中,客户端通过负载均衡器的对外IP+Port来访问此服务。每个Service都有一个全局唯一的虚拟Cluster IP,这样每个服务就变成了具备唯一IP地址的"通信节点",服务调用就变成了最基础的TCP网络通信问题。

**Volume:**是Pod中能够被多个容器访问的共享目录。定义在Pod之上,被一个Pod里的多个容器挂载到具体的文件目录之下;Volume与Pod生命周期相同。Volume可以让一个Pod里的多个容器共享文件、让容器的数据写到宿主机的磁盘上或者写文件到网络存储中,具体如图所示:

在这里插入图片描述

在kubernetes1.2的时候,RC就由Replication Controller升级成Replica Set,“下一代RC”。命令兼容使用,Replica Set主要被Deployment这个更高层的资源对象所使用,从而形成一套Pod创建、删除、更新的编排机制。当我们使用Deployment时,无需关心它是如何创建和维护ReplicaSet的,这一切是自动发生的。

**Docker:**既然k8s是基于容器的,那么就不得不提到docker。2013初,docker横空出世,孕育者新思想的"容器",Docker选择容器作为核心和基础,以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理元设计,用于构建、发布和运行分布式应用的平台。是一个跨平台、可移植并且简单易用的容器解决方案。通过操作系统内核技术(namspace、cgroups等)为容器提供资源隔离与安全保障。

在这里插入图片描述

上图时一个image的简单使用。我们可以通过一个dockerfile来build自己的image。可以吧image上传(push)到自己的私有镜像仓库,也可以从私有仓库pull到本地进行使用。可以单独使用命令行,直接run container,可以对container进行stop、start、restart操作。也可以对image进行save保存操作以及加载load操作,大家具体可以根据自己的使用,选择不同的操作即可。

Docker资源镜像隔离技术

Docker选择容器作为核心和基础,以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员设计,用于构建、发布和运行分布式应用分的平台。Docker是一个跨平台、可移植并且简单容易的容器解决方案,通过操作系统内核技术(namespace、cgroups等)为容器提供资源隔离与安全

Docker监控

cAdvisor(Container Advisor)是Google开发的用于分析运行中容器的资源占用和性能指标的开源工具。cAdvisor是一个运行时的守护进程,负责收集、聚合、处理和输出运行中容器的信息。对于每个容器,cAdvisor都有资源隔离参数、资源使用历史情况以及完整的历史资源使用和网络统计信息的柱状图。cAdvisor不但可以为用户提供监控服务,还可以结合其他应用为用户提供良好的服务移植和定制。包括结合InfluxDB对数据进行存储,以及结合Grafana提供web控制台,自定义查询指标,并进行展示:

当下配合Kubernetes集群比较成熟的监控方案是: Prometheus +Grafana

五:Kubernetes集群里容器之间的通讯方式

Kubernetes集群里面容器是存在于pod里面的,所以容器之间通讯,一般分为三种类型:

  • Pod内部容器之间
  • pod与pod容器之间
  • pod访问service服务

1)pod内部容器之间

这种情况下容器通讯比较简单,因为k8s pod内部容器是共享网络空间的,所以容器直接可以使用localhost访问其他容器。k8s在启动容器的时候会先启动一个pause容器,这个容器就是实现这个功能的

2)pod和pod容器之间

这种类型又可以分为两种情况:

  • 两个pod在同一台主机上面
  • 两个pod分布在不同主机上

第一种情况,就比较简单了,就是docker默认的docker网桥互联容器。

第二种情况需要更为复杂的网络模型,k8s官方推荐的是使用flannel组件一个大二层扁平网络,pod的ip分配由flannel统一分配,通讯过程也是走flannel的网桥。比如:

# docker --daemon --bip=172.17.18.1/24
注意,这其中的"--bip=172.17.18.1/24"这个参数,它限制了所在节点容器获得的IP范围。

每个node上面都会创建一个flannel0虚拟网卡,用于跨node之间通讯。所以容器可以直接使用pod ip进行通讯。跨节点通讯时,发送端数据会从docker0出来以后就被投递到了flannel0。同理在目标节点上,由于投递的地址是一个容器,因此目的地址一定会落在docker0对于的172.12.12.0/24这个记录上,自然的被投递到 了docker0网卡。

**flannel的原理:**是将网络包封装在udp里面,所以发送端和接收端需要装包和解包,对性能有一定的影响。除了flannel,k8s也支持其他的网络模型,比较有名的还有calico.

3)pod访问service服务

这里涉及到k8s里面一个重要的概念service。它是一个服务的抽象,通过label**(k8s会根据service和pod直接的关系创建endpoint**,可以通过**kubectl get ep**查看)关联到后端的容器。**Service分配的ip叫cluster ip是一个虚拟ip(相对固定,除非删除service),**这个ip只能在k8s集群内部使用,如果service需要对外提供,只能使用Nodeport方式映射到主机上,使用主机的ip和端口对外提供服务。(另外还可以使用LoadBalance方式,但这种方式是在gce这样的云环境使用的)

节点上面有个kube-proxy进程,这个进程从master apiserver获取信息,感知service和endpoint的创建,然后做下面两个事情:

  • 为每个service在集群中每个节点上面创建一个随机端口,任何该端口上面的连接会代理到相应的pod
  • 集群中每个节点安装iptables规则,用于cluster + port路由到上一步定义的随机端口上面,所以集群中每个node上面都有service的转发规则:
1. KUBE-PORTALS-CONTAINER 从容器中通过service cluster ip和端口访问service请求
2. KUBE-PORTALS-HOST 从主机中通过service cluster ip和端口访问service的请求
3. KUBE-NODEPORT-CONTAINER 从容器中通过service nodeport端口访问service的请求
4. KUBE-NODEPORT-HOST 从主机中通过service nodeport端口访问service请求。

六:kubernetes日常维护命令

一. 查看集群信息
=============================================================================================================
[root@k8s-master01 ~]# kubectl cluster-info
[root@k8s-master01 ~]# kubectl cluster-info dump
    
二. 查看各组件状态
=============================================================================================================
[root@k8s-master01 ~]# kubectl -s http://localhost:8080 get componentstatuses
NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok              
scheduler            Healthy   ok              
etcd-0               Healthy   {"health":"true"}
    
或者
[root@k8s-master01 ~]# kubectl -s http://172.16.60.220:8080 get componentstatuses
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok              
controller-manager   Healthy   ok              
etcd-0               Healthy   {"health":"true"}
    
三. GET信息
=============================================================================================================
1) 查看节点 (k8s-master01 对应的是 172.16.60.220的主机名)
[root@k8s-master01 ~]# kubectl get node                                #将命令中的node变为nodes也是可以的
NAME         STATUS    AGE
k8s-node01   Ready     1d
k8s-node02   Ready     1d
    
[root@k8s-master01 ~]# kubectl -s http://k8s-master01:8080 get node    #将命令中的node变为nodes也是可以的
NAME         STATUS    AGE
k8s-node01   Ready     1d
k8s-node02   Ready     1d
    
2) 查看pods清单(查看pod ip地址,下面命令加上"-o wide")
[root@k8s-master01 ~]# kubectl get pod                           #将pod变为pods也可以。如果有namespace,需要跟上"-n namespace名字" 或 "--all-namespaces"            
NAME                      READY     STATUS    RESTARTS   AGE
nginx-controller-d97wj    1/1       Running   0          1h
nginx-controller-lf11n    1/1       Running   0          1h
tomcat-controller-35kzb   1/1       Running   0          18m
tomcat-controller-lsph4   1/1       Running   0          18m
    
[root@k8s-master01 ~]# kubectl -s http://k8s-master01:8080 get pod          #将命令中的pod变为pods也是可以的
NAME                      READY     STATUS    RESTARTS   AGE
nginx-controller-d97wj    1/1       Running   0          1h
nginx-controller-lf11n    1/1       Running   0          1h
tomcat-controller-35kzb   1/1       Running   0          18m
tomcat-controller-lsph4   1/1       Running   0          18m
    
3) 查看service清单
[root@k8s-master01 ~]# kubectl get service                                             #将命令中的service变为services也是可以的
NAME                       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes                 172.16.0.1       <none>        443/TCP          1d
nginx-service-clusterip    172.16.77.193    <none>        8001/TCP         1h
nginx-service-nodeport     172.16.234.94    <nodes>       8000:32172/TCP   59m
tomcat-service-clusterip   172.16.144.116   <none>        8801/TCP         14m
tomcat-service-nodeport    172.16.183.234   <nodes>       8880:31960/TCP   11m
    
[root@k8s-master01 ~]# kubectl -s http://172.16.60.220:8080 get service               #将命令中的service变为services也是可以的
NAME                       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes                 172.16.0.1       <none>        443/TCP          1d
nginx-service-clusterip    172.16.77.193    <none>        8001/TCP         1h
nginx-service-nodeport     172.16.234.94    <nodes>       8000:32172/TCP   1h
tomcat-service-clusterip   172.16.144.116   <none>        8801/TCP         17m
tomcat-service-nodeport    172.16.183.234   <nodes>       8880:31960/TCP   14m
    
或者  (后面的sed表示 打印奇数行)
[root@k8s-master01 ~]# kubectl get services -o json|grep '"name":'|sed -n '1~2p'
                "name": "kubernetes",
                "name": "nginx-service-clusterip",
                "name": "nginx-service-nodeport",
                "name": "tomcat-service-clusterip",
                "name": "tomcat-service-nodeport",
  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忙里偷闲学python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值