Docker入门与实战——Kubernetes(生产级容器集群平台)(一)
Kubernetes生产级容器集群平台1、主要版本历史2、核心概念2.1、操作资源2.2、控制器2.3、辅助概念3、资源抽象对象3.1、容器组3.2、服务3.3、存储卷3.4、控制器3.4.1、部署和副本集3.4.2、状态集3.4.3、Daemon集3.4.4、任务和计划任务3.4.5、横向Pod扩展器3.4.6、端点控制器3.4.7、持久卷控制器3.5、其他抽象对象3.5.1、标签3.5.2、注解3.5.3、选择器3.5.4、秘密数据3.5.5、UID和名字3.5.6、命名空间3.5.7、污点和容忍4、快速体验4.1、下载minikube和kubectl4.2、启动集群4.3、查看Kubernetes服务4.4、使用部署控制器管理服务Kubernetes是由Google团队发起并坚持维护的开源容器集群管理系统构建在Docker等强大的容器技术基础之上为用户提供了卓越的应用管理与资源调度能力。如今Kubernetes已经成为在容器云领域具有最大影响力的开源平台利用Kubernetes用户能够轻松构建和管理一个具备扩展性的生产级别的容器云。在本章中笔者将详细介绍与Kubernetes相关的关键概念和核心实现组件还会探讨如何进行有效的安装和部署。通过学习和理解Kubernetes的各种命令读者能够深入领悟如何在实际生产环境中灵活地运用Kubernetes以提升应用开发和部署的效率和质量。Kubernetes是一款由Google公司于2014年开源的容器集群管理工具采用Go语言编写并遵循Apache V2许可。此项目力图创建一套强大且易用的平台为基于容器的应用部署和运维管理提供支持。Kubernetes来自希腊语是“领航员”的意思按照惯例经常被缩写为K8S。自开源以来Kubernetes迅速获得了多家公司以及容器技术爱好者的广泛关注已成为当前最优秀的容器集群管理开源项目之一。其中Microsoft、RedHat、IBM、Docker、Mesosphere、CoreOS以及SaltStack等公司已加入Kubernetes社区同时它已在box、bay、sap等企业广泛应用也成为众多容器云项目的基础平台。Kubernetes的前身—Borg系统在Google内部已有十多年的应用历程支持每周处理数十亿规模的容器管理积累了大量来自生产环境的实践经验。在设计Kubernetes时开发团队充分吸纳了社区的建议现在它由云原生计算基金会(Cloud Native Computing FoundationCNCF)管理并以开源项目的形式持续演进。正是因为这些积累作为一套分布式应用容器集群系统Kubernetes拥有鲜明的技术优势精良的API设计和简洁高效的架构主要组件少而精各组件间通过接口调用交互。提出了基于微服务模式的多层资源抽象模型兼顾灵活性与可操作性其提出的Pod模型已被许多平台采用。显著的可拓展性模块化设计易于替换弹性伸缩能力卓越单集群即可支持5000个节点可同时运行150000个Pod。高度自动化实现“所得即所需”用户只需通过模板声明服务便可实现整个生命周期的自动化管理包括伸缩、负载均衡、资源分配、故障恢复、更新等。多环境部署支持包括虚拟机、物理机部署并良好地支持如AWS、GCE等常见云平台。提供丰富的运维和配置工具方便用户对集群进行性能测试、问题检查和状态监控。自带控制台、客户端命令等工具为用户与Kubernetes集群交互提供多种途径。基于Kubernetes用户可以很容易地实现一套容器云。Kubernetes支持用户通过模板来定义服务配置用户提交配置模板后Kubernetes会自动管理包括部署、发布、伸缩、更新等应用容器以保持服务在预定状态下运行从而实现极高的可靠性用户无须过多关注底层细节。Kubernetes目前在github.com/kubernetes/kubernetes进行维护欢迎全球的开发者和用户共同参与共享并贡献于这个开源项目的发展。1、主要版本历史2015年7月发布的1.0版本是Kubernetes的第一个正式版本标志着核心功能已经逐渐成熟稳定可以正式投入生产环境使用。2016年3月发布的1.2版本在性能、稳定性和可管理性上都有了重大的优化和升级包括对多可用域的支持、监控服务增强、上千物理节点的支持等令人振奋的特性。此后基本上在每个季度末发行一次版本的更新。1.3版本2016年6月发布中增强了多集群之间的联盟(Cross-Cluster Federated Services)服务引入了PetSet来支持持久化带状态应用并支持更大的集群规模。1.4版本中增强了对带状态应用的支持完善了多集群联盟的API增强了安全控制和调度机制。1.5版本中将PetSet更名为StatefulSet修复稳定性进一步提高了节点的鲁棒性和集群的可扩展性。1.6版本实现了高级调度功能引入最新的Etcd V3扩大集群规模为5000个节点。并新增了基于角色的访问控制支持存储动态分配。1.17版本正式支持云服务商标签。1.18版本支持新的pathType域和新的IngressClass资源同时提供了API服务器的OIDC发现和对Windows节点的增强支持。1.19版本将支持时间窗口从9个月提升到了12个月意味着产品质量提升到了新的阶段。新特性包括存储容量跟踪、通用临时数据卷、CSI卷健康监控等。1.20版本中数据卷快照已经成熟并且弃用了dockershim。1.21版本中CronJobs、不可变Secret、Configmap已经成为稳定功能并且弃用了PodSecurityPolicy和topologyKeys。1.22版本中正式支持服务器端应用、外部凭据提供者提升Etcd版本到3.5.0。1.23版本开始支持IPv4/IPv6双栈支持新的对象存储API和自动删除状态集附带的持久数据卷。1.24版本删除了dockershim组件默认关闭beta状态的API并且提供签名的发布工件。1.25版本中正式支持cgroup v2。1.26版本中开始允许从跨命名空间快照配置卷支持将准入控制器的规则定义为Kubernetes对象。1.27版本中镜像仓库从k8s.gcr.io切换到registry.gcr.io优化了大型集群中kube-proxy的iptables模式性能。1.28版本增强了可观测性改进了存储的灵活性和性能同时提供了更精细的流量控制。1.29版本优化了调度算法引入了新的节点健康检查机制提升了节点的可靠性同时加强了对敏感数据的保护改进了凭据管理。1.30版本原生支持多集群部署改进了资源配额和限制的管理支持更多的扩展场景。1.31版本加强了对集群内通信的加密提升了整体安全性同时改进了控制平面的性能减少了资源消耗。1.32版本优化了动态资源分配提升了对GPU、FPGA等硬件资源的支持同时改进了负载均衡的灵活性。本书将以最新的Kubernetes 1.32版本系列为主兼顾新特性进行剖析和实践。2、核心概念要想深入理解Kubernetes的特性和工作机制首先要掌握Kubernete模型中的核心概念。这些核心概念反映了Kubernetes设计过程中对应用容器集群的认知模型主要包括操作资源、控制器和辅助概念。2.1、操作资源Kubernetes为了更好地管理应用的生命周期将不同资源对象进行了进一步的操作抽象。学习使用Kubernetes实际上就是要掌握这些不同的抽象对象。Kubernetes中每种对象都拥有一个对应的声明式API。对象包括三大属性元数据(metadata)、规范(spec)和状态(status)。通过这三个属性用户可以定义让某个对象处于给定的状态如哪些Pod运行在哪些节点上以及表现策略如如何升级、容错而无须关心具体的实现细节。当使用Kubernetes管理这些对象时每个对象可以使用一个外部的JSON或YAML模板文件来定义通过参数传递给命令或API。每个模板文件中将定义apiVersion、kind如Deployment、Service、metadata包括名称、标签信息等、spec具体的定义等信息。例如基础的操作对象主要包括容器组(Pod)Kubernetes中进行管理的最小的资源单位由位于同一节点上的若干容器组成彼此共享网络命名空间和存储卷(Volume)是最为基础的概念。与容器类似Pod是短暂的、随时可变的通常不带有状态。一般每个Pod中除了应用容器外还包括一个初始的pause容器完成网络和存储空间的初始化。服务(Service)对外提供某个特定功能的一组Pod可通过标签来选择和所关联的访问配置。由于Pod的地址是不同的而且可能改变因此直接访问Pod将无法获得稳定的业务。Kubernetes通过服务提供唯一固定的访问地址如IP地址或者域名不随后面Pod的改变而变化。用户无须关心具体的Pod信息。存储卷(Volume)存储卷类似Docker中的概念提供数据的持久化存储如Pod重启后并支持更高级的生命周期管理和参数指定功能支持多种本地和云存储类型。命名空间(Namespace)Kubernetes通过命名空间来实现虚拟化将同一组物理资源虚拟为不同的抽象集群避免不同租户的资源发生命名冲突另外可以进行资源限额。2.2、控制器为了方便操作这些基础对象Kubernetes还引入了控制器(Controller)的高级抽象概念。这些控制器面向特定场景提供了自动管理Pod的功能用户使用控制器而无须关心具体的Pod相关细节。控制器抽象对象主要包括副本集(ReplicaSet)旧版本中叫作复制控制器(Replication Controller)。副本集是一个基于Pod的抽象使用它可以让集群中始终维持某个Pod的指定副本数的健康实例。副本集中的Pod相互并无差异可以彼此替换。由于操作相对底层一般不推荐直接使用。部署(Deployment)自1.2.0版本开始引入是比副本集更高级的抽象可以管理Pod或副本集并且支持升级操作。部署控制器可以提供比副本集更方便的操作推荐使用。状态集(StatefulSet)管理带有状态的应用。相比部署控制器状态集可以为Pod分配独一无二的身份确保在进行重新调配等操作时也不会相互替换。自1.9版本开始正式支持。Daemon集(DaemonSet)确保节点上肯定运行某个Pod一般用来采集日志如logstash、监控节点如collectd或提供存储如glusterd。任务(Job)适用于短期处理场景。任务将创建若干Pod并确保给定数目的Pod最终正常退出完成指定的处理。计划任务(CronJob)用于执行常规计划操作如备份、生成报告等。类似于Linux系统中的cron任务它按照给定的时间表以Cron格式编写定期运行。完成任务清理(Automatic Cleanup for FinishedJobs)通过限时完成任务清理控制器可以对完成的任务进行清理工作。入口控制器(Ingress Controller)定义外部访问集群中资源的一组规则用来提供七层代理和负载均衡服务。横向Pod扩展器(Horizontal Pod AutoscalerHPA)类似云中的自动扩展组根据Pod的使用率典型的如CPU自动调整一个部署里面Pod的个数保障服务可用性。端点列表(EndpointSlices)端点列表提供了跟踪集群内网络端点的机制具有可伸缩性和可扩展性。2.3、辅助概念以下主要是一些与管理资源相关的辅助概念包括标签(Label)键值对可以标记到资源对象上用来对资源进行分类和筛选。选择器(Selector)基于标签概念的一个正则表达式可通过标签筛选出一组资源。注解(Annotation)键值对可以存放大量任意数据一般用来添加对资源对象的详细说明可供其他工具处理。秘密数据(Secret)存放敏感数据例如用户认证的口令等。名字(Name)用户提供给资源的别名同类资源不能重名。持久化存储(Persistent Volume)确保数据不会丢失。安全上下文(Security Context)应用到容器上的系统安全配置包括uid、gid、capabilities、SELinux角色等。服务账号(Service Account)操作资源的用户账号。本章后续将分别解释这些核心概念的含义和用法。3、资源抽象对象Kubernetes对集群中的资源进行了不同级别的抽象每个资源都是一个REST对象通过API进行操作通过JSON/YAML格式的模板文件进行定义。在使用Kubernetes的过程中要注意积累这些模板文件。在Kubernetes代码包的example目录下自带了十分翔实的示例模板文件推荐读者参考使用。3.1、容器组在Kubernetes中并不直接操作容器最小的管理单位是容器组(Pod)。容器组由一个或多个容器组成Kubernetes围绕容器组进行创建、调度、停止等生命周期管理。同一个容器组中各个容器共享命名空间包括网络、IPC、文件系统等容器支持的命名空间、cgroups限制和存储卷。这意味着在同一容器组中各个应用可以很方便地相互进行访问比如通过localhost地址进行网络访问通过信号量和共享内存进行进程间通信等类似经典场景中运行在同一个操作系统中的一组进程。可以简单地将一个Pod当作一个抽象的“虚拟机”在其中运行若干个不同的进程每个进程实际上就是一个容器。实现上是先创建一个gcr.io/google_containers/pause容器并创建相关命名空间然后创建Pod中的其他应用容器并共享pause容器的命名空间。组成容器组的若干容器往往是存在共同的应用目的彼此关联十分紧密例如一个Web应用和对应的日志采集应用或状态监控应用。如果单纯把这些相关的应用放一个容器中又会造成过度耦合管理升级都不方便。容器组的经典应用场景包括内容管理、文件和数据加载缓存管理等。日志处理、状态快照等。监控代理、消息发布等。代理机制网桥、网卡等。控制器、管理器配置以及更新等。与其他资源类似容器组是一个REST对象用户可以通过YAML或者JSON模板来定义一个容器组资源例如可以说容器组既保持了容器轻量解耦的特性又提供了调度操作的便利性在实践中提供了比单个容器更为灵活和更有意义的抽象。容器组生命周期包括五种状态值待定(Pending)、运行(Running)、成功(Succeeded)、失败(Failed)、未知(Unknown)。待定已经被系统接受但容器镜像还未就绪。运行分配到节点所有容器都被创建至少一个容器在运行中。成功所有容器都正常退出不需要重启任务完成。失败所有容器都退出至少一个容器是非正常退出。未知未知状态例如所在节点无法汇报状态。3.2、服务服务(Service)可以给集群中的网络应用提供外部可访问能力。服务的提出主要是要解决Pod地址可变的问题。由于Pod随时可能出现故障并可能在其他节点上被重启它的地址是不能保持固定的因此用一个服务来代表提供某一类功能可以通过标签来筛选的一些Pod并分配不随Pod位置变化而改变的虚拟访问地址(Cluster IP)。这也符合微服务的理念。典型地比如网站的后端服务可能有多个Pod都运行了后端处理程序它们可以组成一个服务。前端只需要通过服务的唯一虚拟地址来访问即可而无须关心具体是访问到了哪个Pod。可见服务与负载均衡器实现的功能很相似。根据访问方式的不同服务可以分为如下几种类型ClusterIP提供一个集群内部的地址该地址只能在集群内解析和访问。ClusterIP是默认的服务类型。NodePort在每个集群节点上映射服务到一个静态的本地端口默认范围为3000032767。从集群外部可以直接访问并自动路由到内部自动创建的ClusterIP。LoadBalancer使用外部的路由服务自动路由访问到自动创建的NodePort和ClusterIP。ExternalName将服务映射到externalName域指定的地址需要1.7以上版本kube-dns的支持。组成一个服务的Pod可能是属于不同的复制控制器的但服务自身是不知道复制控制器的存在的。同样地服务也是一个REST对象用户可以通过模板来定义一个服务资源这个模板会筛选所有带有标签app:webApp的Pod作为web-service对外呈现的访问端口为80映射到Pod的80端口上。创建服务后服务会被自动分配一个集群地址(ClusterIP)这个地址并不绑定到任何接口而是作为访问服务的抽象地址。访问该地址会被映射到Pod的实际地址这将通过Kube-Proxy进程实现。每个节点上都会运行一个Kube-Proxy进程负责将到某个服务的访问给代理或者均衡到具体的Pod上去。同时会为每一个服务创建环境变量指向集群地址或者在DNS中注册该服务的集群地址。也许会有用户考虑使用DNS方式来替代服务的集群IP机制这是完全可以的Kubernetes也提供了基于SkyDNS的插件支持但是要处理好DNS查找的缓存过期时间问题。当某个Pod发生变化时要让客户端本地的DNS缓存过期。另外服务支持进行不同类型的健康检查通过容器spec中的LIVENESSPROBE或READINESSPROBE字段定义目前包括三种类型通过HTTP获取资源是否成功。在容器中执行指定命令返回值是否为0。打开给定Socket端口是否成功。探测的结果可能为成功、失败或未知。其中LIVENESSPROBE字段反映的是容器自身状态如果配置了重启策略则失败状态会触发自动重启而READINESSPROBE字段则用来反映容器内的服务是否可用。3.3、存储卷存储卷即容器挂载的数据卷有与Pod一致的生命周期在Pod生存过程包括重启中数据卷跟着存在Pod退出则数据卷跟着退出。几个比较常见的数据卷类型包括ConfigMap、emptyDir、hostPath和nfs。ConfigMapConfigMap提供了一种将配置数据注入Pod的方法。存储在ConfigMap中的数据可以在ConfigMap类型的卷中引用然后由在Pod中运行的容器化应用程序使用。emptyDir当Pod创建的时候在节点上创建一个空的挂载目录挂载到容器内。当Pod从节点离开例如删除掉的时候挂载目录内的数据被自动删除。节点上的挂载位置可以为物理硬盘或内存。这一类挂载适用于非持久化的存储例如与Pod任务相关的临时数据等。除此之外其他存储格式大多是持久化的。hostPath将节点上某个已经存在的目录挂载到Pod中Pod退出后节点上的数据将保留。nfs使用NFS协议的网络存储也是持久化数据存储。其他类型还包括cephfs、downwardAPI、fibrechannel、iscsi、local等。持久化的存储以插件的形式提供为PersistentVolume资源用户通过请求某个类型的PersistentVolumeClaim资源来从匹配的持久化存储卷上获取绑定的存储。资源定义仍然通过YML或JSON格式的模板文件实现例如定义一个持久化存储卷3.4、控制器控制器是基于对所操控对象的进一步抽象附加了各种资源的管理功能目前主要包括部署、副本集、状态集、Daemon集、任务等。所有的控制器实现都可以在https://github.com/kubernetes/kubernetes/tree/master/pkg/controller上找到。3.4.1、部署和副本集部署(Deployment)和副本集(ReplicaSet)都适合于长期运行的应用类型。在Kubernetes看来Pod资源是可以随时出现故障的并不一定要保证Pod的运行而是在发生失败后重新生成。Kubernetes通过复制控制器来实现这一功能。用户申请容器组后复制控制器将负责调度容器组到某个节点上并保证它的给定份数正常运行。当实际运行的Pod份数超过限制则终止某些Pod当不足时则创建新的Pod。一般建议即使Pod份数是1也要使用复制控制器来创建而不是直接创建Pod。可以将副本集类比为进程的监管者只不过它不仅能保持Pod的持续运行还能保持集群中给定类型Pod同时运行的个数为指定值。Pod是临时性的可以随时被副本集创建或销毁这意味着通过Pod自身的地址访问应用是不能保证一致性的。Kubernetes通过服务的概念来解决这个问题。从1.2版本开始Kubernetes将正式引入部署机制来支持更灵活的Pod管理从而让用户无须直接与复制控制器打交道。部署代表用户对集群中应用的一次更新操作在副本集的基础上还支持更新操作。每次滚动升级(rolling-update)会自动将副本集中旧版本的Pod逐渐替换为新版本。另外副本集也可以支持成为横向Pod扩展器的操作对象。3.4.2、状态集状态集(StatefulSet)是1.5版本开始引入的新概念。通常情况下使用容器的应用都是不带状态的这意味着部署同一个应用的多个Pod彼此可以替换而且生命周期可以是很短暂的。任何一个Pod退出后Kubernetes在集群中可以自动创建一个并按照调度策略调度到节点上。对于无状态的应用关注的主要是副本的个数而不关心名称、位置等。与此对应对某些应用需要关注Pod的状态包括各种数据库和配置服务等挂载独立的存储。一旦某个Pod故障退出Kubernetes会创建同一命名的Pod并挂载原来的存储以便Pod中的应用继续执行实现了该应用的高可用性。状态集正是针对这种需求设计的提供比副本集和部署更稳定可靠的运行支持。3.4.3、Daemon集Daemon集(DaemonSet)适合于长期运行在后台的伺服类型的应用例如对节点的日志采集或状态监控等后台支持服务。Daemon集的应用会确保在指定类型的每个节点上都运行一个该应用的Pod可能是集群中所有节点也可能是指定标签的一类节点。3.4.4、任务和计划任务不同于长期运行的应用任务(Job)代表批处理类型的应用。任务中应用完成某一类的处理即可退出有头有尾。例如计算Pi到多少位可以指定若干个Pod成功完成计算即算任务成功执行。计划任务(CronJob)则可以在指定的时间自动执行适合定期重复作业例如打印报告。3.4.5、横向Pod扩展器横向Pod扩展器(Horizontal Pod AutoscalerHPA)解决应用波动问题。类似云里面的自动扩展组扩展器根据Pod的使用率典型如CPU、内存等自动调整一个部署中Pod的个数以确保服务在不同压力情况下保证平滑的输出效果。控制管理器会定期检查性能指标在满足条件时触发横向伸缩。Kubernetes 1.6版本开始支持基于多个指标的伸缩。3.4.6、端点控制器端点控制器(endpoint controller)负责更新和维护Kubernetes集群中的端点列表。它监视服务和Pod资源。当添加、删除或更新服务或Pod时它会选择与服务Pod条件选择器匹配的Pod及其IP和端口到Endpoint对象。删除服务时控制器会删除该服务的依赖端点。3.4.7、持久卷控制器当用户创建一个PVCPersistent Volume Claim持久卷声明时Kubernetes必须找到一个合适的持久卷来满足这个请求并将其绑定到这个声明上。当PVC被删除时该卷将根据其回收策略解除绑定和回收。持久卷控制器(Persistent Volume Controller)负责执行此类任务。3.5、其他抽象对象3.5.1、标签标签(Label)是一组键值对用来标记所绑定对象典型的就是Pod的识别属性进而可以分类比如nameapache|nginx、typeweb|db、releasealpha|beta|stable、tierfrontend|backend等。另外Label键支持通过/来添加前缀可以用来标注资源的组织名称等。一般地前缀不能超过253个字符键名不能超过63个字符。标签所定义的属性是不唯一的这意味着不同资源可能带有相同的标签键值对。这些属性可以将业务的相关信息绑定到对象上用来对资源对象进行分类和选择过滤。3.5.2、注解注解(Annotation)与标签很相似也是键值对但并非用来标识对象同时可以存储更多更复杂的信息。不同的是注解并不是为了分类资源对象而是为了给对象增加更丰富的描述信息。这些信息是任意的数据量可以很大可以包括各种结构化、非结构化的数据。常见的注解包括时间戳、发行信息、开发者信息等一般是为了方便用户查找相关线索。3.5.3、选择器基于资源对象上绑定的标签信息选择器(Selector)可以通过指定标签键值对来过滤出一组特定的资源对象。选择器支持的语法包括基于等式(Equality-based)的和基于集合(Set-based)的。基于等式的选择即指定某个标签是否等于某个值例如envproduction或者tier!frontend等。多个等式可以通过AND逻辑组合在一起。基于集合的选择即指定某个标签的值是否在某个集合内例如env in(staging,production)。3.5.4、秘密数据秘密数据(Secret)资源用来保存一些敏感的数据这些数据例如密码往往不希望对别的用户展示但是在启动某个资源例如Pod的时候需要提供。通过把敏感数据放到Secret里面用户只需要提供Secret的别名即可使用。例如可以通过环境变量传递用户名和密码信息到一个Pod中。首先将用户名和密码使用base64进行编码然后编写一个Secret的对象模板添加前面的base64编码数据通过kubectl创建秘密数据对象test_secret例如通过环境变量在Pod中使用秘密数据例如在对应容器(secret-test-pod.test-container)内通过环境变量$SECRET_USERNAME和$SECRET_PASSWORD即可获取到原始的用户名和密码信息。此外还可以采用数据卷的方式把秘密数据的值以文件的形式放到容器内。通常秘密数据的大小不要超过1MB。在整个过程中只有秘密数据的所有人和最终运行的容器准确的说需要处于同一个服务账号下能获取原始敏感数据只接触到Pod定义模板的人是无法获取秘密数据的。3.5.5、UID和名字Kubernetes用UID和名字(Name)来标识对象。其中UID是全局唯一的并且不能复用而名字则仅仅要求对某种类型的资源在同一个命名空间内内是唯一的并且当某个资源移除后其名字可以被新的资源复用。这意味着可以创建一个Pod对象命名为test同样可以创建一个复制控制器命名也为test。一般地名字字符串的长度不要超过253个字符。3.5.6、命名空间命名空间(Namespace)用来隔离不同用户的资源类似租户或项目的概念。默认情况下相同命名空间中的对象将具有相同的访问控制策略。同一个命名空间内资源不允许重名但不同命名空间之间允许存在重名。用户在创建资源时可以通过--namespacesome_namespace来指定所属的命名空间。Kubernetes集群启动后会保留两个特殊的命名空间default在资源未指定命名空间的情况下默认属于该空间。kube-system由Kubernetes系统自身创建的资源。另外大部分资源都属于某个命名空间但部分特殊资源如节点、持久存储等不属于任何命名空间。3.5.7、污点和容忍污点(Taint)和容忍(Toleration)用于辅助管理Pod到工作节点的调度过程。对于不容忍的Pod要尽量避免将具有污点的工作节点调度到它上面去。通常情况下可以为一个工作节点注明若干污点只有对这些污点容忍的Pod才可以被调度到这些具有污点的节点上。4、快速体验目前Kubenetes支持在多种环境下的安装包括本地主机、云服务Google GAE、AWS等。最快速体验Kubernetes的方式是通过社区提供的minikube工具。minikube工具支持快速在本地安装一套Kubenetes集群可在Linux、macOS或Windows等操作系统上使用。最新的代码可以从kubernetes/minikube下载。下面以Linux平台为例讲解使用minikube工具快速搭建集群的过程。4.1、下载minikube和kubectl下载最新版本的minikube并复制到/usr/local/bin目录下kubectl是Kubernetes提供的客户端使用它可以操作启动后的集群。下载最新版本的kubectl并复制到/usr/local/bin目录下4.2、启动集群minikube启动集群有两种模式一种是先在本地创建一个虚拟机然后在里面创建Kubernetes集群另一种是在本地直接创建集群需要制定-vm-drivernone参数。这里采用直接模式来创建kubernetes集群启动过程中的日志如下所示如果没有报错则说明启动成功4.3、查看Kubernetes服务可以使用kubectl cluster-info命令查看集群信息查看本地新启动的容器创建了一个基于gcr.io/k8s-minikube/kicbase镜像的minikube容器。4.4、使用部署控制器管理服务切换到预置的minikube客户端环境上下文用户也可以在执行kubectl命令的同时使用–contextminikube参数来指定上下文。下面运行一个Nginx的示例部署该部署主要内容为启动了两个Nginx应用内容如下此时查看本地Pod可以看到启动的两个Nginx容器正在运行中删除部署此时再次查看本地的Pod发现两个Nginx Pod已被删除