Kubernetes入门

时间:2024-10-23 20:33:42

目录

什么是kubernetes

为什么要用k8s

那么同为容器化技术,为什么docker逐渐没落了呢?

k8s的特性

弹性伸缩

自我修复

服务发现和负载均衡

自动发布

集中化配置管理和密钥管理

存储编排

任务批处理运行

kubernetes 架构与组件

master组件

Kube-apiserver

kube-controller-manager

Kube-scheduler

etcd

node组件

kubelet

Kube-Proxy

rocket

kubernets 核心概念

Pod

Pod 控制器

ReplicaSet

Deployment

Daemonset

StatefulSet 

Job&CronJob

Label

Label选择器

Service

Ingress

Name

Namespace


什么是kubernetes

Kubernetes(通常简称为K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它最初由Google开发,并于2014年发布为开源项目。Kubernetes的设计目标是提供一个平台,使得在分布式系统中运行和管理容器化应用变得更加简单和高效

为什么要用k8s

首先,k8s身为容器化技术,使用容器作为部署单元,相较于传统运维依赖于物理服务器或者虚拟机来说是轻量级的,启动速度快,资源占用少;而且无需手动配置和管理操作系统,不依赖库和应用程序,可以快速部署和扩展容器,无需重启整个服务器或虚拟机;再者,容器镜像包含了应用程序及其所有依赖,确保环境一致性,不会出现传统运维 开发、测试和生产环境之间存在差异,在这台机器上可以运行,在别的机器上就不行的问题。

其次是,容器化技术共享宿主机的操作系统内核,资源占用较少,启动和关闭速度快,资源利用率高;传统运维则需要更多资源,包括操作系统、内核等

尽管容器化技术有诸多优势,但传统运维并非一无是处,毕竟是一个已经成熟的技术,有大量的文档和社区支持,而且传统运维提供了较强的资源隔离,每个虚拟机运行独立的操作系统,安全性较高,一台机器故障不会影响其他机器

那么同为容器化技术,为什么docker逐渐没落了呢?

K8s 解决了裸跑 Docker (在没有使用任何容器编排平台(如Kubernetes、Docker Swarm等)的情况下,直接在单机或少量机器上使用Docker引擎来运行和管理容器)的若干痛点,提供了更高级的功能和工具,使得容器化应用的管理和运维更加高效和可靠,比如说:

单机使用,无法有效集群

Docker主要用于单机环境中的容器管理,无法有效实现多机集群,且单机环境下的容器管理和资源利用率有限。

而Kubernetes提供了强大的集群管理功能,支持多节点、多主机的容器编排;Kubernetes的调度器可以根据资源需求和节点状态智能分配容器,实现高效的资源利用。

随着容器数量的上升,管理成本攀升

随着容器数量的增加,手动管理和维护容器的成本会显著上升。

需要手动配置和管理容器的网络、存储、资源等。

Kubernetes 则提供了自动化管理工具,可以自动部署、扩展和管理大量容器。

没有有效的容灾、自愈机制

Docker本身没有内置的容灾和自愈机制,容器的故障需要手动处理,故障又可能导致应用的中断和服务不可用。

Kubernetes提供了自我修复功能,可以自动重启失败的容器,替换不健康的容器;支持高可用性配置,确保应用在节点故障时仍然可用。

没有预设编排模板,无法实现快速、大规模容器调度

Docker没有预设的编排模板,大规模容器的调度和部署需要手动配置,且大规模容器的调度和部署过程复杂且容易出错。

Kubernetes提供了丰富的编排模板和资源定义(如Deployment、ReplicaSet、Service等),支持快速、大规模的容器调度。

没有统一的配置管理中心工具

Docker没有统一的配置管理中心工具,配置管理分散且容易出错。

Kubernetes提供了ConfigMap和Secret等资源,用于统一管理配置数据和敏感信息。

没有容器生命周期的管理工具

Docker主要关注容器的创建和运行,没有完整的容器生命周期管理工具,即容器的启动、停止、更新等操作需要手动处理。

Kubernetes提供了完整的容器生命周期管理工具,支持容器的创建、运行、更新、回滚等操作。

没有图形化运维管理工具

Docker主要通过命令行工具进行管理,没有图形化运维管理工具,对于大规模、复杂的容器环境,管理起来不够直观和高效。

Kubernetes生态系统中有许多图形化运维管理工具,如Kubernetes Dashboard、Rancher、Portainer等。

那说了这么多,docker 难道没有容器编排工具吗?当然是有的,docker swarm 就是docker 的容器编排工具,尽管它和 k8s 都旨在简化容器化应用的部署和管理,但在功能、生态系统和社区支持等方面存在显著差异

docker swarm的功能不如k8s 丰富,k8s提供如自动扩展、服务发现、负载均衡、自动修复、配置管理、存储编排、网络策略、安全策略等,尽管 Swarm 也支持服务发现和负载均衡,但在高级功能和灵活性方面不如 Kubernetes;

可扩展性和灵活性不如k8s,swarm的设计相对简单,而 k8s 设计为高度可扩展和灵活,支持自定义资源定义和自定义控制器,可以根据需求扩展其功能;

生态较小、社区支持不如k8s活跃,swarm 主要由docker公司维护,而k8s有众多云服务提供商的支持,以及拥有大量的第三方工具和插件支持;

k8s拥有如此灵活、丰富的功能组件,自然,它的学习曲线,就会比较陡峭,它的配置管理相对来说也会比较复杂。

k8s的特性

 在深入了解k8s的各个组件之前,需要再了解一下k8s的特性,之前与docker swarm 对比也只是简单介绍相对的优点,下面我们深入了解一下 k8s 具有哪些特点

弹性伸缩

使用命令、UI等根据 CPU 使用情况或其他自定义指标自动扩展和缩减应用程序实例,在业务并发量高的时候,提高资源占比;业务并发量变低的时候,及时回收资源,减少资源占比,以最小的成本运行服务

自我修复

在节点故障时重新启动失败的容器,替换和重新部署,保证预期的副本数量。杀死健康检査失败的容器,并且在未准备好之前不会处理客户端请求,确保线上服务不中断。

服务发现和负载均衡

 K8s 为多个容器提供一个统一的访问入口,并自动进行负载均衡,通过service资源为一组 Pod 提供一个稳定的 IP 地址和 DNS 名称,使得用户无需关心 Pod 的具体 IP 地址,会自动将请求分发到后端的多个 Pod 上,确保负载均衡和高可用性

service 组件和 pod 之后详细说明

自动发布

 Kubernetes 支持滚动更新策略,逐步更新应用程序的版本,而不是一次性更新所有 Pod,这样可以确保在更新过程中,应用程序仍然可用。如果更新过程中出现问题,那么就会自动回滚到之前的版本,确保升级不影响业务。

集中化配置管理和密钥管理

k8s 使用 configmap 和 secret 来管理机密数据,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性。并可以将一些常用的配置存储在其中,方便应用程序使用。

存储编排

k8s 支持挂载外部存储系统,并对外部存储资源进行编排,无论是来自本地存储,还是公有云、网络存储等都作为集群资源的一部分使用,极大提高存储使用灵活性。

任务批处理运行

K8s 提供了 Job 和 Cronjob 资源,用于支持一次性任务和定时任务。Job 用于运行一次性任务,而Cronjob 用于定时运行任务,这些资源适用于批量数据处理、数据分析等场景,确保任务能够按时执行并完成。

kubernetes 架构与组件

k8s 在模式上和主从(Master-Slave 架构 )很像,有个Master 节点负责集群的调度和管理,那么slave 节点是集群的被调度的工作负载节点,一般称为 worker node 节点。

通常情况下,master 节点 单独占据一个服务器,因为 Master 是整个集群的控制中心,如果 master节点宕机下线,那么整个集群就瘫痪了,所有控制命令都会失效。node节点宕机影响不大,master 会将其工作负载转移到其他节点上

整体的工作模式就是这样,非常易懂,但节点内的核心组件才是重中之重

master组件
Kube-apiserver

kube-apiserver 负责提供 Kubernetes API,是集群的入口点,验证所有进入的请求,确保请求来自被授权的用户或组件,任何请求资源或者调用操作都是通过 kube-apiserver 提供的接口进行,以 HTTP Restful API 提供接口服务,所有对象资源的增删改查和监听操作都交给 API Server 处理后再提交给 Etcd 存储。

除此之外,kube-apiserver还负责集群状态的管理,所有 Kubernetes 组件的状态都存储在 etcd 数据库中,kube-apiserver是负责与etcd进行交互的组件,它从etcd 获取集群的当前状态并响应请求,确保状态的一致性。

kube-controller-manager

Kube-controller-manager 中集成了多个控制器,这些控制器通过与Kube-apiserver 交互,监控集群的状态,确保实际状态与用户所期望的状态保持一致,集群中一个资源对应一个控制器,而 Controller manager 就是负责管理这些控制器的。

这些控制器主要包括:

Node Controller:监视节点的健康状况,如果发现节点不可达或失联,则进行处理,比如驱逐节点上的 Pod。

Replication Controller:确保每个指定的 Pod 副本数在任何时间点都正确。例如,如果某个 Pod 意外退出,控制器会启动新的 Pod 来恢复到指定的副本数。

Endpoint Controller:维护 Service 和 Pod 之间的映射,确保服务能够正确访问相应的 Pod。

Service Account & Token Controller:为新创建的命名空间生成默认的 ServiceAccount 对象,并为其分配 API 访问令牌。

ResourceQuota Controller:确保指定的资源对象在任何时候都不会超量占用系统物理资源。

Namespace Controller:管理 namespace 的生命周期。

Service Controller:属于 K8S 集群与外部的云平台之间的一个接口控制器。

…………

Kube-scheduler

Kube-scheduler 负责将新的待调度的 Pod 分配到合适的节点上。它的主要功能是根据集群的资源状况和调度策略,选择最适合的节点来运行这些 Pod。

kube-scheduler通常通过个调度算法和策略来选择合适的节点,分为过滤阶段和优选阶段

首先调度器会筛选掉那些不符合 Pod 调度要求的节点。例如,某些节点可能因为资源不足、标签不匹配、节点不可达等原因而被过滤掉。

在通过过滤阶段的节点中,kube-scheduler 会根据多种优选策略对节点进行打分,选择分数最高的节点。这些策略可能包括节点的 CPU、内存负载、Pod 的亲和性/反亲和性、数据本地性等,比如,资源越富裕、负载越小的 Node 那么可能它的排名越高 。

etcd

etcd是一个分布式键值存储系统,Kubernetes 使用它来保存集群的所有数据,作为 Kubernetes 集群的核心数据库。它是 Kubernetes 的集中式状态存储,所有关于集群的状态信息(如节点信息、Pod 信息、配置数据等)都存储在etcd中,K8S 中仅 API Server 才具备读写权限,其他组件必须通过 API Server 的接口才能读写数据。

node组件
kubelet

kubelet 有点像master 安装在node节点上的监控兼通讯器,它会定时向 API Server 汇报自己 Node 节点上运行的服务的状态,并接受来自 Master 节点的指示采取调整措施。 它不直接管理容器的生命周期,而是通过与容器运行时(进行交互,创建和管理容器。它遵循 Kubernetes 的 CRI,确保容器的标准化管理。

Kube-Proxy

kube-proxy是 Kubernetes 集群中的网络代理组件,负责为每个节点上的服务提供网络路由功能。它在每个节点上运行,并管理节点上的网络规则, 负责写入规则至iptables、ipvs实现服务映射访问 ,使得 Kubernetes 集群中的服务能够被正确访问,确保服务和 Pod 之间的通信顺畅

此外,kube-proxy还负责集群中的负载均衡,负责将对某个服务的网络请求,分发到该服务后端的多个 Pod 上

rocket

容器引擎,运行容器,负责本机的容器创建和管理工作。

kubernets 核心概念

在之前的介绍中提到过多次专有名词比如pod、service 等,这些包括Label、Replication、Controller等都是kubernetes的资源对象,所有资源对象都是通过 kubectl 工具进行增删改等操作的,并将其存入etcd中持久化存储

Pod

Pod 是最小的可部署计算单元,包含一个或多个容器。每个 Pod 都代表一个正在集群中运行的进程环境,并且这些 Pod 可以在集群中调度、管理和运行;

一个 Pod 由一个或多个容器组成,Pod 中容器共享网络、存储和计算资源,在同一台 Docker 主机上运行;

同一个 Pod 之间的容器可以通过 localhost 互相访问,并且可以挂载 Pod 内所有的数据卷;但是不同的 Pod 之间的容器不能用 localhost 访问,也不能挂载其他 Pod 的数据卷。

Pod 控制器

Pod 控制器是用于管理 Pod 生命周期的组件。控制器通过监控集群状态和当前运行的 Pod,确保系统保持所需的状态。Pod 控制器根据定义的期望状态创建、更新、删除 Pod,确保 Pod 在运行中的可用性和稳定性,常见的Pod控制器有

ReplicaSet

ReplicaSet 是确保集群中始终运行指定数量 Pod 的控制器。它可以根据定义的标签选择器选择要管理的 Pod,并监控它们的状态,如果某个 Pod 失败或被删除,ReplicaSet 会创建新的 Pod 来替代它,受控于Deployment

Deployment

Deployment 无状态应用部署 ,它是更高级的控制器,构建在 ReplicaSet 之上,提供了更丰富的功能。Deployment 允许用户定义 Pod 的期望状态,并支持版本控制和回滚功能。还负责管理Replicaset,用户只需操作Deployment 部署服务即可,K8S 会自动生成要求的 ReplicaSet 和 Pod

Daemonset

DaemonSet 是用于在每个节点上运行一个 Pod 实例的控制器。它确保每个节点都运行指定的 Pod,适合集群级别的后台服务

StatefulSet 

StatefulSet 有状态应用部署,是用于管理有状态应用程序的控制器,适用于需要稳定的标识、持久化存储和顺序部署的场景

Job&CronJob

和centos系统中的命令含义一样,Job 控制器用于运行一次性任务,确保任务成功完成。CronJob 控制器用于定期调度任务。

Label

Label(标签)是一种用于组织和选择对象的键值对,用于标识、选择和分组资源,如 Pod、Node、Service、ReplicaSet等

每个标签由一个键和一个对应的值组成,通常的格式为 key=value ,由用户自己指定,如 app=nginx;

一个资源对象可以定义任意数量的Label,同一个Label 也可以被添加到任意数量的资源对象中,也可以在对象创建后动态添加或者删除;

可以通过给指定的资源对象捆绑一个或多个不同的 Label,来实现多维度的资源分组管理功能。

Label选择器

简而言之,来根据标签选择对象

标签选择器有两种主要类型:

等式选择:如 app=nginx 或 app!=nginx 选择标为/不为nginx的对象

集合选择:选择标签值在指定集合中的对象,如 tier in (frontend, backend),选择 tier 标签值为 frontend 或 backend 的对象,如果选择标签不为 fronted或backend的, 就是 tier notin ...

Service

Service 是一种抽象资源,定义了一组 Pod 的访问策略。它为这些 Pod 提供了一个稳定的、可持久化的网络接口,使得其他应用程序可以通过统一的方式访问这些 Pod,而无需关心 Pod 的实际 IP 地址变化或生命周期,它更像是网关层,可以看作一组提供相同服务的Pod的对外访问接口、流量均衡器

每个 Service 都会分配一个固定的虚拟 IP 地址,用于在集群内与其后端 Pod 通信。集群也会为每个 Service 提供一个可解析的 DNS 名称,方便其他服务通过名称访问

Service 使用标签选择器来选择一组 Pod,作为其后端目标。这使得 Service 可以根据 Pod 的标签动态地调整后端 Pod

Service 除了提供稳定的对外访问方式之外,还能起到负载均衡(Load Balance)的功能,自动把请求流量分布到后端所有的服务上,Service 可以做到对客户透明地进行水平扩展

Ingress

service 主要负责集群内,而Ingress主要用于管理外部访问集群内部服务的资源。它提供了 HTTP 和 HTTPS 路由规则,允许用户将外部请求路由到集群内的不同服务

Ingress是整个集群的接入层,允许用户定义基于请求的 URL 路径和主机名的路由规则,从而将请求路由到相应的后端服务,相当于在 OSI 网络参考模型下,第7层的应用,对外暴露的接囗


Name

Name 是每个资源对象的标识符,用于唯一地识别集群中的不同资源

Name 通常定义在元数据信息里。在同一个 namespace 空间中必须是唯一的。

Namespace

命名空间,于将集群中的资源进行逻辑隔离的机制,使得用户能够在同一集群中创建多个虚拟集群,便于管理、组织和资源分配