一、实验环境
系统版本:CentOS7.6
内核版本:3.10.0-957.el7.x86_64
kubernetes版本:1.23.6
docker版本:docker-ce-20.10.9-3.el7
角色 IP地址 节点主机名 硬件配置 系统 master 172.17.0.41 master01 4c4g CentOS7.6 master 172.17.0.42 master02 4c4g CentOS7.6 node 172.17.0.31 slave01 4c4g CentOS7.6 node 172.17.0.32 slave02 4c4g CentOS7.6
二、 配置hosts信息(全部节点都要操作)
cat >> /etc/hosts <<EOF
172.17.0.41 master01
172.17.0.42 master02
172.17.0.31 node01
172.17.0.32 node02
EOF
三、修改主机名
master01
hostnamectl set-hostname master01
master02
hostnamectl set-hostname master02
node01
hostnamectl set-hostname slave01
node02
hostnamectl set-hostname slave02
四、修改 .bashrc 环境变量(全部节点都要操作)
cat > .bashrc <<EOF
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias ll='ls -l --color=auto --time-style=long-iso'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
export LANG=en_US.UTF-8
export PS1='[\[\e[36;1m\]\u@\[\e[32;1m\]\$(hostname)\[\e[31;1m\] \t\[\e[36;1m\]\w\[\e[0m\]]\\$ '
UserIP=\$(who -u am i | cut -d"(" -f 2 | sed -e "s/[()]//g")
export HISTTIMEFORMAT="[%F %T] [\$(whoami)] [\${UserIP}] "
export HISTFILESIZE=10000
export HISTSIZE=10000
shopt -s histappend
ulimit -HSc unlimited
ulimit -HSn 1024000
EOF
五、内核优化(全部节点都要操作)
cat > /etc/sysctl.conf<<EOF # sysctl settings are defined through files in # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/. # # Vendors settings live in /usr/lib/sysctl.d/. # To override a whole file, create a new file with the same in # /etc/sysctl.d/ and put new settings there. To override # only specific settings, add a file with a lexically later # name in /etc/sysctl.d/ and put new settings there. # # For more information, see sysctl.conf(5) and sysctl.d(5). # # 减少DDoS攻击,校验数据包的反向路径,如果反向路径不合适,则直接丢弃数据包,避免过多的无效连接消耗系统资源 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # 接收带有SRR选项的数据报。主机设为0,路由设为1 net.ipv4.conf.default.accept_source_route = 0 # 因为打开sysrq键的功能以后,有终端访问权限的用户将会拥有一些特殊的功能,所以生产上不建议打开 kernel.sysrq = 0 # 生产程序错误Core文件时文件名是否添加应用程序pid做为扩展 kernel.core_uses_pid = 1 # Core文件命令规则 kernel.core_pattern = core-%e-pid%p-uid%u-gid%g-timestamp%t # 服务器资源不足的情况下,尽量把syn请求缓存起来,留着有能力的时候再处理这些TCP的连接请求 net.ipv4.tcp_syncookies = 1 # 消息队列的最大消息大小,默认8k,建议64kb kernel.msgmax = 65536 # 增三次握手大半连接队列,backlog和somaxconn同时增加,SYNC等待队列长度,适当,太大了排队也没用 net.ipv4.tcp_max_syn_backlog = 65536 # 请求队列,超过的请求将会存储在这里 # 如web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而 nginx 定义的 NGX_LISTEN_BACKLOG 默认511,所以有必要调整这个值。 # net.core.somaxconn 的值不能超过65535,所以这边配置为一半,设置大多没用 net.core.somaxconn = 32768 # socket缓冲区默认值和最大值,读写 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 # 禁用TCP时间戳(会在TCP包头增加12个字节),增加了报文大小,高并发下设置为0 net.ipv4.tcp_timestamps = 0 # 允许重用TCP连接 net.ipv4.tcp_tw_reuse = 1 # 发送 SYNC+ACK 的重试次数,不宜太大,5以内,重传会经历 1(确认连不上)、2(第一次重试)、4 秒 net.ipv4.tcp_synack_retries = 2 # 发送SYNC的重试次数,不宜太大,5以内 net.ipv4.tcp_syn_retries = 2 # 开启数据包转发,keepalived+HA+MQ之间需要转发 net.ipv4.ip_forward = 1 # 开启绑定本机不存在的 IP,默认是关闭的 net.ipv4.ip_nonlocal_bind = 1 # ACCEPT等待队列长度,适当,太大了堆积也无用 net.core.netdev_max_backlog = 65535 # 单个消息队列中允许的最大字节长度(限制单个消息队列中所有消息包含的字节数之和) kernel.msgmnb = 131070 # 系统中同时运行的消息队列的个数 kernel.msgmni = 4096 # 不开启快速回收time_wait,对于长链接不应该开启,如果产生很多time_wait可以启动该参数 # 不建议快速回收,但可以重用TCP,否则NAT环境会有问题 # 该参数比较适用于客户端,所以作为服务器一般设置为0(关闭) net.ipv4.tcp_tw_recycle = 0 #同样有3个值,意思是: #net.ipv4.tcp_mem[0]:低于此值,TCP无内存压力。 #net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段。 #net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket。 #上述内存单位是页,而不是字节。可参考优化值是:786432 1048576 1572864(*16) net.ipv4.tcp_mem = 12582912 16777216 25165824 net.ipv4.tcp_rmem = 4096 4096 16777216 net.ipv4.tcp_wmem = 4096 4096 16777216 # 系统作为TCP客户端连接自动使用的端口(start,end),可发起并发连接数为end-start net.ipv4.ip_local_port_range = 1024 65535 # 对sack协议加以完善,改进tcp的拥塞控制机制 net.ipv4.tcp_fack = 1 # 是对sack的改进,能够检测不必要的重传 net.ipv4.tcp_dsack = 1 # 管理TCP的选择性应答,允许接收端向发送端传递关于字节流中丢失的序列号,减少了段丢失时需要重传的段数目,当段丢失频繁时,sack是很有益的 net.ipv4.tcp_sack = 1 #系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上,如超过,连接将即刻被复位并打印警告信息,这个限制仅是为防止简单的DoS攻击,不能过分依靠它或人为减小这个值,更应该增加这个值(如果增加内存后)。 net.ipv4.tcp_max_orphans = 3276800 # swappiness,Linux内核参数,控制换出运行时内存的相对权重。swappiness参数值可设置范围在0到100之间。 低参数值会让内核尽量少用交换,更高参数值会使内核更多的去使用交换空间。默认值为60(参考网络资料:当剩余物理内存低于40%(40=100-60)时,开始使用交换空间)。对于大多数操作系统,设置为100可能会影响整体性能,而设置为更低值(甚至为0)则可能减少响应延迟。高并发的情况下10-30,容器话情况下建议为0,但0并非禁用SWAP,只是充分利用物理内存 vm.swappiness = 0 # 绑定本机不存在的 IP, 本机服务有 HAproxy 或 Nginx 需要用到 net.ipv4.ip_nonlocal_bind = 1 # 内核日志级别,别一共有8个级别 # kernel.printk = 6 4 1 7 # 该文件有四个数字值,它们根据日志记录消息的重要性,定义将其发送到何处,关于不同日志级别的更多信息,请阅读syslog。该文件4个值为: # 控制台日志级别,优先级高于该值的消息将打印值控制台。 # 缺省消息日志级别:将用该优先级来打印没有优先级的消息。 # 最低的控制台日志级别:控制台日志级别可被设置最小值(最高优先级) # 缺省的控制台日志级别:控制台日志级别的缺省值、 # 缺省设置:6 4 1 7 # time_wait空闲60s就回收 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10 # 整个系统的最大数量的消息队列 kernel.msgmni=4096 # 路由缓存刷新频率,当一个路由失败后多长时间跳到另一个,默认是300 net.ipv4.route.gc_timeout = 100 #如果arp_announce参数配置为0,则网卡在发送arp请求时,可能选择的源IP地址并不是该网卡自身的IP地址,这时候收到该arp请求的其他节点或者交换机上的arp表中记录的该网卡IP和MAC的对应关系就不正确,可能会引发一些未知的网络问题,存在安全隐患。所以DR模式下要求arp_announce参数要求配置为2。 net.ipv4.conf.default.arp_announce = 2 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.all.arp_announce = 2 # 因为DR模式下,每个真实服务器节点都要在环回网卡上绑定虚拟服务IP。这时候,如果客户端对于虚拟服务IP的arp请求广播到了各个真实服务器节点,如果arp_ignore参数配置为0,则各个真实服务器节点都会响应该arp请求,此时客户端就无法正确获取LVS节点上正确的虚拟服务IP所在网卡的MAC地址。假如某个真实服务器节点A的网卡eth1响应了该arp请求,客户端把A节点的eth1网卡的MAC地址误认为是LVS节点的虚拟服务IP所在网卡的MAC,从而将业务请求消息直接发到了A节点的eth1网卡。这时候虽然因为A节点在环回网卡上也绑定了虚拟服务IP,所以A节点也能正常处理请求,业务暂时不会受到影响。但时此时由于客户端请求没有发到LVS的虚拟服务IP上,所以LVS的负载均衡能力没有生效。造成的后果就是,A节点一直在单节点运行,业务量过大时可能会出现性能瓶颈。所以DR模式下要求arp_ignore参数要求配置为1。 net.ipv4.conf.default.arp_ignore = 1 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.lo.arp_ignore = 1 # 对于tcp长链接的配置,防止当使用LVS做负载,当一个长连接过段时间不发消息时,LVS之后就不会再转发这个长连接的TCP数据包 # 允许持续空闲时长,也就是说在TCP保活打开的情况下,最后一次数据交换到TCP发送第一个保活探测包的间隔,默认值为7200s(2h) net.ipv4.tcp_keepalive_time = 30 # 在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包次数,默认值为9(次) net.ipv4.tcp_keepalive_probes = 1 # 在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包的发送频率,默认值为75s net.ipv4.tcp_keepalive_intvl = 30 # TIME_WAIT socket的最大数目,如果超哥限制数量则立即清除,不宜太大或者太小,需要反向代理的必备 # 根据net.ipv4.ip_local_port_range给出的范围去配置,不要超过ip_local_port_range的范围值end-start net.ipv4.tcp_max_tw_buckets = 50000 # 服务端主动关闭后,客户端释放连接的超时,重要,<30 net.ipv4.tcp_fin_timeout = 5 # 用逗号隔开,预留作为服务的端口,防止出现端口被占用了服务无法启动(作为反代服务器服务器时,使用的端口较多的情况下) net.ipv4.ip_local_reserved_ports = 22222,45454,33333-33335 # 将桥接的IPv4流量传递到iptables的链 # net.ipv4.conf.all.promote_secondaries = 1 # net.ipv4.conf.default.promote_secondaries = 1 # 主备IP地址切换控制机制:0当接口的主IP地址被移除时,删除所有次IP地址;1当接口的主IP地址被移除时,将次IP地址提升为主IP地址 net.ipv4.conf.default.promote_secondaries = 1 net.ipv4.conf.all.promote_secondaries = 1 # 在 NUMA 架构下,CPU与CPU之间通过核间互连总线连接,内存的访问速率出现了本地和远程的区别,访问远程内存的延时会明显高于访问本地内存 # numa balance的终极目标: 任务访问本节点内存。实现上将其拆分成两个小目标: # 1、如果任务访问的大部分内存不在本节点,那么把任务迁移到该节点的CPU上运行; # 2、如果任务访问的大部分数据都在本节点,那么将其他节点上的数据迁移到该节点上。 # 是否使能自动的numa balance,这个开启需要问开发代码 kernel.numa_balancing = 0 # 单个进程每次进行numa_balancing扫描的间隔时间 kernel.numa_balancing_scan_delay_ms= 1000 # 每次扫描最多花费的时间? kernel.numa_balancing_scan_period_max_ms = 60000 # 每次扫描最少花费的时间? kernel.numa_balancing_scan_period_min_ms = 1000 # 一次扫描进程多少MB的虚拟地址空间内存 kernel.numa_balancing_scan_size_mb = 256 kernel.numa_balancing_settle_count = 4 # Linux的GID为32位,但有些文件系统只支持16位的GID,此时若进行写操作会出错;当GID超过65535时会自动被转换为一个固定值,这个固定值保存在这个文件中 kernel.overflowgid = 65534 # Linux的UID为32位,但有些文件系统只支持16位的UID,此时若进行写操作会出错;当UID超过65535时会自动被转换为一个固定值,这个固定值保存在这个文件中 kernel.overflowuid = 65534 # 系统发生panic时内核重新引导之前的等待时间 kernel.panic = 0 # 系统最多允许同时打开(即包含所有用户打开文件数总和)524288个文件, # 假设打开一个文件需要4K的内存,这台服务器是16G的,那么计算出最大值为:16*1024*1024 fs.file-max = 4194304 # 一个进程最多同时打开的文件句柄数量,同上 fs.nr_open = 4194304 # 决定检查一次相邻层记录(网关邻居条目)的有效性的周期. 当相邻层记录失效时,将在给它发送数据前,再解析一次.(单位 秒) net.ipv4.neigh.default.gc_stale_time = 60 # vm.max_map_count定义了一个进程能拥有的最多的内存区域 # 这个配置需要咨询开发人员,默认为65530,这个默认值有点偏小,ElasticSearch启动必备 vm.max_map_count=562144 # 设置每个用户可以运行的inotifywait或inotifywatch命令的进程数,默认128,有点偏小 fs.inotify.max_user_instances = 1024 # 同一用户同时可以添加的watch数目(watch一般是针对目录,决定了同时同一用户可以监控的目录数量 fs.inotify.max_user_watches = 81920 # 激活窗口扩充因子,支持64kb以上数据传输 # 要支持超过64KB的TCP窗口,必须启用该值,TCP连接双方都启用时才生效 net.ipv4.tcp_window_scaling = 1 # 是否将LAST_ACK状态保存各种连接信息到路由缓存中:方便下次连接时快速恢复现场 net.ipv4.tcp_no_metrics_save = 0 # 是否允许内存的过量分配,允许进程分配比它实际使用的更多的内存,redis常用 vm.overcommit_memory = 1 # 提高tcp三次握手的效率和提高受攻击的安全性 # 但只在内核高于 3.7.1 才能启用 # 1表示客户端开启,2表示服务端开启,3表示客户端和服务器同时开启 # net.ipv4.tcp_fastopen = 3 # 配置TCP拥塞控制算法,没找到相关的详细文档介绍,没弄清楚前不建议使用 # 对于几种算法的分析,详情参考下:TCP拥塞控制算法的优缺点、适用环境、性能分析,如高延时可以试用hybla,中等延时可以试用htcp算法等。 # bbr拥塞控制算法,能尽量跑满带宽,但内核版本要求 4.9+ # 查看算法:sysctl net.ipv4.tcp_available_congestion_control # 加载模块:modprobe tcp_htcp 或者 modprobe tcp_hybla # net.core.default_qdisc=fq # net.ipv4.tcp_congestion_control=hybla ######################### 数据库的相关优化 ########################################################## # 可以使用的共享内存的总页数,那么需要共享内存页数是 16GB/4KB==4194304 (页) kernel.shmall = 4194304 # 内存为 16G 时,该值为 16*1024*1024*1024/2 = 8589934592,默认是32M,通常不需要修改 kernel.shmmax = 134217728 # 系统范围内共享内存段的最大数量,默认值4096,通常不需要修改 kernel.shmmni = 4096 # 可以使用的共享内存总量(以页为单位)。默认是2097152,通常不需要修改 kernel.msgmnb = 2097152 # 单个共享内存段的最大尺寸,设置为物理内存的50%,一般有数据库服务时才会用到 # kernel.sem = 250 32000 100 128 # cat /proc/sys/kernel/sem # 250 32000 32 128 # 250 SEMMSL max semaphores per array 信号集容纳最大信号数量 # 32000 SEMMNS max semaphores system wide 所有信号的最大数量 # 32 SEMOPM max ops per semop call 调用单个信号集中最大信号数量 # 128 SEMMNI max number of arrays 信号集的最大值 # 这个参数有四个值, 其实这四个不同的值又分别对应了另外四个不同的参数,按照上面值的顺序排列 # SEMMSL: Maximum number of semaphores per set # SEMMNS: Maximum number of semaphores system-wide # SEMOPM: Maximum number of semaphore operations per system call # SEMMNI: Maximum number of semaphore sets for the entire Linux system # 在Suse Linux中这几个参数是独立存在的. # Oracle(包括9i/10g/11g)推荐将sem设置为250 32000 100 128或更高的值. # 在一个并发很高的数据库中这个值可以设置为PROCESSES+10,SEMMNI也要相应的增加.目的是减少IPC通讯时 # semaphore的争用. # SEMOPM定义了每次IPC调用时影响的semaphore,建议设置SEMOPM=SEMMSL,SEMMNS定义为(SEMMSL * SEMMNI) # 禁用IPV6 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF
# 添加需要开启自动加载内核模块
echo 'modprobe ip_conntrack' >> /etc/profile echo 'modprobe br_netfilter' >> /etc/profile source /etc/profile sysctl -p
六、优化文件打开数(全部节点都要操作)
cat >> /etc/security/limits.conf <<EOF
* soft nofile 655350
* hard nofile 131072
* soft nproc 655350
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimited
EOF
rm -f /etc/security/limits.d/*
七、关闭防火墙和关闭安全子系统(全部节点都要操作)
# 禁用防火墙
systemctl stop firewalld && systemctl disable firewalld
# 临时禁用selinux
setenforce 0
# 永久修改,重启服务器后生效
sed -i '/^enforcing=/s/enforcing=.*/enforcing=disabled/' /etc/selinux/config
八、安装ipvs(全部节点都要操作)
# 创建脚本
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
ipvs_modules="ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_sh ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack"
for kernel_module in \${ipvs_modules}; do
/sbin/modinfo -F filename \${kernel_module} > /dev/null 2>&1
if [ 0 -eq 0 ]; then
/sbin/modprobe \${kernel_module}
fi
done
EOF
# 执行并检查
chmod +x /etc/sysconfig/modules/ipvs.modules && \
/etc/sysconfig/modules/ipvs.modules && \
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 安装ipset和ipvsadm(便于查看 ipvs 的代理规则)
yum -y install ipset ipvsadm
九、安装 时间同步服务(全部节点都要操作)
yum -y install chrony
# 修改配置文件
sed -i.bak '3,6d' /etc/chrony.conf && \
sed -i '3cserver ntp1.aliyun.com iburst' /etc/chrony.conf
# 启动并设置开机自启
systemctl start chronyd && systemctl enable chronyd
# 查看同步结果
[root@master01 16:28:41~]# chronyc sources
210 Number of sources = 1
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 120.25.115.20 2 10 332 51m +176us[ +259us] +/- 4782us
[root@master01 16:28:52~]#
十、关闭swap分区(全部节点都要操作)
# 关闭开机自启 sed -i '/swap/s/^/#/' /etc/fstab
# 检查结果(全部节点都要操作)
十一、重启服务器(全部节点都要操作)
init 6
十二、安装docker(全部节点都要操作)
1、安装yum资源库管理命令
yum -y install yum-utils
2、添加阿里云yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3、查看可用版本
yum list docker-ce --showduplicates | sort -r
4、安装20.10.9-3.el7
yum -y install docker-ce-20.10.9-3.el7 docker-ce-cli-20.10.9-3.el7
5、配置阿里云docker镜像加速
mkdir -p /etc/docker/ cat > /etc/docker/daemon.json <<EOF { "registry-mirrors": ["https://nr240upq.mirror.aliyuncs.com", "https://gqk8w9va.mirror.aliyuncs.com"] } EOF
6、修改docker Cgroup Driver为systemd
# 将/usr/lib/systemd/system/docker.service文件中的这一行 # ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock # 修改为 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd # 如果不修改,在添加 worker 节点时可能会碰到如下错误 # [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The # recommended driver is "systemd". # Please follow the guide at https://kubernetes.io/docs/setup/cri/ # 使用如下命令修改 sed -i.bak "s#^ExecStart=/usr/bin/dockerd.*#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd#g" /usr/lib/systemd/system/docker.service
7、启动docker并设置开机自启
systemctl daemon-reload && \ systemctl restart docker && \ systemctl enable docker
8、验证信息
docker info
版本信息确认
阿里云镜像加速确认
十三、安装Kubeadm(全部节点都要操作)
1、使用阿里云的yum源
cat >/etc/yum.repos.d/kubernetes.repo <<EOF [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
2、安装 kubeadm、kubelet、kubectl
yum -y install kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6
3、查看版本信息
4、设置开机自启
systemctl enable kubelet
5、配置k8s命令和参数tab自动补全
yum -y install bash-completion source /usr/share/bash-completion/bash_completion source <(kubectl completion bash) echo "source <(kubectl completion bash)" >> ~/.bashrc
十四、初始化集群(只在master01上操作)
1、配置 kubeadm 初始化文件
cat > ./kubeadm-config.yaml <<EOF apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.23.6 imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers #master地址 controlPlaneEndpoint: "172.17.0.41:6443" # 这里需要改自己的配置 networking: serviceSubnet: "10.96.0.0/16" # 这里自定义k8s的service网段 podSubnet: "10.20.0.1/16" # 这里自定义k8s的pod网段 dnsDomain: "cluster.local" EOF
2、初始化master
kubeadm init --config=kubeadm-config.yaml --upload-certs
# 注意,这步不用操作,如果发现需要重新改配置文件,重新初始化master,则执行这步
kubeadm reset -f kubeadm-config.yaml
3、按提示要求操作,直接复制操作就行了
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
十五、添加master节点(只在master02上操作)
1、从master01复制所需要的配置文件过master02上
mkdir -p $HOME/.kube
scp master01:/root/.kube/config $HOME/.kube
chown $(id -u):$(id -g) $HOME/.kube/config
2、master节点添加,复制这段来添加
复制到master02节点上执行命令
3、等待执行完成,查看结果
kubectl get node
十六、添加node节点(只在slave01和slave02上操作)
1、从master01复制所需要的配置文件过node节点上(这步可以不操作,只是为了方便node节点可以想master节点一样,可以执行kubectl命令操作)
mkdir -p $HOME/.kube
scp master01:/root/.kube/config $HOME/.kube
chown $(id -u):$(id -g) $HOME/.kube/config
2、node节点添加,复制这段来添加
3、复制到slave01和slave02节点上执行命令
十七、安装网络插件
1、下载yaml文件,官网地址:Project Calico DocumentationHomehttps://projectcalico.docs.tigera.io/
wget https://docs.projectcalico.org/archive/v3.21/manifests/calico.yaml
2、修改配置文件
vim calico.yaml
搜索关键字:CALICO_IPV4POOL_CIDR,打开注释(删除#号和一个空格)
修改成如下,要对齐上面的#号,value里的变量填写为第 十四 步骤里的 kubeadm-config.yaml 中 podSubnet 变量一致
3、执行
kubectl apply -f calico.yaml
4、等待一会,检查pod安装情况
kubectl get pod -n kube-system
5、全部状态为Running时,再检查节点情况,节点的状态全部为Ready就正常了
kubectl get node
十八、配置storageclass动态存储,实现k8s自动管理PV,这里用的是nfs做存储后端
1、安装 nfs-utils 和 socat 依赖包(全部节点都要操作)
yum -y install nfs-utils socat
2、master01 节点安装 rpcbind 服务,这里用 master01 作为nfs服务端
yum -y install rpcbind
# 创建目录并修改权限
mkdir -p /data/software/nfs_data
chmod 777 /data/software/nfs_data
# 编辑配置文件
cat >/etc/exports <<EOF
/data/software/nfs_data *(insecure,rw,async,no_root_squash)
EOF
# 启动服务并设置开机自启动
systemctl enable nfs-server rpcbind && systemctl start nfs-server rpcbind
# 检查nfs存储介质,有个显示,证明nfs配置是正常的
[root@master01 10:43:16~]# showmount -e 172.17.0.41
Export list for 172.17.0.41:
/data/software/nfs_data *
[root@master01 10:45:17~]#
3、配置storageclass的yaml文件,注意修改nfs服务端IP和共享目录
cat > storageclass.yaml <<EOF
---
apiVersion: v1
kind: Namespace
metadata:
name: nfs-data
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
namespace: nfs-data
---
apiVersion: v1
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-provisioner-runner
namespace: nfs-data
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get","create","list", "watch","update"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: nfs-data
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-provisioner
namespace: nfs-data
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-provisioner
namespace: nfs-data
subjects:
- kind: ServiceAccount
name: nfs-provisioner
roleRef:
kind: Role
name: leader-locking-provisioner
apiGroup: rbac.authorization.k8s.io
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-provisioner
namespace: nfs-data
spec:
selector:
matchLabels:
app: nfs-provisioner
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-provisioner
spec:
serviceAccountName: nfs-provisioner
containers:
- name: nfs-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client
mountPath: /persistentvolumes #容器内挂载点
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 172.17.0.41 # 此处修改为nfs服务器ip
- name: NFS_PATH
value: /data/software/nfs_data # 这里为nfs共享目录
volumes:
- name: nfs-client # 宿主机挂载点
nfs:
server: 172.17.0.41 # 此处修改为nfs服务器ip
path: /data/software/nfs_data # 这里为nfs共享目录
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
namespace: nfs-data
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
reclaimPolicy: Retain #回收策略:Retain(保留)、 Recycle(回收)或者Delete(删除)
volumeBindingMode: Immediate #volumeBindingMode存储卷绑定策略
allowVolumeExpansion: true #pvc是否允许扩容
EOF
4、创建storageclass
kubectl apply -f storageclass.yaml
5、设置自动创建PVC(strorageclass)时默认选择nfs-storage
kubectl patch storageclass nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
6、检查情况,查看nfs-storage是否带有default字样
kubectl get sc
7、检查nfs-client pod状态
kubectl get pods
8、创建pvc测试看看storageclass是否生效
cat > pvc-test.yaml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-test
spec:
storageClassName: "nfs-storage"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Mi
EOF
kubectl apply -f pvc-test.yaml
9、查看创建的PVC ,状态为Pending不正常
9、查看nfs-client pod日志,kubectl logs -n nfs-data 之后用tab键来补全
kubectl logs -n nfs-data #tab键来完成后续的补全pod名称
kubectl logs -n nfs-data nfs-provisioner-6d457c6f8d-wn4wq
检查发现全部显示的都是该类报错 ,查询到官网的git说明:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/issues/25https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/issues/25
10、修改/etc/kubernetes/manifests/kube-apiserver.yaml解决问题(master节点都要添加,这里添加节点有 master01 和 master02)
添加内容
- --feature-gates=RemoveSelfLink=false
11、等待一会,返回第 9 步骤,查看PVC的状态,如果状态为Bound就正常了,按理来说 kubeadm 部署的k8s是不需要执行以下操作的,如果为了以防万一,可以执行下面操作
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml # 执行两次操作
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
12、如果执行了 11 步操作,要查看pod的状态,如果看多于的pod的,kube-apiserver的pod是带有后缀为主机名的,不是就是多余的
kubectl get pod -n kube-system
13、删除多余的pod
kubectl delete -n kube-system pods kube-apiserver
14、再次查看PVC状态,如果状态为Bound就正常了
kubectl get pvc
15、如果PVC还是不正常,可以删掉再重新创建,还是不行就只能重新开始创建storageclass
kubectl delete -f pvc-test.yaml
kubectl apply -f pvc-test.yaml
16、查看存储介质情况,多了一些东西在里面
[root@master01 14:32:26/data/recycle]# ls /data/software/nfs_data/
default-pvc-test-pvc-f350362e-b69b-4b20-84f4-0f77f1264f91
[root@master01 14:32:35/data/recycle]#
补充:另一种方式安装storageclass动态存储
1、先下载helm,GitHub地址:Releases · helm/helm · GitHub
2、安装helm
tar zxf helm-v3.10.1-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/
helm version # 能查看到版本,说明安装正常
# 加载tab补全命令和参数
echo 'source <(helm completion bash)' >> ~/.bashrc
# 设置helm连接k8s的配置
echo 'KUBECONFIG=/root/.kube/config' >> ~/.bashrc
# 加载变量
source ~/.bashrc
3、添加仓库
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner
4、部署 storageclass动态存储 时,先把注释删掉
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ # 指定helm的仓库
--namespace=nfs-data \ # 指定命名空间
--create-namespace \ # 自动创建命令空间
--set image.repository=willdockerhub/nfs-subdir-external-provisioner \ # 指定镜像
--set image.tag=v4.0.2 \ # 指定版本,必须要4.0.0版本以上,否则会报错: unexpected error getting claim reference: selfLink was empty, can't make reference
--set replicaCount=2 \ # 启动两个pod
--set storageClass.name=nfs-storage \ # 指定sc的名字
--set storageClass.defaultClass=true \ # 指定为默认sc
--set nfs.server=172.17.0.41 \ # 指定nfs地址
--set nfs.path=/data/software/nfs_data # 指定nfs的共享目录
5、查看相关信息
kubectl get pod -n nfs-data
kubectl get sc
6、测试创建pvc
cat > pvc-test.yaml <<'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-test
spec:
storageClassName: "nfs-storage"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Mi
EOF
kubectl apply -f pvc-test.yaml
kubectl get pvc
十九、部署KubeSphere,官方地址:在 Kubernetes 上最小化安装 KubeSphere了解在现有 Kubernetes 集群上如何使用最小安装包安装 KubeSphere。您可以使用托管在云服务器上或者安装在本地的 Kubernetes 集群。https://kubesphere.io/zh/docs/quick-start/minimal-kubesphere-on-k8s/
1、下载yaml文件
wget https://github.com/kubesphere/ks-installer/releases/download/v3.2.1/kubesphere-installer.yaml
wget https://github.com/kubesphere/ks-installer/releases/download/v3.2.1/cluster-configuration.yaml
2、创建 KubeSphere 相关pod
kubectl apply -f kubesphere-installer.yaml
kubectl apply -f cluster-configuration.yaml
3、查看安装log,直到出现账号密码提示
kubectl logs -n kubesphere-system \
$(kubectl get pod \
-n kubesphere-system \
-l app=ks-install \
-o jsonpath='{.items[0].metadata.name}') -f
4、确认pod状态情况
kubectl get pod -n kubesphere-system
5、登陆网页,
url: http://172.17.0.41:30880
账号: admin
密码: P@88w0rd