Kubernetes

概述:

Kubernetes 源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。开源、用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,它提供了应用部署,规划,更新,维护的一种机制。它的一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着,比如用户想让apache一直运行,用户不需要关心怎么去做,Kubernetes会自动去监控,然后去重启,新建,总之让apache一直提供服务。在K8s中,所有的容器均在Pod中运行,一个Pod可以承载一个或者多个相关的容器,同一个Pod中的容器会部署在同一个物理机器上并且能够共享资源。一个Pod也可以包含0个或者多个磁盘卷组, 这些卷组将会以目录的形式提供给一个容器,或者被所有Pod中的容器共享,对于用户创建的每个Pod,系统会自动选择那个健康并且有足够容量的机器,然后创建类似容器的容器,当容器创建失败的时候,容器会被node agent自动的重启,这个node agent叫kubelet,但是,如果是Pod失败它不会自动的转移并且启动,除非用户定义了 replication controller。

部署变化:

 传统部署时代:

早期,各个组织机构在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界,这会导致资源分配问题。 例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况, 结果可能导致其他应用程序的性能下降。 一种解决方案是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展, 并且维护许多物理服务器的成本很高。

虚拟化部署时代:

作为解决方案,引入了虚拟化。虚拟化技术允许你在单个物理服务器的 CPU 上运行多个虚拟机(VM)。虚拟化允许应用程序在 VM 之间隔离,并提供一定程度的安全,因为一个应用程序的信息 不能被另一应用程序随意访问。虚拟化技术能够更好地利用物理服务器上的资源,并且因为可轻松地添加或更新应用程序 而可以实现更好的可伸缩性,降低硬件成本等等。每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

容器部署时代:

容器类似于 VM,但是它们具有被放宽的隔离属性,可以在应用程序之间共享操作系统(OS)。 因此,容器被认为是轻量级的。容器与 VM 类似,具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。容器因具有许多优势而变得流行起来。下面列出的是容器的一些好处:

  • 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
  • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),支持可靠且频繁的 容器镜像构建和部署。
  • 关注开发与运维的分离:在构建/发布时而不是在部署时创建应用程序容器镜像, 从而将应用程序与基础架构分离。
  • 可观察性:不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  • 跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。
  • 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
  • 资源隔离:可预测的应用程序性能。
  • 资源利用:高效率和高密度。

Kubernetes 为你提供:

  • 服务发现和负载均衡:Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

  • 存储编排:Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。

  • 自动部署和回滚:你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。

  • 自动完成装箱计算:Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。

  • 自我修复:Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。

  • 密钥与配置管理:Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

        非NOT:但K8s不是一个传统的,包罗一切的PaaS系统。保留用户的选择,这一点非常重要,还有其他不是的特点是:1)K8s不限制支持应用的种类。它不限制应用框架,或者支持的运行时语言,也不去区分 “apps” 或者“services”。 K8s致力于支持不同负载应用,包括有状态、无状态、数据处理类型的应用。只要这个应用可以在容器里运行,那么它就可以在Kubernetes上很多地运行。2)K8s不提供中间件(如message buses),数据处理框架(如Spark),数据库(如Mysql),或者集群存储系统(如Ceph)。但这些应用都可以运行于K8s。3)K8s没有一个点击即可用的应用市场。4)K8s不部署源码不编译应用。持续集成的 (CI)工作流方面,不同的用户有不同的需求和偏好,因此,我们提供分层的 CI工作流,但并不定义它应该怎么做。5)K8s允许用户选择自己的日志、监控和报警系统。6)K8s不提供可理解的应用配置语言(e.g., jsonnet). 7)K8s不提供或者任何综合的机器配置,维护,管理或者自愈系统。

 架构

Kubernetes集群包含有节点代理kubelet和Master组件(APIs, scheduler, etc),一切都基于分布式的存储系统。下面这张图是Kubernetes的架构图。

K8s节点服务分为运行在工作节点上的服务和组成集群级别控制板的服务。K8s节点有运行应用容器必备的服务,而这些都是受Master的控制。如下图Master节点:与工作节点

       

控制平面组件

1)etcd保存了整个集群的状态,所有master的持续状态都存在etcd的一个实例中。这可以很好地存储配置数据。因为有watch(观察者)的支持,各部件协调中的改变可以很快被察觉;

2)kube-apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;

3)controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;

4)kube-scheduler负责资源的调度,控制平面组件,负责监视新创建的、未指定运行节点的pod ,选择节点让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限;

node: 组件

1):kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;2)Container runtime负责镜像管理以及Pod和容器的真正运行(CRI)Kubernetes 支持容器运行时,例如 DockercontainerdCRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。3)kube-proxy负责为Service提供cluster内部的服务发现和负载均衡。

插件:     

 除了核心组件,还有一些推荐的Add-ons:如:1)kube-dns负责为整个集群提供DNS服务;2)Ingress Controller为服务提供外网入口;2)Heapster提供资源监控;3)Dashboard提供GUI;4)Federation提供跨可用区的集群;5)Fluentd-elasticsearch提供集群日志采集、存储与查询。 K8s还提供了控制面板,K8s控制面板可以分为多个部分。目前它们都运行在一个master节点,然而为了达到高可用性需要改变。不同部分一起协作提供一个统一的关于集群的视图。

分层结构:Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示

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

       设计理念:对于云计算系统,系统API实际上处于系统设计的统领地位,K8s集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的API对象,支持对该功能的管理操作。因此API设计及控制设计都应遵循一些原则。每个API对象都有3大类属性:元数据metadata、规范spec和状态status。元数据是用来标识API对象的,每个对象都至少有3个元数据:namespace,name和uid;除此以外还有各种各样的标签labels用来标识和匹配不同的对象,例如用户可以用标签env来标识区分不同的服务部署环境,分别用env=dev、env=testing、env=production来标识开发、测试、生产的不同服务。规范描述了用户期望K8s集群中的分布式系统达到的理想状态(Desired State),例如用户可以通过复制控制器Replication Controller设置期望的Pod副本数为3;status描述了系统实际当前达到的状态(Status),例如系统当前实际的Pod副本数为2;那么复制控制器当前的程序逻辑就是自动启动新的Pod,争取达到副本数为3。

       K8s中所有的配置都是通过API对象的spec去设置的,也就是用户通过配置系统的理想状态来改变系统,这是k8s重要设计理念之一,即所有的操作都是声明式(Declarative)的而不是命令式(Imperative)的。声明式操作在分布式系统中的好处是稳定,不怕丢操作或运行多次,例如设置副本数为3的操作运行多次也还是一个结果,而给副本数加1的操作就不是声明式的,运行多次结果就错了。最基础微服务Pod:Pod是在K8s集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。Pod对多容器的支持是K8s最基础的设计理念。Pod可以看作运行在K8s集群中的小机器人,不同类型的业务就需要不同类型的小机器人去执行。目前K8s中的业务主要可以分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-daemon)和有状态应用型(stateful application);分别对应的小机器人控制器为Deployment、Job、DaemonSet和PetSet。

      复制控制器(Replication Controller,RC):RC是K8s集群中最早的保证Pod高可用的API对象。通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。RC是K8s较早期的技术概念,只适用于长期伺服型的业务类型,比如控制小机器人提供高可用的Web服务。

      副本集(Replica Set,RS):RS是新一代RC,提供同样的高可用能力,区别主要在于RS后来居上,能支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用。

      部署(Deployment):部署表示用户对K8s集群的一次更新操作。部署是一个比RS应用模式更广的API对象,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的RS,然后逐渐将新RS中副本数增加到理想状态,将旧RS中的副本数减小到0的复合操作;这样一个复合操作用一个RS是不太好描述的,所以用一个更通用的Deployment来描述。以K8s的发展方向,未来对所有长期伺服型的的业务的管理,都会通过Deployment来管理。

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

      任务(Job):Job是K8s用来控制批处理型任务的API对象。批处理业务与长期伺服业务的主要区别是批处理业务的运行有头有尾,而长期伺服业务在用户不停止的情况下永远运行。Job管理的Pod根据用户的设置把任务成功完成就自动退出了。成功完成的标志根据不同的spec.completions策略而不同:单Pod型任务有一个Pod成功就标志完成;定数成功型任务保证有N个任务全部成功;工作队列型任务根据应用确认的全局成功而标志成功。

       后台支撑服务集(DaemonSet):长期伺服型和批处理型服务的核心在业务应用,可能有些节点运行多个同类业务的Pod,有些节点上又没有这类Pod运行;而后台支撑型服务的核心关注点在K8s集群中的节点(物理机或虚拟机),要保证每个节点上都有一个此类Pod运行。节点可能是所有集群节点也可能是通过nodeSelector选定的一些特定节点。典型的后台支撑型服务包括,存储,日志和监控等在每个节点上支持K8s集群运行的服务。

    有状态服务集(PetSet):K8s在1.3版本里发布了Alpha版的PetSet功能。在云原生应用的体系里,有下面两组近义词;第一组是无状态(stateless)、牲畜(cattle)、无名(nameless)、可丢弃(disposable);第二组是有状态(stateful)、宠物(pet)、有名(having name)、不可丢弃(non-disposable)。RC和RS主要是控制提供无状态服务的,其所控制的Pod的名字是随机设置的,一个Pod出故障了就被丢弃掉,在另一个地方重启一个新的Pod,名字变了、名字和启动在哪儿都不重要,重要的只是Pod总数;而PetSet是用来控制有状态服务,PetSet中的每个Pod的名字都是事先确定的,不能更改。对于RC和RS中的Pod,一般不挂载存储或者挂载共享存储,保存的是所有Pod共享的状态,Pod像牲畜一样没有分别(这似乎也确实意味着失去了人性特征);对于PetSet中的Pod,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂载上原来Pod的存储继续以它的状态提供服务。适合于PetSet的业务包括数据库服务MySQL和PostgreSQL,集群化管理服务Zookeeper、etcd等有状态服务。PetSet的另一种典型应用场景是作为一种比普通容器更稳定可靠的模拟虚拟机的机制。传统的虚拟机正是一种有状态的宠物,运维人员需要不断地维护它,容器刚开始流行时,我们用容器来模拟虚拟机使用,所有状态都保存在容器里,而这已被证明是非常不安全、不可靠的。使用PetSet,Pod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,PetSet做的只是将确定的Pod与确定的存储关联起来保证状态的连续性。PetSet还只在Alpha阶段,后面的设计如何演变,我们还要继续观察。

      集群联邦(Federation):K8s在1.3版本里发布了beta版的Federation功能。在云计算环境中,服务的作用距离范围从近到远一般可以有:同主机(Host,Node)、跨主机同可用区(Available Zone)、跨可用区同地区(Region)、跨地区同服务商(Cloud Service Provider)、跨云平台。K8s的设计定位是单一集群在同一个地域内,因为同一个地区的网络性能才能满足K8s的调度和计算存储连接要求。而联合集群服务就是为提供跨Region跨服务商K8s集群服务而设计的。每个K8s Federation有自己的分布式存储、API Server和Controller Manager。用户可以通过Federation的API Server注册该Federation的成员K8s Cluster。当用户通过Federation的API Server创建、更改API对象时,Federation API Server会在自己所有注册的子K8s Cluster都创建一份对应的API对象。在提供业务请求服务时,K8s Federation会先在自己的各个子Cluster之间做负载均衡,而对于发送到某个具体K8s Cluster的业务请求,会依照这个K8s Cluster独立提供服务时一样的调度模式去做K8s Cluster内部的负载均衡。而Cluster之间的负载均衡是通过域名服务的负载均衡来实现的。所有的设计都尽量不影响K8s Cluster现有的工作机制,这样对于每个子K8s集群来说,并不需要更外层的有一个K8s Federation,也就是意味着所有现有的K8s代码和机制不需要因为Federation功能有任何变化。

      存储卷(Volume):K8s集群中的存储卷跟Docker的存储卷有些类似,只不过Docker的存储卷作用范围为一个容器,而K8s的存储卷的生命周期和作用范围是一个Pod。每个Pod中声明的存储卷由Pod中的所有容器共享。K8s支持非常多的存储卷类型,特别的,支持多种公有云平台的存储,包括AWS,Google和Azure云;支持多种分布式存储包括GlusterFS和Ceph;也支持较容易使用的主机本地目录hostPath和NFS。K8s还支持使用Persistent Volume Claim即PVC这种逻辑存储,使用这种存储,使得存储的使用者可以忽略后台的实际存储技术(例如AWS,Google或GlusterFS和Ceph),而将有关存储实际技术的配置交给存储管理员通过Persistent Volume来配置。

持久存储卷(Persistent Volume,PV)和持久存储卷声明(Persistent Volume Claim,PVC):PV和PVC使得K8s集群具备了存储的逻辑抽象能力,使得在配置Pod的逻辑里可以忽略对实际后台存储技术的配置,而把这项配置的工作交给PV的配置者,即集群的管理者。存储的PV和PVC的这种关系,跟计算的Node和Pod的关系是非常类似的;PV和Node是资源的提供者,根据集群的基础设施变化而变化,由K8s集群管理员配置;而PVC和Pod是资源的使用者,根据业务服务的需求变化而变化,有K8s集群的使用者即服务的管理员来配置。

    节点(Node):K8s集群中的计算能力由Node提供,最初Node称为服务节点Minion,后来改名为Node。K8s集群中的Node也就等同于Mesos集群中的Slave节点,是所有Pod运行所在的工作主机,可以是物理机也可以是虚拟机。不论是物理机还是虚拟机,工作主机的统一特征是上面要运行kubelet管理节点上运行的容器。

      密钥对象(Secret):Secret是用来保存和传递密码、密钥、认证凭证这些敏感信息的对象。使用Secret的好处是可以避免把敏感信息明文写在配置文件里。在K8s集群中配置和使用服务不可避免的要用到各种敏感信息实现登录、认证等功能,例如访问AWS存储的用户名密码。为了避免将类似的敏感信息明文写在所有需要使用的配置文件中,可以将这些信息存入一个Secret对象,而在配置文件中通过Secret对象引用这些敏感信息。这种方式的好处包括:意图明确,避免重复,减少暴漏机会。

       用户帐户(User Account)和服务帐户(Service Account):顾名思义,用户帐户为人提供账户标识,而服务账户为计算机进程和K8s集群中运行的Pod提供账户标识。用户帐户和服务帐户的一个区别是作用范围;用户帐户对应的是人的身份,人的身份与服务的namespace无关,所以用户账户是跨namespace的;而服务帐户对应的是一个运行中程序的身份,与特定namespace是相关的。

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

      RBAC访问授权:K8s在1.3版本中发布了alpha版的基于角色的访问控制(Role-based Access Control,RBAC)的授权模式。相对于基于属性的访问控制(Attribute-based Access Control,ABAC),RBAC主要是引入了角色(Role)和角色绑定(RoleBinding)的抽象概念。在ABAC中,K8s集群中的访问策略只能跟用户直接关联;而在RBAC中,访问策略可以跟某个角色关联,具体的用户在跟一个或多个角色相关联。显然,RBAC像其他新功能一样,每次引入新功能,都会引入新的API对象,从而引入新的概念抽象,而这一新的概念抽象一定会使集群服务管理和使用更容易扩展和重用。

      总结:从K8s的系统架构、技术概念和设计理念,我们可以看到K8s系统最核心的两个设计理念:一个是容错性,一个是易扩展性。容错性实际是保证K8s系统稳定性和安全性的基础,易扩展性是保证K8s对变更友好,可以快速迭代增加新功能的基础。

k8s的service和ingress

在Kubernetes中,Service和Ingress都是用于管理和暴露应用程序网络流量的资源,但它们的用途和功能有所不同。

Service

Service 是Kubernetes中用于定义一组Pod的逻辑集合,并提供一种策略来访问这些Pod的方式。Service可以在集群内部或外部暴露应用程序。

  • 类型

    • ClusterIP(默认):在集群内部创建一个虚拟IP地址,供集群内部的其他服务访问。
    • NodePort:在每个节点上开放一个端口,通过该端口可以从外部访问服务。
    • LoadBalancer:使用云提供商的负载均衡器,将流量分发到后端的Pod。
    • ExternalName:将服务映射到DNS名称。
  • 功能

    • 提供服务发现和负载均衡:提供持久IP地址和DNS名称,在多个pod分发流量,可以通过service名进行服务发现
    • 通过标签选择器将流量路由到一组Pod。
    • 支持多种访问类型,适应不同的网络需求。

Ingress

Ingress 是Kubernetes中用于管理外部访问HTTP和HTTPS流量的API对象。它提供了基于规则的路由功能,可以将外部请求路由到集群内部的服务。

  • 功能

    • 提供HTTP和HTTPS路由。
    • 支持基于主机名和路径的路由规则。
    • 可以配置TLS终止,提供安全的HTTPS访问。
    • 支持负载均衡、SSL/TLS终止和基于名称的虚拟主机。
  • 工作方式

    • Ingress资源定义了如何将外部HTTP/HTTPS请求路由到集群内部的服务。
    • 需要一个Ingress Controller来实现这些规则,常见的有NGINX Ingress Controller、Traefik等。

k8s中的configmap和secret

在Kubernetes中,ConfigMap和Secret是用于管理配置数据和敏感信息的两种重要资源。它们帮助开发者和运维人员将配置与应用程序代码分离,从而提高应用程序的可移植性和安全性。

ConfigMap

作用: ConfigMap用于存储非敏感的配置数据,以键值对的形式存在。它可以用于存储环境变量、配置文件、命令行参数等。

使用场景

  • 环境配置:将应用程序的环境配置存储在ConfigMap中,以便在不同环境中使用不同的配置。
  • 命令行参数:通过ConfigMap传递命令行参数给应用程序。
  • 配置文件:将配置文件内容存储在ConfigMap中,并在Pod中挂载为文件

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  # 键值对形式
  database_url: "mongodb://localhost:27017"
  log_level: "DEBUG"

pod中使用

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    env:
    - name: DATABASE_URL
      valueFrom:
        configMapKeyRef:
          name: my-config
          key: database_url

Secret

作用: Secret用于存储敏感信息,如密码、OAuth令牌、SSH密钥等。与ConfigMap不同,Secret中的数据是经过Base64编码的,以提供一定程度的安全性。

使用场景

  • 存储敏感信息:如数据库密码、API密钥等。
  • TLS证书:存储和管理TLS证书和密钥。
  • Docker镜像拉取凭证:存储私有Docker仓库的访问凭证。

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  # Base64编码后的数据
  username: bXl1c2Vy
  password: bXlwYXNzd29yZA==

pod中使用

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    env:
    - name: USERNAME
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: username

资源配额

在Kubernetes中,资源配额(Resource Quotas)是一种用于限制和管理命名空间中资源使用的机制。它可以帮助集群管理员控制资源的分配,防止某个命名空间过度消耗集群资源,从而确保集群的稳定性和公平性。

资源配额的作用

  1. 限制资源使用:通过设置资源配额,可以限制一个命名空间中可以使用的CPU、内存、存储等资源的总量。

  2. 公平资源分配:确保集群中的多个团队或应用程序能够公平地使用资源,防止资源被某个命名空间独占。

  3. 提高集群稳定性:通过限制资源使用,可以防止资源过度消耗导致的集群不稳定。

资源配额可以限制多种类型的资源,包括但不限于:计算资源:如CPU和内存。存储资源:如持久卷(Persistent Volume)的存储大小。对象数量:如Pod、Service、ConfigMap等对象的数量。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: example-quota
  namespace: example-namespace
spec:
  hard:
    pods: "10"  # 限制Pod的数量
    requests.cpu: "4"  # 限制CPU请求总量
    requests.memory: "8Gi"  # 限制内存请求总量
    limits.cpu: "8"  # 限制CPU限制总量
    limits.memory: "16Gi"  # 限制内存限制总量
    persistentvolumeclaims: "5"  # 限制PVC的数量
    configmaps: "20"  # 限制ConfigMap的数量
    services: "10"  # 限制Service的数量

使用资源配额的注意事项

  1. 命名空间级别:资源配额是针对命名空间设置的,因此需要为每个命名空间单独配置。

  2. 资源请求和限制:在Pod定义中,确保为容器设置了资源请求和限制,以便资源配额能够正确生效。

  3. 监控和调整:定期监控资源使用情况,根据需求调整资源配额,以确保资源的合理分配。

  4. 与LimitRange结合使用:可以与LimitRange结合使用,限制单个Pod或容器的资源使用,进一步细化资源管理。

通过合理配置资源配额,Kubernetes管理员可以有效地管理集群资源,确保资源的合理分配和使用,提升集群的稳定性和效率。

Namespaces

Kubernetes中的Namespace是一种用于将集群中的资源进行逻辑分组的机制。它提供了一种方法来组织和管理资源,使得在同一集群中可以支持多个用户、团队或项目的隔离和管理。

Namespace的作用

  1. 资源隔离:Namespace允许在同一Kubernetes集群中创建多个隔离的环境。不同的Namespace中的资源(如Pod、Service、ConfigMap等)可以同名而不冲突。

  2. 访问控制:通过Namespace,可以结合RBAC(基于角色的访问控制)来限制用户对特定Namespace中资源的访问权限,从而提高安全性。

  3. 资源管理:Namespace可以与资源配额(Resource Quotas)结合使用,限制每个Namespace中资源的使用量,确保公平分配。

  4. 环境管理:可以使用Namespace来管理不同的环境,如开发、测试和生产环境。每个环境可以有独立的资源和配置。

使用场景

  1. 多租户环境:在一个集群中,多个团队或用户可以使用不同的Namespace来隔离他们的资源,避免资源冲突和管理混乱。

  2. 环境隔离:在同一集群中,可以为开发、测试和生产环境创建不同的Namespace。这样可以确保不同环境之间的资源和配置不会相互影响。

  3. 项目管理:对于大型项目,可以为每个子项目创建独立的Namespace,以便于管理和监控。

  4. 资源配额管理:结合资源配额,可以为每个Namespace设置资源限制,确保不同团队或项目在资源使用上的公平性。

  5. 访问控制:使用RBAC,可以为不同的用户或团队设置不同的权限,以控制他们对特定Namespace中资源的访问。

默认Namespace:Kubernetes集群中有几个默认的Namespace,如default、kube-system和kube-public。用户可以在这些Namespace中创建资源,但通常建议为特定应用或团队创建新的Namespace。

命名冲突:虽然不同Namespace中的资源可以同名,但在同一Ns中,资源名称必须唯一。

通过使用Namespace,Kubernetes提供了一种灵活的方式来管理和组织集群资源,确保资源的有效利用和安全性。

持久化存储

在Kubernetes中,持久化存储是通过使用持久卷(Persistent Volumes, PV)和持久卷声明(Persistent Volume Claims, PVC)来实现的。持久化存储允许数据在Pod重启或迁移时保持不变,确保应用程序的数据持久性。

持久化存储的原理

  1. 持久卷(PV):PV是集群中的一块存储资源,它是由管理员预先配置的。PV可以是多种存储类型,如NFS、iSCSI、云存储(如AWS EBS、GCP Persistent Disk等)或本地存储。PV是集群级别的资源,与具体的命名空间无关。

  2. 持久卷声明(PVC):PVC是用户对存储的请求,它描述了所需的存储大小和访问模式(如ReadWriteOnce、ReadOnlyMany等)。PVC是命名空间级别的资源,用户可以在其命名空间中创建PVC来请求PV。

  3. 绑定:Kubernetes控制平面会根据PVC的请求自动查找符合条件的PV,并将其绑定到PVC。绑定后,PVC可以被Pod使用。

  4. 使用:Pod通过引用PVC来使用持久化存储。Kubernetes会将PVC挂载到Pod中,使得应用程序可以访问持久化存储

PV声明

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /path/to/nfs
    server: nfs-server.example.com

创建PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
  namespace: my-namespace
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

 Pod使用PVC

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: my-namespace
spec:
  containers:
  - name: my-container
    image: my-image
    volumeMounts:
    - mountPath: /data
      name: my-storage
  volumes:
  - name: my-storage
    persistentVolumeClaim:
      claimName: my-pvc

持久卷的访问模式定义了如何访问存储,主要有以下几种:

  • ReadWriteOnce (RWO):该卷可以被单个节点以读写方式挂载。
  • ReadOnlyMany (ROX):该卷可以被多个节点以只读方式挂载。
  • ReadWriteMany (RWX):该卷可以被多个节点以读写方式挂载。

注意事项:

  1. 存储类型:选择合适的存储类型(如NFS、云存储等)以满足应用程序的需求。
  2. 动态供应:K8s还支持动态供应持久卷,允许在创建PVC时自动创建PV简化存储管理。
  3. 数据备份:考虑数据备份和恢复策略,以防止数据丢失。

通过使用PV和PVC,Kubernetes提供了一种灵活且强大的方式来管理持久化存储,确保应用程序数据的持久性和可靠性。

k8s安全配置

Kubernetes的安全配置是确保集群和应用程序安全的重要组成部分。Kubernetes提供了多种机制和最佳实践来保护集群、节点和应用程序。以下是一些常用的安全配置方法:

1. 身份验证和授权

  • RBAC(基于角色的访问控制):使用RBAC来控制用户和服务账户对Kubernetes资源的访问权限。通过定义角色(Role)和角色绑定(RoleBinding),可以精细化地管理权限。

  • Webhook身份验证:可以配置Webhook来实现自定义的身份验证机制,增强集群的安全性。

2. 网络安全

  • 网络策略(Network Policies):使用网络策略来控制Pod之间的网络流量,限制哪些Pod可以相互通信,增强网络安全。

  • 服务网格:使用服务网格(如Istio)来实现更细粒度的流量管理和安全策略,包括流量加密和身份验证。

3. Pod安全

  • Pod安全策略(Pod Security Policies):定义Pod的安全标准,限制Pod的运行方式,例如限制特权模式、使用特定的用户ID等。

  • 安全上下文(Security Context):在Pod和容器级别设置安全上下文,定义用户、组、特权等安全配置。

4. 数据安全

  • 加密存储:对Kubernetes中的敏感数据(如Secrets和ConfigMaps)进行加密存储,确保数据在存储时的安全性。

  • 使用Secrets:将敏感信息(如密码、API密钥)存储在Kubernetes的Secrets中,而不是硬编码在应用程序中。

5. 审计和监控

  • 审计日志:启用Kubernetes的审计日志功能,记录对API的访问和操作,以便于后续的安全审计和问题排查。

  • 监控和告警:使用监控工具(如Prometheus、Grafana)监控集群的安全状态,并设置告警以便及时响应安全事件。

6. 节点安全

  • 节点硬化:确保Kubernetes节点的操作系统和软件包是最新的,应用安全补丁,减少攻击面。

  • 运行时安全:使用容器运行时安全工具(如Falco)监控容器的行为,检测异常活动。

7. 镜像安全

  • 镜像扫描:在部署之前,对容器镜像进行安全扫描,确保没有已知的漏洞。

  • 使用可信的镜像源:从可信的镜像仓库(如Docker Hub、Google Container Registry等)拉取镜像,避免使用不明来源的镜像。

8. 最小权限原则

  • 最小权限访问:确保用户和服务账户只拥有完成任务所需的最低权限,减少潜在的安全风险。

9. 定期安全审计

  • 安全审计和评估:定期进行安全审计和评估,识别潜在的安全漏洞和配置错误,及时修复。

POD

在Kubernetes中,Pod是Kubernetes的基本部署单位,是一个或多个容器的集合,这些容器共享存储、网络和运行环境。Pod是Kubernetes中最小的可部署单元,通常用于运行单个应用程序或服务。

Pod的作用

  1. 容器组合:Pod可以包含一个或多个容器,这些容器通常是紧密相关的,协同工作以提供某个功能。例如一个Web应用程序的Pod可能包含一个Web服务器容器和一个反向代理容器。

  2. 共享网络和存储:Pod中的所有容器共享同一个网络命名空间,意味着它们可以通过localhost进行通信。Pod还可以定义共享的存储卷,使得容器之间可以共享数据。

  3. 简化管理:Pod作为Kubernetes的基本单元,简化了容器的管理。用户可以通过Pod来管理多个容器的生命周期,而不必单独管理每个容器。

  4. 负载均衡和服务发现:Kubernetes通过Service对象为Pod提供负载均衡和服务发现功能,使得用户可以通过稳定的IP地址或DNS名称访问Pod中的应用程序。

  5. 扩展性:Pod可以轻松地进行水平扩展,用户可以根据需要增加或减少Pod的数量,以应对不同的负载需求。

  6. 生命周期管理:Kubernetes负责Pod的生命周期管理,包括创建、调度、监控和故障恢复。用户可以定义Pod的期望状态,Kubernetes会自动确保实际状态与期望状态一致。

Pod的组成部分

  1. 容器:Pod中可以包含一个或多个容器,容器是运行应用程序的实际环境。

  2. 共享存储卷:Pod可以定义一个或多个存储卷,供容器共享数据。

  3. 网络设置:Pod中的所有容器共享同一个IP地址和端口空间,允许它们通过localhost进行通信。

  4. 元数据:Pod包含一些元数据,如名称、标签、注释等,用于标识和管理Pod。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐