在学习Kubernetes 之前,需要我们了解docker,否则不建议各位直接阅读这篇文档,也可以查看作者之前写的docker系列的文章:
标题 | 链接 |
---|---|
Dockerfile不会写?于是我花十分钟看了这篇文章 | juejin.cn/post/749428... |
SpringBoot应用:Docker与Kubernetes全栈实战秘籍 | juejin.cn/post/744068... |
Docker入门之Windows安装Docker初体验 | juejin.cn/post/741565... |
从零开始玩转 Docker:一站式入门指南,带你快速掌握镜像、容器与仓库 | juejin.cn/post/740318... |
面试官让你介绍一下docker,别再说不知道了 | juejin.cn/post/740283... |
Windows 10环境用Docker发布SpringBoot项目 | juejin.cn/post/724197... |
Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、扩缩和管理。而在业界我们一般叫它 k8s 因为首字母K 和尾字母s中间刚刚有8个单词,所以为了好叫好记,我们就叫他K8s。
为什么需要 Kubernetes,它能做什么?
容器是打包和运行应用程序的好方式。在生产环境中, 你需要管理运行着应用程序的容器,并确保服务不会下线。 例如,如果一个容器发生故障,则你需要启动另一个容器。 如果此行为交由给系统处理,是不是会更容易一些?
这就是 Kubernetes 要来做的事情! Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移你的应用、提供部署模式等。
这是k8s的一个部署演化图,不知道大家公司现在是处于哪个阶段呢?

这里是k8s的官方概述介绍,推荐大家看一看:kubernetes.io/zh-cn/docs/...
那么,我们作为开发人员如何快速入手k8s呢,k8s的架构和里面的原理非常的复杂,那么作者认为作为开发的我们并不需要在有限的时间的前提下对它掌握的太深,但是我们至少得学会怎么用k8s,以及里面的一些基础概念,所以我们这次不讲k8s里面深层的原理,我们来了解里面的一些基础概念和组件,例如pod,Deployment 等作为开发经常听到的一些名词。
K8s 组件
Node

在k8s中,一个物理机或者一套虚拟机叫做node,就是上面浅灰色的框
Pod

这也是作者作为开发最经常听到的一个名词,一个 Pod 就是一个或者多个应用容器的组合。它创建了一个容器的运行环境,在这个环境中容器可以共享一些资源,比如网络、存储和运行时的一些配置等等。例如我们可以把我们的一个web服务放入到一个pod中,而在微服务架构的角度来说,我们添加了一个pod意味着添加了一个节点,就多了一个消费者。

ConfigMap
类似操作系统中的环境变量,pod可以读取环境变量中的key对应的value值

里面的内容就像这样:

Secret
大家可能注意到了上面ConfigMap的第二张如中的配置信息是明文的,所以一般我们会配置一个Secret用于加密,封装敏感信息

Service & Deployment
这两我觉得可以合在一起讲,如果看过作者这篇文章的话,就会发现我们将引用部署到k8s的时候,我们会写到两个配置文件:

而这两个文件也决定了我们的web服务在k8s中的整体部署和访问方向,而这两个文件也是用于配置Service & Deployment这两个好兄弟。
前面我们也说了,pod是可以动态配置的,而pod里面都是容器,容器也每次创建都是一个全新的容器。那么也决定了他是一个活动的,是一个不固定的ip,那么这个时候如果我们的前端需要访问后端web服务就会发现pod的ip一直在变!!所以这个时候service就出现了

Service API 是 Kubernetes 的组成部分,它是一种抽象,帮助你将 Pod 集合在网络上公开出去。 每个 Service 对象定义端点的一个逻辑集合(通常这些端点就是 Pod)以及如何访问到这些 Pod 的策略。其实有点像SpringCloud中的gateway。
而在service.yaml中,我们通过标签选择器(Label Selector)定位一组 Pod
yaml
# selector:
# 定义服务选择哪些 Pod。
selector:
# app: aijava
# 定义标签选择器,选择带有 app: aijava 标签的 Pod。
# 用途:确保服务将流量路由到正确的 Pod。
app: aijava
但是这个时候有个问题,例如我们的pod(后端服务)突然挂掉了,那咋办,别急,k8s自然而然想到了一个方法:Deployment
Deployment 用于管理运行一个应用负载的一组 Pod,通常适用于不保持状态的负载。即无状态的。

而我们的对应的关联图就像这样,他可以动态的去管理pod。

例如在deployment.yaml文件中,replicas就是定义我们的pod数量,如果是2,那么在Deployment 的管理下,他会始终保证有两个pod运行,假如有一个pod突然挂掉,则Deployment 会自动补上一个pod。
deployment.yaml:
yaml
# spec:
# 定义 Deployment 的规格,即 Deployment 的具体配置。
spec:
# replicas: 2
# Pod 的副本数量,即 Deployment 将运行的相同 Pod 数量。
# 用途:确保应用程序具有高可用性和负载均衡。
replicas: 2
Deployment 和 Service 的关联
- Deployment 定义了如何创建和管理 Pod,而 Service 定义了如何访问这些 Pod。
- 通过 Deployment 创建 Pod: Deployment 定义了 Pod 的模板和副本数,它会确保这些 Pod 按需求运行。
- 通过 Service 访问 Pod: Service 通过 Label Selector 找到 Deployment 创建的 Pod,提供网络访问和负载均衡。
在一个典型的微服务中,通常是用 Deployment 部署服务的 Pod,用 Service 连接和暴露这些 Pod。
Ingress
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。说白了,就是配置域名的,一般来说,前端通过我们service提供的ip和端口就可以访问我们的后端服务,但是严格意义来讲,我们应该通过域名去访问我们的api接口,就像这样:

而在我们的web(Rancher)页面中就是这样:

其实我们把他理解成dns加nginx配置域名解析到gateway是不是就很好理解了。

但是在最新的k8s官方文档上面,官方表示:
入口(Ingress)目前已停止更新。新的功能正在集成至网关 API 中。

StatefulSet
Deployment 是 Kubernetes 中最早的工作负载资源之一,主要设计用于无状态应用程序,例如我们前面说的提供http接口的web应用,而且根据我们前面的了解,Deployment 里面的pod是无状态的,即重启即丢失内容。部署java这种jar包服务还好,但是如果是rabbitmq这种呢?

所以Kubernetes 提供了 StatefulSet 组件来管理

StatefulSet 和 Deployment 的区别
特性 | StatefulSet | Deployment |
---|---|---|
Pod 的标识(身份) | 每个 Pod 有一个稳定的标识(如 my-app-0 , my-app-1 ),即使重新调度或删除也保持不变。 |
Pod 是无状态的,Pod 的名称和顺序是动态分配的,删除后重建的 Pod 无法保证与之前的身份相同。 |
存储(持久化存储) | 每个 Pod 绑定一个独立的存储卷(PersistentVolume),即使 Pod 重建也能保持数据的一致性。 | 默认情况下,Pod 使用临时存储(ephemeral storage)。即使使用持久化存储卷,不会与 Pod 的特定实例绑定。 |
Pod 的启动顺序 | 启动和终止 Pod 时,遵循严格的顺序(例如,Pod 0 必须在 Pod 1 之前启动)。 | 没有启动和终止顺序,Pod 的创建和终止是并发的。 |
适用场景 | 适用于需要有状态、需要持久化存储、需要严格顺序或唯一标识的应用程序(如数据库、分布式存储、队列系统)。 | 适用于无状态的应用程序,如 Web 服务、API 服务或业务逻辑层应用。 |
网络标识(DNS 名称) | 每个 Pod 都有一个唯一且稳定的网络标识(DNS 名称,例如 my-app-0.my-app-svc ),方便集群内的直接访问。 |
Pod 不会有稳定的 DNS 名称。负载均衡通常通过 Service 完成,所有 Pod 的访问入口是统一的。 |
滚动更新行为 | 按顺序进行滚动更新,确保前一个 Pod 完全就绪后才更新下一个。 | 并发地滚动更新,多个 Pod 可以同时更新,更新速度快。 |
数据一致性保障 | 支持强一致性或应用场景需要的顺序要求(如分布式数据库节点)。 | 不保证 Pod 的数据一致性或节点之间的依赖关系。 |
Volume
最后再介绍一下Volume ,上面我们也说了StatefulSet 和 Deployment 一个部署有状态的(可以理解为不允许数据丢失的),一个部署无状态(允许数据丢失的),那么我们开发过程中会有这样的场景:我的java程序创建了一个excel文件,该文件需要长期保存在本地磁盘中。如果文件仅保存在容器内,Pod 重启后文件就会丢失,此时容器状态未保存, 因此在容器生命周期内创建或修改的所有文件都将丢失。生成的excel文件自然而然也就被删除了。
所以因此需要挂载 Volume。可以按照作者举得例子去理解Volume(卷)存在的意义。Volume 为 Pod 提供了一种将数据存储在持久化存储(如磁盘、网络存储、云存储等)上的方法,从而避免数据丢失。
至此,我们只要理解了这几个关键的k8s的组件,这样我们就对k8s有个基础的概念了,那么由于篇幅有限,作者还会再后面介绍k8s的一些其他的内容,不仅限于k8s的架构,部署,命令的使用等等,欢迎大家关注一波。