跟我一步步部署 Kubernetes 集群(二):初始化系统与全局变量 文档教程云原生【免费下载链接】follow-me-install-kubernetes-cluster和我一步步部署 kubernetes 集群项目地址https://gitcode.com/gh_mirrors/fo/follow-me-install-kubernetes-cluster点击查看免费下载导读本文是「follow-me-install-kubernetes-cluster」二进制部署 Kubernetes v1.16.6 集群系列的第二篇核心任务是完成集群所有节点的系统级前置初始化设置主机名与节点互信、安装依赖、关闭防火墙/SELinux/Swap、优化内核参数、同步时钟、创建目录并分发全局变量脚本最后升级内核规避 3.10.x 内核的已知缺陷。读完本文你将掌握一套可复用的 Kubernetes 节点初始化清单并能理解每个操作背后的原理与对后续 etcd、kubelet、kube-proxy 等组件部署的直接影响。本系列所有文档在部署完成后会启用 x509 双向认证、RBAC 授权等严格安全机制因此建议从头开始按顺序部署而本初始化文档就是整个集群的第一块基石。集群规划与操作范围本仓库文档对应的演示集群由三台 CentOS 7 及以上版本机器组成三台机器混合部署etcd、master控制面与 worker 节点主机名IPzhangjun-k8s-01172.27.138.251zhangjun-k8s-02172.27.137.229zhangjun-k8s-03172.27.138.239注意如果没有特殊说明本文档的初始化操作需要在所有节点上执行。个别仅需在单一节点执行的操作如添加节点信任关系会在文中明确标注。这些 IP 与主机名会被写入后续部署全程使用的全局变量脚本 manifests/environment.sh因此初始化阶段的主机名设置必须与该脚本中的NODE_NAMES保持一致。设置主机名在每台机器上执行hostnamectl设置各自的静态主机名hostnamectl set-hostname zhangjun-k8s-01 # 将 zhangjun-k8s-01 替换为当前主机名如果 DNS 不支持主机名称解析还需要在每台机器的/etc/hosts文件中添加主机名与 IP 的对应关系cat /etc/hosts EOF 172.27.138.251 zhangjun-k8s-01 172.27.137.229 zhangjun-k8s-02 172.27.138.239 zhangjun-k8s-03 EOF退出并重新登录 root 账号即可看到主机名生效。主机名将在后续 etcd 集群的成员命名如zhangjun-k8s-01https://172.27.138.251:2380中直接使用务必保证名称唯一且可解析。添加节点信任关系本操作只在 zhangjun-k8s-01 节点上执行目的是让管理节点 root 账户可以无密码登录所有节点后续大量「批量分发二进制文件 / 配置文件 / 远程执行命令」的操作都依赖这条信任链ssh-keygen -t rsa ssh-copy-id rootzhangjun-k8s-01 ssh-copy-id rootzhangjun-k8s-02 ssh-copy-id rootzhangjun-k8s-03ssh-copy-id会把公钥写入目标节点的authorized_keys。这一步是后续所有for node_ip in ${NODE_IPS[]}批量循环例如 04.etcd集群.md 中的 scp 分发、06-2.apiserver高可用.md 中远程启动 kube-nginx能够免密执行的前提。更新 PATH 变量将本系列部署的所有二进制程序统一目录/opt/k8s/bin加入 PATHecho PATH/opt/k8s/bin:$PATH /root/.bashrc source /root/.bashrc/opt/k8s/bin目录保存本文档下载安装的程序例如 etcd、kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy、kubectl、containerd、crictl、calicoctl 等manifests/environment.sh 末尾同样执行了export PATH/opt/k8s/bin:$PATH以保证source environment.sh后命令行可直接使用这些二进制。安装依赖包yum install -y epel-release yum install -y chrony conntrack ipvsadm ipset jq iptables curl sysstat libseccomp wget socat git各依赖包的用途如下chronyetcd 集群各机器需要精确的时间同步chrony 用于系统时钟同步对应后文「设置系统时钟同步」一节ipvsadm / ipset本文档的 kube-proxy 使用ipvs 代理模式ipvsadm 是 ipvs 的管理工具ipset 用于管理 IP 集合两者是 ipvs 模式工作的基础conntrack连接跟踪工具配合内核参数nf_conntrack_max调节连接跟踪表容量jq命令行 JSON 处理器后续校验集群状态、解析证书与 API 输出时大量使用iptables防火墙与 NAT 规则管理工具libseccompseccomp 安全计算模式库containerd/runc 运行容器所需的依赖socat多用途 socket 转发工具sysstat / wget / curl / git系统性能监控工具、下载工具与版本管理工具。关闭防火墙Kubernetes 集群内部组件kubelet、kube-proxy、calico、Service/Pod 网络之间需要大量互访系统自带防火墙可能拦截这些流量因此统一关闭systemctl stop firewalld systemctl disable firewalld iptables -F iptables -X iptables -F -t nat iptables -X -t nat iptables -P FORWARD ACCEPT前两条停止并禁用 firewalld 服务中间两条清空 iptables 的 filter 表与 nat 表的规则最后一条将 FORWARD 链默认策略设置为 ACCEPT——Pod 间跨节点通信依赖内核转发若 FORWARD 策略为 DROP 将导致 Pod 网络不通calico/flannel 均依赖该链放行。关闭 swap 分区swapoff -a sed -i / swap / s/^\(.*\)$/#\1/g /etc/fstabswapoff -a立即关闭所有 swap第二条命令将/etc/fstab中所有包含swap的行注释掉防止重启后 swap 重新挂载。为什么要关闭 swap不关闭 swap 时 kubelet 会启动失败——kubelet 默认会检查 swap 状态由启动参数--fail-swap-on控制默认为 true。如果确实无法关闭 swap也可以设置--fail-swap-onfalse跳过该检查但生产环境强烈建议关闭以避免内存回收抖动影响容器稳定性。关闭 SELinuxsetenforce 0 sed -i s/^SELINUX.*/SELINUXdisabled/ /etc/selinux/configsetenforce 0立即将 SELinux 切换到 permissive 模式第二条命令把/etc/selinux/config中的SELINUXenforcing改为SELINUXdisabled保证重启后仍生效。为什么要关闭不关闭 SELinux 时kubelet 挂载目录可能报错Permission denied。开启状态的 SELinux 会对容器卷挂载、文件访问施加强制访问控制与 kubelet/containerd 的文件操作冲突。优化内核参数创建并加载 Kubernetes 专属内核参数文件cat kubernetes.conf EOF net.bridge.bridge-nf-call-iptables1 net.bridge.bridge-nf-call-ip6tables1 net.ipv4.ip_forward1 net.ipv4.tcp_tw_recycle0 net.ipv4.neigh.default.gc_thresh11024 net.ipv4.neigh.default.gc_thresh22048 net.ipv4.neigh.default.gc_thresh34096 vm.swappiness0 vm.overcommit_memory1 vm.panic_on_oom0 fs.inotify.max_user_instances8192 fs.inotify.max_user_watches1048576 fs.file-max52706963 fs.nr_open52706963 net.ipv6.conf.all.disable_ipv61 net.netfilter.nf_conntrack_max2310720 EOF cp kubernetes.conf /etc/sysctl.d/kubernetes.conf sysctl -p /etc/sysctl.d/kubernetes.conf各参数的作用参数作用net.bridge.bridge-nf-call-iptables1/ip6tables1让经过 Linux 网桥如 docker0、cni0的 IPv4/IPv6 流量也经过 iptables/ip6tables 规则处理保证 Service 的 DNAT 规则对 Pod 流量生效是集群网络功能正确的前提net.ipv4.ip_forward1开启内核 IPv4 转发容器间、Pod 间跨节点通信的基础net.ipv4.tcp_tw_recycle0关闭 TIME_WAIT 快速回收。该参数与 NAT 冲突开启时可能导致服务访问不通必须保持为 0net.ipv4.neigh.default.gc_thresh1/2/3设置 ARP 邻居表 GC 阈值1024/2048/4096防止大规模集群下邻居表被过早回收导致丢包vm.swappiness0尽量不使用 swap与关闭 swap 的策略一致vm.overcommit_memory1允许内核过度分配内存避免某些程序在申请内存时被拒绝保证容器化场景下内存申请更宽松vm.panic_on_oom0内存不足时由内核 OOM killer 选择进程杀掉而不是触发内核 panic 重启fs.inotify.max_user_instances8192/max_user_watches1048576提升 inotify 文件监控实例数与监视数量上限支撑 kubelet 对大量配置/日志文件的高频监控fs.file-max52706963/fs.nr_open52706963提升系统文件句柄上限避免高并发容器场景下 too many open filesnet.ipv6.conf.all.disable_ipv61关闭 IPv6本方案集群暂不使用 IPv6net.netfilter.nf_conntrack_max2310720提升连接跟踪表容量匹配大规模 Service/Endpoint 场景内核参数的更多背景可参考 OpenShift 文档中关于 overcommit过度分配的论述。设置系统时区timedatectl set-timezone Asia/Shanghai统一时区为Asia/Shanghai。日志时间戳、证书有效期、kubelet 上报的时间都会受到影响集群所有节点必须使用同一时区。设置系统时钟同步etcd 集群对时钟偏差非常敏感Raft 依赖任期与心跳超时因此必须开启 chronyd 服务systemctl enable chronyd systemctl start chronyd查看同步状态timedatectl status输出System clock synchronized: yes NTP service: active RTC in local TZ: noSystem clock synchronized: yes表示时钟已同步NTP service: active表示开启了时钟同步服务RTC in local TZ: noRTC硬件时钟使用 UTC 时间符合 Linux 惯例。随后将当前 UTC 时间写入硬件时钟并重启依赖系统时间的服务# 将当前的 UTC 时间写入硬件时钟 timedatectl set-local-rtc 0 # 重启依赖于系统时间的服务 systemctl restart rsyslog systemctl restart crond重启 rsyslog 与 crond 是为了让它们立即应用同步后的系统时间日志时间戳与定时任务调度都依赖时钟。关闭无关的服务systemctl stop postfix systemctl disable postfixpostfix 邮件服务与集群部署无关且会占用资源、产生日志噪音统一停止并禁止开机自启。创建相关目录mkdir -p /opt/k8s/{bin,work} /etc/{kubernetes,etcd}/cert/opt/k8s/bin存放本系列下载的所有可执行程序已加入 PATH/opt/k8s/work存放下载的源码包、生成过程中的中间文件如证书 CSR、临时配置/etc/kubernetes/cert与/etc/etcd/cert分别存放 Kubernetes 组件与 etcd 的证书和私钥后续 02.创建CA根证书和秘钥.md 的 CA 证书分发正是写入/etc/kubernetes/cert。分发集群配置参数脚本后续所有部署步骤使用到的环境变量都集中定义在 manifests/environment.sh 中。该脚本是整个集群的「参数中枢」必须先根据自己的机器、网络情况修改再拷贝到所有节点source environment.sh # 先修改 for node_ip in ${NODE_IPS[]} do echo ${node_ip} scp environment.sh root${node_ip}:/opt/k8s/bin/ ssh root${node_ip} chmod x /opt/k8s/bin/* done脚本中的关键变量结合仓库源码 manifests/environment.sh 逐项说明变量示例值说明ENCRYPTION_KEY运行时生成由head -c 32 /dev/urandom \| base64生成用于 apiserver 的 EncryptionConfigetcd 中敏感数据加密NODE_IPS(172.27.138.251 172.27.137.229 172.27.138.239)集群各机器 IP 数组是后续所有批量分发/远程执行循环的遍历对象NODE_NAMES(zhangjun-k8s-01 zhangjun-k8s-02 zhangjun-k8s-03)集群各 IP 对应的主机名数组与本文「设置主机名」一节严格对应ETCD_ENDPOINTShttps://172.27.138.251:2379,...etcd 集群服务地址列表供各组件连接ETCD_NODESzhangjun-k8s-01https://...:2380,...etcd 集群成员间通信peer的 IP 与端口 2380KUBE_APISERVERhttps://127.0.0.1:8443kube-apiserver 的反向代理kube-nginx地址端口见 06-2.apiserver高可用.mdIFACEeth0节点间互联网络接口名称calico/flannel 网络配置使用ETCD_DATA_DIR/ETCD_WAL_DIR/data/k8s/etcd/data//data/k8s/etcd/waletcd 数据目录与 WAL 目录WAL 建议使用 SSD 或与数据目录不同的磁盘分区K8S_DIR/data/k8s/k8sk8s 各组件数据目录DOCKER_DIR/CONTAINERD_DIR/data/k8s/docker//data/k8s/containerd容器运行时数据目录二选一本系列 v1.16.x 默认使用 containerd见 06-3.containerd.md如需 docker 请参考附件 F.部署docker.mdBOOTSTRAP_TOKEN41f7e4ba8b7be874fcff18bf5cf41a7cTLS Bootstrapping 使用的 Token可使用head -c 16 /dev/urandom \| od -An -t x \| tr -d 自行生成一般无需修改SERVICE_CIDR10.254.0.0/16服务网段。最好使用当前未用的网段部署前路由不可达部署后集群内由 kube-proxy 保证路由可达CLUSTER_CIDR172.30.0.0/16Pod 网段建议 /16 段部署后集群内由 Pod 网络插件保证互通NODE_PORT_RANGE30000-32767Service NodePort 端口范围CLUSTER_KUBERNETES_SVC_IP10.254.0.1kubernetes 服务 IP一般为SERVICE_CIDR中第一个 IPCLUSTER_DNS_SVC_IP10.254.0.2集群 DNS 服务 IP从SERVICE_CIDR中预分配CLUSTER_DNS_DOMAINcluster.local集群 DNS 域名末尾不带点号脚本中标注「以下参数一般不需要修改」的部分BOOTSTRAP_TOKEN、两个网段、端口范围等在首次部署时保持默认即可而NODE_IPS、NODE_NAMES、ETCD_*、KUBE_APISERVER、IFACE、数据目录等必须按实际环境调整。该脚本随后会被所有部署文档反复source使用例如 04.etcd集群.md、06-2.apiserver高可用.md 中都是通过source /opt/k8s/bin/environment.sh加载后执行批量 scp 分发。从源码结构看全仓库近 20 个文档步骤均以该脚本为参数来源可见「先改好脚本再分发」是本系列部署的单一事实来源single source of truth。升级内核CentOS 7.x 系统自带的3.10.x 内核存在一些 Bugs会导致运行的 Docker、Kubernetes 不稳定典型问题包括高版本 docker1.13 以后启用了 3.10 kernel 实验支持的 kernel memory account 功能无法关闭当节点压力大、频繁启动和停止容器时会导致cgroup memory leak网络设备引用计数泄漏导致类似报错kernel:unregister_netdevice: waiting for eth0 to become free. Usage count 1。针对以上问题有三类解决方案升级内核到 4.4.X 以上本文采用此方案手动编译内核disableCONFIG_MEMCG_KMEM特性安装修复了该问题的 Docker 18.09.1 及以上版本。但由于 kubelet 也会设置 kmem它 vendor 了 runc还需重新编译 kubelet 并指定GOFLAGS-tagsnokmemgit clone --branch v1.14.1 --single-branch --depth 1 https://github.com/kubernetes/kubernetes cd kubernetes KUBE_GIT_VERSIONv1.14.1 ./build/run.sh make kubelet GOFLAGS-tagsnokmem本系列采用最简单的升级内核方案rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm # 安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置如果没有再安装一次 yum --enablerepoelrepo-kernel install -y kernel-lt # 设置开机从新内核启动 grub2-set-default 0说明通过 ELRepo 仓库安装kernel-ltLong Term 长期支持内核线grub2-set-default 0将默认启动项设置为新内核安装完成后需检查/boot/grub2/grub.cfg中对应内核 menuentry 是否包含initrd16配置若缺失需重装一次否则新内核可能无法正常引导。升级完成后重启机器sync reboot重启后可通过uname -r确认内核版本已升至 4.4.X 以上。参考系统内核相关参数overcommit的背景资料可查阅 OpenShift 企业版管理手册中关于内存过度分配的章节3.10.x 内核 kmem bugs 的讨论与解决办法可参考 kubernetes 官方 issue 以及相关技术博客如 TiDB Operator 在 K8s 中测试时对内核 bug 的修复实践。小结与下一步完成本文的全部操作后每台节点将具备唯一可解析的主机名、免密互信、统一的二进制目录与 PATH、完整依赖包、关闭的防火墙/SELinux/swap、优化过的内核参数、统一的时区与同步时钟、以及分发到位的全局变量脚本environment.sh。后续部署顺序为02.创建CA根证书和秘钥.md —— 基于/opt/k8s/work与/etc/kubernetes/cert生成并分发 CA 证书04.etcd集群.md —— 基于ETCD_ENDPOINTS/ETCD_NODES等变量部署三节点高可用 etcd05-1.master节点.md 系列与 06-1.worker节点.md 系列 —— 依次部署控制面与工作节点组件。每个组件的启动参数都会大量引用本初始化阶段定义的变量因此务必确认environment.sh中的 IP、主机名、网段与真实环境完全一致后再继续。赞分享文档教程云原生【免费下载链接】follow-me-install-kubernetes-cluster和我一步步部署 kubernetes 集群项目地址https://gitcode.com/gh_mirrors/fo/follow-me-install-kubernetes-cluster点击查看免费下载相关推荐k-skill 的 seoul-bike首尔따릉이实时租赁点查询基于 k-skill-proxy 的无密钥 API 架构与 CLI 实战指南k skill 的 seoul bike首尔따릉이实时租赁点查询基于 k skill proxy 的无密钥 API 架构与 CLI 实战指南 本篇技术指南文档教程云原生Keras 3变量管理系统跨后端变量初始化与状态同步Keras 3变量管理系统跨后端变量初始化与状态同步 引言深度学习框架的变量管理困境 在多后端深度学习开发中开发者常面临变量碎片化挑战TensorF人工智能深度学习机器学习预训练告别部署难题3步实现YOLOv5模型的Kubernetes集群化部署告别部署难题3步实现YOLOv5模型的Kubernetes集群化部署 在AI视觉应用落地过程中你是否遇到过模型部署复杂、资源利用率低、扩展困难等问题本文将人工智能深度学习计算机视觉预训练微调上一篇如何用Upscayl将模糊照片变高清7大AI模型终极指南下一篇AMD显卡驱动精简终极指南Radeon Software Slimmer让你的系统飞起来创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考