为什么要学习Kubernetes? 虽然Docker已经很强大了,但是在实际使用上还是有诸多不便,比如集群管理、资源调度、文件管理等等。那么在这样一个百花齐放的容器时代涌现出了很多解决方案,比如Mesos、Swarm、Kubernetes等等,其中谷歌开源的Kubernetes是作为老大哥的存在。也可参考:k8s和Docker关系简单说明 kubernetes已经成为容器编排领域的王者,它是基于容器的集群编排引擎,具备扩展集群、滚动升级回滚、弹性伸缩、自动治愈、服务发现等多种特性能力。kubernetes介绍 Kubernetes解决的核心问题服务发现和负载均衡Kubernetes可以使用DNS名称或自己的IP地址公开容器,如果到容器的流量很大,Kubernetes可以负载均衡并分配网络流量,从而使部署稳定。存储编排Kubernetes允许您自动挂载您选择的存储系统,例如本地存储、公共云提供商等。自动部署和回滚您可以使用Kubernetes描述已部署容器的所需状态,它可以以受控的速率将实际状态更改为所需状态。例如,您可以自动化Kubernetes来为您的部署创建新容器,删除现有容器并将它们的所有资源用于新容器。自动二进制打包Kubernetes允许您指定每个容器所需CPU和内存(RAM)。当容器指定了资源请求时,Kubernetes可以做出更好的决策来管理容器的资源。自我修复Kubernetes重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。密钥与配置管理Kubernetes允许您存储和管理敏感信息,例如密码、OAuth令牌和ssh密钥。您可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。 Kubernetes的出现不仅主宰了容器编排的市场,更改变了过去的运维方式,不仅将开发与运维之间边界变得更加模糊,而且让DevOps这一角色变得更加清晰,每一个软件工程师都可以通过Kubernetes来定义服务之间的拓扑关系、线上的节点个数、资源使用量并且能够快速实现水平扩容、蓝绿部署等在过去复杂的运维操作。Kubernetes知识图谱 主要介绍学习一些什么知识 Kubernetes软件架构 传统的客户端服务端架构 架构说明 Kubernetes遵循非常传统的客户端服务端的架构模式,客户端可以通过RESTful接口或者直接使用kubectl与Kubernetes集群进行通信,这两者在实际上并没有太多的区别,后者也只是对Kubernetes提供的RESTfulAPI进行封装并提供出来。每一个Kubernetes集群都是由一组Master节点和一系列的Worker节点组成,其中Master节点主要负责存储集群的状态并为Kubernetes对象分配和调度资源。 主节点服务Master架构 作为管理集群状态的Master节点,它主要负责接收客户端的请求,安排容器的执行并且运行控制循环,将集群的状态向目标状态进行迁移。Master节点内部由下面三个组件构成: APIServer:负责处理来自用户的请求,其主要作用就是对外提供RESTful的接口,包括用于查看集群状态的读请求以及改变集群状态的写请求,也是唯一一个与etcd集群通信的组件。 etcd:是兼具一致性和高可用性的键值数据库,可以作为保存Kubernetes所有集群数据的后台数据库。 Scheduler:主节点上的组件,该组件监视那些新创建的未指定运行节点的Pod,并选择节点让Pod在上面运行。调度决策考虑的因素包括单个Pod和Pod集合的资源需求、硬件软件策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。 controllermanager:在主节点上运行控制器的组件,从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器包括:节点控制器(负责在节点出现故障时进行通知和响应)、副本控制器(负责为系统中的每个副本控制器对象维护正确数量的Pod)、端点控制器(填充端点Endpoints对象,即加入Service与Pod))、服务帐户和令牌控制器(为新的命名空间创建默认帐户和API访问令牌)。 工作节点Node架构 其他的Worker节点实现就相对比较简单了,它主要由kubelet和kubeproxy两部分组成。 kubelet:是工作节点执行操作的agent,负责具体的容器生命周期管理,根据从数据库中获取的信息来管理容器,并上报pod运行状态等。 kubeproxy:是一个简单的网络访问代理,同时也是一个LoadBalancer。它负责将访问到某个服务的请求具体分配给工作节点上同一类标签的Pod。kubeproxy实质就是通过操作防火墙规则(iptables或者ipvs)来实现Pod的映射。 ContainerRuntime:容器运行环境是负责运行容器的软件,Kubernetes支持多个容器运行环境:Docker、containerd、crio、rktlet以及任何实现KubernetesCRI(容器运行环境接口)。 Kubernetes组件说明 主要介绍关于K8s的一些基本概念 主要由以下几个核心组件组成:apiserver所有服务访问的唯一入口,提供认证、授权、访问控制、API注册和发现等机制controllermanager负责维护集群的状态,比如副本期望数量、故障检测、自动扩展、滚动更新等scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上etcd键值对数据库,保存了整个集群的状态kubelet负责维护容器的生命周期,同时也负责Volume和网络的管理kubeproxy负责为Service提供cluster内部的服务发现和负载均衡Containerruntime负责镜像管理以及Pod和容器的真正运行 除了核心组件,还有一些推荐的插件:CoreDNS可以为集群中的SVC创建一个域名IP的对应关系解析的DNS服务Dashboard给K8s集群提供了一个BS架构的访问入口IngressController官方只能够实现四层的网络代理,而Ingress可以实现七层的代理Prometheus给K8s集群提供资源监控的能力Federation提供一个可以跨集群中心多K8s的统一管理功能,提供跨可用区的集群 以上内容参考链接:https:www。escapelife。siteposts2c4214e7。htmlKubernetes安装 安装v1。16。0版本,竟然成功了。记录在此,避免后来者踩坑。 本篇文章,安装大步骤如下:安装dockerce18。09。9(所有机器)设置k8s环境前置条件(所有机器)安装k8sv1。16。0master管理节点安装k8sv1。16。0node工作节点安装flannel(master) 详细安装步骤参考:CentOS搭建K8S,一次性成功,收藏了!集群安装教程请参考:全网最新、最详细基于V1。20版本,无坑部署最小化K8S集群教程KubernetesPod实现原理 Pod就是最小并且最简单的Kubernetes对象 Pod、Service、Volume和Namespace是Kubernetes集群中四大基本对象,它们能够表示系统中部署的应用、工作负载、网络和磁盘资源,共同定义了集群的状态。Kubernetes中很多其他的资源其实只对这些基本的对象进行了组合。Pod集群中的基本单元Service解决如何访问Pod里面服务的问题Volume集群中的存储卷Namespace命名空间为集群提供虚拟的隔离作用 详细介绍请参考:Kubernetes之Pod实现原理Harbor仓库 Kuternetes企业级Docker私有仓库Harbor工具。 Harbor的每个组件都是以Docker容器的形式构建的,使用DockerCompose来对它进行部署。用于部署Harbor的DockerCompose模板位于Deployerdockercompose。yml中,其由5个容器组成,这几个容器通过Dockerlink的形式连接在一起,在容器之间通过容器名字互相访问。对终端用户而言,只需要暴露Proxy(即Nginx)的服务端口即可。Proxy由Nginx服务器构成的反向代理Registry由Docker官方的开源官方的开源Registry镜像构成的容器实例UI即架构中的coreservices服务,构成此容器的代码是Harbor项目的主体MySQL由官方MySQL镜像构成的数据库容器Log运行着rsyslogd的容器,通过logdriver的形式收集其他容器的日志 详细介绍与搭建步骤请参考:企业级环境中基于Harbor搭建YAML语法 YAML是一种非常简洁强大专门用来写配置文件的语言! YAML全称是YAMLAin’taMarkupLanguage的递归缩写,该语言的设计参考了JSONXML和SDL等语言,强调以数据为中心,简洁易读,编写简单。 YAML语法特性 学过编程的人理解起来应该非常容易 语法特点大小写敏感通过缩进表示层级关系禁止使用tab缩进,只能使用空格键缩进的空格数目不重要,只要相同层级左对齐使用表示注释 推荐给大家一篇文章:Kubernetes之YAML语法,这篇文章介绍的非常详细,有很多例子说明。Kubernetes资源清单 K8S中所有的内容都抽象为了资源,资源实例化之后就叫做对象。 在Kubernetes系统中,Kubernetes对象是持久化的实体,Kubernetes使用这些实体去表示整个集群的状态。特别地,它们描述了如下信息:哪些容器化应用在运行,以及在哪个Node上可以被应用使用的资源关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略 Kubernetes对象是目标性记录一旦创建对象,Kubernetes系统将持续工作以确保对象存在。通过创建对象,本质上是在告知Kubernetes系统,所需要的集群工作负载看起来是什么样子的,这就是Kubernetes集群的期望状态。 Kubernetes之资源清单详细介绍看这里Kubernetes资源控制器 Kubernetes资源控制器配置文件的编写是学习K8S的重中之重! 资源配额控制器确保了指定的资源对象始终不会超过配置的资源,能够有效的降低整个系统宕机的机率,增强系统的鲁棒性,对整个集群的稳定性有非常重要的作用。 Kubernetes资源控制器使用指南手册Kubernetes服务发现 Kubernetes中为了实现服务实例间的负载均衡和不同服务间的服务发现,创造了Service对象,同时又为从集群外部访问集群创建了Ingress对象。 可参考:Kubernetes之服务发现Ingress服务 我们都知道传统的SVC只支持四层上面的代码,而对于七层上的代码而无能为力。比如:我们使用K8S集群对外提供HTTPS的服务,为了方便和便捷,我们需要在对外的Nginx服务上面配置SSL加密,但是将请求发送给后端服务的时候,进行证书卸载的操作,后续都是用HTTP的协议进行处理。而面对此问题,K8S中给出了使用Ingress(K8S在1。11版本中推出了)来进行处理。 更多详细内容请参阅:Kubernetes之Ingress服务,介绍关于Ingress服务的安装方式,配置关于Ingress服务的HTTP代理访问,介绍Ingress服务的BasicAuth认证方式,介绍Ingress的进行规则重写的方式。Kubernetes数据存储 在之前的文章中,我们已经知道了很多K8S中的组件了,包括资源控制器等。在资源控制器中,我们说到了StatefulSet这个控制器组件,其专门为了有状态服务而生的,而对应的存储要存放到哪里呢? 介绍K8S中常见的存储机制可以让我们所使用的:Kubernetes之数据存储Kubernetes集群调度 有这样一个需求,就是集群中多台服务的配置是不一致的。这就导致资源分配并不是均匀的,比如我们需要有些服务节点用来运行计算密集型的服务,而有些服务节点来运行需要大量内存的服务。而在k8s中当然也配置了相关服务来处理上述的问题,那就是Scheduler。 Scheduler是kubernetes的调度器,主要的任务是把定义的Pod分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:公平如何保证每个节点都能被分配资源资源高效利用集群所有资源最大化被使用效率调度的性能要好,能够尽快地对大批量的Pod完成调度工作灵活允许用户根据自己的需求控制调度的逻辑 Scheduler是作为单独的程序运行的,启动之后会一直坚挺APIServer,获取PodSpec。NodeName为空的Pod,对每个Pod都会创建一个binding,表明该Pod应该放到哪个节点上。 详细的介绍请参考:Kubernetes之集群调度kubectl使用指南 kubectl是Kubernetes自带的客户端,可以用它来直接操作Kubernetes集群。 日常在使用Kubernetes的过程中,kubectl工具可能是最常用的工具了,所以当我们花费大量的时间去研究和学习Kuernetes的时候,那么我们就非常有必要去了解下如何高效的使用它了。 从用户角度来说,kubectl就是控制Kubernetes的驾驶舱,它允许你执行所有可能的Kubernetes操作;从技术角度来看,kubectl就是KubernetesAPI的一个客户端而已。 KubernetesAPI是一个HTTPRESTAPI服务,该API服务才是Kubernetes的真正用到的用户接口,所以Kubernetes通过该API进行实际的控制。这也就意味着每个Kubernetes的操作都会通过API端点暴露出去,当然也就可以通过对这些API端口进行HTTP请求来执行相应的操作。所以,kubectl最主要的工作就是执行KubernetesAPI的HTTP请求。Kubernetes工具使用参数get显示一个或多个资源describe显示资源详情create从文件或标准输入创建资源update从文件或标准输入更新资源delete通过文件名、标准输入、资源名或者label删除资源log输出pod中一个容器的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志arollingupdate对指定的RC执行滚动升级exec在容器内部执行命令portforward将本地端口转发到Podproxy为KubernetesAPIserver启动代理服务器run在集群中使用指定镜像启动容器expose将SVC或pod暴露为新的kubernetesservicelabel更新资源的labelconfig修改kubernetes配置文件clusterinfo显示集群信息apiversions以组版本的格式输出服务端支持的API版本version输出服务端和客户端的版本信息help显示各个命令的帮助信息ingressnginx管理ingress服务的插件(官方安装和使用方式)Kubernetes使用相关配置Kubectl自动补全source(kubectlcompletionzsh)source(kubectlcompletionbash)显示合并后的kubeconfig配置kubectlconfigview获取pod和svc的文档kubectlexplainpods,svc创建资源对象分步骤创建yamlkubectlcreatefxxxrc。yamlkubectlcreatefxxxservice。yamljsonkubectlcreatef。pod。jsoncatpod。jsonkubectlcreatefyaml2jsonkubectlcreatefdockerregistry。yamleditojson一次性创建kubectlcreatefxxxservice。yamlfxxxrc。yaml根据目录下所有的yaml文件定义内容进行创建kubectlcreatef目录使用url来创建资源kubectlcreatefhttps:git。iovPieo查看资源对象查看所有Node或Namespace对象kubectlgetnodeskubectlgetnamespace查看所有Pod对象查看子命令帮助信息kubectlgethelp列出默认namespace中的所有podkubectlgetpods列出指定namespace中的所有podkubectlgetpodsnamespacetest列出所有namespace中的所有podkubectlgetpodsallnamespaces列出所有pod并显示详细信息kubectlgetpodsowidekubectlgetreplicationcontrollerwebkubectlgetkdirkubectlgetfpod。yamlojsonkubectlgetrcwebservicefrontendpodswebpod13je7kubectlgetpodsappprod78998bf7c6ttp9gnamespacetestowidekubectlgetotemplatepodwebpod13je7template{{。status。phase}}列出该namespace中的所有pod包括未初始化的kubectlgetpods,rc,servicesincludeuninitialized查看所有RC对象kubectlgetrc查看所有Deployment对象查看全部deploymentkubectlgetdeployment列出指定deploymentkubectlgetdeploymentmyapp查看所有Service对象kubectlgetsvckubectlgetservice查看不同Namespace下的Pod对象kubectlgetpodsndefaultkubectlgetpodsallnamespace查看资源描述显示Pod详细信息kubectldescribepodsnginxkubectldescribepodsmypodkubectldescribefpod。json查看Node详细信息kubectldescribenodesc1查看RC关联的Pod信息kubectldescribepodsrcname更新修补资源滚动更新滚动更新podfrontendv1kubectlrollingupdatefrontendv1ffrontendv2。json更新资源名称并更新镜像kubectlrollingupdatefrontendv1frontendv2imageimage:v2更新frontendpod中的镜像kubectlrollingupdatefrontendimageimage:v2退出已存在的进行中的滚动更新kubectlrollingupdatefrontendv1frontendv2rollback强制替换;删除后重新创建资源;服务会中断kubectlreplaceforcef。pod。json添加标签kubectllabelpodsmypodnewlabelawesome添加注解kubectlannotatepodsmypodiconurlhttp:goo。glXXBTWq修补资源部分更新节点kubectlpatchnodek8snode1p{spec:{unschedulable:true}}更新容器镜像;spec。containers〔〕。name是必须的,因为这是合并的关键字kubectlpatchpodvalidpodp{spec:{containers:〔{name:kubernetesservehostname,image:newimage}〕}}Scale资源Scaleareplicasetnamedfooto3kubectlscalereplicas3rsfooScalearesourcespecifiedinfoo。yamlto3kubectlscalereplicas3ffoo。yamlIfthedeploymentnamedmysqlscurrentsizeis2,scalemysqlto3kubectlscalecurrentreplicas2replicas3deploymentmysqlScalemultiplereplicationcontrollerskubectlscalereplicas5rcfoorcbarrcbaz删除资源对象基于xxx。yaml文件删除Pod对象yaml文件名字按照你创建时的文件一致kubectldeletefxxx。yaml删除包括某个label的pod对象kubectldeletepodslnamelabelname删除包括某个label的service对象kubectldeleteserviceslnamelabelname删除包括某个label的pod和service对象kubectldeletepods,serviceslnamelabelname删除所有podservices对象kubectldeletepodsallkubectldeleteserviceallkubectldeletedeploymentall编辑资源文件 在编辑器中编辑任何API资源编辑名为dockerregistry的servicekubectleditsvcdockerregistry直接执行命令 在寄主机上,不进入容器直接执行命令执行pod的date命令,默认使用pod的第一个容器执行kubectlexecmypoddatekubectlexecmypodnamespacetestdate指定pod中某个容器执行date命令kubectlexecmypodcrubycontainerdate进入某个容器kubectlexecmypodcrubycontaineritbash查看容器日志直接查看日志不实时刷新kubectllogsmypodkubectllogsmypodnamespacetest查看日志实时刷新kubectllogsfmypodcrubycontainerKubernetes管理工具 Kubernetes正在不断加快在云原生环境的应用,但如何以统一、安全的方式对运行于任何地方的Kubernetes集群进行管理面临着挑战,而有效的管理工具能够大大降低管理的难度。K9s k9s是基于终端的资源仪表板。它只有一个命令行界面。无论在Kubernetes仪表板WebUI上做什么,都可以在终端使用K9s仪表板工具进行相同的操作。k9s持续关注Kubernetes集群,并提供命令以使用集群上定义的资源。 详细介绍:Kubernetes集群管理工具K9S 推荐:轻松管理Kubernetes集群的7个工具Kubernetes生产环境最佳实践 使用Kubernetes的一些策略,在安全性、监控、网络、治理、存储、容器生命周期管理和平台选择方面应用最佳实践。下面让我们来看看Kubernetes的一些生产最佳实践。在生产中运行Kubernetes并不容易;有以下几个方面需要注意。是否使用存活探针和就绪探针进行健康检查? 管理大型分布式系统可能会很复杂,特别是当出现问题时,我们无法及时得到通知。为了确保应用实例正常工作,设置Kubernetes健康检查至关重要。 通过创建自定义运行健康检查,可以有效避免分布式系统中僵尸服务运行,具体可以根据环境和需要对其进行调整。 就绪探针的目的是让Kubernetes知道该应用是否已经准备好为流量服务。Kubernetes将始终确保准备就绪探针通过之后开始分配服务,将流量发送到Pod。Liveness存活探针 你怎么知道你的应用程序是活的还是死的?存活探针可以让你做到这一点。如果你的应用死了,Kubernetes会移除旧的Pod并用新Pod替换它。ResourceManagement资源管理 为单个容器指定资源请求和限制是一个很好的实践。另一个好的实践是将Kubernetes环境划分为不同团队、部门、应用程序和客户机的独立名称空间。Kubernetes资源使用情况 Kubernetes资源使用指的是容器pod在生产中所使用的资源数量。 因此,密切关注pods的资源使用情况是非常重要的。一个明显的原因是成本,因为越高的资源利用证明越少的资源浪费。Resourceutilization资源利用率 Ops团队通常希望优化和最大化pods消耗的资源百分比。资源使用情况是Kubernetes环境实际优化程度的指标之一。 您可以认为优化后的Kubernetes环境中运行的容器的平均CPU等资源利用率是最优的。启用RBAC RBAC代表基于角色的访问控制。它是一种用于限制系统网络上的用户和应用程序的访问和准入的方法。 他们从Kubernetes1。8版本引入了RBAC。使用rbac。authorization。k8sRBAC用于创建授权策略。 在Kubernetes中,RBAC用于授权,使用RBAC,您将能够授予用户、帐户、添加删除权限、设置规则等权限。因此,它基本上为Kubernetes集群添加了额外的安全层。RBAC限制谁可以访问您的生产环境和集群。集群置备和负载均衡 生产级Kubernetes基础设施通常需要考虑某些关键方面,例如高可用性、多主机、多etcdKubernetes集群等。此类集群的配置通常涉及到Terraform或Ansible等工具。 一旦集群都设置好了,并且为运行应用程序创建了pods,这些pods就配备了负载平衡器;这些负载均衡器将流量路由到服务。开源的Kubernetes项目并不是默认的负载平衡器;因此,它需要与NGINXIngresscontroller与HAProxy或ELB等工具集成,或任何其他工具,扩大Kubernetes的Ingress插件,以提供负载均衡能力。给Kubernetes对象添加标签 标签就像附加到对象上的键值对,比如pods。标签是用来标识对象的属性的,这些属性对用户来说是重要的和有意义的。 在生产中使用Kubernetes时,不能忽视的一个重要问题是标签;标签允许批量查询和操作Kubernetes对象。标签的特殊之处在于,它们还可以用于识别Kubernetes对象并将其组织成组。这样做的最佳用例之一是根据pod所属的应用程序对它们进行分组。在这里,团队可以构建并拥有任意数量的标签约定。配置网络策略 使用Kubernetes时,设置网络策略至关重要。网络策略只不过是一个对象,它使你能够明确地声明和决定哪些流量是允许的,哪些是不允许的。这样,Kubernetes将能够阻止所有其他不想要的和不符合规则的流量。在我们的集群中定义和限制网络流量是强烈推荐的基本且必要的安全措施之一。 Kubernetes中的每个网络策略都定义了一个如上所述的授权连接列表。无论何时创建任何网络策略,它所引用的所有pod都有资格建立或接受列出的连接。简单地说,网络策略基本上就是授权和允许连接的白名单一个连接,无论它是到还是从pod,只有在应用于pod的至少一个网络策略允许的情况下才被允许。集群监控和日志记录 在使用Kubernetes时,监控部署是至关重要的。确保配置、性能和流量保持安全更是重要。如果不进行日志记录和监控,就不可能诊断出发生的问题。为了确保合规性,监视和日志记录变得非常重要。在进行监视时,有必要在体系结构的每一层上设置日志记录功能。生成的日志将帮助我们启用安全工具、审计功能和分析性能。从无状态应用程序开始 运行无状态应用要比运行有状态应用简单得多,但随着Kubernetes运营商的不断增长,这种想法正在改变。对于刚接触Kubernetes的团队来说,建议首先使用无状态应用程序。 建议使用无状态后端,这样开发团队就可以确保不存在长时间运行的连接,从而增加了扩展的难度。使用无状态,开发人员还可以更有效地、零停机部署应用程序。人们普遍认为,无状态应用程序可以方便地根据业务需要进行迁移和扩展。边启动自动扩缩容 Kubernetes有三种用于部署的自动伸缩功能:水平pod自动伸缩(HPA)、垂直pod自动伸缩(VPA)和集群自动伸缩。 水平podautoscaler根据感知到的CPU利用率自动扩展deployment、replicationcontroller,replicaset,statefulset的数量。 Verticalpodautoscaling为CPU和内存请求和限制推荐合适的值,它可以自动更新这些值。 ClusterAutoscaler扩展和缩小工作节点池的大小。它根据当前的利用率调整Kubernetes集群的大小。控制镜像拉取来源 控制在集群中运行所有容器的镜像源。如果您允许您的Pod从公共资源中拉取镜像,您就不知道其中真正运行的是什么。 如果从受信任的注册表中提取它们,则可以在注册表上应用策略以提取安全和经过认证的镜像。持续学习 不断评估应用程序的状态和设置,以学习和改进。例如,回顾容器的历史内存使用情况可以得出这样的结论:我们可以分配更少的内存,在长期内节省成本。保护重要服务 使用Pod优先级,您可以决定设置不同服务运行的重要性。例如,为了更好的稳定性,你需要确保RabbitMQpod比你的应用pod更重要。或者你的入口控制器pods比数据处理pods更重要,以保持服务对用户可用。零停机时间 通过在HA中运行所有服务,支持集群和服务的零停机升级。这也将保证您的客户获得更高的可用性。 使用pod反亲和性来确保在不同的节点上调度一个pod的多个副本,从而通过计划中的和计划外的集群节点停机来确保服务可用性。 使用podDisruptions策略,不惜一切代价确保您有最低的Pod副本数量!计划失败 硬件最终会失败,软件最终会运行。(迈克尔哈顿)结论 众所周知,Kubernetes实际上已经成为DevOps领域的编排平台标准。Kubernetes从可用性、可伸缩性、安全性、弹性、资源管理和监控的角度来应对生产环境产生的风暴。由于许多公司都在生产中使用Kubernetes,因此必须遵循上面提到的最佳实践,以顺利和可靠地扩展应用程序。 来源:https:my。oschina。netu1787735blog4870582介绍5款顶级Kubernetes日志监控工具 对于新安装的Kubernetes,经常出现的一个问题是Service没有正常工作。如果您已经运行了Deployment并创建了一个Service,但是当您尝试访问它时没有得到响应,希望这份文档(全网最详细的K8sService不能访问排查流程)能帮助您找出问题所在。Kubernetes常见问题总结如何删除不一致状态下的rc,deployment,service 在某些情况下,经常发现kubectl进程挂起现象,然后在get时候发现删了一半,而另外的删除不了〔rootk8smaster〕kubectlgetffluentdelasticsearchNAMEDESIREDCURRENTREADYAGErcelasticsearchloggingv102215hNAMEDESIREDCURRENTUPTODATEAVAILABLEAGEdeploykibanalogging011115hErrorfromserver(NotFound):serviceselasticsearchloggingnotfoundErrorfromserver(NotFound):daemonsets。extensionsfluentdesv1。22notfoundErrorfromserver(NotFound):serviceskibanaloggingnotfound 删除这些deployment,service或者rc命令如下:kubectldeletedeploymentkibanaloggingnkubesystemcascadefalsekubectldeletedeploymentkibanaloggingnkubesystemignorenotfounddeletercelasticsearchloggingv1nkubesystemforcenowgraceperiod0删除不了后如何重置etcdrmrfvarlibetcd 删除后重新rebootmaster结点。resetetcd后需要重新设置网络etcdctlmkatomic。ionetworkconfig{Network:192。168。0。016}启动apiserver失败 每次启动都是报如下问题:startrequestrepeatedtooquicklyforkubeapiserver。service 但其实不是启动频率问题,需要查看,varlogmessages,在我的情况中是因为开启ServiceAccount后找不到ca。crt等文件,导致启动出错。May2107:56:41k8smasterkubeapiserver:Flagporthasbeendeprecated,seeinsecureportinstead。May2107:56:41k8smasterkubeapiserver:F052107:56:41。6924804299universalvalidation。go:104〕Validateserverrunoptionsfailed:unabletoloadclientCAfile:openvarrunkubernetesca。crt:nosuchfileordirectoryMay2107:56:41k8smastersystemd:kubeapiserver。service:mainprocessexited,codeexited,status255naMay2107:56:41k8smastersystemd:FailedtostartKubernetesAPIServer。May2107:56:41k8smastersystemd:Unitkubeapiserver。serviceenteredfailedstate。May2107:56:41k8smastersystemd:kubeapiserver。servicefailed。May2107:56:41k8smastersystemd:kubeapiserver。serviceholdofftimeover,schedulingrestart。May2107:56:41k8smastersystemd:startrequestrepeatedtooquicklyforkubeapiserver。serviceMay2107:56:41k8smastersystemd:FailedtostartKubernetesAPIServer。 在部署fluentd等日志组件的时候,很多问题都是因为需要开启ServiceAccount选项需要配置安全导致,所以说到底还是需要配置好ServiceAccount。出现Permissiondenied情况 在配置fluentd时候出现cannotcreatevarlogfluentd。log:Permissiondenied错误,这是因为没有关掉SElinux安全导致。 可以在etcselinuxconfig中将SELINUXenforcing设置成disabled,然后reboot基于ServiceAccount的配置 首先生成各种需要的keys,k8smaster需替换成master的主机名。opensslgenrsaoutca。key2048opensslreqx509newnodeskeyca。keysubjCNk8smasterdays10000outca。crtopensslgenrsaoutserver。key2048echosubjectAltNameIP:10。254。0。1extfile。cnfip由下述命令决定kubectlgetservicesallnamespacesgrepdefaultgrepkubernetesgrep443awk{print3}opensslreqnewkeyserver。keysubjCNk8smasteroutserver。csropensslx509reqinserver。csrCAca。crtCAkeyca。keyCAcreateserialextfileextfile。cnfoutserver。crtdays10000 如果修改etckubernetesapiserver的配置文件参数的话,通过systemctlstartkubeapiserver启动失败,出错信息为:Validateserverrunoptionsfailed:unabletoloadclientCAfile:openrootkeysca。crt:permissiondenied 但可以通过命令行启动APIServerusrbinkubeapiserverlogtostderrtruev0etcdservershttp:k8smaster:2379address0。0。0。0port8080kubeletport10250allowprivilegedtrueserviceclusteriprange10。254。0。016admissioncontrolServiceAccountinsecurebindaddress0。0。0。0clientcafilerootkeysca。crttlscertfilerootkeysserver。crttlsprivatekeyfilerootkeysserver。keybasicauthfilerootkeysbasicauth。csvsecureport443varlogkuberneteskubeapiserver。log 命令行启动Controllermanagerusrbinkubecontrollermanagerlogtostderrtruev0masterhttp:k8smaster:8080rootcafilerootkeysca。crtserviceaccountprivatekeyfilerootkeysserver。keyvarlogkuberneteskubecontrollermanage。logETCD启动不起来问题 etcd是kubernetes集群的zookeeper进程,几乎所有的service都依赖于etcd的启动,比如flanneld,apiserver,docker。。。。。在启动etcd是报错日志如下:May2413:39:09k8smastersystemd:StoppedFlanneldoverlayaddressetcdagent。May2413:39:28k8smastersystemd:StartingEtcdServer。。。May2413:39:28k8smasteretcd:recognizedandusedenvironmentvariableETCDADVERTISECLIENTURLShttp:etcd:2379,http:etcd:4001May2413:39:28k8smasteretcd:recognizedenvironmentvariableETCDNAME,butunused:shadowedbycorrespondingflagMay2413:39:28k8smasteretcd:recognizedenvironmentvariableETCDDATADIR,butunused:shadowedbycorrespondingflagMay2413:39:28k8smasteretcd:recognizedenvironmentvariableETCDLISTENCLIENTURLS,butunused:shadowedbycorrespondingflagMay2413:39:28k8smasteretcd:etcdVersion:3。1。3May2413:39:28k8smasteretcd:GitSHA:21fdcc6May2413:39:28k8smasteretcd:GoVersion:go1。7。4May2413:39:28k8smasteretcd:GoOSArch:linuxamd64May2413:39:28k8smasteretcd:settingmaximumnumberofCPUsto1,totalnumberofavailableCPUsis1May2413:39:28k8smasteretcd:theserverisalreadyinitializedasmemberbefore,startingasetcdmember。。。May2413:39:28k8smasteretcd:listeningforpeersonhttp:localhost:2380May2413:39:28k8smasteretcd:listeningforclientrequestson0。0。0。0:2379May2413:39:28k8smasteretcd:listeningforclientrequestson0。0。0。0:4001May2413:39:28k8smasteretcd:recoveredstorefromsnapshotatindex140014May2413:39:28k8smasteretcd:namemasterMay2413:39:28k8smasteretcd:datadirvarlibetcddefault。etcdMay2413:39:28k8smasteretcd:memberdirvarlibetcddefault。etcdmemberMay2413:39:28k8smasteretcd:heartbeat100msMay2413:39:28k8smasteretcd:election1000msMay2413:39:28k8smasteretcd:snapshotcount10000May2413:39:28k8smasteretcd:advertiseclientURLshttp:etcd:2379,http:etcd:4001May2413:39:28k8smasteretcd:ignoredfile00000000000000010000000000012700。wal。brokeninwalMay2413:39:29k8smasteretcd:restartingmember8e9e05c52164694dinclustercdf818194e3a8c32atcommitindex148905May2413:39:29k8smasteretcd:8e9e05c52164694dbecamefolloweratterm12May2413:39:29k8smasteretcd:newRaft8e9e05c52164694d〔peers:〔8e9e05c52164694d〕,term:12,commit:148905,applied:140014,lastindex:148905,lastterm:12〕May2413:39:29k8smasteretcd:enabledcapabilitiesforversion3。1May2413:39:29k8smasteretcd:addedmember8e9e05c52164694d〔http:localhost:2380〕toclustercdf818194e3a8c32fromstoreMay2413:39:29k8smasteretcd:settheclusterversionto3。1fromstoreMay2413:39:29k8smasteretcd:startingserver。。。〔version:3。1。3,clusterversion:3。1〕May2413:39:29k8smasteretcd:raftsavestateandentrieserror:openvarlibetcddefault。etcdmemberwal0。tmp:isadirectoryMay2413:39:29k8smastersystemd:etcd。service:mainprocessexited,codeexited,status1FAILUREMay2413:39:29k8smastersystemd:FailedtostartEtcdServer。May2413:39:29k8smastersystemd:Unitetcd。serviceenteredfailedstate。May2413:39:29k8smastersystemd:etcd。servicefailed。May2413:39:29k8smastersystemd:etcd。serviceholdofftimeover,schedulingrestart。 核心语句:raftsavestateandentrieserror:openvarlibetcddefault。etcdmemberwal0。tmp:isadirectory 进入相关目录,删除0。tmp,然后就可以启动啦!ETCD启动不起来超时问题 问题背景:当前部署了3个etcd节点,突然有一天3台集群全部停电宕机了。重新启动之后发现K8S集群是可以正常使用的,但是检查了一遍组件之后,发现有一个节点的etcd启动不了。 经过一遍探查,发现时间不准确,通过以下命令ntpdatentp。aliyun。com重新将时间调整正确,重新启动etcd,发现还是起不来,报错如下:Mar0514:27:15k8snode2etcd〔3248〕:etcdVersion:3。3。13Mar0514:27:15k8snode2etcd〔3248〕:GitSHA:98d3084Mar0514:27:15k8snode2etcd〔3248〕:GoVersion:go1。10。8Mar0514:27:15k8snode2etcd〔3248〕:GoOSArch:linuxamd64Mar0514:27:15k8snode2etcd〔3248〕:settingmaximumnumberofCPUsto4,totalnumberofavailableCPUsis4Mar0514:27:15k8snode2etcd〔3248〕:theserverisalreadyinitializedasmemberbefore,startingasetcdmember。。。Mar0514:27:15k8snode2etcd〔3248〕:peerTLS:certoptetcdsslserver。pem,keyoptetcdsslserverkey。pem,ca,trustedcaoptetcdsslca。pem,clientcertauthfalse,crlfileMar0514:27:15k8snode2etcd〔3248〕:listeningforpeersonhttps:192。168。25。226:2380Mar0514:27:15k8snode2etcd〔3248〕:Theschemeofclienturlhttp:127。0。0。1:2379isHTTPwhilepeerkeycertfilesarepresented。Ignoredkeycertfiles。Mar0514:27:15k8snode2etcd〔3248〕:listeningforclientrequestson127。0。0。1:2379Mar0514:27:15k8snode2etcd〔3248〕:listeningforclientrequestson192。168。25。226:2379Mar0514:27:15k8snode2etcd〔3248〕:member9c166b8b7cb6ecb8hasalreadybeenbootstrappedMar0514:27:15k8snode2systemd〔1〕:etcd。service:mainprocessexited,codeexited,status1FAILUREMar0514:27:15k8snode2systemd〔1〕:FailedtostartEtcdServer。Mar0514:27:15k8snode2systemd〔1〕:Unitetcd。serviceenteredfailedstate。Mar0514:27:15k8snode2systemd〔1〕:etcd。servicefailed。Mar0514:27:15k8snode2systemd〔1〕:etcd。servicefailed。Mar0514:27:15k8snode2systemd〔1〕:etcd。serviceholdofftimeover,schedulingrestart。Mar0514:27:15k8snode2systemd〔1〕:StartingEtcdServer。。。Mar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDNAME,butunused:shadowedbycorrespondingflagMar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDDATADIR,butunused:shadowedbycorrespondingflagMar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDLISTENPEERURLS,butunused:shadowedbycorrespondingflagMar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDLISTENCLIENTURLS,butunused:shadowedbycorrespondingflagMar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDINITIALADVERTISEPEERURLS,butunused:shadowedbycorrespondingflagMar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDADVERTISECLIENTURLS,butunused:shadowedbycorrespondingflagMar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDINITIALCLUSTER,butunused:shadowedbycorrespondingflagMar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDINITIALCLUSTERTOKEN,butunused:shadowedbycorrespondingflagMar0514:27:15k8snode2etcd〔3258〕:recognizedenvironmentvariableETCDINITIALCLUSTERSTATE,butunused:shadowedbycorrespondingflag 解决方法: 检查日志发现并没有特别明显的错误,根据经验来讲,etcd节点坏掉一个其实对集群没有大的影响,这时集群已经可以正常使用了,但是这个坏掉的etcd节点并没有启动,解决方法如下: 进入etcd的数据存储目录进行备份备份原有数据:cdvarlibetcddefault。etcdmembercpdatabak 删除这个目录下的所有数据文件rmrfvarlibetcddefault。etcdmember 停止另外两台etcd节点,因为etcd节点启动时需要所有节点一起启动,启动成功后即可使用。master节点systemctlstopetcdsystemctlrestartetcdnode1节点systemctlstopetcdsystemctlrestartetcdnode2节点systemctlstopetcdsystemctlrestartetcdCentOS下配置主机互信 在每台服务器需要建立主机互信的用户名执行以下命令生成公钥密钥,默认回车即可sshkeygentrsa 可以看到生成个公钥的文件。 互传公钥,第一次需要输入密码,之后就OK了。sshcopyidiroot。sshidrsa。pubroot192。168。199。132(p2222) p端口默认端口不加p,如果更改过端口,就得加上p。可以看到是在。ssh下生成了个authorizedkeys的文件,记录了能登陆这台服务器的其他服务器的公钥。 测试看是否能登陆:ssh192。168。199。132(p2222)CentOS主机名的修改hostnamectlsethostnamek8smaster1Virtualbox实现CentOS复制和粘贴功能 如果不安装或者不输出,可以将update修改成install再运行。yuminstallupdateyumupdatekernelyumupdatekerneldevelyuminstallkernelheadersyuminstallgccyuminstallgccmake 运行完后shVBoxLinuxAdditions。run删除Pod一直处于Terminating状态 可以通过下面命令强制删除kubectldeletepodNAMEgraceperiod0force 删除namespace一直处于Terminating状态 可以通过以下脚本强制删除〔rootk8smaster1k8s〕catdeletens。sh!binbashseteuseage(){echouseage:echodelns。shNAMESPACE}if〔lt1〕;thenuseageexitfiNAMESPACE1JSONFILE{NAMESPACE}。jsonkubectlgetns{NAMESPACE}ojson{JSONFILE}vi{JSONFILE}curlkHContentType:applicationjsonXPUTdatabinary{JSONFLE}http:127。0。0。1:8001apiv1namespaces{NAMESPACE}finalize容器包含有效的CPU内存requests且没有指定limits可能会出现什么问题? 下面我们创建一个对应的容器,该容器只有requests设定,但是没有limits设定,name:busyboxcnt02image:busyboxcommand:〔binsh〕args:〔c,whiletrue;doechohellofromcnt02;sleep10;done〕resources:requests:memory:100Micpu:100m 这个容器创建出来会有什么问题呢? 其实对于正常的环境来说没有什么问题,但是对于资源型pod来说,如果有的容器没有设定limit限制,资源会被其他的pod抢占走,可能会造成容器应用失败的情况。可以通过limitrange策略来去匹配,让pod自动设定,前提是要提前配置好limitrange规则。 来源:https:www。cnblogs。compasszhang Kubernetes上对应用程序进行故障排除的6个技巧推荐给大家,日常排错必备。分享一份阿里云内部超全K8s实战手册,免费下载!Kubernetes面试题 一个目标:容器操作;两地三中心;四层服务发现;五种Pod共享资源;六个CNI常用插件;七层负载均衡;八种隔离维度;九个网络模型原则;十类IP地址;百级产品线;千级物理机;万级容器;相如无亿,k8s有亿:亿级日服务人次。 一个目标:容器操作 Kubernetes(k8s)是自动化容器操作的开源平台。这些容器操作包括:部署、调度和节点集群间扩展。具体功能:自动化容器部署和复制。实时弹性收缩容器规模。容器编排成组,并提供容器间的负载均衡。调度:容器在哪个机器上运行。组成:kubectl:客户端命令行工具,作为整个系统的操作入口。kubeapiserver:以RESTAPI服务形式提供接口,作为整个系统的控制入口。kubecontrollermanager:执行整个系统的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等。kubescheduler:负责节点资源管理,接收来自kubeapiserver创建Pods任务,并分配到某个节点。etcd:负责节点间的服务发现和配置共享。kubeproxy:运行在每个计算节点上,负责Pod网络代理。定时从etcd获取到service信息来做相应的策略。kubelet:运行在每个计算节点上,作为agent,接收分配该节点的Pods任务及管理容器,周期性获取容器状态,反馈给kubeapiserver。DNS:一个可选的DNS服务,用于为每个Service对象创建DNS记录,这样所有的Pod就可以通过DNS访问服务了。 下面是k8s的架构拓扑图: 两地三中心 两地三中心包括本地生产中心、本地灾备中心、异地灾备中心。 两地三中心要解决的一个重要问题就是数据一致性问题。 k8s使用etcd组件作为一个高可用、强一致性的服务发现存储仓库。用于配置共享和服务发现。 它作为一个受到Zookeeper和doozer启发而催生的项目。除了拥有他们的所有功能之外,还拥有以下4个特点:简单:基于HTTPJSON的API让你用curl命令就可以轻松使用。安全:可选SSL客户认证机制。快速:每个实例每秒支持一千次写操作。可信:使用Raft算法充分实现了分布式。 四层服务发现 先一张图解释一下网络七层协议: k8s提供了两种方式进行服务发现:环境变量:当创建一个Pod的时候,kubelet会在该Pod中注入集群内所有Service的相关环境变量。需要注意的是,要想一个Pod中注入某个Service的环境变量,则必须Service要先比该Pod创建。这一点,几乎使得这种方式进行服务发现不可用。比如,一个ServiceName为redismaster的Service,对应的ClusterIP:Port为10。0。0。11:6379,则对应的环境变量为: DNS:可以通过clusteraddon的方式轻松的创建KubeDNS来对集群内的Service进行服务发现。 以上两种方式,一个是基于TCP,DNS基于UDP,它们都是建立在四层协议之上。 五种Pod共享资源 Pod是k8s最基本的操作单元,包含一个或多个紧密相关的容器。 一个Pod可以被一个容器化的环境看作应用层的逻辑宿主机;一个Pod中的多个容器应用通常是紧密耦合的,Pod在Node上被创建、启动或者销毁;每个Pod里运行着一个特殊的被称之为Volume挂载卷,因此他们之间通信和数据交换更为高效。在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod中。 同一个Pod里的容器之间仅需通过localhost就能互相通信。 一个Pod中的应用容器共享五种资源:PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围。IPC命名空间:Pod中的多个容器能够使用SystemVIPC或POSIX消息队列进行通信。UTS命名空间:Pod中的多个容器共享一个主机名。Volumes(共享存储卷):Pod中的各个容器可以访问在Pod级别定义的Volumes。 Pod的生命周期通过ReplicationController来管理;通过模板进行定义,然后分配到一个Node上运行,在Pod所包含容器运行结束后,Pod结束。 Kubernetes为Pod设计了一套独特的网络配置,包括为每个Pod分配一个IP地址,使用Pod名作为容器间通信的主机名等。 六个CNI常用插件 CNI(ContainerNetworkInterface)容器网络接口是Linux容器网络配置的一组标准和库,用户需要根据这些标准和库来开发自己的容器网络插件。CNI只专注解决容器网络连接和容器销毁时的资源释放,提供一套框架。所以CNI可以支持大量不同的网络模式,并且容易实现。 下面用一张图表示六个CNI常用插件: 七层负载均衡 提负载均衡就不得不先提服务器之间的通信。 IDC(InternetDataCenter)也可称数据中心、机房,用来放置服务器。IDC网络是服务器间通信的桥梁。 上图里画了很多网络设备,它们都是干啥用的呢? 路由器、交换机、MGWNAT都是网络设备,按照性能、内外网划分不同的角色。内网接入交换机:也称为TOR(topofrack),是服务器接入网络的设备。每台内网接入交换机下联4048台服务器,使用一个掩码为24的网段作为服务器内网网段。内网核心交换机:负责IDC内各内网接入交换机的流量转发及跨IDC流量转发。MGWNAT:MGW即LVS用来做负载均衡,NAT用于内网设备访问外网时做地址转换。外网核心路由器:通过静态互联运营商或BGP互联美团统一外网平台。 先说说各层负载均衡:二层负载均衡:基于MAC地址的二层负载均衡。三层负载均衡:基于IP地址的负载均衡。四层负载均衡:基于IP端口的负载均衡。七层负载均衡:基于URL等应用层信息的负载均衡。 这里用一张图来说说四层和七层负载均衡的区别: 上面四层服务发现讲的主要是k8s原生的kubeproxy方式。k8s关于服务的暴露主要是通过NodePort方式,通过绑定minion主机的某个端口,然后进行Pod的请求转发和负载均衡,但这种方式有下面的缺陷:Service可能有很多个,如果每个都绑定一个Node主机端口的话,主机需要开放外围的端口进行服务调用,管理混乱。无法应用很多公司要求的防火墙规则。 理想的方式是通过一个外部的负载均衡器,绑定固定的端口,比如80;然后根据域名或者服务名向后面的ServiceIP转发。 Nginx很好的解决了这个需求,但问题是如果有的新的服务加入,如何去修改并且加载这些Nginx配置? Kubernetes给出的方案就是Ingress。这是一个基于七层的方案。 八种隔离维度 k8s集群调度这边需要对上面从上到下、从粗粒度到细粒度的隔离做相应的调度策略。 九个网络模型原则 k8s网络模型要符合四个基础原则、三个网络要求原则、一个架构原则、一个IP原则。 每个Pod都拥有一个独立的IP地址,而且假定所有Pod都在一个可以直接连通的、扁平的网络空间中,不管是否运行在同一Node上都可以通过Pod的IP来访问。 k8s中的Pod的IP是最小粒度IP。同一个Pod内所有的容器共享一个网络堆栈,该模型称为IPperPod模型。Pod由docker0实际分配的IP。Pod内部看到的IP地址和端口与外部保持一致。同一个Pod内的不同容器共享网络,可以通过localhost来访问对方的端口,类似同一个虚拟机内不同的进程。 IPperPod模型从端口分配、域名解析、服务发现、负载均衡、应用配置等角度看,Pod可以看做是一台独立的虚拟机或物理机。所有容器都可以不用NAT的方式同别的容器通信。所有节点都可以在不同NAT方式下同所有容器通信,反之亦然。容器的地址和别人看到的地址是同一个地址。 要符合下面的架构: 由上图架构引申出来IP概念从集群外部到集群内部: 十类IP地址 大家都知道IP地址分为ABCDE类,另外还有五类特殊用途的IP。 第一类A类:1。0。0。01226。255。255。255,默认子网掩码8,即255。0。0。0。B类:128。0。0。0191。255。255。255,默认子网掩码16,即255。255。0。0。C类:192。0。0。0223。255。255。255,默认子网掩码24,即255。255。255。0。D类:224。0。0。0239。255。255。255,一般用于组播。E类:240。0。0。0255。255。255。255(其中255。255。255。255为全网广播地址)。E类地址一般用于研究用途。 第二类0。0。0。0严格来说,0。0。0。0已经不是一个真正意义上的IP地址了。它表示的是这样一个集合:所有不清楚的主机和目的网络。这里的不清楚是指在本机的路由表里没有特定条目指明如何到达。作为缺省路由。127。0。0。1本机地址。 第三类224。0。0。1组播地址。如果你的主机开启了IRDP(internet路由发现,使用组播功能),那么你的主机路由表中应该有这样一条路由。 第四类169。254。x。x使用了DHCP功能自动获取了IP的主机,DHCP服务器发生故障,或响应时间太长而超出了一个系统规定的时间,系统会为你分配这样一个IP,代表网络不能正常运行。 第五类10。xxx、172。16。x。x172。31。x。x、192。168。x。x私有地址。大量用于企业内部。保留这样的地址是为了避免亦或是哪个接入公网时引起地址混乱。