01.系统初始化和全局变量
集群机器
- m7-autocv-gpu01:172.27.128.150
- m7-autocv-gpu02:172.27.128.149
- m7-autocv-gpu03:172.27.128.148
可以使用 vagrant 和 Vagrantfile 创建三台虚机:
$ cd vagrant $ vagrant up
本文档中的 etcd 集群、master 节点、worker 节点均使用这三台机器。
主机名
设置永久主机名称,然后重新登录:
$ sudo hostnamectl set-hostname m7-autocv-gpu01 # 将 m7-autocv-gpu01 替换为当前主机名
- 设置的主机名保存在
/etc/hostname
文件中;
修改每台机器的 /etc/hosts
文件,添加主机名和 IP 的对应关系:
$ grep kube-node /etc/hosts 172.27.128.150 m7-autocv-gpu01 m7-autocv-gpu01 172.27.128.149 m7-autocv-gpu02 m7-autocv-gpu02 172.27.128.148 m7-autocv-gpu03 m7-autocv-gpu03
添加 k8s 和 docker 账户
在每台机器上添加 k8s 账户,可以无密码 sudo:
$ sudo useradd -m k8s $ sudo sh -c 'echo 123456 | passwd k8s --stdin' # 为 k8s 账户设置密码 $ sudo visudo $ sudo grep '%wheel.*NOPASSWD: ALL' /etc/sudoers %wheel ALL=(ALL) NOPASSWD: ALL $ sudo gpasswd -a k8s wheel
在每台机器上添加 docker 账户,将 k8s 账户添加到 docker 组中,同时配置 dockerd 参数:
$ sudo useradd -m docker $ sudo gpasswd -a k8s docker $ sudo mkdir -p /etc/docker/ $ cat /etc/docker/daemon.json { "registry-mirrors": ["https://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"], "max-concurrent-downloads": 20 }
无密码 ssh 登录其它节点
如果没有特殊指明,本文档的所有操作均在 m7-autocv-gpu01 节点上执行,然后远程分发文件和执行命令。�
设置 m7-autocv-gpu01 可以无密码登录所有节点的 k8s 和 root 账户:
[k8s@m7-autocv-gpu01 k8s]$ ssh-keygen -t rsa [k8s@m7-autocv-gpu01 k8s]$ ssh-copy-id root@m7-autocv-gpu01 [k8s@m7-autocv-gpu01 k8s]$ ssh-copy-id root@m7-autocv-gpu02 [k8s@m7-autocv-gpu01 k8s]$ ssh-copy-id root@m7-autocv-gpu03 [k8s@m7-autocv-gpu01 k8s]$ ssh-copy-id k8s@m7-autocv-gpu01 [k8s@m7-autocv-gpu01 k8s]$ ssh-copy-id k8s@m7-autocv-gpu02 [k8s@m7-autocv-gpu01 k8s]$ ssh-copy-id k8s@m7-autocv-gpu03
将可执行文件路径 /opt/k8s/bin 添加到 PATH 变量中
在每台机器上添加环境变量:
$ sudo sh -c "echo 'PATH=/opt/k8s/bin:$PATH:$HOME/bin:$JAVA_HOME/bin' >>/root/.bashrc" $ echo 'PATH=/opt/k8s/bin:$PATH:$HOME/bin:$JAVA_HOME/bin' >>~/.bashrc
安装依赖包
在每台机器上安装依赖包:
CentOS:
$ sudo yum install -y epel-release $ sudo yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp
Ubuntu:
$ sudo apt-get install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp
- ipvs 依赖 ipset;
关闭防火墙
在每台机器上关闭防火墙:
$ sudo systemctl stop firewalld $ sudo systemctl disable firewalld $ sudo iptables -F && sudo iptables -X && sudo iptables -F -t nat && sudo iptables -X -t nat $ sudo sudo iptables -P FORWARD ACCEPT
关闭 swap 分区
如果开启了 swap 分区,kubelet 会启动失败(可以通过将参数 --fail-swap-on 设置为 false 来忽略 swap on),故需要在每台机器上关闭 swap 分区:
$ sudo swapoff -a
为了防止开机自动挂载 swap 分区,可以注释 /etc/fstab
中相应的条目:
$ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
关闭 SELinux
关闭 SELinux,否则后续 K8S 挂载目录时可能报错 Permission denied
:
$ sudo setenforce 0 $ grep SELINUX /etc/selinux/config SELINUX=disabled
- 修改配置文件,永久生效;
关闭 dnsmasq
linux 系统开启了 dnsmasq 后(如 GUI 环境),将系统 DNS Server 设置为 127.0.0.1,这会导致 docker 容器无法解析域名,需要关闭它:
$ sudo service dnsmasq stop $ sudo systemctl disable dnsmasq
设置系统参数
$ cat > kubernetes.conf <<EOF net.bridge.bridge-nf-call-iptables=1 net.bridge.bridge-nf-call-ip6tables=1 net.ipv4.ip_forward=1 vm.swappiness=0 vm.overcommit_memory=1 vm.panic_on_oom=0 fs.inotify.max_user_watches=89100 EOF $ sudo cp kubernetes.conf /etc/sysctl.d/kubernetes.conf $ sudo sysctl -p /etc/sysctl.d/kubernetes.conf $ sudo mount -t cgroup -o cpu,cpuacct none /sys/fs/cgroup/cpu,cpuacct
加载内核模块
$ sudo modprobe br_netfilter $ sudo modprobe ip_vs
设置系统时区
$ # 调整系统 TimeZone $ sudo timedatectl set-timezone Asia/Shanghai $ # 将当前的 UTC 时间写入硬件时钟 $ sudo timedatectl set-local-rtc 0 $ # 重启依赖于系统时间的服务 $ sudo systemctl restart rsyslog $ sudo systemctl restart crond
创建目录
在每台机器上创建目录:
$ sudo mkdir -p /opt/k8s/{bin,download,cert} /etc/kubernetes/cert /etc/etcd/cert /var/lib/etcd
检查系统内核和模块是否适合运行 docker (仅适用于 linux 系统)
$ curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh $ bash ./check-config.sh
集群环境变量
后续的部署步骤将使用下面定义的全局环境变量,请根据自己的机器、网络情况修改:
#!/usr/bin/bash # 生成 EncryptionConfig 所需的加密 key ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64) # 最好使用 当前未用的网段 来定义服务网段和 Pod 网段 # 服务网段,部署前路由不可达,部署后集群内路由可达(kube-proxy 和 ipvs 保证) SERVICE_CIDR="10.254.0.0/16" # Pod 网段,建议 /16 段地址,部署前路由不可达,部署后集群内路由可达(flanneld 保证) CLUSTER_CIDR="172.30.0.0/16" # 服务端口范围 (NodePort Range) export NODE_PORT_RANGE="30000-32767" # 集群各机器 IP 数组 export NODE_IPS=(172.27.128.150 172.27.128.149 172.27.128.148) # 集群各 IP 对应的 主机名数组 export NODE_NAMES=(m7-autocv-gpu01 m7-autocv-gpu02 m7-autocv-gpu03) # kube-apiserver 的 VIP(HA 组件 keepalived 发布的 IP) export MASTER_VIP=172.27.129.253 # kube-apiserver VIP 地址(HA 组件 haproxy 监听 8443 端口) export KUBE_APISERVER="https://${MASTER_VIP}:8443" # HA 节点,VIP 所在的网络接口名称 export VIP_IF="eth0" # etcd 集群服务地址列表 export ETCD_ENDPOINTS="https://172.27.128.150:2379,https://172.27.128.149:2379,https://172.27.128.148:2379" # etcd 集群间通信的 IP 和端口 export ETCD_NODES="m7-autocv-gpu01=https://172.27.128.150:2380,m7-autocv-gpu02=https://172.27.128.149:2380,m7-autocv-gpu03=https://172.27.128.148:2380" # flanneld 网络配置前缀 export FLANNEL_ETCD_PREFIX="/kubernetes/network" # kubernetes 服务 IP (一般是 SERVICE_CIDR 中第一个IP) export CLUSTER_KUBERNETES_SVC_IP="10.254.0.1" # 集群 DNS 服务 IP (从 SERVICE_CIDR 中预分配) export CLUSTER_DNS_SVC_IP="10.254.0.2" # 集群 DNS 域名,注意域名不以 . 结尾 export CLUSTER_DNS_DOMAIN="cluster.local" # 将二进制目录 /opt/k8s/bin 加到 PATH 中 export PATH=/opt/k8s/bin:$PATH
- 打包后的变量定义见 environment.sh,后续部署时会提示导入该脚本;
分发集群环境变量定义脚本
把全局变量定义脚本拷贝到所有节点的 /opt/k8s/bin
目录:
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