K8S实战笔记--7(容器损坏 + 负载均衡原理简述 + 线上Linux服务器优化经验)
在学习K8S时,系统管理人员需要了解有哪些Disruption(损坏)可能发生在Pod上。
1. 容器损坏
1.1 非自愿的损坏
包括:节点资源耗尽、管理员操作失误、集群硬件损坏等等。为了弥补此类损失,我们应当确保Pod申请合适的计算资源并为程序准备足够的副本数目,若想保证更高的高可用,需要将副本分布在多个机架上。
1.2 自愿的损坏
集群中自愿的Pod损坏不同于我们常规意义上的“损坏”,它指的是由集群管理员或应用管理员主动执行的导致Pod删除、停止或重启的操作。这些操作包括:删除Pod的控制器、修改Pod定义致其重启、删除Pod(以便重新调度或单纯的删除)、排空节点(以便升级维护或集群收缩),这些操作可能是管理员执行的,也可能是由设定的脚本执行的。自愿发生的损坏频率不定,所以K8S提供了Disruption Budget
用于在有可能高频次地发生自愿毁坏的情况下,仍能运行高可用的应用程序。
1.3 Disruption Budget
管理员可以为每个应用创建一个PodDisruptionBudget
对象,此对象限制了在应用程序发生自愿的损坏时,有多少个副本可以被同时停止。例如:一个前端应用程序应当保证在可用的副本数目不能低于总副本数目的一定比例,若某应用程序有5个副本,而该应用的PodDisruption
对象规定了最小副本数目为4(副本期望值),则此时系统只会允许1个而不是更多的副本进行自愿损毁。鉴于此保护特性,管理员在集群维护时,应当使用兼容PodDisruptionBudget
的工具,避免Pod或Deployment被直接删除。兼容PodDisruptionBudget
的工具例如kubectl drain
,该工具会尝试将节点上的所有Pod全部驱逐,在驱逐指令遭到拒绝时,将会周期性地请求直到该节点上的所有Pod都被终止或超出了设定的超时时间。
那么PodDisruptionBudget
如何完成此操作呢?PDB通过Pod的.metadata.ownerReferences
查找到其对应的控制器;通过 控制器的.spec.replicas
字段来确定期望的副本数;通过控制器的abel selector
来确定哪些Pod属于同一个应用程序。但是PDB并不能阻止非自愿毁坏的发生,当这类毁坏发生时,会被计入当前毁坏数里,通过kubectl drain
驱逐Pod时,Pod将被gracefull terminate
。举个例子:假设某集群中共有三个节点,每个节点的资源可容纳两个Pod。node01
上拥有Podpod-a
与pod-x
,node02
上拥有pod-b
,node03
上拥有pod-c
。其中,pod-a
、pod-b
与pod-c
同属一个应用程序,且具有对应的PDB对象,限制了其最少Pod数目为2,pod-x
为独立于此应用程序的Pod,没有PDB与之对应。在管理员想要进行集群维护升级时,需要排空节点中的Pod以便更新机器。首先排空node01
,在使用kubectl drain
进行节点的排空时,该节点上的Pod会被驱逐,pod-a
与pod-x
都进入了terminating
状态。管理pod-a
与pod-x
的控制器检测到Pod正在停止,立刻做出决策分别创建新的Podpod-a1
与pod-x1
,由于当前节点资源已不可用,需要将Pod调度到集群中的其它节点,于是pod-a1
被调度到了node02
,pod-x1
被调度到了node03
。此时,考虑到节点资源限制,集群中剩余两台节点已无法支持调度更多的Pod。此时,若管理员继续选择排空node02
,kubectl drain
按照顺序依次驱逐pod-b
与pod-a1
。在驱逐pod-b
时,操作将被接受,在驱逐pod-a1
时,操作将被拒绝,因为该应用程序的PDB规定了同一时刻至少要有两个Pod可用,否则其可用Pod将只剩一个。在进行pod-b
的驱逐操作中,控制器创建一个pod-b1
来代替pod-b
,但由于集群已无剩余可用资源,没有办法进行pod-b1
的调度,所以此时的kubectl drain
将再次被拒绝。如此,集群的维护操作将无法继续,除非管理员将更多的节点添加入集群。在此时,我们将不得不接受更新所导致的停机,或故障转移至另外的集群副本,但这样带来的代价将是极大的,所以我们最好编写容错的应用程序并使用PDB。
在我们无法防止应用被自愿损坏时,我们应当思考如何应对应对此类损坏。对于常见的应用,可以分为:
- 无状态的前端:最低可用不得低于90%;
- 单实例有状态的应用:未经允许不得随意关闭应用程序,可以不使用PDB并容忍偶尔的停机;或使用PDB设置最大不可用为0,与集群管理员达成一致,做好应对后续处理的准备;
- 多实例有状态的应用:不能将实例数降低至某个值,否则会写入失败,可以将最大不可用设为1,或设置最小可用数目为最低数目
- 可以重新开始的批处理任务:在发生自愿损坏时,Job仍需要完成其任务,此时不需要设置PDB,Job会新建一个Pod用于替换已损坏的Pod。
在指定可用或不可用比例时,我们有时很难判断在计算结果不是整数时究竟应当如何取值,此时系统将选择向上取整。
2. 集群的LVS负载均衡
- 系统扩展方式
- 向上扩展 升级机器
- 向外扩展 增加机器
- 集群类型
- LB 负载均衡
- HA 高可用
- HPC 高性能
- 均衡负载的实现
- 硬件 购买机器
- 软件 LVS Nginx等
- 会话保持的负载均衡
session sticky
cookie绑定session replication
session复制session server
session服务器
- keepalived + LVS用于避免会话调度器单点失败
- LVS由章文嵩博士开发 后来被Linux服务器集成至内核中 工作原理为 VS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS 根据调度算法来选择RS
- VS 即virtual server 用于调度
- RS 即Real server 用于真正提供服务
- L4 四层路由器或交换机
- CIP 客户端IP
- VIP VS的外网IP
- DIP VS的内网IP
- RIP RS的IP
- 访问流程 CIP <–> VIP == DIP <–> RIP
- LVS集群的类型
- lvs-nat 修改请求报文的目标IP 多目标IP的DNAT(变目标IP)
- lvs-dr LVS默认模式 操纵封装新的MAC地址(变MAC)
- lvs-tun 在原请求IP报文之外新加一个IP首部
- lvs-fullnat 修改请求报文的原和目标IP
- LVS工作模式
- VS/NAT
- 服务器类型 任意类型
- 网络模式 私网地址
- 服务器数量 10-20
- 服务器网关 load balancer
- VS/TUN
- 服务器类型 支持Tunneling
- 网络模式 LAN/WAN
- 服务器数量 100
- 服务器网关 自己的路由器
- VS/DR
- 服务器类型 无ARP设备
- 网络模式 LAN
- 服务器数量 100
- 服务器网关 自己的路由器
- VS/NAT
- 静态调度算法
- RR 轮询
- WRR 加权调度
- SH 原哈希 用于实现session绑定 将来自于同一个IP的请求始终法网第一次挑中的RS
- DH 目标地址哈希 正向代理 将发往同一个目标地址的请求始终发往第一次挑中的RS 如宽带运营商
- 动态调度算法 考虑后端负载情况 overhead负载 activeconns活动连接数 inactiveconns非活动连接数
- LC least connections 适用于长连接 ovh = act * 256 + ina 值越小 调度越多
- WLC 加权的LC 根据性能为机器设置好权重 ovh(LC)/weight 值越小 调度越多
- SED shortest expection delay 初始权重高者优先 用于解决加权LC集群使用初期act为0的情况 ovh = (act + 1) * 256 / weight
- NQ never queue 第一轮均匀分配 后续使用SED
- LBLC locality-based LC 动态D 适用于根据负载状态实现正向代理
- LBLCR LBLC with replication 带复制的LBLC 用于解决LBLC负载不均衡问题 从负载重的复制到负载轻的RS
3. 线上Linux调优经验
- 磁盘策略
- 系统盘 raid1
- 数据盘 多种选择
- raid0 两块数据盘在逻辑上组合成一块盘
- raid1 两块盘形成主备关系 高可用 安全性
- raid5 至少三块盘 奇偶校验模式 常用读写盘
- raid10 在raid0基础上建设raid1 满足高可用 但浪费较大 适用对数据要求高的服务器 性能高 价格昂贵
- 分区策略
- 系统分区于数据分区分离
- 不适用LVM(逻辑卷管理) LVM提供中间服务 磁盘修复概率低
- 多分区原则(/ /boot /var /usr…)
- swap策略
- 即便大内存服务器也有物理内存耗尽的风险 所以针对业务需求设置不同体量的swap是必要的
- 精简安装策略 仅安装需要的开发包 基本网络包 基本应用包 按需安装
- 服务器网络配置
- IP
/etc/sysconfig/network-scripts/
- 重启网卡
service network restart
- 网关 主机名配置
/etc/sysconfig/network
若IP配置文件中配置了网关 优先生效IP配置文件 - DNS
/etc/resolv.conf
- HOSTS
/etc/hosts
- IP
- 网络安全配置
- 关闭selinux
setenforce 0
- iptables配置示例
/etc/sysconfig/iptables
- 清除所有规则和计数器
iptables -F
iptables -X
- 设置默认策略拒绝所有传入传出流量
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
- 允许回环接口用于本地通信
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
- 允许SSH端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
- 允许HTTP端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
- 查看iptables策略
iptables -L -n
- 关闭selinux
- 登录安全与SSH
/etc/sudoers
- 文件格式
<user list><host list> = <operator list><tag list><command list>
- user list 用户列表
- host list 主机列表
- operator list 用户与用户组列表
- tag list 决定是否需要密码
- command list 命令列表
- 文件格式
- 常见配置
user1 ALL=(ALL) NOPASSWORD:ALL
- SSH安全
- 备份SSH配置
cp /etc/ssh/sshd_config sshd_config_bak
- 关闭SSH反查 可提高SSH连接速度
UseDNS no
- 关闭GSSAPI验证 可提高SSH连接速度
GSSAPIAuthentication no
- 禁止root账号登录 防止暴力破解
PermitRootLogin no
- SSH 端口默认22且被注释 22端口暴露在公网中十分危险 防止被恶意扫描 设为4位以上的数字可降低被扫描的机率
Port 2222
- 备份SSH配置
- yum源
- 更新yum源
- 升级内核
yum update
- 服务器时间
- 通过crontab设置时间同步
- 或通过ntp server校准时间
- 系统资源调优
unlimit -a
列出资源信息unlimit -n
配置系统打开的最大连接数- 常见问题
java.net.SocketException: Too many open files
打开太多文件 解决方法- 修改
/etc/security/limits.conf
(主配置文件) 与/etc/security/limits.d/90-nproc.conf
添加如下内容* soft nofile 65536
* hard nofile 65536
- 修改完成后需要重启当前终端观察是否生效 随后重启java进程
- 修改
- 常见问题
unlimit -u
最大用户数- 修改最大用户数 在上述两个文件中添加
* soft nproc 65536
root soft nproc unlimited
- 系统最大连接数是系统根据资源计算得出的 若修改后的设置值低于该默认值才生效 否则不生效 观察该更改不需要重启终端
- 常见问题
kernel: ip_conntrack: table full, dropping packet
常出现于web线上服务器 解决方法- 调整
ip-conntrack max
参数 根据业务量调整为足够即可 - 修改完成后执行
sysctl -p
使其生效
- 调整
- 修改最大用户数 在上述两个文件中添加
swappiness
- 表示适用swap的概率 值越大适用swap的概率越大
- 推荐配置
/etc/sysctl.conf
中vm.swappiness = 10
表示内存超过100% - 10% = 90%时才适用swappiness - 查看当前配置
cat /proc/sys/vm/swappiness
默认值为60 - redis官方指明实用redis时 此值应当为0 否则redis效率低下
- 精简系统服务与开机进程
- 建议开启的服务
- crond
- netword
- syslog
- sshd
- iptables
- sshd
- iptables
- udev-post
- sysstat
- 快捷开启的方法
- 先关闭所有服务
for serv in `chkconfig --list | grep 3: on | awk '{print $1}'`; do chkconfig --level 3 $serv off; done
- 再开启所有服务
for serv in `crond network syslog sshd iptables udev-post sysstat`; do chkconfig --level 3 $serv on; done
- 先关闭所有服务
- 可删除的系统用户和组
- 删除不必要的用户
userdel
amd Ip sync shutdown halt news nncp video games gopher ftp - 不必要的群组
groupdel
amd Ip news uucp games dip
- 删除不必要的用户
- 建议开启的服务