Kubernetes系统初始化全攻略 roles-prepare ②
·
📁 目录结构(prepare/)
prepare/
├── files/ # 静态文件,直接复制到目标主机
│ └── sctp.conf # 示例:一个配置文件,会被拷贝到远程机器
│
├── tasks/ # 执行任务的核心部分
│ ├── common.yml # 共同任务(适用于所有系统)
│ ├── debian.yml # Debian/Ubuntu 系统专用任务
│ ├── main.yml # 主任务文件(默认执行入口)
│ ├── offline.yml # 离线部署时使用的任务
│ ├── redhat.yml # RHEL/CentOS/Fedora 专用任务
│ └── suse.yml # SUSE Linux 专用任务
│
├── templates/ # 模板文件(Jinja2),根据变量动态生成
│ ├── 10-k8s-modules.conf.j2
│ ├── 30-k8s-ulimits.conf.j2
│ ├── 95-k8s-journald.conf.j2
│ └── 95-k8s-sysctl.conf.j2
│
└── vars/ # 角色变量定义(全局或平台相关)
└── main.yml
📄 1.1 files/sctp.conf
# 将 SCTP 协议加入内核模块黑名单,防止意外加载
# 用于避免 Kubernetes 环境中不必要的内核模块干扰
install sctp /bin/true
📄 1.2 tasks/ 任务文件
📄 1.2.1 common.yml
# 公共系统初始化任务(适用于所有 Linux 发行版)
# 禁用 swap(Kubernetes 要求)
- name: 禁用系统 swap
shell: "source /etc/profile; swapoff -a && sysctl -w vm.swappiness=0"
ignore_errors: true
- name: 删除 fstab 中 swap 相关配置
lineinfile:
path: /etc/fstab
regexp: 'swap'
state: absent
backup: 'yes'
# 加载 Kubernetes 所需的内核模块
- name: 加载内核模块
modprobe:
name: "{{ item }}"
state: present
loop:
- br_netfilter
- dm_snapshot
- dm_thin_pool
- ip_vs
- ip_vs_rr
- ip_vs_wrr
- ip_vs_sh
- nf_conntrack
ignore_errors: true
# 尝试加载 nf_conntrack_ipv4(旧内核可能需要)
- name: 尝试加载 nf_conntrack_ipv4
shell: 'modprobe nf_conntrack_ipv4 || echo "NoFound"'
register: NF_CONNTRACK_IPV4
# 启用 systemd-modules-load 服务,确保模块开机自动加载
- name: 启用 systemd 自动加载模块服务
service:
name: systemd-modules-load
enabled: yes
- name: 增加内核模块开机加载配置
template:
src: 10-k8s-modules.conf.j2
dest: /etc/modules-load.d/10-k8s-modules.conf
# 设置 Kubernetes 所需的 sysctl 参数
- name: 设置系统参数
template:
src: 95-k8s-sysctl.conf.j2
dest: /etc/sysctl.d/95-k8s-sysctl.conf
# 动态判断是否需要设置 fs.may_detach_mounts(某些内核版本需要)
- name: 查看是否需要设置 fs.may_detach_mounts
stat:
path: /proc/sys/fs/may_detach_mounts
get_attributes: no
get_checksum: no
get_mime: no
register: fs_may_detach_mounts
ignore_errors: true
- name: 当需要时,设置 fs.may_detach_mounts 为 1
sysctl:
sysctl_file: "/etc/sysctl.d/95-k8s-sysctl.conf"
name: fs.may_detach_mounts
value: 1
state: present
reload: yes
when: fs_may_detach_mounts.stat.exists | bool
# tcp_tw_recycle 在较新内核中已废弃,但旧系统可能仍存在
- name: 查看是否需要设置 net.ipv4.tcp_tw_recycle
stat:
path: /proc/sys/net/ipv4/tcp_tw_recycle
register: tcp_tw_recycle
ignore_errors: true
- name: 设置 tcp_tw_recycle 为 0(避免 NAT 环境问题)
sysctl:
sysctl_file: "/etc/sysctl.d/95-k8s-sysctl.conf"
name: net.ipv4.tcp_tw_recycle
value: 0
state: present
reload: yes
when: tcp_tw_recycle.stat.exists | bool
- name: 生效系统参数
shell: "source /etc/profile; sysctl -p /etc/sysctl.d/95-k8s-sysctl.conf"
ignore_errors: true
# 设置系统级 ulimits(提升文件描述符等限制)
- name: 创建 systemd 配置目录
file:
path: /etc/systemd/system.conf.d
state: directory
- name: 设置系统 ulimits
template:
src: 30-k8s-ulimits.conf.j2
dest: /etc/systemd/system.conf.d/30-k8s-ulimits.conf
# 黑名单 SCTP 模块(安全加固)
- name: 把 SCTP 列入内核模块黑名单
copy:
src: sctp.conf
dest: /etc/modprobe.d/sctp.conf
📄 1.2.2 debian.yml
# Debian/Ubuntu 系统专用初始化任务
# 更新 apt 缓存(仅在线模式)
- name: apt 更新缓存刷新
apt:
update_cache: yes
cache_valid_time: 72000
ignore_errors: true
when: INSTALL_SOURCE != "offline"
# 移除 Ubuntu 默认安装的无用组件
- name: 删除 ubuntu 默认安装
package:
name:
- ufw
- lxd
- lxcfs
- lxc-common
state: absent
ignore_errors: true
# 安装 Kubernetes 所需的基础软件包(在线模式)
- name: 安装 ubuntu/debian 基础软件
package:
name:
- bash-completion # bash 补全
- conntrack # 连接跟踪清理
- ipset # IPVS 模式依赖
- ipvsadm # IPVS 管理工具
- jq # JSON 处理
- libseccomp2 # containerd 依赖
- lvm2 # LVM 存储插件
- nfs-common # NFS 客户端
- psmisc # killall 命令
- rsync # 配置同步
- socat # 端口转发
state: present
when: INSTALL_SOURCE != "offline"
# 离线安装逻辑
- import_tasks: offline.yml
when: INSTALL_SOURCE == "offline"
# 优化 journald 日志配置
- name: 准备 journal 日志相关目录
file:
path: "{{ item }}"
state: directory
loop:
- "/etc/systemd/journald.conf.d"
- "/var/log/journal"
- name: 优化设置 journal 日志
template:
src: 95-k8s-journald.conf.j2
dest: /etc/systemd/journald.conf.d/95-k8s-journald.conf
- name: 重启 journald 服务
service:
name: systemd-journald
state: restarted
📄 1.2.3 main.yml
# 主任务入口:根据系统类型调用对应子任务,并执行通用配置
- name: 检查是否已执行过 prepare_tasks(幂等性控制)
stat:
path: "/opt/kubeasz_prepare_tasks"
register: p
- name: 已完成提示
debug:
msg: "节点已完成 prepare_tasks,跳过"
when: p.stat.isreg is defined
- block:
# 根据操作系统类型导入对应任务
- import_tasks: debian.yml
when: ansible_distribution_file_variety in ["Debian"]
- import_tasks: redhat.yml
when: ansible_distribution_file_variety in ["RedHat"] or ansible_distribution in ["CentOS"]
- import_tasks: suse.yml
when: ansible_distribution_file_variety in ["SUSE"]
- import_tasks: redhat.yml
when: ansible_distribution in ["Anolis OS", "openEuler"]
# 执行通用任务
- import_tasks: common.yml
# 创建必要目录
- name: prepare some dirs
file:
path: "{{ item }}"
state: directory
loop:
- "{{ bin_dir }}"
- "{{ ca_dir }}"
- /root/.kube
# 分发 kubeconfig(仅 master 和 node 节点)
- name: 复制 kubectl kubeconfig
copy:
src: "{{ cluster_dir }}/kubectl.kubeconfig"
dest: /root/.kube/config
when: inventory_hostname in groups['kube_master'] or inventory_hostname in groups['kube_node']
# 设置 PATH 环境变量
- name: 写入环境变量 $PATH
lineinfile:
dest: ~/.bashrc
state: present
regexp: 'custom PATH'
line: 'export PATH={{ bin_dir }}:$PATH # generated by kubeasz:custom PATH'
# 为 Ansible 控制机设置别名(方便调试)
- name: ansible 控制端写入命令别名
lineinfile:
dest: ~/.bashrc
state: present
regexp: 'docker exec'
line: "alias dk='docker exec -it kubeasz' # generated by kubeasz"
when: inventory_hostname == ansible_env.SSH_CLIENT.split(' ')[0]
# 添加本地 registry 的 hosts 解析
- name: 添加 local registry hosts 解析
lineinfile:
dest: /etc/hosts
state: present
regexp: 'easzlab.io.local'
line: "{{ ansible_env.SSH_CLIENT.split(' ')[0] }} easzlab.io.local"
# 设置唯一 hostname(Calico 要求)
- name: 设置节点 hostname
hostname:
name: "{{ K8S_NODENAME }}"
use: systemd
when: ENABLE_SETTING_HOSTNAME | bool
# 在第一个 master 节点记录 nodename 解析
- name: 设置 k8s_nodename 在 master[0] 节点 /etc/hosts 地址解析
lineinfile:
dest: /etc/hosts
state: present
regexp: "{{ K8S_NODENAME }} .* generated by kubeasz"
line: "{{ inventory_hostname }} {{ K8S_NODENAME }} # generated by kubeasz"
delegate_to: "{{ groups.kube_master[0] }}"
when: inventory_hostname != K8S_NODENAME
tags: set_hosts
# 同步解析到所有节点
- block:
- name: 获取 master[0] 节点由 kubeasz 创建的 /etc/hosts 地址解析
shell: 'grep "generated by kubeasz" /etc/hosts | sort | uniq'
register: RESOLVE_K8S_NODENAME
delegate_to: "{{ groups.kube_master[0] }}"
- name: 清理 master[0] 的临时记录
lineinfile:
dest: /etc/hosts
state: absent
regexp: "generated by kubeasz"
delegate_to: "{{ groups.kube_master[0] }}"
- name: 设置 k8s_nodename 在所有节点的 /etc/hosts 地址解析
blockinfile:
path: /etc/hosts
block: |
{{ RESOLVE_K8S_NODENAME.stdout }}
marker: "### {mark} KUBEASZ MANAGED BLOCK"
delegate_to: "{{ item }}"
loop: "{{ groups.kube_master + groups.kube_node }}"
run_once: true
tags: set_hosts
# 标记任务已完成(幂等性)
- name: 设置 prepare_tasks 文件
shell: "echo done > /opt/kubeasz_prepare_tasks"
when: p.stat.isreg is not defined
📄 1.2.4 offline.yml
# 离线安装基础系统包(适用于无网络环境)
- name: 检查是否已下载离线软件包 {{ SYS_PKG_NAME }}
stat:
path: "{{ base_dir }}/down/packages/{{ SYS_PKG_NAME }}"
register: pkg
connection: local
run_once: true
- name: 准备离线安装包目录
file:
path: /opt/kube/packages/basic
state: directory
- block:
- name: 分发离线软件包 {{ SYS_PKG_NAME }}
copy:
src: "{{ base_dir }}/down/packages/{{ SYS_PKG_NAME }}"
dest: "/opt/kube/packages/basic/{{ SYS_PKG_NAME }}"
# Debian 系:使用 dpkg 安装
- name: 安装离线软件包 {{ SYS_PKG_NAME }}
shell: |
cd /opt/kube/packages/basic && tar zxf {{ SYS_PKG_NAME }} && \
dpkg -i *.deb > /tmp/install_basic.log 2>&1
register: install_info
until: not install_info.failed
retries: 3
delay: 1
when: ansible_distribution_file_variety in ["Debian"]
# RedHat/SUSE 系:使用 rpm 安装
- name: 安装离线软件包 {{ SYS_PKG_NAME }}
shell: |
cd /opt/kube/packages/basic && tar zxf {{ SYS_PKG_NAME }} && \
rpm -Uvh --force --nodeps *.rpm > /tmp/install_basic.log 2>&1
when: ansible_distribution_file_variety in ["RedHat", "SUSE"]
when: pkg.stat.exists | bool
ignore_errors: true
📄 1.2.5 redhat.yml
# RHEL/CentOS/Fedora/openEuler/Anolis OS 专用任务
- name: 删除 centos/redhat 默认安装的防火墙组件
package:
name:
- firewalld
- python-firewall
- firewalld-filesystem
state: absent
ignore_errors: true
- name: 安装基础软件包
package:
name:
- bash-completion
- conntrack-tools
- ipset
- ipvsadm
- libseccomp
- lvm2
- nfs-utils
- psmisc
- rsync
- socat
state: present
when: INSTALL_SOURCE != "offline"
- import_tasks: offline.yml
when: INSTALL_SOURCE == "offline"
# 关闭 SELinux(Kubernetes 不兼容)
- name: 临时关闭 selinux
shell: "setenforce 0"
failed_when: false
- name: 检查 /etc/selinux/config 是否存在
stat:
path: "/etc/selinux/config"
register: se
- name: 永久关闭 selinux(文件存在时)
lineinfile:
dest: /etc/selinux/config
regexp: "^SELINUX="
line: "SELINUX=disabled"
ignore_errors: true
when: se.stat.isreg is defined
- name: 永久关闭 selinux(文件不存在时)
shell: |
echo 'SELINUX=disabled' > /etc/selinux/config && \
echo 'SELINUXTYPE=targeted' >> /etc/selinux/config
when: se.stat.isreg is not defined
# 优化日志:禁止 rsyslog 重复采集 journald 日志
- name: 禁止 rsyslog 获取 journald 日志1
lineinfile:
dest: /etc/rsyslog.conf
state: present
regexp: 'ModLoad imjournal'
line: '#$ModLoad imjournal # provides access to the systemd journal'
ignore_errors: true
- name: 禁止 rsyslog 获取 journald 日志2
lineinfile:
dest: /etc/rsyslog.conf
state: present
regexp: 'IMJournalStateFile'
line: '#$IMJournalStateFile imjournal.state'
ignore_errors: true
- name: 重启 rsyslog 服务
service:
name: rsyslog
state: restarted
ignore_errors: true
📄 1.2.6 suse.yml
# SUSE Linux 专用任务
- name: 安装基础软件包
package:
name:
- bash-completion
- conntrack-tools
- ipset
- ipvsadm
- libseccomp2
- lvm2
- nfs-client
- psmisc
- rsync
- socat
state: present
when: INSTALL_SOURCE != "offline"
- import_tasks: offline.yml
when: INSTALL_SOURCE == "offline"
📄 1.3 templates/ 模板文件
📄 1.3.1 10-k8s-modules.conf.j2
# Kubernetes 所需内核模块列表
br_netfilter
dm_snapshot
dm_thin_pool
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
{% if 'NoFound' not in NF_CONNTRACK_IPV4.stdout %}
nf_conntrack_ipv4
{% endif %}
📄 1.3.2 30-k8s-ulimits.conf.j2
[Manager]
# 提升系统资源限制(文件描述符、进程数等)
DefaultLimitCORE=infinity
DefaultLimitNOFILE=100000
DefaultLimitNPROC=100000
📄 1.3.3 95-k8s-journald.conf.j2
[Journal]
# journald 日志持久化与限制
Storage=persistent
SystemMaxUse=2G
SystemMaxFileSize=200M
MaxRetentionSec=2week
ForwardToSyslog=no
ForwardToWall=no
📄 1.3.4 95-k8s-sysctl.conf.j2
## 网络优化
net.ipv4.ip_forward = 1
net.ipv4.tcp_tw_reuse = 2
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_fin_timeout = 30
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65536
net.ipv4.tcp_max_syn_backlog = 65536
net.ipv4.tcp_rmem = 4096 12582912 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.netfilter.nf_conntrack_max = 1048576
{% if PROXY_MODE == "ipvs" %}
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 10
{% endif %}
# 文件系统
fs.file-max = 2097152
fs.inotify.max_user_instances = 8192
fs.inotify.max_user_watches = 524288
# 内存管理
vm.swappiness = 0
vm.max_map_count = 262144
vm.overcommit_memory = 1
vm.panic_on_oom = 0
kernel.panic = 10
# 容器支持
kernel.pid_max = 4194304
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-arptables = 1
# Kubernetes 要求
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
kernel.softlockup_panic = 1
📄 1.4 vars/main.yml
# 离线软件包命名规则:根据系统类型和版本生成
SYS_PKG_NAME: "{{ ansible_distribution | lower | replace(' ', '_') }}_{{ ansible_distribution_major_version }}.tgz"
更多推荐


所有评论(0)