服务器搭建k8s内存需要多大

服务器搭建k8s内存需要多大,第1张

你好!2gb或者4gb都行
1什么是k8s?
k8s是一个docker容器管理工具
它是一个全新的基于容器技术的分布式架构领先方案,是开源的容器集群管理系统。
在docker的基础上,为容器化的应用提供部署运行,资源调度,服务发现和动态伸缩等一系列完整功能
2----k8s的优势:
a,容器编排
b,轻量级
c,开源
d,d性伸缩
e,负载均衡
二:k8s的核心功能
1自愈: 重新启动失败的容器,在节点不可用时,替换和重新调度节点上的容器,对用户定义的健康检查不响应的容器会被中止,并且在容器准备好服务之前不会把其向客户端广播。
d性伸缩: 通过监控容器的cpu的负载值,如果这个平均高于80%,增加容器的数量,如果这个平均低于10%,减少容器的数量
服务的自动发现和负载均衡: 不需要修改您的应用程序来使用不熟悉的服务发现机制,Kubernetes 为容器提供了自己的 IP 地址和一组容器的单个 DNS 名称,并可以在它们之间进行负载均衡。
滚动升级和一键回滚: Kubernetes 逐渐部署对应用程序或其配置的更改,同时监视应用程序运行状况,以确保它不会同时终止所有实例。 如果出现问题,Kubernetes会为您恢复更改,利用日益增长的部署解决方案的生态系统。

本文讲解kubernetes内的dns服务。

每个集群内的service都分配得有一个dns 名称,默认情况下一个客户端POD的DNS搜索将会包含POD自己名称空间以及CLUSTER默认域名。如:

A record通常是一个域名指向一个IP地址。

命名端口需要SRV记录,这些端口正常是service 或者是headless services的一部分,SRV格式记录如: _my-port-name_my-port-protocolmy-svcmy-namespacesvccluster-domainexample

当前,创建 Pod 后,它的主机名是该 Pod 的 metadataname 值。可以通过设置hostname 来重新主机名,此外还可以设置subdomain来指定pod的子域名。
如:Pod 的主机名 annotation 设置为 “foo”,子域名 annotation 设置为 “bar”,在 Namespace “my-namespace” 中对应的 FQDN 为 “foobarmy-namespacesvcclusterlocal”。

例:

如果 Headless Service 与 Pod 在同一个 Namespace 中,它们具有相同的子域名,集群的 KubeDNS 服务器也会为该 Pod 的完整合法主机名返回 A 记录。 例如,在同一个 Namespace 中,给定一个主机名为 “busybox-1” 的 Pod,子域名设置为 “default-subdomain”,名称为 “default-subdomain” 的 Headless Service ,Pod 将看到自己的 FQDN 为 “busybox-1default-subdomainmy-namespacesvcclusterlocal”。 DNS 会为那个名字提供一个 A 记录,指向该 Pod 的 IP。 “busybox1” 和 “busybox2” 这两个 Pod 分别具有它们自己的 A 记录。

踩坑完毕,回到主线。

前面关于port的理解存在偏差,需要用实验来确认port配置的含义。

k8s官方文档对于对于这些配置项的解释还是没有很完善。下面是在其他博文中找到的解释。

已知:

从k8s集群内部的宿主机(物理机、虚拟机)可以直接访问pod的服务地址 ip:80

未知(需要测试):

1、同一局域网内,但没有加入k8s集群的其他服务器能否访问pod的服务地址 ip:80---无法访问

2、能否跳过pod直接访问容器的服务地址 ip:80---没查到ip

首先要知道容器的IP地址

可以看到上面的命令查出的结果是 - 无法看出ip,尝试进入容器查看

然后我就没辙了,不过根据linux系统的精神,所有内容都是文件,但是我google了好久也没找到ip地址到底存在哪一个文件中。然后我就怀疑是不是一定要容器开放端口,ip地址才可以用docker inspect查询,起了一个不开端口的容器,结果也是有ip的。后来问了一个底层开发的朋友,据说ip是不写文件的。

那只能先认为通过k8s启动的容器其实是没有容器ip的。

从侧面看,也很有可能k8s启动的容器确实没有ip

3、访问pod所在的主机的80端口能否返回相同的响应---无法访问

从以上的信息来看,这个port配置应该和docker中暴露端口的意思是一样的,例如下面的例子

来做一下实验:

在我们之前的pod配置文件上增加配置,如下

结果和我们之前的猜测保持一致,增加ports的配置之后,访问宿主机的ip:80也可以访问到pod的内容了。

我这里pod ip 是 101913067,宿主机是 101001237。curl 101913067 和 curl 101001237 得到的结果是一样的。正当我想再仔细看看的时候,服务器又挂了,wc,只能明天找网管重启了。

---第二天

昨天,我还想看看

1、关了这个pod之后是否就不能访问了

启动了2个pod如下,mynginx1没有配置ports,mynginx2配置了ports。

当我关了pod-mynginx2之后访问宿主机101002167应该就不能通了,结果居然是---能访问到!

大吃一惊!结果ip弄错了,宿主机不是101002167,而是101001237,犯了个低级错误。

结果如下:这回和预期的结果终于一样了。

2、宿主机上是不是本身就开启了nginx,所以恰巧就能访问

确认宿主机上没有开启nginx

3、宿主机上的端口开放情况

使用netstat查看宿主机的端口开放,居然没有发现80端口开着,好奇怪。

那如果在101001237宿主机上启动一个nginx端口开在80,结果会是什么样子呢。

我居然启动了,没有端口已被占用的报错。现在把宿主机上的nginx的index页面的内容改一下,看访问101001237:80时,到底访问的是哪一个nginx。

分别从集群内部3台服务器和集群外部1台服务器的机器取访问101001237:80,访问到的都是pod中的nginx。

会不会跟启动顺序有关,因为现在的情况是先启动了pod-nignx,后启动 宿主机-nginx,那现在将pod-nginx关闭,访问101001237:80,看是啥。

集群内部3台服务器和集群外部1台服务器访问101001237:80,结果一致,都是宿主机-nginx。

再启动pod-nginx,查看结果。

访问结果又变回pod-nginx了,4台服务器结果一致。

再去看一下宿主机-nginx的日志,有没有报错信息-----------没有错误日志

现在基本可以得出结论了:当pod和宿主机同时使用某一个端口时,不会因为冲突而报错,但是pod会优先占用端口,而与启动顺序无关。

至于为什么会这样,就不去深究了,毕竟精力有限,作为运维实施,了解到这样子的程度应该够用了。

自从我们的kubernetes集群部署到生产环境后,将流量从原有的服务器上切过来之后,部分节点出现挂载目录容量爆满的情况。

运维的同事报给我们之后,我们首先想到的是节点镜像过多,于是我们提供一个命令用于清理当前节点上无用的、报错的、镜像和docker资源文件

docker system prune  命令可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及dangling镜像(即无tag的镜像)

docker system prune -a 命令清理得更加彻底,可以将没有容器使用Docker镜像都删掉。

待运维执行之后,目录存储资源释放了一些,我们本以为这就告一段落了。然而,事与愿违,没过多久,再次容量报警。。。

我们开始重视起来,开始检视节点上工作的容器,发现在日志爆炸的节点上运行了定时任务,开发人员将定时任务的日志输出到控制台,于是我们回到节点docker的工作目录,通过 du -sh 方式查看每个文件夹大小,发现docker目录下containers目录占用空间巨大,进去看原来是每个运行的容器存放日志的目录,我们找出占用空间最大的日志目录,发现容器日志特别的大

我们可使用如下命令查看各个日志的文件大小

ls -lh $(find /var/lib/docker/containers/ -name -jsonlog)

那我们如何清理日志呢,如果docker容器正在运行,那么使用rm -rf 方式删除日志后,通过df -h会发现磁盘空间并没有释放

原因:在Linux或者Unix系统中,通过rm或者文件管理器删除文件将会从文件系统的目录结构上解除链接(unlink)然而如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也一直被占用

我们通过 cat /dev/null > -jsonlog 来清理相应的日志,然后重启

systemctl daemon-reload

systemctl restart docker

然而,我思考,不能每次满的时候找运维清理日志啊,这多麻烦,难道docker没有相应的机制应付输出到控制台的日志吗?答案是:当然不会

在新版的docker中我们可以通过设置 vim /etc/docker/daemonjson 来限制docker的日志量

"log-driver":"json-file","log-opts":{ "max-size" :"200m","max-file":"5"}

顾名思义max-size就是每个日志文件大小,max-file是最多生成的文件数,如上我设置成功后,每个容器运行的日志最多有五份每份200M大小,这样就基本限制了容器的日志大小。

然后你觉得结束了吗??并不!!

容器日志我们是限制完了,本以为高枕无忧,不用担心出现日志爆满的情况了,但是事与愿违,过几天硬盘容量又满了。。。

我们究其原因,发现在docker的运行目录下overlay这个文件夹里存放着所有的容器挂载目录,也就是容器的系统文件在这里放着,在容器中跑着的服务产生日志很可能并不是输出到控制台,而是保存到本地,容器内的日志文件也是会占用磁盘空间的,这就让我们犯愁了,这个不好限制开发团队不存日志或者规定团队存放目录啊,对于一个成熟的容器平台来说,海纳百川那是必须的~

于是我们打起了kubelet的主意

在 k8s中文社区中有详细的限制方法  那具体做法呢,其实就是为节点加上驱逐策略,当cpu或者内存或者硬盘空间不满足要求时,自动驱逐一些消耗资源大的容器,保证节点稳定性。

里面主要是有以下几个关键驱逐信号
上面的每个信号都支持整数值或者百分比。百分比的分母部分就是各个信号的总量。kubelet 支持两种文件系统分区。

nodefs:保存 kubelet 的卷和守护进程日志等。

imagefs:在容器运行时,用于保存镜像以及可写入层。

imagefs 是可选的。Kubelet 能够利用 cAdvisor 自动发现这些文件系统。Kubelet 不关注其他的文件系统。所有其他类型的配置,例如保存在独立文件系统的卷和日志,都不被支持。

因为磁盘压力已经被驱逐策略接管,因此未来将会停止对现有 垃圾收集 方式的支持。

具体的内容大家可以详细去看看社区里的介绍,我这里就不再赘述了,我这边献上我的驱逐方案~

执行vim /etc/systemd/system/kubeletserviced/10-kubeadmconf

在里面插入

Environment="KUBELET_OTHER_ARGS=

--eviction-hard=memoryavailable<2Gi,nodefsavailable<5Gi,imagefsavailable<5Gi 

--eviction-minimum-reclaim=memoryavailable=500Mi,nodefsavailable=5Gi,imagefsavailable=5Gi 

--node-status-update-frequency=10s 

--eviction-pressure-transition-period=30s"

解读:内存小于2G驱逐,root目录磁盘空间小于5G驱逐,镜像目录磁盘空间小于5G驱逐,节点检测为每10秒一次,在跳出压力状态之前要等待的时间为30秒。

在某些场景下,驱逐 Pod 可能只回收了很少的资源。这就导致了 kubelet 反复触发驱逐阈值。另外回收资源例如磁盘资源,是需要消耗时间的。

要缓和这种状况,Kubelet 能够对每种资源定义 minimum-reclaim。kubelet 一旦发现了资源压力,就会试着回收至少 minimum-reclaim 的资源,使得资源消耗量回到期望范围。

也就是说当内存触发驱逐时,kubelet至少要让内存有25G,当root和镜像磁盘空间发生驱逐时,kubelet至少要让磁盘有10G的空间。

那驱逐的规则是什么呢,对什么样的容器做驱逐呢?这个我们下回分解哈。

那总的来说,若要解决节点镜像存储报警,我们可以从三个方面入手

1容器:通过docker限制容器日志大小

2k8s:通过kubelet来驱逐过大的容器

3跟开发人员沟通,精简容器,不让内存泄漏,不随意使用资源(很难啦~~~)

                                                                                                                                    祝各位新春快乐~


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/13082983.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-08-29
下一篇2025-08-29

发表评论

登录后才能评论

评论列表(0条)

    保存