Kubernetes基础概念总结

1、基础架构

1.1 Master

  Master节点上面主要由四个模块组成:APIServer、scheduler、controller manager、etcd。

    APIServer。APIServer负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd。如架构图中所示,kubectl(Kubernetes提供的客户端工具,该工具内部就是对Kubernetes API的调用)是直接和APIServer交互的。

    schedule。scheduler的职责很明确,就是负责调度pod到合适的Node上。如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node组成的列表,输出是Pod和一个Node的绑定,即将这个pod部署到这个Node上。Kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。

    controller manager。如果说APIServer做的是“前台”的工作的话,那controller manager就是负责“后台”的。每个资源一般都对应有一个控制器,而controller manager就是负责管理这些控制器的。比如我们通过APIServer创建一个pod,当这个pod创建成功后,APIServer的任务就算完成了。而后面保证Pod的状态始终和我们预期的一样的重任就由controller manager去保证了。

    etcd。etcd是一个高可用的键值存储系统,Kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。

1.2 Node

  每个Node节点主要由三个模块组成:kubelet、kube-proxy、runtime。

    runtime。runtime指的是容器运行环境,目前Kubernetes支持docker和rkt两种容器。

    kube-proxy。该模块实现了Kubernetes中的服务发现和反向代理功能。反向代理方面:kube-proxy支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与service对应的一组后端pod。服务发现方面,kube-proxy使用etcd的watch机制,监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响。另外kube-proxy还支持session affinity。

    kubelet。Kubelet是Master在每个Node节点上面的agent,是Node节点上面最重要的模块,它负责维护和管理该Node上面的所有容器,但是如果容器不是通过Kubernetes创建的,它并不会管理。本质上,它负责使Pod得运行状态与期望的状态一致。

至此,Kubernetes的Master和Node就简单介绍完了。下面我们来看Kubernetes中的各种资源/对象。

2、Pod

  Pod 是Kubernetes的基本操作单元,也是应用运行的载体。整个Kubernetes系统都是围绕着Pod展开的,比如如何部署运行Pod、如何保证Pod的数量、如何访问Pod等。另外,Pod是一个或多个机关容器的集合,这可以说是一大创新点,提供了一种容器的组合的模型。

2.1 基本操作


创建


kubectl create -f xxx.yaml


查询


kubectl get pod yourPodName

kubectl describe pod yourPodName


删除


kubectl delete pod yourPodName


更新


kubectl replace /path/to/yourNewYaml.yaml

2.2 Pod与容器

  在Docker中,容器是最小的处理单元,增删改查的对象是容器,容器是一种虚拟化技术,容器之间是隔离的,隔离是基于Linux Namespace实现的。而在Kubernetes中,Pod包含一个或者多个相关的容器,Pod可以认为是容器的一种延伸扩展,一个Pod也是一个隔离体,而Pod内部包含的一组容器又是共享的(包括PID、Network、IPC、UTS)。除此之外,Pod中的容器可以访问共同的数据卷来实现文件系统的共享。

2.3 镜像

  在kubernetes中,镜像的下载策略为:

    Always:每次都下载最新的镜像

    Never:只使用本地镜像,从不下载

    IfNotPresent:只有当本地没有的时候才下载镜像

  Pod被分配到Node之后会根据镜像下载策略进行镜像下载,可以根据自身集群的特点来决定采用何种下载策略。无论何种策略,都要确保Node上有正确的镜像可用。

2.4 其他设置

  通过yaml文件,可以在Pod中设置:

    启动命令,如:spec-->containers-->command;

    环境变量,如:spec-->containers-->env-->name/value;

    端口桥接,如:spec-->containers-->ports-->containerPort/protocol/hostIP/hostPort(使用hostPort时需要注意端口冲突的问题,不过Kubernetes在调度Pod的时候会检查宿主机端口是否冲突,比如当两个Pod均要求绑定宿主机的80端口,Kubernetes将会将这两个Pod分别调度到不同的机器上);

    Host网络,一些特殊场景下,容器必须要以host方式进行网络设置(如接收物理机网络才能够接收到的组播流),在Pod中也支持host网络的设置,如:spec-->hostNetwork=true;

    数据持久化,如:spec-->containers-->volumeMounts-->mountPath;

    重启策略,当Pod中的容器终止退出后,重启容器的策略。这里的所谓Pod的重启,实际上的做法是容器的重建,之前容器中的数据将会丢失,如果需要持久化数据,那么需要使用数据卷进行持久化设置。Pod支持三种重启策略:Always(默认策略,当容器终止退出后,总是重启容器)、OnFailure(当容器终止且异常退出时,重启)、Never(从不重启);

2.5 Pod生命周期

  Pod被分配到一个Node上之后,就不会离开这个Node,直到被删除。当某个Pod失败,首先会被Kubernetes清理掉,之后ReplicationController将会在其它机器上(或本机)重建Pod,重建之后Pod的ID发生了变化,那将会是一个新的Pod。所以,Kubernetes中Pod的迁移,实际指的是在新Node上重建Pod。以下给出Pod的生命周期图。

  生命周期回调函数:PostStart(容器创建成功后调研该回调函数)、PreStop(在容器被终止前调用该回调函数)。以下示例中,定义了一个Pod,包含一个JAVA的web应用容器,其中设置了PostStart和PreStop回调函数。即在容器创建成功后,复制/sample.war到/app文件夹中。而在容器终止之前,发送HTTP请求到http://monitor.com:8080/waring,即向监控系统发送警告。具体示例如下:

………..
containers:
- image: sample:v2
     name: war
     lifecycle:
      posrStart:
       exec:
         command:
          - “cp”
          - “/sample.war”
          - “/app”
      prestop:
       httpGet:
        host: monitor.com
        psth: /waring
        port: 8080
        scheme: HTTP

3、Replication Controller

  Replication Controller(RC)是Kubernetes中的另一个核心概念,应用托管在Kubernetes之后,Kubernetes需要保证应用能够持续运行,这是RC的工作内容,它会确保任何时间Kubernetes中都有指定数量的Pod在运行。在此基础上,RC还提供了一些更高级的特性,比如滚动升级、升级回滚等。

3.1 RC与Pod的关联——Label

  RC与Pod的关联是通过Label来实现的。Label机制是Kubernetes中的一个重要设计,通过Label进行对象的弱关联,可以灵活地进行分类和选择。对于Pod,需要设置其自身的Label来进行标识,Label是一系列的Key/value对,在Pod-->metadata-->labeks中进行设置。

  Label的定义是任一的,但是Label必须具有可标识性,比如设置Pod的应用名称和版本号等。另外Lable是不具有唯一性的,为了更准确的标识一个Pod,应该为Pod设置多个维度的label。如下:

    "release" : "stable", "release" : "canary"

    "environment" : "dev", "environment" : "qa", "environment" : "production"

    "tier" : "frontend", "tier" : "backend", "tier" : "cache"

    "partition" : "customerA", "partition" : "customerB"

    "track" : "daily", "track" : "weekly"

  举例,当你在RC的yaml文件中定义了该RC的selector中的label为app:my-web,那么这个RC就会去关注Pod-->metadata-->labeks中label为app:my-web的Pod。修改了对应Pod的Label,就会使Pod脱离RC的控制。同样,在RC运行正常的时候,若试图继续创建同样Label的Pod,是创建不出来的。因为RC认为副本数已经正常了,再多起的话会被RC删掉的。

3.2 弹性伸缩

  弹性伸缩是指适应负载变化,以弹性可伸缩的方式提供资源。反映到Kubernetes中,指的是可根据负载的高低动态调整Pod的副本数量。调整Pod的副本数是通过修改RC中Pod的副本是来实现的,示例命令如下:

  扩容Pod的副本数目到10

$ kubectl scale relicationcontroller yourRcName --replicas=10

  缩容Pod的副本数目到1

$ kubectl scale relicationcontroller yourRcName --replicas=1

3.3 滚动升级

  滚动升级是一种平滑过渡的升级方式,通过逐步替换的策略,保证整体系统的稳定,在初始升级的时候就可以及时发现、调整问题,以保证问题影响度不会扩大。Kubernetes中滚动升级的命令如下:

$ kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s

  升级开始后,首先依据提供的定义文件创建V2版本的RC,然后每隔10s(--update-period=10s)逐步的增加V2版本的Pod副本数,逐步减少V1版本Pod的副本数。升级完成之后,删除V1版本的RC,保留V2版本的RC,及实现滚动升级。

  升级过程中,发生了错误中途退出时,可以选择继续升级。Kubernetes能够智能的判断升级中断之前的状态,然后紧接着继续执行升级。当然,也可以进行回退,命令如下:

$ kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s --rollback

回退的方式实际就是升级的逆操作,逐步增加V1.0版本Pod的副本数,逐步减少V2版本Pod的副本数。

4、Job

  从程序的运行形态上来区分,我们可以将Pod分为两类:长时运行服务(jboss、mysql等)和一次性任务(数据计算、测试)。RC创建的Pod都是长时运行的服务,而Job创建的Pod都是一次性任务。

  在Job的定义中,restartPolicy(重启策略)只能是Never和OnFailure。Job可以控制一次性任务的Pod的完成次数(Job-->spec-->completions)和并发执行数(Job-->spec-->parallelism),当Pod成功执行指定次数后,即认为Job执行完毕。

5、Service

  为了适应快速的业务需求,微服务架构已经逐渐成为主流,微服务架构的应用需要有非常好的服务编排支持。Kubernetes中的核心要素Service便提供了一套简化的服务代理和发现机制,天然适应微服务架构。

5.1 原理

  在Kubernetes中,在受到RC调控的时候,Pod副本是变化的,对于的虚拟IP也是变化的,比如发生迁移或者伸缩的时候。这对于Pod的访问者来说是不可接受的。Kubernetes中的Service是一种抽象概念,它定义了一个Pod逻辑集合以及访问它们的策略,Service同Pod的关联同样是居于Label来完成的。Service的目标是提供一种桥梁, 它会为访问者提供一个固定访问地址,用于在访问时重定向到相应的后端,这使得非 Kubernetes原生应用程序,在无须为Kubemces编写特定代码的前提下,轻松访问后端。

  Service同RC一样,都是通过Label来关联Pod的。当你在Service的yaml文件中定义了该Service的selector中的label为app:my-web,那么这个Service会将Pod-->metadata-->labeks中label为app:my-web的Pod作为分发请求的后端。当Pod发生变化时(增加、减少、重建等),Service会及时更新。这样一来,Service就可以作为Pod的访问入口,起到代理服务器的作用,而对于访问者来说,通过Service进行访问,无需直接感知Pod。

  需要注意的是,Kubernetes分配给Service的固定IP是一个虚拟IP,并不是一个真实的IP,在外部是无法寻址的。真实的系统实现上,Kubernetes是通过Kube-proxy组件来实现的虚拟IP路由及转发。所以在之前集群部署的环节上,我们在每个Node上均部署了Proxy这个组件,从而实现了Kubernetes层级的虚拟转发网络。

5.2 Service代理外部服务

  Service不仅可以代理Pod,还可以代理任意其他后端,比如运行在Kubernetes外部Mysql、Oracle等。这是通过定义两个同名的service和endPoints来实现的。示例如下:

mysql-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
   - port: 3306
targetPort: 3306
protocol: TCP

mysql-endpoints.yaml

apiVersion: v1
kind: Endpoints
metadata:
  name: mysql
subsets:
- addresses:
 - ip: 192.168.31.22
 ports: 3306
  protocol: TCP

基于文件创建完Service和Endpoints之后,在Kubernetes的Service中即可查询到自定义的Endpoints。

5.3 Service内部负载均衡

  当Service的Endpoints包含多个IP的时候,及服务代理存在多个后端,将进行请求的负载均衡。默认的负载均衡策略是轮训或者随机(有kube-proxy的模式决定)。同时,Service上通过设置Service-->spec-->sessionAffinity=ClientIP,来实现基于源IP地址的会话保持。

5.4 发布Service

  Service的虚拟IP是由Kubernetes虚拟出来的内部网络,外部是无法寻址到的。但是有些服务又需要被外部访问到,例如web前段。这时候就需要加一层网络转发,即外网到内网的转发。Kubernetes提供了NodePort、LoadBalancer、Ingress三种方式。

    NodePort,在之前的Guestbook示例中,已经延时了NodePort的用法。NodePort的原理是,Kubernetes会在每一个Node上暴露出一个端口:nodePort,外部网络可以通过(任一Node)[NodeIP]:[NodePort]访问到后端的Service。

    LoadBalancer,在NodePort基础上,Kubernetes可以请求底层云平台创建一个负载均衡器,将每个Node作为后端,进行服务分发。该模式需要底层云平台(例如GCE)支持。

    Ingress,是一种HTTP方式的路由转发机制,由Ingress Controller和HTTP代理服务器组合而成。Ingress Controller实时监控Kubernetes API,实时更新HTTP代理服务器的转发规则。HTTP代理服务器有GCE Load-Balancer、HaProxy、Nginx等开源方案。

6、Deployment

  Kubernetes提供了一种更加简单的更新RC和Pod的机制,叫做Deployment。通过在Deployment中描述你所期望的集群状态,Deployment Controller会将现在的集群状态在一个可控的速度下逐步更新成你所期望的集群状态。Deployment主要职责同样是为了保证pod的数量和健康,90%的功能与Replication Controller完全一样,可以看做新一代的Replication Controller。但是,它又具备了Replication Controller之外的新特性:

    Replication Controller全部功能:Deployment继承了上面描述的Replication Controller全部功能。

    事件和状态查看:可以查看Deployment的升级详细进度和状态。

    回滚:当升级pod镜像或者相关参数的时候发现问题,可以使用回滚操作回滚到上一个稳定的版本或者指定的版本。

    版本记录: 每一次对Deployment的操作,都能保存下来,给予后续可能的回滚使用。

    暂停和启动:对于每一次升级,都能够随时暂停和启动。

    多种升级方案:Recreate----删除所有已存在的pod,重新创建新的; RollingUpdate----滚动升级,逐步替换的策略,同时滚动升级时,支持更多的附加参数,例如设置最大不可用pod数量,最小升级间隔时间等等。

6.1 滚动升级

  相比于RC,Deployment直接使用kubectl edit deployment/deploymentName 或者kubectl set方法就可以直接升级(原理是Pod的template发生变化,例如更新label、更新镜像版本等操作会触发Deployment的滚动升级)。操作示例——首先 我们同样定义一个nginx-deploy-v1.yaml的文件,副本数量为2:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

创建deployment:

$ kubectl create -f nginx-deploy-v1.yaml --record
deployment "nginx-deployment" created
$ kubectl get deployments
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         0         0            0           1s
$ kubectl get deployments
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           18s

正常之后,将nginx的版本进行升级,从1.7升级到1.9。第一种方法,直接set镜像:

$ kubectl set image deployment/nginx-deployment2 nginx=nginx:1.9
deployment "nginx-deployment2" image updated

第二种方法,直接edit:

$ kubectl edit deployment/nginx-deployment
deployment "nginx-deployment2" edited

最后介绍下Deployment的一些基础命令:

$ kubectl describe deployments  #查询详细信息,获取升级进度
$ kubectl rollout pause deployment/nginx-deployment2  #暂停升级
$ kubectl rollout resume deployment/nginx-deployment2  #继续升级
$ kubectl rollout undo deployment/nginx-deployment2  #升级回滚

  关于多重升级,举例,当你创建了一个nginx1.7的Deployment,要求副本数量为5之后,Deployment Controller会逐步的将5个1.7的Pod启动起来;当启动到3个的时候,你又发出更新Deployment中Nginx到1.9的命令;这时Deployment Controller会立即将已启动的3个1.7Pod杀掉,然后逐步启动1.9的Pod。Deployment Controller不会等到1.7的Pod都启动完成之后,再依次杀掉1.7,启动1.9。

6.2 升级回滚

  升级完成之后,若发现新版本不稳定,或不符合业务需求,可进行回退操作。假设我们在刚刚完成升级的nginx1.9中发现了错误,那么可以通过以下命令进行回滚。

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91
deployment "nginx-deployment" image updated
$ kubectl rollout status deployments nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
时间: 03-04

Kubernetes基础概念总结的相关文章

关系型数据库常用基础概念知识归纳

声明:我的文章都是只挑主要的写,次要细节太多,归纳就没意义了,同时归纳主要是给自己看的, 而且基本都是凭自己的一些记忆和理解即时写的.不一定对和全(但大多是一些需要理解的概念),请各位看管见谅! 数据库设计篇 1.范式 A.1范式,原子性,即列不可分 B.2范式,完全依赖,即有个主键唯一区分 C.3范式,不能传递依赖,即表中不能还有其他表的非主键信息 2.模型 A.概念模型,即ER图等 B.逻辑模型,即建逻辑表 C.物理模型,即生成物理表 事务 1.四大特性, A.原子,要么..要么.. B.隔

分布式学习——基础概念篇

概述 最近这段时间一直在看分布式有关的东西,但是关于分布式自己还是不能很好的理解,所以本文对分布式基础概念进行下学习. 分布式处理 首先先了解一下分布式处理,分布式处理和集中式处理正好是相反的的体系架构,集中传输集中到式处理顾名思义就是将所有的信息都一个统一的信息中心进行处理:分布式处理就是将不同地点的,或具有不同功能的,或拥有不同数据的多台计算机利用通信网络连接起来,让各个计算机各自承担同一个工作任务的不同部分,在控制中心的管理下,同时运行,共同完成同一个工作任务. 提到分布式处理就不能不提到

js基础--javascript基础概念之语法

掌握一门语言 必须先掌握它的语法! javascript 的语法和C.Java.Perl 的语法有些相似.但是比它们更加宽松. javascript 中的一切都是严格区分大小写的.例如变量: demo 和 Demo 两个变量是完全不同的. javascript 标示符,所谓标示符 是指 变量.函数.属性 的名字或函数的参数.标示符的格式是按照以下规则组合的一个或多个字符. 1.第一个字符必须是字母,下划线,或 $ 符号. 2.其他字符可以是字母.下划线.$ . 或数字. 注意 不能把关键字 保留

js基础--javascript基础概念之数组(二)

js基础--javascript基础概念之数组 数组栈方法 数组可以像栈一样.栈是一种先进后出的数据结构,最先添加的数据最后一个出来.栈方法添加数据也称为 推入  移除数据称为 弹出. js为数值栈方法提供了 push()   和  pop() ;  两个方法. push() push() 方法接受参数就是你要添加进入到数组的值.push()  方法会将他们逐一添加到数组的末尾  数组的length属性会跟着更新数据. *push(多个数组元素值) 返回的修改后的数组长度 var array =

js基础--javascript基础概念之数组

js基础--javascript基础概念之数组 在ECMAScript 中 ,数组是很常用的数据类型,js中的数组和其他很多语言的数组有明显的区别.js的数组可以保持任何类型的数值,一个数组中可以保存着多个不同类型的数值.js数组大小(长度)是可以调整的.可以随着数据的添加自动增长数组长度. 创建数组: 一.数组字面量 数组字面量由一对包含数组项的方括号[]表示. var array = [ 'kin', 'cheong', 'change', 'hello', 'haha', 'hi' ];

Linux基础概念-----环境变量

Shell 环境变量 Shell也是应用程序,工作与用户模式 变量类型 整形 浮点型 字符型 布尔型 bash变量类型 本地变量:仅对当前Shell有效 局部变量:仅对局部代码段有效(函数) 环境变量:expor VAR_NAME=Value,对当前Shell及子Shell有效 位置变量:$1;$2 .... 特殊变量:$?;$!;$$ .... 查看环境变量 printenv export 查看所有变量 set bash的引号 双引号:弱引用,可以实现变量替换: 单引号:强引用,不替换,而显示

Linux基础概念-----Linux I/O重定向 ,管道

标准输入:键盘 标准输出:显示器 错误输出:显示器 FD:文件描述符:让程序可以文件交互,并且便于内核识别文件,打开的每一个文件都有一个描述符 程序在和文件交互式,通过文件描述符来进行交互,而非文件名,文件名是方便用户分别文件. Linux一切皆文件,所以标准输入,标准输出都有各自的文件描述符 标准输入描述符:0 标准输出描述符:1 标准错误输出描述符:2 将其默认数据流改为其他设备:IO重定向 输出重定向 > 覆盖重定向 >> 追加重定向 /dev/null  黑洞 只针对当前Shel

js基础--javascript基础概念之语句(二)

js基础--javascript基础概念之语句(二)label,break,continue.. break .  continue 语句. break  continue 语句用于在循环中精确控制代码的执行,其中break语句会立即退出循环,执行循环后面的语句. continue 则退出循环后返回到再次进入循环中. 如: var num = 0; for(var i = 0; i<=100; i++){ if(i >= 10){ break; } num = i; } alert(num);

iOS开发OC基础:OC基础概念总结,OC面向对象的思想

一.什么是OOP: OOP(Object Oriented Programming):面向对象编程 二.面向对象和面向过程的区别: 面向过程编程:分析解决问题的步骤,实现函数,依次使用面向对象编程:分解问题组成的对象,协调对象间的联系和通信,解决问题. 面向过程是以事件为中心,关心的是完成这个事件的详细步骤:面向对象是以事物为中心,关心的是事物应该具备的功能,而完成一个事件只是事物所有功能里面的一个小功能(以过程为中心,以对象为中心) 三.类和对象 对象定义了解决问题的步骤中的行为,不刻意完成一