#k8s集群部署# #Ansible#前期手动部署了k8s集群过程比较复杂为了提高集群部署的效率所以决定做一下自动化部署为此最近学习了ansible同时也进一步巩固一下k8s基础知识。刚完成了基础环境配置部分记录一下如有建议请不吝赐教。我使用的操作系统是RockyLinux 9最小化安装集群为3master2node。1、服务管理在部署期间可以暂时关闭防火墙以减少因端口问题产生的问题生产环境中完成部署后要开启防火墙按需开放端口- name: Stop and disable firewalld ansible.builtin.systemd: namefirewalld statestopped enabledno另外需要关闭SELinux这是Linux内核的强制访问控制安全模块主要用来限制进程对文件、端口、资源的访问K8s Docker/containerd CNI 网络插件很容易和 SELinux 策略冲突导致容器无法挂载目录、端口无法绑定、socket无法访问、容器启动失败等问题生产环境可以配置SELinux策略容器securityContext。- name: Disable SELinux immediately ansible.builtin.command: setenforce 0 changed_when: true ignore_errors: yes - name: Disable SELinux permanently ansible.builtin.selinux: statedisabled - name: Disable SELinux in /etc/sysconfig/selinux ansible.builtin.replace: path: /etc/sysconfig/selinux regexp: ^SELINUXenforcing replace: SELINUXdisabled ignore_errors: yes一般Linux中会有dnsmasq服务属于轻量dns缓存dhcp服务其端口53会与k8s集群的CoreDNS端口冲突也要关闭。- name: Stop and disable dnsmasq ansible.builtin.systemd: name: dnsmasq state: stopped enabled: no本集群中日志方面使用的是rsyslog服务原因如下①默认预装不用额外安装节点零侵入②轻量、高性能、低资源占用③稳定可靠、配置简单④完美适配k8s容器日志架构不依赖容器运行时日志驱动⑤方便对接各种日志平台。- name: Enable and start rsyslog ansible.builtin.systemd: name: rsyslog state: started enabled: yes2、关闭SWAPSWAP本质是从磁盘取一部分空间作为“低速内存”当内存不足时缓解内存压力但磁盘速度比内存慢上万倍而k8s集群的硬性需求是高并发、低延迟一旦使用SWAPPod响应延迟将会暴增、接口超时相关网络组件kube-proxy、Calico、CoreDNS对延迟和内存及其敏感……据说k8s官方设计之初就假设所有容器只使用物理内存不依赖磁盘交换在新版集群中kubelet启动会硬性校验/proc/meminfo如果SWAP不为0则直接启动失败。- name: Disable swap immediately ansible.builtin.command: swapoff -a changed_when: true ignore_errors: yes - name: Comment out swap entries in fstab ansible.builtin.replace: path: /etc/fstab regexp: ^([^#].*swap) replace: #\1 backup: yes - name: Set vm.swappiness to 0 ansible.builtin.sysctl: name: vm.swappiness value: 0 state: present reload: yes3、基础软件和系统方面配置3.1 host解析- name: Configure /etc/hosts ansible.builtin.blockinfile: path: /etc/hosts block: | 10.0.1.31 k8s-master01 10.0.1.32 k8s-master02 10.0.1.33 k8s-master03 10.0.1.41 k8s-node01 10.0.1.42 k8s-node02 marker: # {mark} ANSIBLE MANAGED BLOCK backup: yes3.2 配置yum源#配置yum源注释mirrorlist - name: Comment out mirrorlist in repo files ansible.builtin.replace: path: {{ item }} regexp: ^mirrorlist replace: #mirrorlist backup: yes loop: {{ lookup(fileglob, /etc/yum.repos.d/*.repo) }} #配置yum源替换为阿里云baseurl - name: Replace baseurl with Aliyun mirror ansible.builtin.replace: path: {{ item }} regexp: ^#baseurlhttp://dl\.rockylinux\.org/\$contentdir replace: baseurlhttps://mirrors.aliyun.com/rockylinux backup: yes loop: {{ lookup(fileglob, /etc/yum.repos.d/*.repo) }} #更新缓存 - name: Update yum cache ansible.builtin.command: yum makecache changed_when: true3.3 安装基础软件这里将epel跟其他软件分开安装了因为这个epel-release是一个特殊的 RPM它会创建/etc/yum.repos.d/epel*.repo仓库文件。如果把它和依赖 EPEL 源的包如ntpsec放在同一个dnf任务里第一次执行时dnf可能还没刷新到新仓库导致找不到包而报错。- name: Install epel-release repository ansible.builtin.dnf: name: epel-release state: present - name: Install base packages ansible.builtin.dnf: name: - ntpsec - ipvsadm - ipset - sysstat - conntrack - libseccomp state: present enablerepo: epel update_cache: yes3.4 系统升级基础软件安装完后做一次系统升级- name: Upgrade all packages ansible.builtin.dnf: name: * state: latest update_cache: yes3.5 配置时区与时间同步- name: Set timezone to Shanghai ansible.builtin.file: src: /usr/share/zoneinfo/Asia/Shanghai dest: /etc/localtime state: link force: yes - name: Set timezone file ansible.builtin.copy: content: Asia/Shanghai\n dest: /etc/timezone mode: 0644 - name: Sync time with ntpdate ansible.builtin.command: /usr/sbin/ntpdate time2.aliyun.com changed_when: true - name: Add ntpdate to crontab ansible.builtin.cron: name: sync time with aliyun ntp minute: */5 job: /usr/sbin/ntpdate time2.aliyun.com3.6 系统资源配置blockinfile模块功能①在指定文件中插入/更新一整块多行文本②通过marker标记区块幂等执行同一个操作执行多次结果保持一致③只修改标记范围内的内容不影响其他原有配置。/etc/security/limits.conf是Linux PAM资源限制配置文件控制系统用户/进程的最大打开文件数、最大进程数、内存锁定等限制。*表示对所有用户生效含root、普通用户、容器进程soft表示软限制系统默认上限进程可临时调高至hard值hard表示硬限制为最高上限进程无法突破。nofile最大可打开文件句柄数nproc最大用户进程数memlock锁定内存设置为unlimited不限制锁定内存大小防止关键进程内存被换入SWAP。- name: Configure system limits ansible.builtin.blockinfile: path: /etc/security/limits.conf block: | * soft nofile 65536 * hard nofile 131072 * soft nproc 65535 * hard nproc 655350 * soft memlock unlimited * hard memlock unlimited marker: # {mark} ANSIBLE MANAGED BLOCK backup: yes3.7 k8s网络相关内核模块配置第一部分modprobe等价系统命令modprobe 模块名overlay容器叠加网络模块负责容器跨主机通信Flannel、Calico等主流CNI都依赖br_netfilter网桥网络过滤模块开启iptables对网桥流量的转发/过滤以上两个模块是容器网络的基础不加载则CNI插件无法正常工作。第二部分 kube-proxy有两种模式iptables默认和IPVS高性能负载均衡临时加载IPVS全套调度模块保证kube-proxy切换到IPVS模式可以正常运行。第三部分路径/etc/modules-load.d/*.conf是systemd标准目录其中为内核模块列表开机自动加载前两部分是modprobe临时加载立即生效重启后丢失这里是永久生效重启后由systemd-modules-load读取配置后再加载。第四部分systemd-modules-load是systemd自带服务专门负责开机读取/etc/modules-load.d/下的配置、自动加载内核模块。#加载k8s网络相关内核模块 - name: Load overlay and br_netfilter modules ansible.builtin.modprobe: name: {{ item }} state: present loop: - overlay - br_netfilter - name: Load ipvs kernel modules ansible.builtin.modprobe: name: {{ item }} state: present loop: - ip_vs - ip_vs_rr - ip_vs_wrr - ip_vs_sh - nf_conntrack #配置开机自动加载的模块ipvs.conf - name: Create ipvs modules load config ansible.builtin.copy: dest: /etc/modules-load.d/ipvs.conf content: | 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_fo ip_vs_nq ip_vs_sed ip_vs_ftp ip_vs_sh nf_conntrack ip_tables ip_set xt_set ipt_set ipt_rpfilter ipt_REJECT ipip mode: 0644 - name: Enable systemd-modules-load service ansible.builtin.systemd: name: systemd-modules-load state: started enabled: yes ignore_errors: yes3.8 内核优化配置第一部分/etc/sysctl.d/是systemd管理的内核参数目录目录下所有.conf文件都会被统一加载永久生效。单独建立k8s.conf文件和系统配置解耦便于维护、排查、回滚。第二部分生效所有sysctl配置- name: Configure sysctl for Kubernetes ansible.builtin.copy: dest: /etc/sysctl.d/k8s.conf content: | #网络转发 net.ipv4.ip_forward 1 net.bridge.bridge-nf-call-iptables 1 net.bridge.bridge-nf-call-ip6tables 1 fs.may_detach_mounts 1 net.ipv4.conf.all.route_localnet 1 #内存管理 vm.overcommit_memory 1 vm.panic_on_oom 0 #文件描述符、inotify fs.inotify.max_user_watches 89100 #值偏低建议改为524288 fs.file-max 52706963 fs.nr_open 52706963 #连接追踪 net.netfilter.nf_conntrack_max 2310720 #tcp保活与孤儿连接回收 net.ipv4.tcp_keepalive_time 600 net.ipv4.tcp_keepalive_probes 3 net.ipv4.tcp_keepalive_intvl 15 net.ipv4.tcp_max_orphans 327680 net.ipv4.tcp_orphan_retries 3 #高并发与syn flood防护 net.ipv4.tcp_max_tw_buckets 36000 net.ipv4.tcp_tw_reuse 1 net.ipv4.tcp_syncookies 1 net.ipv4.tcp_max_syn_backlog 16384 net.ipv4.tcp_timestamps 0 net.core.somaxconn 16384 mode: 0644 - name: Apply sysctl configuration ansible.builtin.command: sysctl --system changed_when: true3.8 master01节点克隆源码可以在master01上提前准备Calico、krm、metrics-server的源码。- name: Clone k8s-ha-install repository on master01 ansible.builtin.git: repo: https://xxxx dest: /root/ when: inventory_hostname (groups[master] | first)4、其他说明Ansible 执行每个任务后会报告三种状态之一ok绿色已处于期望状态无需修改changed黄色执行了修改操作failed红色执行失败在上述配置中很多地方都使用了changed_when: true表示无论实际有没有发生变化都显示为 changed黄色。原因是比如command 模块只能执行命令它无法判断其命令是否真的修改了 某服务的状态可能本来已经修改了。默认情况下command 模块每次都会返回 changed但 Ansible 有时会提示你确认这一点。显式写上 changed_when: true 就是告诉 Ansible“我知道这个命令会改变系统状态每次都报 changed 即可”。