-
Docker 移除带来的潜在风险分析 工具链与生态兼容性 对于大量使用 Jenkins 等 CI/CD 工具的企业而言,原先基于 Docker 的镜像构建、推送和拉取流程可能需要重构。Jenkinsfile 中的 Docker 构建步骤需调整为兼容 containerd 的方式进行,否则可能造成流水线中断。 监控系统和其他依赖于 Docker API 的周边工具需要进行改造或更换,以适应新的容器运行时环境,这涉及到了大量的验证工作和可能的二次开发成本。 开发环境一致性 开发者们习惯了在本地使用 Docker 进行快速迭代和测试,移除 Docker 后,需要重新适应 containerd 或寻找兼容 Docker API 的替代方案,以保持开发环境与生产环境的一致性。 现有运维脚本失效 许多自动化脚本、运维命令和 Helm Chart 等资源文件可能直接引用了 Docker 命令或依赖于 Docker 的特定行为,这些都需要逐步审查和适配。 升集群时手动保留 Docker 特性的成本分析 运维复杂度增加 需要在 Kubernetes 集群中手动集成第三方插件或其他兼容方案以模拟 Docker 的运行时环境,这要求运维团队具备更高的技术水平和对 Kubernetes 内部机制的深入了解。 需要密切关注 Kubernetes 更新与 Docker 兼容性之间的差异,每次升级 Kubernetes 都可能导致与 Docker 集成的部分出现问题,需要额外的时间和精力进行维护和调试。 集群规模操作成本剧增 假设面临如 100 个节点的集群时,每个节点上的容器运行时切换都需要单独进行,这意味着至少需要分别在 100 个节点上执行启停容器运行时的操作,耗费巨大的人力和时间成本。 对于大型集群,这种逐一操作的管理模式极其低效且容易出错,可能需要编写复杂的脚本或者使用批量管理工具,进一步增加实施难度。 测试验证与恢复预案 若操作过程中遇到问题,需要有完备的回滚策略和恢复预案,准备应对可能发生的各类异常状况,以防业务长时间受到影响。 总结: 因此,在 Kubernetes 1.24 之后,手动保留 Docker 特性并进行大规模节点运行时切换是一项极具挑战的任务,不仅会导致高昂的操作成本,还可能带来较大的业务风险。相比之下,寻求平滑过渡和兼容方案(如 KubeKey)成为更具性价比的选择。 什么是 Kubekey KubeKey 是一个开源的轻量级工具,用于部署 Kubernetes 集群。它提供了一种灵活、快速、方便的方式来安装 Kubernetes/K3s、Kubernetes/K3s 和 KubeSphere,以及相关的云原生附加组件。它也是扩展和升级集群的有效工具。此外,KubeKey 还支持定制离线包(artifact),方便用户在离线环境下快速部署集群。 为什么选择 Kubekey? KubeKey 由 Go 语言开发,使用便捷、轻量,支持多种主流 Linux 发行版。KubeKey 支持多种集群部署模式,例如 All-in-One、多节点、高可用以及离线集群部署。KubeKey 也支持支持快速构建离线安装包,加速离线交付场景下的集群交付效率。KubeKey 实现多节点并行安装,且利用 Kubeadm 对集群和节点进行初始化,极大地节省了集群部署时间,同时也遵循了 Kubernetes 社区主流集群部署方法。KubeKey 提供内置高可用模式,支持一键部署高可用 Kubernetes 集群。 升级实操 etcd 数据备份 ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \ --cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> \ snapshot save <backup-file-location> 1 2 下载 Kubekey 工具 版本:v3.1.0-rc.2 (这个版本当前是稳定已测,即将发布 v3.1.0)。 export KKZONE=cn 支持手动下载:https://github.com/kubesphere/kubekey/releases。 curl -sfL https://get-kk.kubesphere.io | sh - 检查当前集群状态 kubectl get node -o wide 准备集群配置文件 如果创建集群时的配置文件存在,本步骤可跳过。 创建当前集群配置 ./kk create config [--with-kubernetes version] [(-f | --filename) path] 填入真实集群信息 修改 configmap 修改 kubeadm-config 注意:确保配置中的 featuregate 在新版本中没有被移除。 kubectl -n kube-system edit cm kubeadm-config 修改 kubelet-config-1.23 注意:确保配置中的 featuregate 在新版本中没有被移除。 kubectl -n kube-system edit cm kubelet-config-1.23 开始升级 ./kk upgrade -f sample.yaml --with-kubernetes v1.24.17 --skip-dependency-check 验证集群版本 kubectl get node -A -o wide 验证容器运行时 kubectl get nodes -o json | jq '.items[].status.nodeInfo.containerRuntimeVersion' 结尾彩蛋 正如我们在这篇文章中所揭示的,Kubernetes 1.24 版本及其后续迭代虽逐步摒弃了对 Docker 的直接依赖,但这并不意味着我们必须舍弃熟悉的 Docker 工作流。通过 KubeKey 这样的强大工具,我们可以享受到 Kubernetes 最新版本的种种改进,同时还能优雅地保留 Docker 的某些关键特性,让升级之路变得更为顺畅。勇敢拥抱变化,善用工具的力量,每一次的技术升级都将成为我们打造高效、稳定、可扩展基础设施的宝贵经验。 本文由博客一文多发平台 OpenWrite 发布! ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/zpf17671624050/article/details/137555545
-
kubelet 是 Kubernetes 中主要节点组件,执行许多关键任务,特别是:用 kube-apiserver 注册节点。监视 kube-apiserver 中已经调度的 Pod,通知容器运行时在调度新 Pod 之后重新启动容器。监视运行中的容器并将其状态报告给 kube-apiserver。执行 liveness 探针并在容器运行失败后重新启动容器。运行由 kubelet 直接管理的静态 Pod。与 Core Metrics Pipeline 和容器运行时进行交互以收集容器和节点度量。本文中要讨论的是 kubelet 另一个重要功能:当节点资源耗尽时,“主节点代理”驱逐 Pod 的能力。当磁盘、RAM 或 CPU 等计算资源不足时,kubelet 可以极大维护节点稳定性。对于 Kubernetes 管理员而言,了解配置资源外的处理很必要,可以保持节点资源灵活性以及系统的整体容错性和关键系统进程的稳定性。kubelet 如何确定资源不足?kubelet 可以从节点上驱逐工作负载,以释放资源来处理其他 Pod 或系统任务,例如容器运行时或 kubelet 本身,但 kubelet 是如何确定资源不足的?其实 kubelet 是通过 eviction signal(驱逐信号)和 eviction threshold(驱逐阈值)确定何时回收资源。驱逐信号是系统资源(如内存或存储)的当前容量。驱逐阈值则是 kubelet 维护的资源最小值。换句话说,每个驱逐信号都与某个驱逐阈值相关联,该驱逐阈值会告诉 kubelet 何时开始回收资源。目前,kubelet 支持以下驱逐信号:memory.available:描述集群内存状态的信号。内存的默认驱逐阈值为 100Mi。换句话说,当内存下降到 100Mi 时,kubelet 就会开始驱逐 Pod。nodefs.available:nodefs 是 kubelet 用于卷、守护进程日志等的文件系统。默认情况下,如果 nodefs.available<10%,kubelet 将开始回收节点资源。nodefs.inodesFree:描述 nodefs 索引节点内存状态的信号。默认情况下,如果 nodefs.inodesFree<5%,kubelet 将开始驱逐工作负载。imagefs.available—imagefs:文件系统是容器运行时使用的可选文件系统,用于存储容器镜像和容器可写层。默认情况下,如果 imagefs.available<15%,kubelet 将开始逐出工作负载。imagefs.inodesFree:索引 imagefs 节点内存的状态。它没有默认驱逐阈值。上述驱逐阈值都是合理的默认值。用户可以通过在 kubelet binary 上设置适当的 flag 来配置其自定义驱逐阈值。这些用户定义的阈值可以更改默认的 kubelet 驱逐行为。目前,Kubernetes 支持硬驱和软驱逐阈值。如果达到硬驱逐阈值,kubelet 将立即开始回收资源,而没有任何宽限期。软驱逐阈值则会包含用户定义的宽限期。在超过宽限期前,kubelet 不会回收与驱逐信号关联的资源。我们可以使用 kubelet binary 上的 --eviction-hardkubelet flag 定义硬驱逐阈值。例如,kubelet —-eviction-hard=memory.available<1Gi 当节点的 memory.available 大小低于 1Gi 时,kubelet 将开始回收资源。如果要在驱逐之前允许宽限期,可以将 —-eviction-soft 与 —-eviction-soft-grace-period 结合使用。例如,kubelet —-eviction-soft=memory.available<2Gi 以及 kubelet —-eviction-soft-grace-period=1m30s 能将 90 秒的驱逐阈值保持在触发驱逐前。用户还可以通过设置 —-eviction-max-pod-grace-period 秒数来指定允许的最大宽限期。kubelet 如何回收资源?kubelet 会通过终端用户的 Pod 来回收资源,但它首先会尝试回收未使用的容器镜像或已经终止的 Pod 这类资源。如果节点具有特定 imagefs 文件系统和 nodefs 文件系统,kubelet 会以不同的方式回收节点资源。当 nodefs 达到驱逐阈值时,kubelet 会删除所有已经终止的 Pod 及其容器。相应地,如果 imagefs 达到驱逐阈值,kubelet 会删除所有未使用的容器镜像。如果没使用 imagefs,kubelet 将首先删除所有已经终止的 Pod 及其容器,然后删除所有未使用的镜像。有关这一过程的详细信息,请参阅 Kubernetes 文档。文档信息:https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/如果回收容器镜像、已经终止的 Pod 和其他资源没有解决资源匮乏问题,kubelet 最后会开始删除终端用户的 Pod。kubelet 根据 Pod 的 QoS 类、Pod 优先级和许多其他参数来决定回收哪个终端用户的 Pod。这里先介绍一下 Kubernetes 中的基本 QoS 类。Guaranteed pod 是在所有容器中为 CPU 和 RAM 设置资源限制(limit)和请求(request)的 Pod,限制和请求必须一致。Burstable Pod 是为一个或多个容器中为资源(例如CPU、RAM)设置请求和限制的容器,限制和请求不用明确指定。Best-Effort Pod 是未设置资源请求和限制的 Pod。该 QoS 由 kubelet 在其 Pod 排序方案中隐式使用。通常,kubelet 使用以下规则对驱逐进行排序:Pod 是否已超出其资源请求。在 Kubernetes 中,Pod 是根据其请求(request)而不是限制(limit)进行调度的。因此,要保证所有容器和 Pod 都具有它们所请求的 RAM、CPU 数量。但是,如果未设置限制,并且 Pod 超出了其资源请求,那么在保证 Pod 或某些系统任务需要受限资源的情况下,可以终止或限制该 Pod。在某些情况下,某些消耗少于要求量的 Pod 也会被杀死。例如,当系统任务内存严重不足并且没有较低优先级的 Pod 被回收时。按 Pod 优先级。如果没有 Pod 超出其请求,kubelet 会检查 Pod Priority。它将尝试先驱逐优先级较低的 Pod。相对于 Pod 的资源请求消耗量计算资源(例如 RAM)。根据这些规则,kubelet 会按以下顺序逐出终端用户的 Pod:首先驱逐是受限资源的使用超出了请求的 Best-Effort 和 Burstable Pod。如果有多个这样的 Pod,kubelet 会按优先级对它们进行排序。最后是资源低于请求的 Guaranteed 和 Burstable Pod。如果某些系统任务(如 kubelet 或 Docker)需要资源,并且节点上 Best-Effort Pod,kubelet 可以驱逐消耗量低于请求的 Guaranteed Pod。在这种情况下,它会以最低优先级驱逐 Guaranteed 和 Burstable Pod。最低驱逐回收如果 kubelet 回收的资源量很小,系统可能反复达到驱逐阈值,这可能导致会不良的调度决策和 Pod 频繁驱逐。为了避免这种情况,用户可以使用 kubelet binary —-eviction-minimum-reclaimkubelet 的 flag 来设置每个资源的最小回收级别。例如:—-eviction-minimum-reclaim 设置确保 nodefs 回收后的最小可用存储量为 3Gi,imagefs 最小可用存储量为 202 Gi。因此,以上配置可确保系统具有足够的可用资源,以避免频繁达到驱逐阈值。资源不足以处理配置还会遇到另一个问题:节点状态(condition)的波动。当 kubelet 收到驱逐信号后,后者会映射到相应的节点状态。例如,memory.available 达到驱逐阈值时,kubelet 会将 MemoryPressure 节点状态分配给该节点。此状态与相应的污点(taint) 关联,该污点可防止在具有 MemoryPressure 节点状态的节点上调度新 Pod。但如果使用了具有较长宽限期的软驱逐阈值,节点条件会在宽限期 true 和 false 之间振荡。这可能导致调度计划的不确定性。为了避免这种情况,我们可以在 kubelet 上使用 —-eviction-pressure-transition-period,以定义 kubelet 在满足驱逐条件之前必须等待多长时间。简单 Out-of-Resource 处理方案以下将说明如何处理 K8s 集群配置资源不足。想象一个简单的场景,仅考虑节点 RAM。假设节点的内存容量为 10Gi RAM。我们希望为系统守护进程(例如内核、kubelet、Docker 等)保留 10% 的总内存并以 95% 的内存利用率驱逐 Pod。使用默认驱逐阈值启动 kubelet,并且没有 system-reserved 设置。我们需要在 kubelet 上显式设置几个 flag:虽然直观上应该将 system-reserved 设置为 1.5Gi,但实际将其设置为 10%=1Gi。System reserved 应包括驱逐阈值(1Gi+0.5Gi)覆盖的内存量。根据配置 K8s 集群的方式,可以不同地设置 kubelet flag。例如,如果计划使用 Kops 设置 K8s 集群,请运行 kops edit cluster $NAME 以使用集群配置打开编辑器。如果是 VI 辑器,则按 “I” 进入插入模式以编辑文件。上述资源不足处理策略的 kubelet flag 应如下所示:结论本文我们讨论了一些有用的 Kubernetes 管理实践,用于 Kubernetes 中自定义 kubelet 资源不足管理。该平台允许管理员设置自定义驱逐阈值和驱逐宽限期,能决定哪些条件对节点稳定性有用。Kubernetes 附带了资源不足管理默认设置,在将驱逐阈值设置得太高或将驱逐宽限期设置得太长时,要保持谨慎。文章来源:K8sMeetup社区译者:Bach
-
容器所遵循的共享内核模型架构同样会引入安全风险,评判其安全性能的好坏的因素在于主机操作系统能否对容器进行隔离一些商业产品引入了容器安全框架,能够在运行时监视容器并实施动态的控制策略。容器安全服务(Container Security Service, CSS)提供容器资产管理、镜像安全、运行时入侵检测等安全服务,保障容器从镜像生成、存储到运行时的全生命周期,帮助企业构建容器安全防护体系。Docker 具有一下优点:硬件成本低,虚拟化硬件损耗也较低,性能好;可以做到运行环境快速部署,启动极快,伸缩有弹性;支持打包管理,保证一致性;动态调度迁移成本低等。在本次尝试中从Ubuntu 下搭建 Dockers、 安装 Kubnernetes,并且进行了安全测试。一、VMware的安装方法一:去官网下载,然后去网上找相关的许可证方法二:http://mp.weixin.qq.com/s?__biz=MzIyNjU2NzIxNQ==&mid=2247485198&idx=1&sn=fb2461b340e6dd31895d0993ad72e4c4&chksm=e86f324edf18bb58d6f0f7cbd9d30caef8f2b6899a12f9303f9c83cc961f7900058373a1f36e&mpshare=1&scene=23&srcid=0222CQ5598w1CNpqZW61vgzL&sharer_sharetime=1645512785274&sharer_shareid=d91c96e983bc83094af7577cae27fc84#rd二、Ubuntu的安装清华镜像源清华大学开源软件镜像站 | Tsinghua Open Source Mirror三、Ubuntu虚拟机的创建考虑到以后运行服务器时的速度,建议在安装时将内存尽量选大一点,电脑允许的话选择4096MB或者更高吧。磁盘大小的话选择40G或者更大为了操作便捷,建议再安装一下vmware tools,可以参考下面那个链接中的方式安装,也可以自己百度一些其他的博客。关于如何知道是否安装成功vmware tools,可以尝试将自己主机中的一个txt文档拖拽进 Ubuntu中(拖进某个文件夹,直接拖到桌面好像不行),如果可以的话说明vmware tools已经安装好了。四:分析1.IAAS,PAAS,SAAS.如果给云计算服务分层的话,IaaS(Infrastructure as a Service,基础架构即服务)可以被看做第一层,有时候也叫做 Hardware-as-a-Service。该层可以提供给消费者的服务是对所有计算基础设施的利用,包括处理 CPU、内存、存储、网络和其它基本的计算资源,用户能够部署和运行任意软件,包括操作系统和应用程序。PaaS(Platform-as-a-Service,平台即服务)可以被看做第二层,某些时候也叫做中间件。该层可以为用户提供各种开发语36言和工具开发环境,让用户不需要在本地安装各种平台。SaaS(Software-as-a-service,软件即服务)可以被看做第三层,这一层是与用户接触最多的一层,大多数用户是通过网页浏览器来接入。该层可以提供运行在云计算基础设施上的应用程序,让用户在各种设备上通过客户端界面访问,如浏览器。消费者不需要管理或控制任何云计算基础设施,包括网络、服务器、操作系统、存储等。在这里,我拿做饭来举例对比这三种云服务计算。IaaS 就是提供了厨房、锅碗瓢盆等厨具、餐具等等的地方,但还需要用户购买蔬菜调料来做出适合自己的饭菜,如 Amazon、华为云、Mircrosoft 等等2. K8S 在华为云的对比根据查找浏览到的内容,对边缘 k8s 在华为云,华为云收费维度按照 App 数量收费,管理集群费用为 0,节点 Agent资源消耗较小,不兼容 Kubernetes 的 API,不提供 kubectl/命令行,不能远程登录容器调试,但有消息管理和端设备管理。五、 启动 Vulhub 搭建漏洞环境1. 让 windows10 和 docker 通讯如果此时在宿主机中 ping Docker 容器是 ping 不同的,因为在宿主机上没有通往 192.168.150.2 网络的路由,宿主机会将发往 192.168.150.2 网络的数据发往默认路由,这样就无法到达容器。具体操作如下:Cmd: route add -p 172.17.0.0 mask 255.255.255.0 192.168.150.131 //-p 表示永久添加查看添加的路由:route print 172.17.0.0 255.255.0.0 192.168.2.131 192.168.2.200 36docker容器中下载vulhub漏洞环境,Pip安装下载 docker 漏洞环境:VulhubVulhub 是一个面向大众的开源漏洞靶场,是基于 docker 和 docker-compose的漏洞环境集合,简单执行两条命令即可编译、运行一个完整的漏洞靶场镜像。a) 搭建漏洞环境git clone https://github.com/vulhub/vulhub.githttps://github.com/vulhub/vulhub/archive/master.zip//直接下载地址b) 进入 vulhub-master/weblogic/CVE-2017-10271 目录c) 安装漏洞环境docker-compose up -ddocker ps //查看运行服务端口///////////待更新中
-
前言 通过 《容器集群管理工具 Docker Swarm》可以知道,在部署、调度、扩展和管理较多的容器时,如果有一个工具帮忙做这些事,那无疑会大大提高工作效率了。那 Docker Swarm 就是这样的工具,同样 Kubernetes(简称k8s)也是这样的一个工具,相对于 Docker Swarm, Kubernetes 生态比较庞大,有更多的支持、服务和工具。至于用哪个,萝卜青菜各有所爱吧。 本文对 Kubernetes 的概念、常用命令、部署脚本进行简单介绍,更多详细内容可以前往 Kubernetes官网 或 Kuboard 官网 (推荐)进行了解。 Kuboard 是一款免费的 Kubernetes 图形化管理工具,相较于 Kubernetes Dashboard 的管理界面功能和体验友好的多。当然也有其他的 Kubernetes 图形化管理工具 ,比如 Kubesphere。 老样子下面还有投票,一起参与进来吧👍 Kubernetes 集群安装 Kubernetes官网 和 Kuboard 官网 都有详细介绍,这里不做过多赘述,由于官网中的下载地址为外网,网络不稳定,推荐 Kuboard 的安装教程。 Kubernetes 功能 Kubernetes 除部署外还支持自动伸缩、故障自愈、服务发现和负载均衡、金丝雀多种部署模式以及监控等功能,可以非常健壮地运行分布式系统。 服务发现和负载均衡:通过 Kubernetes 部署,同一应用的容器可以实现负载均衡的效果,也不用担心容器的 IP 的变动。 自动伸缩:Kubernetes会根据部署时的声明对容器的实际运行状态进行调整。比如,设置最小及最大副本数量,根据 cpu 使用率进行动态伸缩。 故障自愈:Kubernetes 可以重启已经停机的容器;替换、kill 那些不满足自定义健康检查条件的容器。 金丝雀发布:通过对 Pod 打相同的 Label,可以请求到同一应用的不同版本,达到灰度效果。 Kubernetes 核心概念 很多初学者在入门 Kubernetes 时,都会被各种名词所困扰,比如:Pod、Deployment、Service,可以通过下图进行理解。 Kubernetes Master:集群中的主节点,起部署、调度、管理容器等作用,所有操作在此节点。 Node :集群中的工作节点,相当于一个物理机或虚拟机。 Pod : 最小调度的单位,可以承载多个 Docker 容器,可以理解成容器的“容器”。 Service :同 Docker Swarm 中的 Service,可以起到相同 Pod 的负载作用,并且同 Service 中的 Pod 可以相互通信。 Label:为 Pod 打标签,可以起到分流、金丝雀部署的效果或者指派开发、测试、生产环境。 Deployment:Deployment 指示 Kubernetes 如何创建和更新应用程序的实例,这个实例就是被包含在 Pod 中的容器。 Kubernetes 部署应用 so,如何部署一个应用,首先要声明一个 Deployment 脚本,在 Kubernetes 集群中发布 Deployment 后,master 节点将应用程序实例调度到集群中的具体的节点上。 发布部署脚本 这里创建一个部署文件 nginx-deployment.yaml,内容如下: apiVersion: apps/v1 #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本 kind: Deployment #配置的类型,部署是 Deployment metadata: #译名为元数据,即 Deployment 的一些基本属性和信息 name: nginx-deployment #Deployment 的名称 labels: #标签 app: nginx #为该Deployment设置key为app,value为nginx的标签 spec: #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用 replicas: 1 #replicas 副本集应该维护几个 Pod 副本(实例),这里指使用该Deployment创建一个应用程序实例, selector: #标签选择器,与上面的标签共同作用 matchLabels: #选择包含标签app:nginx的资源 app: nginx template: #这是选择或创建的Pod的模板 metadata: #Pod的元数据 labels: #Pod的标签,上面的selector即选择包含标签app:nginx的Pod app: nginx spec: #期望Pod实现的功能(即在pod中部署) containers: #生成container,与docker中的container是同一种 - name: nginx #container的名称 image: nginx:1.7.9 #使用镜像nginx:1.7.9创建container,该container默认80端口可访问 执行 kubectl apply -f nginx-deployment.yaml 进行部署之后,通过 kubectl get pods 查看部署情况。 发布服务 应用在发布后只能在集群内部进行访问,且需要获得容器的 IP,如何通过节点 IP 即可访问服务?Kubernetes 中的 Service 提供了这样的功能,且 Service 提供了 Pods(容器组)的负载均衡。 为 Nginx Deployment 创建一个 Service 脚本 nginx-service.yaml,内容如下: apiVersion: v1 kind: Service #配置的类型,服务是 Service metadata: name: nginx-service #Service 的名称 spec: #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问 selector: #标签选择器 app: nginx #选择包含标签 app:nginx 的 Pod ports: - name: nginx-port #端口的名字 protocol: TCP #协议类型 TCP/UDP port: 80 #集群内的其他容器组可通过 80 端口访问 Service nodePort: 32600 #通过任意节点的 32600 端口访问 Service targetPort: 80 #将请求转发到匹配 Pod 的 80 端口 type: NodePort # Serive的类型,ClusterIP(默认)/NodePort/LoaderBalancer 执行 kubectl apply -f nginx-service.yaml 进行部署之后,就可以通过集群中<任意节点的 IP>:32600 访问服务。 使用 Ingress Ingress 可以将集群内部的 Service 通过 HTTP/HTTPS 方式暴露到集群外部,并通过规则定义 HTTP/HTTPS 的路由。 为 Nginx Service 创建一个 Service 脚本 nginx-ingress.yaml,内容如下: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress # Ingress 的名字,仅用于标识 spec: rules: # Ingress 中定义 L7 路由规则 - host: demo.com # 根据 virtual hostname 进行路由(请使用您自己的域名) http: paths: # 按路径进行路由 - path: / backend: serviceName: nginx-service # 指定后端的 Service 为之前创建的 nginx-service servicePort: 80 配置自动伸缩 Kubernetes 中 Horizontal Pod Autoscaler 根据观察到的 CPU 利用率(或某些由应用程序提供的指标)自动调整 Pod 的数量。 以文中的 nginx-deployment 为例子,部署脚本中对其进行资源限制,发布后创建自动伸缩指令,脚本内容如下: apiVersion: apps/v1 #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本 kind: Deployment #配置的类型,部署是 Deployment metadata: #译名为元数据,即 Deployment 的一些基本属性和信息 name: nginx-deployment #Deployment 的名称 labels: #标签 app: nginx #为该Deployment设置key为app,value为nginx的标签 spec: #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用 replicas: 1 #replicas 副本集应该维护几个 Pod 副本(实例),这里指使用该Deployment创建一个应用程序实例, selector: #标签选择器,与上面的标签共同作用 matchLabels: #选择包含标签app:nginx的资源 app: nginx template: #这是选择或创建的Pod的模板 metadata: #Pod的元数据 labels: #Pod的标签,上面的selector即选择包含标签app:nginx的Pod app: nginx spec: #期望Pod实现的功能(即在pod中部署) containers: #生成container,与docker中的container是同一种 - name: nginx #container的名称 image: nginx:1.7.9 #使用镜像nginx:1.7.9创建container,该container默认80端口可访问 resources: limits: cpu: 1000m # 该容器使用的cpu资源不能超过1核 requests: cpu: 500m # 该容器最少使用的cpu资源为0.5核 发布后执行自动伸缩指令,这条指令的意思是 nginx-deployment 在 1 到 10 个副本之间伸缩,通过增加或减少 Deployment 的副本数,使得所有 Pod 的平均 CPU 利用率维持在 50% 左右。 kubectl autoscale deployment nginx-deployment --cpu-percent=50 --min=1 --max=10 Kubernetes 常用命令 # 部署资源 kubectl apply -f # 删除部署资源 kubectl delete -f # 查看 Deployment kubectl get deployments # 查看 service kubectl get service # 查看 Pod kubectl get pods #获取类型为Node的资源列表 kubectl get nodes #查看Pod的信息 kubectl describe pod #查看Deployment的信息 kubectl describe deployment #查看Pod内的容器打印的日志 kubectl logs -f #在Pod中运行bash kubectl exec -it pod-xxxxxx /bin/bash #查看名称空间 kubectl get namespaces #查看名称空间的概要信息 kubectl describe namespaces #创建命名空间 kubectl create namespace #删除命名空间 kubectl delete namespace #切换命名空间 kubectl config use-context #查看当前命名空间 kubectl config current-context Kubernetes 故障排查 在Kubernetes中进行故障排除可能是一项艰巨的任务,从下至上解决问题:从Pod开始,然后通过Service和Ingress向上移动堆栈。可以参考下图:Deployment 故障排除图解。 ———————————————— 版权声明:本文为CSDN博主「叫我二蛋」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_28314431/article/details/131207231
-
一、Kubernetes 简介 1 什么是 Kubernetes Kubernetes是由Google开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序的平台。Kubernetes充分利用了云计算和容器化技术,可以大幅简化应用程序的开发、部署和运行过程。 2 Kubernetes 的优势 Kubernetes的优势主要包括以下几点: 高可用性:Kubernetes可以在多个地理位置和云平台上运行,确保高可用性和业务连续性。 易于扩展:Kubernetes通过添加/删除节点进行扩展,从而更好地满足业务需求,还可以自动进行负载和流量管理。 便捷的部署管理:Kubernetes可以帮助用户轻松地创建和管理容器镜像、部署容器应用程序,并释放资源。 自动化:因为 Kubernetes 是一个自动化的平台,它可以自动管理负载均衡、扩展、滚动更新、健康检查等任务,从而释放更多时间来关注核心业务。 可扩展的生态系统:Kubernetes具有丰富的插件、应用程序、工具和社区支持,可以为用户提供更加丰富和可扩展的生态系统。 3 Kubernetes 的应用场景 Kubernetes主要适用于以下几个场景: 云原生应用程序:使用Kubernetes可以轻松地部署和管理云原生应用程序,提高开发效率和应用程序的可靠性。 DevOps:Kubernetes可以帮助开发团队更快更安全地将应用程序部署到生产环境。 分布式计算和分布式数据存储、处理:使用Kubernetes可以帮助用户轻松地搭建分布式计算和数据存储集群,从而提高大数据处理的效率。 容器构建和线上部署管理:通过Kubernetes可以方便地构建和管理容器镜像,并进行线上部署和管理。 二、Kubernetes 架构 1 Kubernetes 架构概述 Kubernetes是一个分布式系统,它的核心是将容器化的应用程序分配到一组机器上,并管理它们的生命周期,从而可以高效、稳定地运行应用程序。 Kubernetes的架构支持将一个容器化的应用程序部署在一个节点上,也支持它跨多个节点和多台机器部署。 2 Kubernetes 架构组件介绍 2.1 控制面板组件 控制面板组件是 Kubernetes 系统的核心,用于管理整个系统。其中包括kube-apiserver,etcd,kube-controller-manager和kube-scheduler等组件。这些组件都是通过API Server进行交互,从而处理集群中的工作。 2.2 API Server API Server是Kubernetes 提供的一种RESTful API,是Kubernetes系统的中心组件。它是 Kubernetes 控制面板的前端组件,用于处理集群中的所有请求并将请求转发给正确的组件,以便它们可以协同工作。 2.3 etcd etcd是Kubernetes系统采用的数据存储系统,用于存储集群中的配置和状态信息等。etcd是一个高可用的分布式键值存储系统,可以确保在整个系统中保持一致的状态。 2.4 kubelet kubelet是每台机器上运行的代理程序,它的任务是对Pod进行创建、调度和维护。kubelet还负责与Control Plane交互,从而接收集群中的任务和工作。 2.5 kube-proxy kube-proxy是在每个节点上运行的网络代理程序,它负责为Pod对象提供服务发现和负载均衡功能。kube-proxy通过传递请求并根据规则将请求路由到正确的Pod,从而将请求从一个服务端口路由到相应的Pod。 2.6 CNI 插件 CNI(容器网络接口)插件是Kubernetes中用于管理容器网络的插件系统。CNI插件为Kubernetes提供支持,可以为Kubernetes管理的每个Pod对象分配IP地址和网络。CNI插件的使用使得Kubernetes的网络模型非常灵活。 2.7 容器运行时 容器运行时是Kubernetes中用于运行容器的组件,支持Docker,rkt等多种容器运行时。Kubernetes提供了一个容器运行时接口,从而可以很容易地切换到其他容器运行时。容器运行时支持管理容器的启动、停止、暂停等操作,实现了容器级别的资源管理和隔离。 三、Kubernetes 应用管理 在 Kubernetes 中应用程序通过 Pod、Deployment、StatefulSet、DaemonSet 和 Job 等模型进行管理。本文将介绍这些模型的概念、使用方法以及注意事项,以帮助您更好地理解和使用 Kubernetes。 1 Pod 概述 1.1 Pod 概念 Pod 是 Kubernetes 中最基本的调度单位,也是容器化的最小单位。它是由一个或多个紧密相连的容器组成的,这些容器共享同一个 IP 地址和网络命名空间,可以共享访问相同的存储卷和主机上的资源。Pod 是 Kubernetes 进行调度和管理的基本对象,一个 Pod 实例在一个节点上只会运行一次。 1.2 Pod 的生命周期 在 Kubernetes 中一个 Pod 实例的生命周期包括以下几个阶段: 创建阶段:Kubernetes API server 创建并初始化 Pod,根据 Pod 中的容器规范创建容器,并为 Pod 设置状态。 运行阶段:Pod 中的容器被初始化后,就开始运行了。在运行过程中,Kubernetes会对容器的运行状态进行监控,如容器是否运行正常,或者容器是否已经退出。 容器异常:如果 Pod 中的容器异常终止,Kubernetes 将根据定义的容器重启策略来决定是否重新启动容器,或者终止 Pod 实例。 删除阶段:当 Pod 不再需要时,可以通过 Kubernetes API 删除 Pod 实例。 2 Kubernetes 模型简介 Kubernetes 提供多种模型用于部署和管理应用程序,包括 Deployment、StatefulSet、DaemonSet 和 Job 等 2.1 Deployment 模型 Deployment 是 Kubernetes 最常用的模型之一,用于部署和更新应用程序。Deployment 可以使用 ReplicaSet 和 Pod 来进行管理,实现应用程序的水平伸缩和升级。创建一个 Deployment,需要定义一个描述 Deployment 的 YAML 文件,下面是一个简单的 Nginx 部署示例: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 该 YAML 文件定义了一个名为 nginx-deployment 的 Deployment 对象,该对象将使用 nginx:1.7.9 镜像来运行一个名为 nginx 的容器。该 Deployment 将会启动 3 个 Pod 进程,每个 Pod 进程都会包含一个 nginx 容器。 2.2 StatefulSet 模型 StatefulSet 用于部署有状态应用程序它能够提供有序的 Pod 管理和服务发现,保证应用程序在多个 Pod 实例之间的稳定性。以下是一个 StatefulSet 的 YAML 文件示例: apiVersion: apps/v1 kind: StatefulSet metadata: name: my-statefulset spec: selector: matchLabels: app: my-app serviceName: my-service replicas: 3 template: metadata: labels: app: my-app spec: containers: - name: my-pod image: my-image ports: - containerPort: 8181 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 在上述 YAML 文件中定义了一个名为 my-statefulset 的 StatefulSet 对象,它使用 my-image 镜像来运行一个名为 my-pod 的容器。该 StatefulSet 对象将会启动 3 个 Pod 进程,并为每个 Pod 进程生成一个唯一的稳定标识符。 2.3 DaemonSet 模型 DaemonSet 用于部署在集群中每个节点上运行的守护进程。DaemonSet 可以确保在每个节点上都有一个 Pod 实例,从而实现节点级别的服务发现和监控。以下是一个 DaemonSet 的 YAML 文件示例: apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd spec: selector: matchLabels: app: fluentd template: metadata: labels: app: fluentd spec: containers: - name: fluentd image: fluentd:v1.0.2 ports: - containerPort: 24224 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 在上述 YAML 文件中定义了一个名为 fluentd 的 DaemonSet 对象,它使用 fluentd:v1.0.2 镜像来运行一个名为 fluentd 的容器。每个节点上都会运行一个 Pod 进程,每个 Pod 进程都包含一个 fluentd 容器 2.4 Job 模型 Job 用于周期性地执行批处理任务可以在 Kubernetes 中实现一次性任务和定时任务。以下是一个 Job 的 YAML 文件示例: apiVersion: batch/v1 kind: Job metadata: name: my-job spec: template: metadata: name: my-job spec: restartPolicy: OnFailure containers: - name: my-job-container image: my-image command: ["/bin/sh", "-c", "echo hello; sleep 30; echo world"] backoffLimit: 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 在上述 YAML 文件中定义了一个名为 my-job 的 Job 对象,它使用 my-image 镜像来运行一个名为 my-job-container 的容器。该容器将会执行命令 echo hello; sleep 30; echo world 3 Kubernetes 配置管理 Kubernetes 提供 ConfigMap 和 Secret 两种机制用于注入配置信息和敏感数据。在使用这些机制时可以将应用程序的配置和密钥集中存储在 Kubernetes 中,方便进行管理和更新 3.1 ConfigMap ConfigMap 可以用于以配置文件的形式将应用程序的相关配置信息注入到 Pod 中。 ConfigMap 配置信息可以被多个 Pod 共享,从而方便进行集中式配置管理和更新维护。 以下是一个 ConfigMap 的 YAML 文件示例: apiVersion: v1 kind: ConfigMap metadata: name: my-config data: database.properties: | database.url=jdbc:mysql://127.0.0.1:3306/test database.username=test database.password=password server.properties: | server.port=8080 server.timeout=300 1 2 3 4 5 6 7 8 9 10 11 12 在上述 YAML 文件中定义了一个名为 my-config 的 ConfigMap 对象,并定义了一个 database.properties 文件和一个 server.properties 文件 3.2 Secret Secret 可以用于将敏感信息以加密的形式注入到 Pod 中。Secret 与 ConfigMap 一样也可以实现多个 Pod 共享的配置信息的管理 以下是一个 Secret 的 YAML 文件示例: apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque stringData: username: admin password: myPassword 1 2 3 4 5 6 7 8 在上述 YAML 文件中定义了一个名为 my-secret 的 Secret 对象,并定义了一个 username 和 password。在实际使用中,Secret 中的数据将会被加密并存储在 etcd 中,在初始化 Pod 时进行解密并注入到容器中。 四、 Kubernetes 网络模型 网络是 Kubernetes 中至关重要的一环它是 Kubernetes 能够实现跨多个节点的负载均衡和服务发现的基础。在 Kubernetes 中,主要有三种网络模型:单节点 Docker 桥接模式、CNI 模式和 Service 模式。 1 Kubernetes 网络概述 Kubernetes 支持多种网络模型但它们都需要协同工作以确保网络可用性和性能。在 Kubernetes 中网络主要用于以下三个方面: Pod 之间的网络通信 容器和宿主机之间的网络通信 外部访问 Kubernetes 集群提供的服务 为了实现这些网络功能 Kubernetes 需要在每个节点上配置一些网络组件和解决方案。 2 Kubernetes 网络方案 Kubernetes 中有多种网络方案可以根据不同的需求选择不同的方案 2.1 单节点 Docker 桥接模式 单节点 Docker 桥接模式是 Kubernetes 中最简单和最常见的网络方案之一。在这种方案中每个 Docker 容器都有自己的 IP 地址,Kubernetes 使用一个名为 Docker0 的网桥将这些 IP 地址连接在一起,实现容器和宿主机之间的通信 2.2 CNI 模式 CNI 模式是 Kubernetes 中的一个更高级的网络方案,它使用一种名为 Container Network Interface(CNI)的标准接口来管理容器网络。CNI 可以在 Kubernetes 中启用多种网络插件,如 Flannel、Calico 和 Canal 等,以实现不同的网络功能 2.3 Service 模式 Service 模式是 Kubernetes 中用于为容器提供负载均衡和服务发现的网络方案。在 Kubernetes 中,Service 是一组 Pod 的抽象,它们使用统一的 DNS 名称和虚拟 IP 地址,Kubernetes 通过 Service 实现了应用程序的服务发现和负载均衡 3 Kubernetes 网络管理工具 在 Kubernetes 中网络管理是一个重要的任务,需要使用专门的工具来进行管理和维护 3.1 kube-router kube-router 是 Kubernetes 中一个完整的网络解决方案,它提供了 Pod 网络、Service 网络和外部网络的解决方案。kube-router 还提供了完整的 IPv6 支持,可以为 Kubernetes 中的 IPv6 网络提供支持 3.2 Cilium Cilium 是一个用于 Kubernetes 中的网络和安全解决方案,它使用 Linux 内核技术提供了高性能的网络 I/O 服务。Cilium 还提供了完整的安全策略、安全插件和安全日志,可以增强 Kubernetes 网络的安全性和可靠性 五、 Kubernetes 存储管理 存储是 Kubernetes 中的另一个重要组成部分它可以提供可靠的持久化存储和数据管理。在 Kubernetes 中,主要有两种存储模型:Volume 和 PersistentVolume/Claim 1 Kubernetes 存储概述 Kubernetes 的存储模型是为容器化应用程序设计的,它提供了多种可插拔的存储后端,如本地存储、NFS 存储和云存储等。Kubernetes 将存储资源抽象为 PersistentVolume(PV)和 PersistentVolumeClaim(PVC)。 2 Kubernetes 存储模型 2.1 Volume Volume 是 Kubernetes 中用于为 Pod 提供持久化存储的基本组件,它可以将容器中的数据存储到 Pod 中。Kubernetes 中支持多种 Volume 类型,如 EmptyDir、HostPath、NFS 和 GlusterFS 等,可以根据不同的需求选择不同的 Volume 类型 2.2 PersistentVolume/Claim PersistentVolume(PV)是 Kubernetes 中用于描述物理存储资源的组件,它提供了抽象层,将存储资源与应用程序分离开来。PersistentVolumeClaim(PVC)是用于向 Kubernetes 请求存储资源的组件,它可以将 Pod 和 PersistentVolume 进行绑定,从而为容器提供持久化存储 53 Kubernetes 存储管理工具 在 Kubernetes 中存储管理是一项关键任务,需要使用专门的工具进行管理和维护 3.1 Ceph Ceph 是一个开源的分布式存储系统它提供了高可用性和高可扩展性的存储服务。在 Kubernetes 中,可以将 Ceph 集群与 Kubernetes 集成,从而为容器提供可靠的存储解决方案 3.2 GlusterFS GlusterFS 是一个开源的分布式文件系统,它可以将多台服务器上的存储设备汇聚成一个大型存储池,以提供高可用性和高可扩展性的存储服务。在 Kubernetes 中,可以将 GlusterFS 集群与 Kubernetes 集成,从而为容器提供可靠的存储解决方案 六、 Kubernetes 安全策略 1 Kubernetes 安全概述 在 Kubernetes 中应用程序和数据的安全是至关重要的。Kubernetes 提供了多种安全机制和工具,以帮助实现应用程序和数据的保护和隔离。Kubernetes 安全主要包括身份认证、授权、准入控制、网络安全和机密管理等方面。 2 Kubernetes 安全模型 Kubernetes 中的安全模型涵盖了多个方面,包括命名空间、ServiceAccount 和 RBAC 等 2.1 命名空间 Namespace 命名空间是 Kubernetes 中的一种资源分类机制,它将一组资源隔离开来,以实现资源管理和权限控制。每个命名空间都拥有自己的资源列表,而且命名空间之间的资源是相互隔离的。Kubernetes 中预定义了一些命名空间,如 default、kube-system 等,用户也可以自定义命名空间 2.2 ServiceAccount ServiceAccount 是 Kubernetes 中用于身份验证和授权的一种机制,它为 Pod 提供了默认的身份认证信息。在 Kubernetes 中,每个 Pod 都有自己的 ServiceAccount,通过 ServiceAccount 可以为 Pod 提供不同的身份认证和授权策略。Kubernetes 还提供了多种身份验证和授权机制,如 OAuth、Webhook 等。 2.3 RBAC RBAC 是 Kubernetes 中用于授权的一种机制,它可以将权限分配给特定的用户或用户组,并在整个 Kubernetes 群集中实施授权策略。RBAC 可以定义角色(Role)和角色绑定(RoleBinding),以将权限授予特定的用户或用户组,并限制其访问群集中的特定资源。 七、 Kubernetes 高可用方案 1 Kubernetes 高可用概述 在 Kubernetes 中,高可用是实现应用程序可靠部署和管理的重要前提条件。通过部署高可用 Kubernetes 集群,可以实现容错性、负载均衡和自动故障切换等功能 2 Kubernetes 高可用方案 2.1 多个控制节点 Kubernetes 中的控制节点(Control Plane)是用于管理整个 Kubernetes 群集的关键组件之一,包括 kube-apiserver、kube-controller-manager 和 kube-scheduler 等。为了实现高可用,可以在 Kubernetes 群集中部署多个控制节点,以实现容错和负载均衡 2.2 基于 etcd 集群的高可用 etcd 是 Kubernetes 中用于存储群集状态的关键组件,它为整个 Kubernetes 群集提供了数据存储和共享功能。为了实现高可用,可以通过部署 etcd 集群来实现数据的冗余和自动故障切换。 2.3 基于虚拟IP的高可用 在 Kubernetes 中可以使用虚拟IP(VIP)来实现高可用。通过使用 VIP,可以将多个 Kubernetes 节点组成一个冗余集群,以实现容错和自动故障切换等功能。 3 Kubernetes 高可用工具 3.1 kubeadm 集群安装工具 kubeadm 是 Kubernetes 官方提供的集群安装工具,它可以快速部署高可用 Kubernetes 集群,并提供了多种可插拔的组件和插件,以扩展和定制 Kubernetes 群集 3.2 kubespray 集群安装工具 kubespray 是一个开源的 Kubernetes 集群安装工具,它基于 Ansible 自动化工具和 Kubernetes 官方指南进行开发。kubespray 可以快速部署高可用 Kubernetes 集群,并提供了多种可插拔的组件和插件,以扩展和定制 Kubernetes 群集。 八、 Kubernetes 故障排查 在 Kubernetes 中故障排查是系统维护和调试的重要一环。本文将从三个方面介绍 Kubernetes 故障排查:概述、常见故障原因分析和排查技巧。 1 Kubernetes 故障排查概述 Kubernetes 故障排查通常涉及到多种组件和技术,包括网络、节点和 Pod 等。在排查问题时,需要先定位故障的范围和具体原因,然后采取相应的措施进行排除。针对不同类型的故障,通常需要采用不同的排查技巧和工具 2 Kubernetes 常见故障原因分析 2.1 网络不通 网络问题是 Kubernetes 中常见的故障原因之一。当集群中的容器无法与其他容器或外部网络通信时,可能是由于网络配置问题、网络故障或跨主机通信错误等引起的。解决网络故障的方法包括检查网络拓扑、配置和路由,以及检查 Kubernetes 中的网络策略和安全组等。 # 示例:检查 Pod IP 和服务 IP 是否冲突 apiVersion: v1 kind: Pod metadata: name: test-pod spec: containers: - name: test-container image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: test-service spec: selector: app: test ports: - name: http port: 80 targetPort: 80 type: ClusterIP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 2.2 节点异常 Kubernetes 节点异常是另一个常见的故障原因。当节点无法正常运行或访问时,可能会导致 Pod 启动失败、容器无法运行或数据丢失等问题。解决节点异常的方法包括检查节点状态、硬件故障、资源利用率和容器日志等 # 示例:查看节点状态和资源利用率 $ kubectl get nodes $ kubectl describe node <nodename> $ kubectl top node 1 2 3 4 2.3 Pod 异常 在 Kubernetes 中Pod 异常通常包括容器崩溃、镜像拉取失败、容器资源不足等问题。当 Pod 无法正常启动或执行命令时,可能会导致服务不可用、数据损失或负载过重等问题。解决 Pod 异常的方法包括检查容器状态、Pod 生命周期、容器资源配额和日志等。 # 示例:查看 Pod 状态和容器日志 $ kubectl get pods $ kubectl describe pod <podname> $ kubectl logs <podname> -c <containername> 1 2 3 4 3 Kubernetes 故障排查技巧 在排查 Kubernetes 故障时,需要掌握一些技巧和工具,以提高排查效率。其中包括: 使用 kubectl 命令查询资源状态、获取日志和执行故障排查命令。 在节点和容器中安装监控和诊断工具,如 Prometheus、Grafana 和 sysdig 等。 使用 Kubernetes Dashboard 或其他资源管理工具来查看和管理集群资源。 记录故障排查过程和结果,并及时更新相关文档和资料。 ———————————————— 版权声明:本文为CSDN博主「格林希尔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/u010349629/article/details/130638487
-
我在尝试部署KubeEdge框架在部署K8s使用 kubeadm init语句初始化集群时遇到了问题使用的Ubuntu版本为18.04Docker版本为18.06.3Kubernetes版本为1.17.4遇到的如下的报错起先是卡在这个位置按照网络上的教学修改了kubelet与Docker的驱动程序改为systemd然后就出现了上面那张图的报错求教错误原因与解决的方案
-
【标题描述】能够简要描述问题: 在使用kubesphere提供的kk工具安装 k8s 1.19.8和Kubesphere v3.1.0时,出现了 kubesphere组件redis-ha-haproxy组件一直无法启动的情况,通过排查内核日志及kubelet日志 ,发现该容器是被kubelet Omm kill掉, 但是服务器节点内存非常充足,3个master 节点分别是16G 、32G 、16g,空闲内存还很多,具体如下 kubelet事件操作系统内核日志Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633785] haproxy invoked oom-killer: gfp_mask=0xcc0(GFP_KERNEL), order=0, oom_score_adj=994 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633788] CPU: 1 PID: 192200 Comm: haproxy Kdump: loaded Not tainted 5.10.0-60.18.0.50.oe2203.x86_64 #1 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633789] Hardware name: OpenStack Foundation OpenStack Nova, BIOS rel-1.10.2-0-g5f4c7b1-20181220_000000-szxrtosci10000 04/01/2014 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633790] Call Trace: Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633799] dump_stack+0x57/0x6a Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633802] dump_header+0x4a/0x1f0 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633804] oom_kill_process.cold+0xb/0x10 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633808] out_of_memory+0x100/0x310 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633812] mem_cgroup_out_of_memory+0x134/0x150 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633813] mem_cgroup_oom+0x14d/0x180 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633815] try_charge+0x2b1/0x580 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633817] ? __pagevec_lru_add_fn+0x183/0x2e0 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633819] mem_cgroup_charge+0xf1/0x250 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633821] do_anonymous_page+0x1f2/0x560 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633823] __handle_mm_fault+0x3dd/0x6d0 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633824] handle_mm_fault+0xbe/0x290 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633827] exc_page_fault+0x273/0x550 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633830] ? asm_exc_page_fault+0x8/0x30 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633831] asm_exc_page_fault+0x1e/0x30 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633833] RIP: 0033:0x55a4a16d2a9a Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633835] Code: 1b 00 ff ff ff ff c7 05 2c 92 1b 00 ff ff ff ff c7 05 1e 92 1b 00 ff ff ff ff 85 ed 7e 34 66 90 48 63 c2 83 c2 01 48 c1 e0 06 <48> c7 04 03 00 00 00 00 48 8b 1d 57 3b 1b 00 48 01 d8 c7 40 18 fd Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633836] RSP: 002b:00007ffe490870e0 EFLAGS: 00010206 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633838] RAX: 000000001f254000 RBX: 00007f68f22b6010 RCX: 00007f62f22b6010 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633839] RDX: 00000000007c9501 RSI: 0000000000000000 RDI: 0000000000000000 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633840] RBP: 000000003ffffff7 R08: 00007f62f22b6010 R09: 0000000000000000 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633841] R10: 0000000000000022 R11: 0000000000000246 R12: 00007f66f22b6010 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633842] R13: 000055a4a225ec30 R14: 0000000000000001 R15: 0000000000000001 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633844] memory: usage 512000kB, limit 512000kB, failcnt 2537 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633844] memory+swap: usage 512000kB, limit 9007199254740988kB, failcnt 0 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633845] kmem: usage 0kB, limit 9007199254740988kB, failcnt 0 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633845] Memory cgroup stats for /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podc9f031a9_b682_459c_ad9d_8fbb491edbdb.slice: Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633855] anon 524288000#012file 0#012kernel_stack 0#012percpu 0#012sock 0#012shmem 0#012file_mapped 0#012file_dirty 0#012file_writeback 0#012anon_thp 511705088#012inactive_anon 524242944#012active_anon 8192#012inactive_file 0#012active_file 0#012unevictable 0#012slab_reclaimable 0#012slab_unreclaimable 0#012slab 0#012workingset_refault_anon 0#012workingset_refault_file 14598#012workingset_activate_anon 0#012workingset_activate_file 6#012workingset_restore_anon 0#012workingset_restore_file 0#012workingset_nodereclaim 0#012pgfault 35036#012pgmajfault 561#012pgrefill 10434#012pgscan 29409#012pgsteal 17231#012pgactivate 9817#012pgdeactivate 10021#012pglazyfree 0#012pglazyfreed 0#012thp_fault_alloc 1967#012thp_collapse_alloc 0 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633856] Tasks state (memory values in pages): Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633857] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633859] [ 186685] 1000 186685 243 1 28672 0 -998 pause Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633861] [ 192200] 1000 192200 23072522 127962 1118208 0 994 haproxy Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633862] oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=docker-be7545b7c95b6f6f011944a5e3c693363db0a18e9a4e4e089a5b4bfea1a12e28.scope,mems_allowed=0,oom_memcg=/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podc9f031a9_b682_459c_ad9d_8fbb491edbdb.slice,task_memcg=/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podc9f031a9_b682_459c_ad9d_8fbb491edbdb.slice/docker-be7545b7c95b6f6f011944a5e3c693363db0a18e9a4e4e089a5b4bfea1a12e28.scope,task=haproxy,pid=192200,uid=1000 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.633870] Memory cgroup out of memory: Killed process 192200 (haproxy) total-vm:92290088kB, anon-rss:511720kB, file-rss:128kB, shmem-rss:0kB, UID:1000 pgtables:1092kB oom_score_adj:994 Dec 15 21:04:20 ahsshjz-k8smaster01 kernel: [16704.637227] oom_reaper: reaped process 192200 (haproxy), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB 以上操作系统日志,我配置的haproxy最大limit限制为500M 出现 oom 以下日志为我配置pod limit限制为1500M 启动仍然是oom Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159234] haproxy invoked oom-killer: gfp_mask=0xcc0(GFP_KERNEL), order=0, oom_score_adj=997 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159237] CPU: 0 PID: 269263 Comm: haproxy Kdump: loaded Not tainted 5.10.0-60.18.0.50.oe2203.x86_64 #1 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159238] Hardware name: OpenStack Foundation OpenStack Nova, BIOS rel-1.10.2-0-g5f4c7b1-20181220_000000-szxrtosci10000 04/01/2014 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159239] Call Trace: Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159246] dump_stack+0x57/0x6a Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159250] dump_header+0x4a/0x1f0 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159252] oom_kill_process.cold+0xb/0x10 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159255] out_of_memory+0x100/0x310 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159259] mem_cgroup_out_of_memory+0x134/0x150 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159261] mem_cgroup_oom+0x14d/0x180 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159262] try_charge+0x2b1/0x580 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159265] ? __pagevec_lru_add_fn+0x183/0x2e0 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159266] mem_cgroup_charge+0xf1/0x250 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159268] do_anonymous_page+0x1f2/0x560 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159271] __handle_mm_fault+0x3dd/0x6d0 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159272] handle_mm_fault+0xbe/0x290 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159275] exc_page_fault+0x273/0x550 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159278] ? asm_exc_page_fault+0x8/0x30 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159279] asm_exc_page_fault+0x1e/0x30 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159281] RIP: 0033:0x562cc41baa9a Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159283] Code: 1b 00 ff ff ff ff c7 05 2c 92 1b 00 ff ff ff ff c7 05 1e 92 1b 00 ff ff ff ff 85 ed 7e 34 66 90 48 63 c2 83 c2 01 48 c1 e0 06 <48> c7 04 03 00 00 00 00 48 8b 1d 57 3b 1b 00 48 01 d8 c7 40 18 fd Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159284] RSP: 002b:00007ffcc9b32e70 EFLAGS: 00010206 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159286] RAX: 000000005da52000 RBX: 00007f58a8a43010 RCX: 00007f52a8a43010 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159286] RDX: 0000000001769481 RSI: 0000000000000000 RDI: 0000000000000000 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159287] RBP: 000000003ffffff7 R08: 00007f52a8a43010 R09: 0000000000000000 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159288] R10: 0000000000000022 R11: 0000000000000246 R12: 00007f56a8a43010 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159289] R13: 0000562cc4afcc30 R14: 0000000000000001 R15: 0000000000000001 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159290] memory: usage 1536000kB, limit 1536000kB, failcnt 1668 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159291] memory+swap: usage 1536000kB, limit 9007199254740988kB, failcnt 0 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159292] kmem: usage 0kB, limit 9007199254740988kB, failcnt 0 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159292] Memory cgroup stats for /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod655eac53_2a9d_4db8_b083_b4776263d81b.slice: Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159302] anon 1572851712#012file 12288#012kernel_stack 0#012percpu 0#012sock 0#012shmem 0#012file_mapped 0#012file_dirty 0#012file_writeback 0#012anon_thp 1560281088#012inactive_anon 1572843520#012active_anon 8192#012inactive_file 4096#012active_file 8192#012unevictable 0#012slab_reclaimable 0#012slab_unreclaimable 0#012slab 0#012workingset_refault_anon 0#012workingset_refault_file 8857#012workingset_activate_anon 0#012workingset_activate_file 0#012workingset_restore_anon 0#012workingset_restore_file 0#012workingset_nodereclaim 0#012pgfault 20892#012pgmajfault 293#012pgrefill 5615#012pgscan 14815#012pgsteal 8858#012pgactivate 5191#012pgdeactivate 5192#012pglazyfree 0#012pglazyfreed 0#012thp_fault_alloc 2987#012thp_collapse_alloc 0 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159303] Tasks state (memory values in pages): Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159303] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159305] [ 267934] 1000 267934 243 1 28672 0 -998 pause Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159307] [ 269263] 1000 269263 23072522 383961 3166208 0 997 haproxy Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159308] oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=docker-4db120f25d7ff16eba42ef22d3daef5201050bb61ff51f460f843c2e8cc62975.scope,mems_allowed=0,oom_memcg=/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod655eac53_2a9d_4db8_b083_b4776263d81b.slice,task_memcg=/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod655eac53_2a9d_4db8_b083_b4776263d81b.slice/docker-4db120f25d7ff16eba42ef22d3daef5201050bb61ff51f460f843c2e8cc62975.scope,task=haproxy,pid=269263,uid=1000 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.159317] Memory cgroup out of memory: Killed process 269263 (haproxy) total-vm:92290088kB, anon-rss:1535832kB, file-rss:12kB, shmem-rss:0kB, UID:1000 pgtables:3092kB oom_score_adj:997 Dec 15 22:22:52 ahsshjz-k8snode2 kernel: [23041.164890] oom_reaper: reaped process 269263 (haproxy), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB配置15000M 依然是启动haproxy 会达到最大内存限制,而被KillDec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922789] haproxy invoked oom-killer: gfp_mask=0xcc0(GFP_KERNEL), order=0, oom_score_adj=997 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922793] CPU: 6 PID: 369292 Comm: haproxy Kdump: loaded Not tainted 5.10.0-60.18.0.50.oe2203.x86_64 #1 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922794] Hardware name: OpenStack Foundation OpenStack Nova, BIOS rel-1.10.2-0-g5f4c7b1-20181220_000000-szxrtosci10000 04/01/2014 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922795] Call Trace: Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922802] dump_stack+0x57/0x6a Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922806] dump_header+0x4a/0x1f0 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922808] oom_kill_process.cold+0xb/0x10 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922811] out_of_memory+0x100/0x310 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922815] mem_cgroup_out_of_memory+0x134/0x150 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922816] mem_cgroup_oom+0x14d/0x180 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922817] try_charge+0x2b1/0x580 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922821] ? free_one_page+0x1f4/0x510 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922823] mem_cgroup_charge+0xf1/0x250 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922824] do_anonymous_page+0x1f2/0x560 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922826] __handle_mm_fault+0x3dd/0x6d0 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922830] ? timerqueue_add+0x96/0xb0 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922831] handle_mm_fault+0xbe/0x290 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922834] exc_page_fault+0x273/0x550 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922837] ? asm_exc_page_fault+0x8/0x30 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922838] asm_exc_page_fault+0x1e/0x30 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922840] RIP: 0033:0x5577fa027a9a Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922842] Code: 1b 00 ff ff ff ff c7 05 2c 92 1b 00 ff ff ff ff c7 05 1e 92 1b 00 ff ff ff ff 85 ed 7e 34 66 90 48 63 c2 83 c2 01 48 c1 e0 06 <48> c7 04 03 00 00 00 00 48 8b 1d 57 3b 1b 00 48 01 d8 c7 40 18 fd Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922843] RSP: 002b:00007fffa81993b0 EFLAGS: 00010206 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922844] RAX: 00000003a9650000 RBX: 00007fb74efb9010 RCX: 00007fb14efb9010 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922845] RDX: 000000000ea59401 RSI: 0000000000000000 RDI: 0000000000000000 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922846] RBP: 000000003ffffff7 R08: 00007fb14efb9010 R09: 0000000000000000 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922846] R10: 0000000000000022 R11: 0000000000000246 R12: 00007fb54efb9010 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922847] R13: 00005577fa8d5c30 R14: 0000000000000001 R15: 0000000000000001 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922849] memory: usage 15360000kB, limit 15360000kB, failcnt 241 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922850] memory+swap: usage 15360000kB, limit 9007199254740988kB, failcnt 0 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922851] kmem: usage 0kB, limit 9007199254740988kB, failcnt 0 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922851] Memory cgroup stats for /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podee31ec4d_d8b6_456a_98b3_2c6617f23c31.slice: Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922861] anon 15728541696#012file 98304#012kernel_stack 0#012percpu 0#012sock 0#012shmem 0#012file_mapped 98304#012file_dirty 0#012file_writeback 0#012anon_thp 15720251392#012inactive_anon 15728500736#012active_anon 8192#012inactive_file 0#012active_file 98304#012unevictable 0#012slab_reclaimable 0#012slab_unreclaimable 0#012slab 0#012workingset_refault_anon 0#012workingset_refault_file 4190#012workingset_activate_anon 0#012workingset_activate_file 0#012workingset_restore_anon 0#012workingset_restore_file 0#012workingset_nodereclaim 0#012pgfault 33424#012pgmajfault 126#012pgrefill 2056#012pgscan 7287#012pgsteal 4167#012pgactivate 2080#012pgdeactivate 2056#012pglazyfree 0#012pglazyfreed 0#012thp_fault_alloc 22494#012thp_collapse_alloc 0 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922862] Tasks state (memory values in pages): Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922862] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922865] [ 367900] 1000 367900 243 1 28672 0 -998 pause Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922866] [ 369292] 1000 369292 23072523 3840521 30867456 0 997 haproxy Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922868] oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=docker-214e3028cd48ecd5b091803d52122ea5f0bc2a1b40c2b8ddb7e4470d7c41a412.scope,mems_allowed=0,oom_memcg=/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podee31ec4d_d8b6_456a_98b3_2c6617f23c31.slice,task_memcg=/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podee31ec4d_d8b6_456a_98b3_2c6617f23c31.slice/docker-214e3028cd48ecd5b091803d52122ea5f0bc2a1b40c2b8ddb7e4470d7c41a412.scope,task=haproxy,pid=369292,uid=1000 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.922876] Memory cgroup out of memory: Killed process 369292 (haproxy) total-vm:92290092kB, anon-rss:15359908kB, file-rss:2176kB, shmem-rss:0kB, UID:1000 pgtables:30144kB oom_score_adj:997 Dec 15 22:26:26 ahsshjz-k8snode3 kernel: [22376.949848] oom_reaper: reaped process 369292 (haproxy), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB问题如上,请问我应该如何处理该问题,以上问题在centos7环境中未出现 目前发现 我部署mysql8.0 容器也会出现以上问题 【环境信息】 硬件信息: 1) 虚拟机.x86架构 2) 官方提供的虚拟机镜像 软件信息: 1) openeuler 22.03lts 2) 5.10.0-60.18.0.50.oe2203.x86_64 3) k8s v1.19.8 kubesphere v3.1.0 harproxy镜像 registry.cn-beijing.aliyuncs.com/kubesphereio/haproxy:2.0.4【问题复现步骤】 3台 openeuler 22.03lts,3个master节点 使用Kubesphere 官方提供的 kk工具创建集群 ./kk create config --with-kubernetes v1.19.8 --with-kubesphere v3.1.0 -f config-sample.yaml ./kk create cluster -f config-sample.yaml 出现概率(必现) 内核sysctl.conf配置内容如下kernel.sysrq=0 net.ipv4.ip_forward = 1 net.ipv4.conf.all.send_redirects=0 net.ipv4.conf.default.send_redirects=0 net.ipv4.conf.all.accept_source_route=0 net.ipv4.conf.default.accept_source_route=0 net.ipv4.conf.all.accept_redirects=0 net.ipv4.conf.default.accept_redirects=0 net.ipv4.conf.all.secure_redirects=0 net.ipv4.conf.default.secure_redirects=0 net.ipv4.icmp_echo_ignore_broadcasts=1 net.ipv4.icmp_ignore_bogus_error_responses=1 net.ipv4.conf.all.rp_filter=1 net.ipv4.conf.default.rp_filter=1 net.ipv4.tcp_syncookies=1 kernel.dmesg_restrict=1 net.ipv6.conf.all.accept_redirects=0 net.ipv6.conf.default.accept_redirects=0
-
华为云鲲鹏openEuler 20.03安装kubesphere,之前已安装好kubernetes,现在在 Kubernetes 上最小化安装 KubeSphere,出现exec /shell-operator: exec format error,看样子,好像是下载了x86的文件?怎么解决[root@master01 ~]# kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.2.1/cluster-configuration.yamlcustomresourcedefinition.apiextensions.k8s.io/clusterconfigurations.installer.kubesphere.io creatednamespace/kubesphere-system createdserviceaccount/ks-installer createdclusterrole.rbac.authorization.k8s.io/ks-installer createdclusterrolebinding.rbac.authorization.k8s.io/ks-installer createddeployment.apps/ks-installer created[root@master01 ~]# kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -fError from server (BadRequest): container "installer" in pod "ks-installer-85dcfff87d-c9jbv" is waiting to start: ContainerCreating[root@master01 ~]# kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -fexec /shell-operator: exec format error
-
华为云鲲鹏openEuler 20.03上,利用kubesphere安装kubernetes出错,之前在另一台服务器鲲鹏Euler OS上没有这个问题,如何解决?[root@master01 ~]# systemctl status etcd.service● etcd.service - etcdLoaded: loaded (/etc/systemd/system/etcd.service; disabled; vendor preset: disabled)Active: activating (auto-restart) (Result: exit-code) since Wed 2022-11-09 15:29:42 CST; 9s agoProcess: 50396 ExecStart=/usr/local/bin/etcd (code=exited, status=203/EXEC)Main PID: 50396 (code=exited, status=203/EXEC)[root@master01 ~]#[root@master01 ~]# journalctl -xe-- Defined-By: systemd-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel---- A start job for unit etcd.service has begun execution.---- The job identifier is 17028.Nov 09 15:31:04 master01 systemd[50452]: etcd.service: Failed to execute command: Exec format errorNov 09 15:31:04 master01 systemd[50452]: etcd.service: Failed at step EXEC spawning /usr/local/bin/etcd: Exec format error-- Subject: Process /usr/local/bin/etcd could not be executed-- Defined-By: systemd-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel---- The process /usr/local/bin/etcd could not be executed and failed.---- The error number returned by this process is ERRNO.Nov 09 15:31:04 master01 systemd[1]: etcd.service: Main process exited, code=exited, status=203/EXEC-- Subject: Unit process exited-- Defined-By: systemd-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel---- An ExecStart= process belonging to unit etcd.service has exited.---- The process' exit code is 'exited' and its exit status is 203.Nov 09 15:31:04 master01 systemd[1]: etcd.service: Failed with result 'exit-code'.-- Subject: Unit failed-- Defined-By: systemd-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel---- The unit etcd.service has entered the 'failed' state with result 'exit-code'.Nov 09 15:31:04 master01 systemd[1]: Failed to start etcd.-- Subject: A start job for unit etcd.service has failed-- Defined-By: systemd-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel---- A start job for unit etcd.service has finished with a failure.---- The job identifier is 17028 and the job result is failed.Nov 09 15:31:04 master01 audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=etcd comm="systemd" exe="/usr/lib/systemd/systemd>[root@master01 ~]#
-
是i↵我想知道,在华为云鲲鹏openEuler 20.03上部署的kubernetes,pull获取k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2,如何自动根据节点判断下载arm还是x86容器?如果是x86的,应该不能在arm上运行吧?
-
1. 组件版本和配置策略1.1 主要组件版本组件版本发布时间kubernetesv1.23.32022-01-26etcdv3.5.22022-02-01cri-ov1.23.02021-12-18flannelv0.16.32022-01-29coredns1.9.02022-02-10cni-pluginsv1.0.12021-09-081.2 主要配置策略kube-apiserver:使用节点本地 nginx 4 层透明代理实现高可用;关闭非安全端口 8080 和匿名访问;在安全端口 5443 接收 https请求;严格的认证和授权策略 (x509、token、RBAC);开启 bootstrap token 认证,支持 kubeletTLS bootstrapping;使用 https 访问 kubelet、etcd,加密通信;kube-controller-manager:3 节点高可用; 关闭非安全端口,在安全端口 10257 接收 https 请求;使用 kubeconfig 访问 apiserver的安全端口;自动 approve kubelet 证书签名请求 (CSR),证书过期后自动轮转;各 controller 使用自己的ServiceAccount 访问 apiserver;kube-scheduler:3 节点高可用; 使用 kubeconfig 访问 apiserver 的安全端口;关闭非安全端口,在安全端口 10259 接收https 请求;kubelet:使用 kubeadm 动态创建 bootstrap token,而不是在 apiserver 中静态配置;使用 TLSbootstrap 机制自动生成 client 和 server 证书,过期后自动轮转;在 KubeletConfiguration类型的 JSON 文件配置主要参数;关闭只读端口,在安全端口 10250 接收 https请求,对请求进行认证和授权,拒绝匿名访问和非授权 访问;使用 kubeconfig 访问 apiserver 的安全端口;kube-proxy:使用 kubeconfig 访问 apiserver 的安全端口;在 KubeProxyConfiguration 类型的 JSON文件配置主要参数;使用 ipvs 代理模式;集群插件:DNS:使用功能、性能更好的 coredns;2. 初始化系统和全局变量2.1 集群规划master节点:节点名称IP地址k8s-master-1192.168.2.175k8s-master-2192.168.2.176k8s-master-3192.168.2.178node 节点:节点名称IP地址k8s-node-1192.168.2.185k8s-node-2192.168.2.187k8s-node-3192.168.3.62k8s-node-4192.168.3.70控制节点/配置生成节点:节点名称IP地址qist192.168.0.151工作目录: /opt三台机器混合部署本文档的 etcd、master 集群和 woker 集群。如果没有特殊说明,需要在所有节点上执行本文档的初始化操作。2.2 kubelet cri-o cgroupCgroup Driver:systemd kubeelt cri-o Cgroup 配置为systemd2.3 设置主机名hostnamectl set-hostname k8s-master-1 # 将 k8s-master-1 替换为当前主机名退出,重新登录 root 账号,可以看到主机名生效。2.4 添加节点信任关系本操作只需要在 qist 节点上进行,设置 root 账户可以无密码登录所有节点:ssh-keygen -t rsa ssh-copy-id root@192.168.2.175 ssh-copy-id root@192.168.2.176 ssh-copy-id root@192.168.2.177 ssh-copy-id root@192.168.2.185 ssh-copy-id root@192.168.2.187 ssh-copy-id root@192.168.3.62 ssh-copy-id root@192.168.3.702.5 安装依赖包yum install -y epel-release yum install -y chrony conntrack ipvsadm ipset jq iptables curl sysstat libseccomp wget socat gitkube-proxy 使用 ipvs 模式,ipvsadm 为 ipvs 的管理工具;etcd 集群各机器需要时间同步,chrony用于系统时间同步;2.6 关闭防火墙关闭防火墙,清理防火墙规则,设置默认转发策略:systemctl stop firewalld systemctl disable firewalld iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat2.7 关闭 swap 分区关闭 swap 分区,否则kubelet 会启动失败(可以设置 kubelet 启动参数 --fail-swap-on 为 false 关闭 swap检查):swapoff -a sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab2.8 关闭 SELinux关闭 SELinux,否则 kubelet 挂载目录时可能报错 Permission denied :setenforce 0 sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config2.9 优化内核参数cat > /etc/sysctl.d/kubernetes.conf <关闭 tcp_tw_recycle,否则与 NAT 冲突,可能导致服务不通;内核低于4版本添加fs.may_detach_mounts=12.10 系统文件打开数cat>>/etc/security/limits.conf<centos7还需修改sed-i's/4096/655350/'/etc/security/limits.d/20-nproc.conf2.11 内核模块配置重启自动加载加载ipvs内核模块cat>/etc/modules-load.d/k8s-ipvs-modules.conf<加载netfilter等模块 内核4版本以下 nf_conntrack 替换 nf_conntrack_ipv4cat>/etc/modules-load.d/k8s-net-modules.conf<2.12 设置系统时区timedatectlset-timezoneAsia/Shanghai2.13 设置系统时钟同步systemctl enable chronyd systemctl start chronyd查看同步状态:timedatectl status输出:System clock synchronized: yes NTP service: active RTC in localTZ: noSystem clock synchronized: yes,表示时钟已同步;NTP service: active,表示开启了时钟同步服务;#将当前的UTC时间写入硬件时钟 timedatectlset-local-rtc0#重启依赖于系统时间的服务 systemctl restart rsyslog systemctl restart crond2.14 关闭无关的服务systemctl stop postfix && systemctl disable postfix2.15 创建相关目录创建目录:master 组件目录#k8s目录 mkdir -p /apps/k8s/{bin,log,conf,ssl,config} mkdir -p /apps/work/kubernetes/{manifests,kubelet} mkdir -p /var/lib/kubelet mkdir- p /usr/libexec/kubernetes/kubelet-plugins/volume/exec/ mkdir -p /apps/k8s/ssl/{etcd,k8s} #etcd目录 mkdir -p /apps/etcd/{bin,conf,data,ssl} #etcd data-dir目录 mkdir -p /apps/etcd/data/default.etcd #etcdwal-dir目录 mkdir -p /apps/etcd/data/default.etcd/walnode 节点目录mkdir -p /apps/k8s/{bin,log,conf,ssl} mkdir -p /apps/work/kubernetes/{manifests,kubelet} mkdir -p /var/lib/kubelet mkdir -p /usr/libexec/kubernetes/kubelet-plugins/volume/exec/cri-o 目录结构创建mkdir -p /apps/crio/{run,etc,keys} mkdir -p /apps/crio/containers/oci/hooks.d mkdir -p /etc/containers mkdir -p /var/lib/containers/storage mkdir -p /run/containers/storage mkdir -p /apps/crio/lib/containers/storage mkdir -p /apps/crio/run/containers/storage2.16 mount目录挂载挂载kubelet 跟cri-o数据目录最大兼容其它依赖组件例如csi插件cat>> /etc/fstab <验证挂载是否有误mount-a重启机器:sync reboot期待下次的分享,别忘了三连支持博主呀~ 我是 念舒_C.ying ,期待你的关注~💪💪💪
-
摘要:KubeEdge设备管理架构的设计实现,有效帮助用户处理设备数字孪生进程中遇到的场景。本文分享自华为云社区《KubeEdge:下一代云原生边缘设备管理标准DMI的设计与实现》。随着5G、AI、分布式云等技术的成熟发展,万物互联、数字孪生、算力泛在等理念不断推进,带来了很多行业业务的创新,越来越多的设备、应用运行在端侧,并产生大量的数据。如何更好地解耦业务应用开发和设备数据访问,为设备提供完整的生命周期数据管理,释放设备数据的价值?如何在保证集群可用性的同时,高效管理和传输设备数据,获得更为方便、灵活的数据访问方式?云原生边缘计算的方案选择可以帮助用户更好地应对这类问题。一、KubeEdge设备管理框架KubeEdge设备管理架构的设计实现,有效帮助用户处理设备数字孪生进程中遇到的场景。用户可以通过KubeEdge,将物理设备抽象成数字孪生,用云原生的方式对设备和数据进行管理。一、KubeEdge设备管理框架 图 1 KubeEdge设备管理架构设计KubeEdge设备管理架构设计如图1所示,具体流程如下:1. 用户调用Kubernetes API接口,创建Device CRD实例到KubeEdge2. KubeEdge云上组件CloudCore watch到Kubernetes中Device CRD实例创建消息3. 此时CloudCore会做两件事情,一方面CloudCore通过云边websocket通道下发Device Twin信息到EdgeCore,另一方面CloudCore会生成一份包含Device Profile信息的Configmap,该Configmap是以Node名称为索引,挂载到对应Mapper的Pod中的4. Mapper通过读取挂载的Configmap中的Device Profile信息,更新本地维护的Device list列表5. EdgeCore把接收到的Device Twin信息发送到指定的mqtt topic6. 该节点上的所有Mapper都会收到该Device Twin消息,并根据Device名称来匹配是否是自己维护的list中的Device7. Mapper根据Device Profile信息,通过对应的协议与设备建立连接8. Mapper通过mqtt topic上报设备状态和采集的数据Device Twin到EdgeCore9. EdgeCore通过云边websocket通道上报Device Twin数据到CloudCore10. CloudCore更新设备Device Twin数据到Kubernetes二、DMI框架设计 在此基础上,KubeEdge团队也对框架不断更新迭代。为帮助用户应对未来更大规模设备场景、更高的可用性需求、更灵活的功能支持以及更优的用户体验,KubeEdge 设计了更优化的设备管理框架——DMI。DMI整合设备管理接口,优化边缘计算场景下的设备管理能力,打造基于云原生技术的,覆盖设备管理、设备数据的设备数字孪生管理平台;同时定义了EdgeCore与Mapper之间统一的连接入口,并分别由EdgeCore和Mapper实现上行数据流和下行数据流的服务端和客户端,承载DMI具体功能。DMI框架设计中解耦了设备管理面与设备业务面数据,让Device CRD只承载设备本身的生命周期管理,而设备业务面数据则直接通过微服务的方式为数据消费者应用提供出来。在这样的架构下,设备就不再是单纯的数据源,而是一种云原生的设备微服务,设备数据消费应用的开发者就可以不再关心如何获取设备数据,而是以更云原生的方式来聚焦应用本身的业务逻辑开发。DMI框架还提供多种数据推送方式,让数据消费者可以更灵活地获取设备数据,用户体验更优。由于DMI的设备管理面与业务面数据分离的特点,业务面数据可以通过业务面通道更灵活地在云端或边端被处理,而管理面的云边通道中只会传输少量管理面信息,大大降低了云边通道拥塞的可能,提高了KubeEdge系统的可用性。另外,DMI提供了统一的设备管理相关接口,无论是设备应用开发者还是设备应用的使用者,都可以以更统一、更灵活、更标准化的方式来开展设备相关工作,不拘泥于具体形式,只要能够实现DMI接口,就能够享受KubeEdge边缘计算平台带来的云原生设备管理体验。▍2.1 DMI框架定位图 2 DMI 在 KubeEdge 架构中的定位DMI在KubeEdge架构中的定位如图2所示。DMI类似Kubernetes的CNI、CSI、CRI等接口,定义了一组EdgeCore与Mapper之间的内部API接口以及外部应用访问Mapper的统一的API接口。其中内部接口底层由gRPC结合UDS的方式来实现,外部API接口支持mqtt和REST两种接入方式。Mapper不论是何种承载、实现方式,只要实现了DMI中所定义的上行、下行数据接口,即可接入KubeEdge云原生边缘计算平台,使用云原生的方式对设备进行管理。▍2.2 DMI设备管理与数据管理DMI框架架构设计如图3所示,其中黄色线条为设备管理面数据流管理,蓝色部分为业务面数据流管理。在DMI的架构设计中,将设备的管理面数据与业务面数据进行分离。其中管理面数据主要包括设备的元数据、设备属性、配置、状态、生命周期等,其特点是相对比较稳定,创建后除状态上报外的信息更新较少,更贴近Pod类型资源所产生的数据,在保证用户可以通过云端Kubernetes API像访问Pod一样维护Device的生命周期的同时,尽量减少设备管理产生的额外数据传输开销。图 3 DMI设备管理与数据管理架构在DMI框架设计下,设备不再是单纯的数据源,而是被抽象为微服务,以云原生的方式为设备数据消费者提供数据服务。DMI框架下的设备数据访问支持多种场景,更加灵活。图3中列出了几种主要的数据访问方式,包括推数据和拉数据等,具体情况如下:1. 边缘侧应用通过REST Service访问设备数据2. 云侧应用通过REST Service访问设备数据3. Mapper通过配置REST目的地址,将数据推送到边缘侧应用4. Mapper通过配置REST目的地址,将数据推送到云侧应用5. Mapper通过配置目的地址,将数据推送到边缘侧数据库6. Mapper通过配置目的地址,将数据推送到mqtt broker7. 边缘侧应用通过mqtt broker topic订阅设备数据8. 云侧应用通过mqtt broker topic 订阅设备数据9. 边缘侧应用处理数据后将处理结果传上云▍2.3 DMI工作流程图 4 DMI设备管理工作流程示例在DMI框架下,设备管理工作的流程有一定的变化。如图4所示,在安装KubeEdge的时候,云端CloudCore会注册DeviceController组件用于监听Device和DeviceModel的CRD资源。DeviceController中存在两个模块,Downstream Controller和Upstream Controller,其中Downstream Controller用于监听云端的Device、DeviceModel事件,并通过Cloudhub下发至边缘,Upstream Controller用于接收从Cloudhub转发来的EdgeHub上报的Device状态和消息,并更新Kubernetes中的Device状态。在边缘侧,Mapper初始化的时候,需要调用DMI中的Mapper注册接口,将Mapper的相关信息注册至Device Manager,并接收接口返回的已下发至该节点的且协议匹配的设备信息。EdgeHub在接收到云端下发的设备消息时,会将其转发到DeviceManager组件,DeviceManager会根据该设备的协议选择对应的Mapper驱动程序,发送创建设备的请求,并且本地数据库也会存储该设备的信息,后续Mapper会将设备孪生消息转化为设备协议格式,跟实际的物理设备进行通信。三、DMI接口定义▍3.1 DMI 接口分类DMI接口实现了EdgeCore与Mapper之间的通信,支持REST和mqtt的通信方式,并以标准化的形式呈现,降低了Mapper开发、适配难度。在数据访问方面,DMI可以实现边缘侧和云侧的应用都可以通过REST Service的方式访问设备数据。图 5 DMI接口定义如图5所示,DMI有六类接口,Mapper管理是针对边缘侧各类设备协议驱动程序,Device管理和Device数据管理对管理面和业务面进行了数据拆分,Device升级管理和Device命令管理为具有升级和命令执行功能的设备提供相关的接口,Device事件管理可以监控Mapper及其纳管的各个设备的运行状态。▍3.2 DMI 接口定义示例图 6 DMI设备管理部分接口定义示例如图6所示,为DMI设备管理部分接口定义,v1版本以gRPC proto的方式定义,可使用make dmi命令创建对应的gRPC-go代码。 ▍3.3 DMI 设备相关 CRD 定义如图7所示,是DMI设备相关CRD定义,主要分为Device和DeviceModel。其中DeviceModel与设备型号是一一对应的关系,代表同一类设备型号的共有属性,主要包含设备产生数据属性Properties和设备支持命令属性Commands。Device为设备实例,与真实的物理设备为一对一的关系,每个DeviceModel可以对应统一型号的多个Device实例。Device类型资源主要包含设备型号对应关系信息、设备协议配置信息、设备部署节点信息、设备状态信息以及设备数据Property采集配置信息。图 7 DMI 设备相关 CRD 定义 四、发布计划 四、发布计划DMI发布计划分为三个版本,Alpha版本提供设备管理相关功能实现,以及提供一个支持DMI接口的Mapper Demo。Beta版本支持设备命令管理、设备升级管理以及设备数据管理的能力,此外还会对接第三方平台,并提供相关对接Demo。GA版本会对多平台、多协议进行对接支持,另外会把设备安全以及事件管理的功能补全。图 8 DMI发布计划目前 KubeEdge Device IoT SIG 专注于第一阶段的设备管理和 Mapper Demo 的开发工作。欢迎大家通过下方联系方式联系我们,一起参与到方案设计和特性开发的工作当中本文作者:华为云 赵然 ;DaoCloud 道客 王梓龙附:KubeEdge社区贡献和技术交流地址网站: https://kubeedge.ioGithub地址: cid:link_1地址: https://kubeedge.slack.com邮件列表: https://groups.google.com/forum/#!forum/kubeedge每周社区例会: https://zoom.us/j/4167237304Twitter: https://twitter.com/KubeEdge文档地址: https://docs.kubeedge.io/en/latest/
-
使用Kubesphere 安装kubernetes集群【摘要】 设置环境变量 [root@master01 ~]# export KKZONE=cn 下载kubeKey [root@master01 ~]# curl -sfL https://get-kk.kubesphere.io | VERSION=v1.2.1 sh - kk赋权 [root@master01 ~]# chmod ...设置环境变量[root@master01 ~]# export KKZONE=cn下载kubeKey[root@master01 ~]# curl -sfL https://get-kk.kubesphere.io | VERSION=v1.2.1 sh -kk赋权[root@master01 ~]# chmod +x kk生成config[root@master01 ~]# ./kk create config --with-kubernetes v1.21.5安装kubernetes[root@master01 ~]# ./kk create cluster -f config-sample.yaml+----------+------+------+---------+----------+-------+-------+-----------+----------+------------+-------------+------------------+--------------+| name | sudo | curl | openssl | ebtables | socat | ipset | conntrack | docker | nfs client | ceph client | glusterfs client | time |+----------+------+------+---------+----------+-------+-------+-----------+----------+------------+-------------+------------------+文章来源: blog.csdn.net,作者:隔壁老瓦,版权归原作者所有,如需转载,请联系作者。原文链接:blog.csdn.net/wxb880114/article/details/123303525
-
> 最近在参加华为推出的[华为云云原生入门级开发者认证人才计划活动](https://edu.huaweicloud.com/signup/521bd9a32c9345d5b240d4173e67437a) 于是想自己动手部署K8S的环境来学习,去年自己也采用二进制的方式部署过,时隔一年K8S的版本已经更新到了v1.24.3啦。在v1.24版本之后,k8s都已经抛弃了docker。抱着学习的心态尝试了k8s的v1.24.3版本的安装,这次采用kubeadm的部署方式,过程非常坎坷,但是还是顺利的部署成功。 # 环境准备 三台机都是采用centos7的操作系统,内核版本号是`3.10.0-693.el7.x86_64` ------------ | 角色 | IP | kubernetes版本 | | --- | --- | --- | | master | 192.168.248.130 | v1.24.3 | | node1 | 192.168.248.131 | v1.24.3 | | node2 | 192.168.248.132 | v1.24.3 | ------------ >由于K8S从1.24版本之后,开始弃用了docker。改用了containerd ,containerd是容器虚拟化技术,从docker中剥离出来,形成开放容器接口(OCI)标准的一部分。 containerd与docker相兼容,相比docker轻量很多,目前较为成熟。 ## 主机间做信任 在master节点上生成秘钥文件,并把它上传到其他两台机上,做好免密登录,方便后续的操作。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065562359970114.png) 执行`ssh-copy-id root@192.168.248.129`命令实现免密登录,其他两台做同样的操作。 ## 安装ansible工具 `ansible`工具主要为了后续多台机器执行同样的命令,从而提供效率用的。安装方式也很简单,通过yum源安装即可。执行如下两条命令: ```shell [root@master ~]# yum install epel-release -y [root@master ~]# yum -y install ansible ``` 配置`/etc/ansible/hosts`,该文件是存放要操作的主机,把上述三台机器加入一个组名字为`k8s`,如下: ```shell [k8s] 192.168.248.128 192.168.248.129 192.168.248.130 ``` 通过执行ansible命令测试连通性,如下图: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065635022984293.png) > -m:是指定ansible的模块,ping是ansible其中一个模块,该模块主要是测试主机的连通性。 > k8s:刚定义的组名 # 升级内核版本 检查当前 `CentOS `系统内核版本 ,执行如下命令查看: ```shell [root@localhost ~]# uname -sr Linux 3.10.0-1160.el7.x86_64 ``` 检查发现当前内核版本是3.10, ## 使用elrepo源升级内核 配置elrepo源,执行如下命令 ```powershell rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm ``` ## 查看最新版内核 执行如下命令查看最新的内核版本 ```shell yum --disablerepo="*" --enablerepo="elrepo-kernel" list available ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065712911474445.png) > 内核版本说明: > - kernel-ml #主线版本,比较新 > - kernel-lt #长期支持版本,比较旧 ## 安装最新的内核版本 执行如下命令安装主线版本: ```shell yum --enablerepo=elrepo-kernel install kernel-ml -y ``` ## 设置系统默认内核 查看系统上的所有内核版本: ```shell [root@localhost ~]# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg 0 : CentOS Linux (5.18.14-1.el7.elrepo.x86_64) 7 (Core) 1 : CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core) 2 : CentOS Linux (0-rescue-9dad18ee9dde4729b1c6df225ce69c4a) 7 (Core) [root@localhost ~]# ``` 设置默认内核为我们刚才升级的内核版本 ```shell cp /etc/default/grub /etc/default/grub-bak #备份 grub2-set-default 0 #设置默认内核版本 vi /etc/default/grub GRUB_DEFAULT=saved修改为GRUB_DEFAULT=0 ``` 重新创建内核配置 ```shell grub2-mkconfig -o /boot/grub2/grub.cfg ``` 查看默认内核 ```shell grubby --default-kernel #/boot/vmlinuz-5.18.14-1.el7.elrepo.x86_64 grub2-editenv list #saved_entry=0 ``` 更新软件包并重启 ```shell yum makecache reboot ``` # 初始化 安装K8S之前需要对系统进行一些设置,比如 关闭防火墙,selinux,swap,设置主机名,ip解析,时间同步 。 ## 关闭防火墙 通过`ansible`把三台机器的防火墙关闭,并设置开机不启动。执行如命令: ```shell ansible k8s -m shell -a "systemctl stop firewalld" ansible k8s -m shell -a "systemctl disable firewalld " ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065765643641740.png) ## 关闭selinux 通过`ansible`把三台机器的selinux永久关闭,执行如命令: ```shell ansible k8s -m shell -a "sed -i 's/enforcing/disabled/' /etc/selinux/config" ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065806500972533.png) ## 关闭swap 执行`swapoff -a` 临时关闭,通过修改/etc/fstab文件实现永久关闭。执行如下命令 ```shell ansible k8s -m shell -a "sed -ri 's/.*swap.*/#&/' /etc/fstab" ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065830661597284.png) ## 修改主机名 分别对三台主机进行主机名的修改,执行如下的命令 ```shell # 根据规划设置主机名【master节点上操作】 hostnamectl set-hostname master # 根据规划设置主机名【node1节点操作】 hostnamectl set-hostname node1 # 根据规划设置主机名【node2节点操作】 hostnamectl set-hostname node2 ``` ## 修改hosts文件 在master节点上修改hosts文件,根据规划进行修改,如下: ``` 192.168.248.130 master1 192.168.248.131 node2 192.168.248.132 node1 ``` ## 将桥接的IPv4流量传递到iptables的链 在`/etc/sysctl.d/`目录上新增`k8s.conf`,内容如下,并把该文件拷贝到其他两台机器上 ``` net.bridge.bridge-nf-call-ip6tables = 11 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 ``` ```shell ansible k8s -m copy -a "src=/etc/sysctl.d/k8s.conf dest=/etc/sysctl.d/k8s.conf" ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065860430811290.png) 执行 `sysctl --system`命令使配置生效: ```shell ansible k8s -m shell -a "sysctl --system" ``` ## 配置时间同步 使用yum命令安装`ntpdate `,如下: ```shell ansible k8s -m shell -a "yum install ntpdate -y" ``` 配置NTP网络时间同步服务器地址为 `ntp.aliyun.com`,执行如下命令: ```shell ansible k8s -m shell -a "ntpdate ntp.aliyun.com" ``` # 安装containerd 执行如下命令下载最新containerd,如下: ```shell wget https://download.fastgit.org/containerd/containerd/releases/download/v1.6.6/cri-containerd-cni-1.6.6-linux-amd64.tar.gz ``` > 如果出现无法建立 SSL 连接 加上--no-check-certificate 解压`containerd`安装包 ```shell tar -C / -zxf cri-containerd-cni-1.6.6-linux-amd64.tar.gz ``` 配置环境变量,编辑用户目录下的`bashrc`文件添加如下内容: ```shell export PATH=$PATH:/usr/local/bin:/usr/local/sbin ``` 并执行如下命令使环境变量立即生效: ```shell source ~/.bashrc ``` 执行如下命令启动`containerd` ```shell systemctl start containerd ``` 执行如下命令查看版本号,出现如下信息表明安装成功。 ```shell [root@master1 ~]# ctr version Client: Version: v1.6.6 Revision: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1 Go version: go1.17.11 Server: Version: v1.6.6 Revision: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1 UUID: c205638a-6c08-43a8-81a4-b15f97ef5cdc ``` 创建默认配置文件 ```shell mkdir /etc/containerd containerd config default > /etc/containerd/config.toml ``` ## 测试containerd是否能创建和启动成功 执行如下命令拉取镜像并创建容器: ```shell ctr i pull docker.io/library/nginx:alpine #拉取容器 ctr c create --net-host docker.io/library/nginx:alpine nginx #创建容器 ctr task start -d nginx ``` 如果启动容器出现如下报错,是由于 缺少 `runc`并升级`libseccomp`,`libseccomp`需要高于`2.4`版本。 > `containerd`在`v1.6.4`版本以后使用`v1.1.2`的`runc`和`v1.1.1`的`cni`。 ```json ctr: failed to create shim task: OCI runtime create failed: unable to retrieve OCI runtime error (open /run/containerd/io.containerd.runtime.v2.task/default/nginx/log.json: no such file or directory): fork/exec / ``` [下载链接](https://github.com/opencontainers/runc/releases/download/v1.1.2/runc.amd64),下载之后,执行如下命令安装并查看版本号: ```shell install -m 755 runc.amd64 /usr/local/sbin/runc runc -v ``` 执行如下命令升级`libseccomp`: ```shell rpm -qa | grep libseccomp #查询原来的版本 rpm -e libseccomp-2.3.1-4.el7.x86_64 --nodeps #卸载原来的版本 #下载高版本的 wget http://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm rpm -ivh libseccomp-2.5.1-1.el8.x86_64.rpm #安装 ``` # 安装kubernetes ## 添加kubernetes源 在master节点上添加k8s软件源,并分发到其他两台机器上。在`/etc/yum.repos.d/`目录下新增`kubernetes.repo`。内容如下: ```latex [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg ``` 把kubernetes.repo文件分发到其他两台机器上,执行如下命令: ```shell ansible k8s -m copy -a "src=/etc/yum.repos.d/kubernetes.repo dest=/etc/yum.repos.d/kubernetes.repo" ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065897405991036.png) ## 安装 在master节点下执行如下命令安装相应的软件: ```shell yum install -y kubelet-1.24.3 kubeadm-1.24.3 kubectl-1.24.3 ``` ## 生成默认配置并修改相应的参数 通过如下命名生成一个默认的配置文件: ```powershell kubeadm config print init-defaults > kubeadm-init.yaml ``` 根据自己的环境修改对应的参数: ```yaml apiVersion: kubeadm.k8s.io/v1beta3 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdef ttl: 24h0m0s usages: - signing - authentication kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.248.130 #master节点IP bindPort: 6443 nodeRegistration: criSocket: unix:///run/containerd/containerd.sock #containerd容器路径 imagePullPolicy: IfNotPresent name: master1 taints: null --- apiServer: timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta3 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {} dns: {} etcd: local: dataDir: /var/lib/etcd imageRepository: registry.aliyuncs.com/google_containers #阿里云容器源地址 kind: ClusterConfiguration kubernetesVersion: 1.24.3 networking: dnsDomain: cluster.local podSubnet: 10.244.0.0/16 #pod的IP网段 serviceSubnet: 10.96.0.0/12 scheduler: {} ``` ## 初始化 执行如下命令进行初始化: ```shell kubeadm init --config=kubeadm-init.yaml --v=6 ``` > --config:指定根据那个配置文件进行初始 > --v:指定日志级别,越高越详细 初始化成功后,会出现以下信息 ```shell ...省略... Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.248.130:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:e9e29c804f92193928f37ca157b73a7ad77e7929314db98855b3ba6e2ce2273d ``` 按照初始化成功提示信息,做如下操作: ```shell mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config ``` 接下来执行`kubectl`就可以看到`node`了 ```shell [root@master1 .kube]# kubectl get node NAME STATUS ROLES AGE VERSION master1 Ready control-plane 55m v1.24.3 ``` 查看k8s各部件启动情况,执行如下命令: ```shell kubectl get pod --all-namespaces -o wide ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065927835960442.png) 通过观察发现`coredns`部件没有运行成功,通过如下命令查看原因: ```shell describe pod coredns-74586cf9b6-c2ddb --namespace=kube-system ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659065970164571642.png) > 根据官方的解析是没有部署CNI,coredns是不会启动的。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659066136690220591.png) ## node节点配置 node节点安装kubeadm ```shell cat /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF ``` 安装相关组件 ```shell yum install -y kubeadm-1.24.3 --disableexcludes=kubernetes ``` 添加join命令 ```powershell kubeadm join 192.168.248.130:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:e9e29c804f92193928f37ca157b73a7ad77e7929314db98855b3ba6e2ce2273d ``` 如果我们后续需要添加node节点时,可以到master节点执行下面的命令获取`token`相关信息 ```shell [root@master1 ~]# kubeadm token create --print-join-command kubeadm join 192.168.248.130:6443 --token ydqnz1.6b0q5ntkvos9z2ir --discovery-token-ca-cert-hash sha256:c0b6f7fb38c7c9764084beb7dd26c9acef027ae6b7d2673572b4c2e3a0dfd6cb ``` > 如果添加某台节点异常了,修改后可以执行 `kubeadm reset `的命令,然后在重新join加入 ## 网络配置 coredns还没启动,因为还没有安装网络插件,接下来安装网络插件,可以在[该文档中](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/)选择我们自己的网络插件,这里安装`flannel` ```shell wget http://down.i4t.com/k8s1.24/kube-flannel.yml ``` 根据需求修改网卡配置,我这里ens33为主的: ```yaml containers: - name: kube-flannel image: quay.io/coreos/flannel:v0.12.0-amd64 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr - --iface=ens33 # 如果是多网卡的话,指定内网网卡的名称 ``` > 在kubeadm.yaml文件中设置了podSubnet网段,同时在flannel中网段也要设置相同的。 (我这里默认就是相同的配置) 执行部署 ```shell kubectl apply -f kube-flannel.yml ``` ## CNI插件问题 默认情况下containerd也会有一个cni插件,但是我们已经安装Flannel了,我们需要使用Flannel的cni插件,需要将containerd里面的cni配置文件进行注释,否则2个配置会产生冲突 。 因为如果这个目录中有多个 cni 配置文件,kubelet 将会使用按文件名的字典顺序排列的第一个作为配置文件,所以前面默认选择使用的是 containerd-net 这个插件。 ```shell mv /etc/cni/net.d/10-containerd-net.conflist /etc/cni/net.d/10-containerd-net.conflist.bak systemctl restart containerd kubelet ``` 接下来我们所有的pod都可以正常运行了 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659066190540760518.png) # 验证 验证dns是否正常能解析和pod之间。这里新建一个测试的yaml文件,内容如下: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx:alpine name: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx type: NodePort ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 30001 --- apiVersion: v1 kind: Pod metadata: name: busybox namespace: default spec: containers: - name: busybox image: abcdocker9/centos:v1 command: - sleep - "3600" imagePullPolicy: IfNotPresent restartPolicy: Always ``` 执行下面命令,创建pod ```shell kubectl apply -f test.yaml ``` ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659066222393991839.png) 使用nslookup查看是否能返回地址 ```shell [root@master1 ~]# kubectl exec -it busybox -- nslookup kubernetes Server: 10.96.0.10 Address: 10.96.0.10#53 Name: kubernetes.default.svc.cluster.local Address: 10.96.0.1 [root@master1 ~]# ``` 测试nginx svc以及Pod内部网络通信是否正常 ,分别在三台机器上进行下面操作 ```powershell ping 10.104.115.26 #nginx svc ip ping 10.244.1.2 #podIP ``` 如果成功ping同说明node跟pod的网络已经打通了。否则检查`kube-proxy`的模式是否正确。 ## nodes/集群内部 无法访问ClusterIP 默认情况下,我们部署的`kube-proxy`通过查看日志,能看到如下信息:`Flag proxy-mode="" unknown,assuming iptables proxy ` **原因分析:** 并没有正确使用ipvs模式 解决方法: 1、 在`master`上修改`kube-proxy`的配置文件,添加`mode `为`ipvs`。 ```shell [root@master1 ~]# kubectl edit cm kube-proxy -n kube-system ipvs: excludeCIDRs: null minSyncPeriod: 0s scheduler: "" strictARP: false syncPeriod: 30s kind: KubeProxyConfiguration metricsBindAddress: 127.0.0.1:10249 mode: "ipvs" ``` 删除原来的POD,会自动重启kube-proxy 的pod ```shell [root@k8s-master ~]# kubectl get pod -n kube-system | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}' ``` # 扩展 在使用过程中发现kubectl 命令不能补全,使用起来很不方便。为了提高使用kubectl命令工具的便捷性,介绍一下kubectl命令补全工具的安装。 1、安装bash-completion: ```shell yum install -y bash-completion source /usr/share/bash-completion/bash_completion ``` 2、 应用kubectl的completion到系统环境: ```shell source (kubectl completion bash) echo "source (kubectl completion bash)" >> ~/.bashrc ``` 3、效果展示 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/29/1659066247701546584.png)
-
一.存储容器化存储作为基础组件,直接和本地盘打交道,所以我们一个要解决的事情就是如果Kubernetes 管理本地盘。kubernetes管理本地盘通过官方提供的local-static-provisioner自动生成LocalPersistentVolume管理磁盘。LocalPersistentVolume是Kubernetes提供的一种管理本地盘的资源。5.1 使用Statefulset管理存储容器通过statefulset 管理有状态的存储服务, 为每个pod分配一个单独的磁盘可以使用volumeClaimTemplates给每个pod生成唯一的pvc,具体规则{podName},事先准备好PVC 和 PV,通过Statefulset 我们就可以把我们的存储托管到云上了。另外借助daemonset,可以把我们gateway模块部署到每一个node上面。处理云存储的请求。5.2 存储容器化的收益1)降低运维成本基于Kubernetes和statfulset获得了滚动更新,灰度更新,健康检查,快速扩容等功能,只需要一组yaml文件就可以快速搭建一个集群,相比于传统写ansible脚本部署的方式复杂度大大降低。2)降低开发运维成本由于Kubernetes把存储抽象成StorageClass PersistentVolume PersistentVolumeClaim。我们可以通过他们管理我们的存储资源,基于Kubernetes lable的过滤功能,可以实现简单的关系查询,通过PVC与PV管理存储资源,减少管理端的开发。定位问题也能通过POD信息快速定位到问题机器和问题云盘。而且接入Kubernetes生态上的prometheus后,监控告警也能快速开发。3)隔离性增强docker限制cpu memory使用,减少进程之间资源互相干扰,进一步提升资源利用率。在做流媒体容器化过程中,各个系统 Portal 平台、中间件、ops 基础设施、监控等都做了相应的适配改造,改造后的架构矩阵如下图所示。1. Portal:流媒体 的 PaaS 平台入口,提供 CI/CD 能力、资源管理、自助运维、应用画像、应用授权(db 授权、支付授权、应用间授权)等功能。2.运维工具:提供应用的可观测性工具, 包括 watcher(监控和报警)、bistoury (Java 应用在线 Debug)、qtrace(tracing 系统)、loki/elk(提供实时日志/离线日志查看)。中间件:应用用到的所有中间件,mq、配置中心、分布式调度系统 qschedule、dubbo 、mysql sdk 等。3.虚拟化集群:底层的 K8s 和 OpenStack 集群。4.Noah:测试环境管理平台,支持应用 KVM/容器混合部署。一.CI/CD 流程改造主要改造点:应用画像: 把应用相关的运行时配置、白名单配置、发布参数等收敛到一起,为容器发布提供统一的声明式配置。授权系统: 应用所有的授权操作都通过一个入口进行,并实现自动化的授权。K8s 多集群方案: 通过调研对比,KubeSphere 对运维优化、压测评估后也满足我们对性能的要求,最终我们选取了 KubeSphere 作为多集群方案。二.中间件适配改造改造关注点:由于容器化后,IP 经常变化是常态,所以各个公共组件和中间件要适配和接受这种变化。Qmq组件改造点:Broker端加快过期数据的处理速度。原因:由于IP变化频繁,对于一个主题有几百个甚至上千个的IP订阅,会产生很多文件Qconfig/Qschedule组件改造点:按实例级别的推送、任务执行在容器场景下不建议使用 。原因:因为IP经常变化,在容器化场景下发布、pod驱逐等都会导致IP变化,按实例维度推送没有意义Dubbo组件改造点:更改上线下线逻辑,下线记录由永久节点改为临时节点。 原因:上下线机制加上频繁的IP变更会导致zookeeper上产生大量的过期数据Openresty改造点:监听多K8s集群的endpoint变更,并更新到upstream; KVM、容器server地址共存,支持KVM和容器混合部署;三应用平滑迁移方案设计为了帮助业务快速平滑地迁移到容器,制定了一些规范和自动化测试验证等操作来实现这个目标。1.容器化的前置条件: 应用无状态、不存在 post_offline hook(服务下线后执行的脚本)、check_url 中不存在预热操作。2.测试环境验证: 自动升级 SDK、自动迁移。我们会在编译阶段帮助业务自动升级和更改 pom 文件来完成 SDK 的升级,并在测试环境部署和验证,如果升级失败会通知用户并提示。3.线上验证: 第一步线上发布,但不接线上流量,然后通过自动化测试验证,验证通过后接入线上流量。4.线上 KVM 与容器混部署:保险起见,线上的容器和 KVM 会同时在线一段时间,等验证期过后再逐步下线 KVM。5.线上全量发布: 确认服务没问题后,下线 KVM。6.观察: 观察一段时间,如果没有问题则回收 KVM。
推荐直播
-
华为AI技术发展与挑战:集成需求分析的实战指南
2024/11/26 周二 18:20-20:20
Alex 华为云学堂技术讲师
本期直播将综合讨论华为AI技术的发展现状,技术挑战,并深入探讨华为AI应用开发过程中的需求分析过程,从理论到实践帮助开发者快速掌握华为AI应用集成需求的框架和方法。
去报名 -
华为云DataArts+DWS助力企业数据治理一站式解决方案及应用实践
2024/11/27 周三 16:30-18:00
Walter.chi 华为云数据治理DTSE技术布道师
想知道数据治理项目中,数据主题域如何合理划分?数据标准及主数据标准如何制定?数仓分层模型如何合理规划?华为云DataArts+DWS助力企业数据治理项目一站式解决方案和应用实践告诉您答案!本期将从数据趋势、数据治理方案、数据治理规划及落地,案例分享四个方面来助力企业数据治理项目合理咨询规划及顺利实施。
去报名
热门标签