Kubernetes集群将所有节点上的资源都整合到一个大的虚拟资源池里,以代替一个个单独的服务器。如果把集群类比为一台传统的服务器,那么Kubernetes(Master)就好比是操作系统内核,其主要职责在于抽象资源并调度任务,而Pod资源对象就是那些运行于用户空间中的进程。
API Server提供了RESTful风格的编程接口,其管理的资源是Kubernetes API中的端点,用于存储某种API对象的集合。Pod、Deployment和Service等都是最常用的核心对象。
Pod资源对象是一种集合了一到多个应用容器、存储资源、专用IP及支撑容器运行的其他选项的逻辑组件,是Kubernetes的部署单元及原子运行单元。
Kubernetes的网络模型要求其各Pod对象的IP地址位于同一网络平面内(同一IP网段),可以将每个Pod对象想象成一个逻辑主机,类似常规的物理主机或VM,运行于同一个Pod对象中的多个进程也类似于物理机或VM上独立运行的进程。
不过,Pod对象中的各进程均运行于彼此隔离的容器中,并于各容器间共享两种关键资源:网络和存储卷
一个Pod对象代表某个应用程序的一个特定实例,如果需要扩展应用程序,就可以通过为此应用程序创建多个Pod实例来实现。
在工作节点甚至是调度器自身导致了运行失败时,Pod对象将会被删除;同样,资源耗尽或节点故障导致的回收操作也会删除相关的Pod对象。
Kubernetes使用Controller实现对一次性的(用后即弃)Pod对象的管理操作,例如,要确保部署的应用程序的Pod副本数量符合用户的设定,以及基于Pod模板来重建Pod对象等,从而实现Pod对象的扩缩容、滚动更新和自愈能力等。
Controller本身也是一种资源类型,它有着多种实现,其中与工作负载相关的实现如:
也可统称它们为Pod控制器,控制器的定义通常由期望的副本数量、Pod模板和标签选择器(Label Selector)组成。它会根据标签选择器对Pod对象的标签进行匹配检查,所有满足选择条件的Pod对象都将受控于当前控制器并计入其副本总数,并确保此数目能够精确反映期望的副本数。
需要注意的是:在实际的应用场景中,在接收到的请求流量负载显著低于或接近于已有Pod副本的整体承载能力时,用户需要手动修改Pod控制器中的期望副本数量以实现应用规模的扩容或缩容。不过,若集群中部署了HeapSter或Prometheus一类的资源指标监控附件时,用户还可以使用“HorizontalPodAutoscaler”(HPA)计算出合适的Pod副本数量,并自动修改Pod控制器中期望的副本数以实现应用规模的动态伸缩,提高集群资源利用率。
Service主要有三种常用类型:
Pod对象重启或被重建后IP地址通常会发生变化,Service资源对象的作用便是在被访问的Pod对象与客户端之间添加一个有着固定IP地址的中间层,客户端向此地址发起访问请求后,相关的Service资源会负责将请求调度并代理至后端的Pod对象。Service IP是一种虚拟IP,也称为Cluster IP,它专用于集群内通信。
Service是“微服务”的一种实现,事实上它是一种抽象:通过规则定义出由多个Pod对象组合而成的逻辑集合,并附带访问这组Pod对象的策略。Service对象挑选、关联Pod对象的方式同Pod控制器一样,都是要基于Label Selector进行。
ClusterIP仅对集群内部开放,外部访问集群可通过NodePort,根据某个Node的IP和端口(NodePort)接入请求,并将其代理至相应的Service对象的Cluster IP上的服务端口,而后由Service对象将请求代理至后端的Pod对象的PodIP及应用程序监听的端口。这种请求需要经过两次转发。
NodePort会部署于集群中的每一个节点,只能访问到指定Node上的Service,如果存在集群外部的LoadBalancer,即可将用户请求负载均衡至集群中的部分或者所有节点。LoadBalancer通常是由Cloud Provider自动创建并提供的软件负载均衡器,也可以是由管理员手工配置的硬件设备。
容器技术使得部署程序时不再需要直接更改主机环境,而K8S又使得创建和运行容器的操作不必再关注其主机位置,并在一定程度上赋予了它动态扩缩容及自愈的能力,从而让用户从主机、系统及应用程序的维护工作中解脱出来。
部署某个应用程序时,用户首先要向API Server请求创建一个Pod控制器,由控制器根据镜像等信息向API Server请求创建出一定数量的Pod对象,并由Master之上的调度器指派至选定的工作节点以运行容器化应用。此外,用户一般还需要创建一个具体的Service对象以便为这些Pod对象建立起一个固定的访问入口,从而使得其客户端能够通过其服务名称或ClusterIP进行访问。
API Server的客户端工具有kubectl和Dashboard。
Kubernetes API(API Server)是管理其各种资源对象的唯一入口,它提供了一个RESTful风格的CRUD(Create、Read、Update和Delete)接口用于查询和修改集群状态,并将结果存储于集群状态存储系统etcd中。
用户可以通过kubectl访问API Server来操作Kubernetes的各种资源对象。
创建资源对象
kubectl run nginx-deploy --image=nginx:1.12 --replicas=1
这样的命令创建了一个名为nginx-deploy的deployment控制器资源,然后由这个资源来根据指定的镜像名称、副本数量来负责pod的创建。
查看资源对象
kubectl get命令用于查看资源对象
~ kubectl get namespaces
NAME STATUS AGE
default Active 23h
kube-node-lease Active 23h
kube-public Active 23h
kube-system Active 23h
~ kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp 1/1 Running 0 14h
nginx-deploy 1/1 Running 0 14h
Kubernetes系统的大部分资源都隶属于某个Namespace对象,缺省的名称空间为default,若需要获取指定Namespace对象中的资源对象的信息,则需要使用-n或--namespace指明其名称
打印资源对象的详细信息
kubectl get -o {yaml|josn}或kubectl describe命令都能够打印出指定资源对象的详细描述信息.
kubectl get -o {yaml|josn}可以查看资源对象的用户期望状态(Spec)和现有的实际状态(Status),比如查看default namespaces下所有pods的状态信息并输出为yaml格式:
~ kubectl get pods -n default -o yaml
kubectl describe命令可以显示资源的event、controller等信息。
~ kubectl describe pods myapp
打印容器中的日志信息
命令格式为:
kubectl logs [-f] [-p](POD|TYPE/NAME) [-c CONTAINER][options]
可打印指定Pod内指定容器的日志,如果Pod内只有一个容器,则容器名可省略,-f可用于持续监控日志输出。
在容器中执行命令
命令格式为:
kubectl exec [-p](POD|TYPE/NAME) [-c CONTAINER][options] -- [COMMAND]
删除资源对象
kubectl delete命令可以删除资源对象,但对于受控于控制器的对象来说,删除之后其控制器可能会重建出类似的对象,例如,Deployment控制器下的Pod对象在被删除时就会被重建。
有些资源类型(如Pod),支持优雅删除的机制,它们有着默认的删除宽限期,可以在命令中使用--grace-period选项或--now选项来覆盖默认的宽限期。
《Kubernetes实战进阶》 马永亮著
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。