网站布局怎么写,注册wordpress博客,成品视频直播软件推荐哪个好一点的,学校网站设计图片〇、前言 Kubernetes#xff0c;将中间八个字母用数字 8 替换掉简称 k8s#xff0c;是一个开源的容器集群管理系统#xff0c;由谷歌开发并维护。它为跨主机的容器化应用提供资源调度、服务发现、高可用管理和弹性伸缩等功能。 下面简单列一下 k8s 的几个特性#xff1a; 自…〇、前言 Kubernetes将中间八个字母用数字 8 替换掉简称 k8s是一个开源的容器集群管理系统由谷歌开发并维护。它为跨主机的容器化应用提供资源调度、服务发现、高可用管理和弹性伸缩等功能。 下面简单列一下 k8s 的几个特性 自动化部署Kubernetes 可以根据应用程序计算资源需求自动分配到 node。 服务发现和负载均衡Kubernetes 可以利用 DNS 名称或自己的 IP 地址暴露容器如果到一个容器的流量过大Kubernetes 能够负载均衡和分发网络流量以保证部署稳定。 自动化容器扩容和缩容根据 CPU 使用情况或其他选择的度量标准Kubernetes 可以自动扩展或缩小运行的容器数量。 自我修复当一个容器失败时Kubernetes 会重新启动它当节点失败时它会替换和重新调度容器当容器没有通过用户定义的健康检查时它会杀死它。只有当容器准备好服务时才会将其视为可用。 密钥和配置管理Kubernetes Secrets 可以用来存储和管理敏感信息如密码、OAuth 令牌和 SSH 密钥等。而 Kubernetes ConfigMaps 则可以用来存储和管理配置信息如 Prometheus 配置文件、数据库连接字符串等。 回到顶部 一、关于 k8s 的一些概念解释 1.1 ContainerNamespace、Cgroup 容器字面意思就是类似于锅碗瓢盆、瓶瓶罐罐等总之就是一个装东西的目的。 IT 里的容器技术是英文单词 Linux Container 的直译。Container 这个单词有集装箱、容器的含义主要偏集装箱意思。在中文环境下人们更喜欢用“容器”这个词。不过如果要形象的理解 Linux Container 技术的话还是得念成集装箱会比较好。例如海边码头里的集装箱是运载货物用的它是一种按规格标准化的钢制箱子。集装箱的特色在于其格式划一并可以层层重叠所以可以大量规整地放置在特别设计的远洋轮船中大大增加了出货和运输效率从而更加快捷方便的为生产商提供廉价的运输服务。
在 Container 出现之前普遍认为硬件抽象层基于 hypervisor 的虚拟化方式可以最大程度上提供虚拟化管理的灵活性。各种不同操作系统的虚拟机都能通过 hypervisorKVM、XEN等来衍生、运行、销毁。然而随着时间推移用户发现 hypervisor 这种方式麻烦越来越多。因为对于 hypervisor 环境来说每个虚拟机都需要运行一个完整的操作系统以及其中安装好的大量应用程序。但实际生产开发环境里我们更关注的是自己部署的应用程序如果每次部署发布我都得搞一个完整操作系统和附带的依赖环境那么这让任务和性能变得很重和很低下。 Linux Container 容器技术的诞生2008 年就解决了 IT 世界里“集装箱运输”的问题。Linux Container简称LXC它是一种内核轻量级的操作系统层虚拟化技术。Linux Container 主要由 Namespace 和 Cgroup 两大机制来保证实现。那么 Namespace 和 Cgroup 是什么呢 Namespace 的目的就是隔离。就如上面提到的集装箱它的作用当然是可以对货物进行打包隔离了不让 A 公司的货跟 B 公司的货混在一起不然卸货就分不清楚了。一个资源只能在一个命名空间中且资源的 Names 在 Namespace 中具有唯一性但不同的 Namespace 中的资源可重名。 Cgroup 就负责资源管理控制作用。光有隔离还不够我们还需要对货物进行资源的管理。同样的航运码头也有这样的管理机制货物用什么样规格大小的集装箱货物用多少个集装箱货物哪些优先运走遇到极端天气怎么暂停运输服务怎么改航道等等。再比如进程组使用 CPU/MEM 的限制进程组的优先级控制进程组的挂起和恢复等等。 下边列一下容器技术的特点 极其轻量容器只打包了必要的二进制文件和库不需要包含整个操作系统这样使得容器更轻量 秒级部署根据镜像的不同容器的部署可以是秒级这比传统的虚拟机部署方式要快得多 易于移植一次构建随处部署从而极大减轻了开发和部署工作量提高开发效率 安全隔离容器会在操作系统级别虚拟化 CPU、内存、存储和网络资源为开发者提供在逻辑上与其他应用相隔离的沙盒化操作系统接口 弹性伸缩Kubernetes这类开源、方便、好使的容器管理平台有着非常强大的弹性管理能力同时减少资源的消耗冲突。 容器的应用 持续集成和持续部署CI/CD 通过容器可以实现代码的快速构建、测试和部署提高开发效率交付速度可提高十几倍。通过持续集成CI和持续部署CD每次开发人员签入代码并顺利测试之后IT 团队都能够集成新代码。作为开发运维方法的基础CI/CD 创造了一种实时反馈回路机制持续地传输小型迭代更改从而加速更改过程提高质量。CI 环境通常是完全自动化的通过 git 推送命令触发测试测试成功时自动构建新镜像然后推送到 Docker 镜像库。通过后续的自动化和脚本可以将新镜像的容器部署到预演环境从而进行进一步测试。 微服务架构 在微服务架构中应用程序被拆分成多个独立的、可伸缩的服务。容器可以帮助将这些服务打包成独立的运行环境简化部署和管理过程。Docker 的端到端安全功能让团队能够构建和运行最低权限的微服务模型服务所需的资源其他应用、涉密信息、计算资源等会适时被创建并被访问。 IT 基础设施优化充分利用基础设施节省资金 容器有助于优化 IT 基础设施的利用率和成本。优化不仅仅是指削减成本还能确保在适当的时间有效地使用适当的资源。容器是一种轻量级的打包和隔离应用工作负载的方法所以 Docker 允许在同一物理或虚拟服务器上毫不冲突地运行多项工作负载。企业可以整合数据中心将并购而来的 IT 资源进行整合从而获得向云端的可迁移性同时减少操作系统和服务器的维护工作。 参考https://www.cnblogs.com/qcloud1001/p/9273549.html 1.2 Pod Pod 是 k8s 调度的最小单元包含一个或者多个容器 Container。用户可以通过 k8s 的 Pod API 生产一个 Pod让 Kubernetes 对这个 Pod 进行调度也就是把它放在某一个 k8s 管理的节点上运行起来。 Pod 拥有一个唯一的 IP 地址在包含多个容器的时候依然是拥有一个IP地址。Pod 包含多个容器的时候用到的就是共享 namespace容器间就可以通过 localhost 通信了就像两个进程一样。而 Pod 与 Pod 之间是互相有 isolation 隔离的保证其运行环境的一致性和稳定性。 针对 Pod 内部的多个容器每个容器都需要有自己独立的端口号以便外部流量能够正确地路由到相应的容器。如果它们都需要被外部访问那么可以通过项目中的配置文件 service.yml 来实现。通过创建一个 service.yml可以将 Pod 内部的多个容器的流量聚合到一个统一的 IP 地址和端口上从而提供统一的访问入口。例如假设一个 Pod 里面运行了两个容器一个是 Web 应用监听 80 端口另一个是数据库监听 3306 端口。此时我们可以创建一个 service.yml将这两个端口映射到一个指定的端口比如 7777然后通过访问 Pod 的 6666 端口就可以同时访问到 Web 应用和数据库了。 另外Pod 可以挂载多个共享的存储卷Volume这时内部的各个容器就可以访问共享的 Volume 进行数据的读写。例如如果需要在一个 Pod 中运行两个容器一个是应用容器另一个是监控容器则可以将这两个容器放在同一个 Pod 中。在这种情况下监控容器可以通过共享内存机制访问应用容器的状态信息从而减少了应用程序和监控系统之间的耦合度。 1.3 VolumeEmptyDir、HostPath 先看下容器在 docker 中的情况。 创建容器时如果没有指定容器的数据卷容器中的文件在磁盘上通常是临时存放的当容器崩溃时数据和文件就会丢失然后 kubelet 会重新启动容器但容器会以干净的状态重启这样就造成了数据安全问题。 在 k8s 中一个 Pod 中可以同时运行多个容器常常需要在这些容器之间共享文件。 基于以上两个问题k8s 中就出现了一个抽象概念“卷”Volumn这个组件。卷的核心是包含一些数据的目录Pod 中的容器可以通过配置访问该目录。 以下是 Volume 的几个特点 Volume 是 k8s 抽象出来的对象它可以配置在 Pod 上然后可以被一个 Pod 里的多个容器挂载到具体的文件目录下 k8s 通过 Volume 实现同一个 Pod 中不同容器之间的数据共享以及数据的持久化存储 Volume 的生命周期不与 Pod 中单个容器的生命周期相关当容器终止或者重启时Volume 中的数据也不会丢失 k8s 可以支持许多类型的卷Pod 也能同时使用任意数量的卷。 另外k8s 中也提供了多种类型的 Volume 常规存储EmptyDir、HostPath 高级存储PV、PVC 配置存储ConfigMap、Secret 其他还有网络存储系统 NFS、CIFS等包括云服务商提供的、本地、分布式。 下边详细介绍下两种常规存储EmptyDir、HostPath。 EmptyDir 适用于临时缓存空间存储一些运行过程中的中继日志。其特点如下 当 Pod 指定到某个节点上时首先创建的是一个 EmptyDir 卷只要 Pod 在该节点上运行卷就一直存在 当 Pod 因为某些原因被从节点上删除时EmptyDir 卷中的数据也会永久删除 容器崩溃并不会导致 Pod 被从节点上移除所以容器崩溃时 EmptyDir 卷中的数据是安全的。 下边是一个绑定 EmptyDir 类型路径的 .yml 配置文件的示例 apiVersion: v1
kind: Pod
metadata:name: test-volume-emptydirnamespace: default
spec:containers:# 第一个容器 nginx- name: test-nginximage: nginx:1.20ports:- containerPort: 80volumeMounts: # 将 nginx-log-volume 挂在到 nginx 容器中对应的目录为 /var/log/nginx- name: test-log-volumemountPath: /var/log/nginx# 第二个容器 busybox- name: test-busyboximage: busybox:1.35.0 command: [/bin/sh,-c,tail -f /usr/local/test/access.log] # 容器启动后初始命令读取指定文件中内容volumeMounts: # 将 nginx-log-volume 挂在到 busybox 容器中对应的目录为 /logs- name: test-log-volumemountPath: /usr/local/test# 卷配置volumes: # 这里声明 volume 存储劵name 为 nginx-log-volume类型是 EmptyDir- name: test-log-volume # 【注意】两个容器配置的卷名需要和此处相同emptyDir: {} 由于 EmptyDir 创建的这个 Volume 是一个虚拟的路径所以当其销毁后Pod 中容器产生的数据也就随之销毁了即无法真正实现数据的落盘持久化。 HostPath 即主机挂载目录可以实现数据的落盘持久化。 HostPath 类型的磁盘就是挂在了主机的一个文件或者目录即容器和宿主机之间的文件共享机制。 通过配置 Volume 的 HostPath 类型我们可以指定一个位于宿主机上的文件或目录然后在 Pod 的配置中将这个目录以 Volume 的形式挂载到容器中的指定路径上。 根据使用场景的不同HostPath 又可以细分成多个类型 Directory 给定的目录路径必须存在 DirectoryOrCreate 如果给定路径不存在将根据需要在那里创建一个空目录 File 给定路径上必须存在对应文件 FileOrCreate 如果给定路径不存在将根据需要在那里创建一个空文件。 下边是一个绑定 Hostpath 类型路径的 .yml 配置文件的示例 apiVersion: v1
kind: Pod
metadata:name: hostpath-volume-testnamespace: default
spec:containers:- name: test-nginximage: nginx:1.20ports:- containerPort: 80volumeMounts: # 将 nginx-log-volume 挂在到 nginx 容器中对应的目录为 /var/log/nginx- name: test-log-volumemountPath: /var/log/nginx- name: test-busyboximage: busybox:1.35.0 command: [/bin/sh,-c,tail -f /usr/local/test/access.log] # 容器启动后初始命令读取指定文件中内容volumeMounts: # 将 nginx-log-volume 挂在到 busybox 容器中对应的目录为 /logs- name: test-log-volumemountPath: /usr/local/testvolumes: # 这里声明 volume 存储劵name 为 test-log-volume类型是 hostPath- name: test-log-volume # 【注意】两个容器配置的卷名需要和此处相同hostPath:path: /usr/local/testtype: DirectoryOrCreate # 如果给定路径不存在将根据需要在那里创建一个空目录 主要的配置和上面的 EmptyDir的案例中的差不多最后的 volumes 类型那里改成 hostPath 相关的参数。 参考k8s数据存储之Volume如何使用 - 开发技术 - 亿速云 1.4 Depeloyment、RC、RS RCReplicationController、RSReplicaSet。 在 k8s 中RS 和 RC 都是用于实现 Pod 的自动化管理。它们的主要作用如下 RC 是 k8s 集群中的核心概念之一它定义了一个期望的场景即确保指定数量的 Pod 副本始终在运行并且正在运行的 Pod 副本的数量等于用户指定的数量。 RS 则是一种更高级的 API 对象可视为是 RC 的增强版它提供了更多的灵活性和功能。例如RS 支持自动扩缩容、滚动更新等功能。 RS 和 RC 的主要区别在于选择器的支持。具体来说就是 RS 支持新的基于集合的选择器需求而 RC 仅支持一个选择器。 官方建议虽然 RS 可以独立使用但现在它主要被 Deployments 用作协调 Pod 的创建、删除和更新的机制。 Deployment 是一个更高级的 API 对象它与 RC 和 RS 的功能类似但提供了更多的灵活性和功能。例如Deployment 可以通过控制 RS 来实现自动扩缩容、滚动更新等功能。 当用户创建一个 Deployment 对象并描述一个期望的状态后Deployment 控制器会生成一个唯一的 RS让它负责管理 Pod 的生命周期。 虽然在实际的工作中Deployment 并不是直接控制着 Pod 的但是为了简化理解过程我们通常会认为 Deployment 是直接管理 Pod 的。 总的来说就是Deployment 是用于描述期望状态的对象而 RC 和 RS 则是用于实现这些期望状态的实际控制器。 1.5 Servicekube-proxy、IPVS、Cluster-IP 从前几节中介绍的可知k8s 集群中的每一个 Pod 都有自己的 IP 地址此时有同学可能会说有 IP 访问起来不就简单了其实不然。 因为在 k8s 中 Pod 不是持久性的摧毁重建将获得新的 IP客户端通过会变更 IP 来访问显然不合理。另外 Pod 还经常会通过多个副本来实现负载均衡客户端如何高效的访问哪个副本的问题也显现出来了。那么本章节将要介绍的 Service 对象应运而生。 如下图当我们通过 API 创建/修改 Service 对象时Endpoints 控制器的 Informer 机制监听到 Service 对象然后根据 Service 的配置的选择器创建一个 Endpoints 对象此对象将 Pod 的 IP、容器端口做记录并存储到 etcd这样 Service 只要看一下自己名下的 Endpoints 就可以知道所对应 Pod 信息了。 当一个服务的副本有多个时请求的流向控制也非常重要此时就用到 kube-proxy 对象了。 kube-proxy 是集群中每个 Node 上运行的网络代理实现 k8s 服务Service概念的一部分。它是一个用于处理单个主机子网划分并向外部世界公开的服务。它跨集群中的各种隔离网络将请求转发到正确的 Pod / 容器。kube-proxy 维护 Node 上的网络规则这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。 如下图kube-proxy 通过 Informer 知道了 Service、Endpoints 对象的创建然后把 Service 身上的 Cluster-IP 和端口以及端点信息拿出来创建 IPtable NAT 规则做转发或通过 IPVS 模块创建 VS 服务器这样经过 Cluster-IP 的流量都被转发到后端 Pod。 kube-proxy 有三种运行模式Userspace、IPtables 和 IPVS。 在 Userspace 模式下kube-proxy 通过观察 k8s 中的 Service 和 Endpoint 对象的变化来实现负载均衡。当有新的 Service 创建时kube-proxy 会创建相应的 NAT 规则并使用 IPtables 的 MARK/PREROUTING 链来实现对 Service 流量的转发。此模式不依赖于内核功能因此可移植性较好但是性能相对较差。 IPtables 模式中kube-proxy 利用 IPtables 强大的数据包处理和过滤能力实现 NAT 和负载均衡功能。IPtables 是 Linux 内核中的一个功能它能在核心数据包处理管线中使用 Hook 挂接一系列的规则。然而这种模式的主要问题是在服务多的时候会产生太多的 IPtables 规则这会影响查询效率。 IPVS 模式是 kube-proxy 的另一种运行方式它基于 Netfilter 实现传输层的负载均衡技术通常被称为第四层 LAN 交换。IPVS 集成在 LVSLinux Virtual Server中运行在主机上并在真实服务器集群前充当负载均衡器。从 k8s 的 1.8 版本开始kube-proxy 引入了 IPVS 模式。这种模式虽然与 IPtables 一样基于 Netfilter但 IPVS 采用 Hash 表而 IPtables 采用一条条的规则列表。因此当集群规模较大时IPVS 模式相比 IPtables 模式有更高的查询效率。 k8s 支持四种类型的 Service分别是 ClusterIP、NodePort、LoadBalancer 和 ExternalName。 ClusterIP 是默认和最常见的服务类型k8s 会为 ClusterIP 服务分配一个集群内部 IP 地址只能在集群内部访问适用于集群内的服务间通信比如应用程序的前端和后端组件之间的通信。 NodePort 则是将 Service 通过指定的 Node 上的端口暴露给外部访问任意一个 NodeIP:NodePort 都将路由到 ClusterIP。这种方式适用于需要在集群外进行业务访问的场景。 LoadBalancer 类型是在 NodePort 的基础上借助 CloudProvider 创建一个外部的负载均衡器并将请求转发到 NodeIP:NodePort此模式适用于云服务器上。 ExternalName 类型是将服务映射到 DNS 名称的方式转发到指定的域名例如通过 spec.externlName 参数指定这些服务。 参考k8s 理解Service工作原理 - 知乎 详解k8s 4种类型Service - 知乎 1.6 Master、Node k8s 里的 Master 指的是集群控制节点每一个 k8s 集群里都必须要有一个 Master 节点来负责整个集群的管理和控制基本上 k8s 的所有控制命令都发给它它来负责具体的执行过程。 通常Master 部署在一个独立的服务器上若想达到高可用性部署建议用 2~3 台服务器Master 也可以扩展副本数来获取更好的可用性和冗余。它是整个集群的“首脑 brain”如果宕机或者不可用那么对集群内容器应用的管理都将失效。 Master 节点上运行着以下三个关键进程 KubernetesAPIServer(kube-apiserver)提供了 HTTP Rest 接口的关键服务进程是 k8s 里所有资源的增、删、改、查等操作的唯一入口也是集群控制的入口进程。 KubernetesControllerManager(kube-controller-manager)k8s 里所有资源对象的自动化控制中心可以理解为资源对象的“大总管”。 KubernetesScheduler(kube-scheduler)负责资源调度Pod 调度的进程安排哪些服务的 Pod 运行在哪些节点上。 另外在 Master 节点上还需要启动一个 etcd 服务正如前面讲到的k8s 里的所有资源对象的数据全部是保存在 etcd 中的。 除了 Masterk8s 集群中的其他机器被称为 Node 节点在较早的版本中也被称为 Minion。 与 Master 一样Node 节点可以是一台物理主机或者是虚拟机。Node 节点才是 k8s 集群中的工作负载节点每个 Node 都会被 Master 分配一些应用程序服务以及云工作流在有些时候Master 节点上也会“安排”一些服务运行或者说是一些 Docker 容器当某个 Node 宕机时其上的工作负载会被 Master 自动转移到其他节点上去。 每个Node节点上都运行着以下一组关键进程 kubelet负责 Pod 对应的容器的创建、启停等任务同时与 Master 节点密切协作实现集群管理的基本功能。 kube-proxy实现 k8s 中 Service 的通信与负载均衡机制的重要组件。 DockerEnginedockerDocker 引擎负责本机的容器创建和管理工作。 Node 节点可以在运行期间动态增加到 k8s 集群中前提是这个节点上已经正确安装、配置和启动了上述关键进程。 在默认情况下kubelet 会向 Master 注册自己这也是 k8s 推荐的 Node 管理方式。一旦 Node 被纳入集群管理范围kubelet 进程就会定时向 Master 节点汇报自身的情报。例如操作系统、Docker 版本、机器的 CPU 和内存情况以及当前有哪些 Pod 在运行等这样 Master 可以获知每个 Node 的资源使用情况并实现高效均衡等资源调度策略。而某个 Node 超过指定时间不上报信息时会被 Master 判断为“失联”Node 的状态被标记为不可用Not Ready随后 Master 会触发“工作负载大转移”的自动流程。 kubectl get nodes // 查看集群中全部 Node
kubectl describe node xxx // 查看某个 Node 的详细信息 1.7 Ingress 在 k8s 中服务和 Pod 的 IP 地址仅可以在集群网络内部使用对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务在 k8s 中目前提供了三种方案NodePort、LoadBalancer、Ingress。
采用 NodePort 方式暴露服务面临问题是由于 NodePort 在每个节点上开启的端口服务一旦多起来会造成暴露端口量极其庞大而且难以维护。LoadBalancer 类型是在 NodePort 的基础上借助 CloudProvider 创建一个外部的负载均衡器并将请求转发到 NodeIP:NodePort缺点依然存在。
那能否使用一个 Nginx 直接在集群内进行转发呢众所周知Pod 与 Pod 之间是可以互相通信的而 Pod 是可以共享宿主机的网络名称空间的也就是说当在共享网络名称空间时Pod 上所监听的就是其上级 Node 的端口。简单的实现就是使用 DaemonSet 在每个 Node 上监听 80然后写好规则因为 Nginx 外面绑定了宿主机 80 端口就像 NodePort本身又在集群内那么向后直接转发到相应 Service IP 就行了。 如上面的方法采用 Nginx-Pod 似乎已经解决了问题但是其实这里面有一个很大缺陷当每次有新服务加入又该如何修改 Nginx 配置呢虽然使用 Nginx 可以通过虚拟主机域名进行区分不同的服务而每个服务通过 upstream 进行定义不同的负载均衡池再加上 location 进行负载均衡的反向代理在日常使用中只需要修改 nginx.conf 即可实现但是在 k8s 中这种方式的调度又成了问题。 假设后端的服务初始服务只有 ECshopB2C 开源商城系统后面增加了 BBSBulletin Board System 论坛和 Member会员服务那么又该如何将这两个服务加入到 Nginx-Pod 进行调度呢总不能每次手动改或者 Rolling Update 前端 Nginx Pod 吧此时 Ingress 出现了如果不算上面的 NginxIngress 包含两大组件Ingress Controller 和 Ingress。 Ingress 简单的理解就是你原来需要改 Nginx 配置然后配置各种域名对应哪个 Service现在把这个动作抽象出来变成一个 Ingress 对象你可以用 yaml 创建每次不要去改 Nginx 了直接改 yaml 然后创建/更新就行了那么问题来了”Nginx 该怎么处理” Ingress Controller 这东西就是解决“Nginx 的处理方式” 的Ingress Controoler 通过与 Kubernetes API 交互动态的去感知集群中 Ingress 规则变化然后读取他按照他自己模板生成一段 Nginx 配置再写到 Nginx Pod 里最后 reload 一下。 实际上Ingress 也是 Kubernetes API 的标准资源类型之一它其实就是一组基于 DNS 名称host或 URL 路径把请求转发到指定的 Service 资源的规则。用于将集群外部的请求流量转发到集群内部完成的服务发布。 需要明白的是Ingress 资源自身不能进行“流量穿透”仅仅是一组规则的集合这些集合规则还需要其他功能的辅助比如监听某套接字然后根据这些规则的匹配进行路由转发这些能够为 Ingress 资源监听套接字并将流量转发的组件就是 Ingress Controller。PSIngress 控制器不同于Deployment 控制器的是Ingress 控制器不直接运行为 kube-controller-manager 的一部分它仅仅是 Kubernetes 集群的一个附件类似于 CoreDNS需要在集群上单独部署。 文章转载自橙子家 原文链接https://www.cnblogs.com/hnzhengfy/p/k8s_concept.html 体验地址引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构