本文完整阅读约需 36 分钟,如时间较长请考虑收藏后慢慢阅读~

最近正在学习Kubernetes,但发现官方的文档仅限于配置单机集群(即Master和Node位于同一台机器上),依旧无法判断哪部分属于Master、哪部分属于Node,而互联网上的相关教程、资源大多还停留在1.3、1.7版本,与最新的版本存在大量差异,且内容不够详细。
在踩了无数坑,与Kubernetes激战了好几天后,我决定将1.14版本Kubernetes通过kubeadm的完整安装过程分享出来,希望对大家有所帮助。

0x01 准备阶段

在安装前,你需要准备以下材料:

1.两台及以上虚拟机/物理机/云主机

两台机器一台作为Master,一台作为Node,但也可以只使用一台进行安装,只是将master与slave的安装过程在一台服务器上进行(不清楚为什么官方教程要将两个安装过程合在一起,反而加深了迷惑)。

该教程使用五台服务器进行(也可以不需要这么多),配置如下:
– Master 192.168.1.40 (master-kubernetes.local)
– Node-01 192.168.1.41 (worker-01-kubernetes.local)
– Node-02 192.168.1.42 (worker-02-kubernetes.local)
– Node-03 192.168.1.43 (worker-03-kubernetes.local)
– Node-04 192.168.1.44 (worker-04-kubernetes.local)
其中括号内是该主机的主机名(即域名),所有服务器均为CentOS 7 64 Bit操作系统。每台服务器推荐配置双核处理器/2G内存及以上的性能。

如果使用虚拟机,需要开启桥接网卡模式,不可以使用NAT模式,参考:
VirtualBox 开启桥接网卡模式
VMware Workstation 开启桥接网卡模式

2. 科学上网

由于Kubernetes是Google的产品(与Go大同小异),很多关键的包(例如部署集群时的组件)存储在Google的Docker Registry上,这就造成了在国内部署Kubernetes极为麻烦。

此处建议有条件在路由器(例如OpenWRT)上针对IP地址进行代理,也可以在宿主机上安装一个Privoxy,来为测试用的虚拟机提供HTTP代理,后者教程见这篇文章

针对这一硬需求,我将部署时所使用的Docker镜像保存成了独立文件(更新日期20190614),需要的读者可以直接下载。

下载地址:
链接:https://pan.baidu.com/s/1VDGJMnhq7yktN-lxuisiGA
提取码:ahpc

0x02 前期配置阶段

该配置需要在Master和Node上同时进行,如果嫌麻烦,可以先开一台虚拟机,然后使用虚拟机的复制功能直接复制(注意复制后修改主机名与ip地址)

此处以Master为例。

1. 修改主机名

对于CentOS 7,原先修改主机名的方式已不再可用,需要使用hostnamectl工具对主机名进行修改。
运行如下命令,修改主机名,重启后正式生效。

hostnamectl set-hostname master-kubernetes.local

其中master-kubernetes.local为我们所配置的主机名。

2. 配置avahi

配置主机名的作用是希望在IP地址变更的情况下,依然能够找到服务器,同时也可以规范服务器环境,是运维过程中极为有效的实践规范。

而avahi是mDNS协议在Linux上的实现,用于自动注册局域网内设备的DNS,即访问内网设备可以通过内部域名,这样就算IP地址变更,也可以准确的找到设备。

安装avahi的方式极为简单:

yum install -y avahi

安装后启动avahi服务:

systemctl enable avahi-daemon
systemctl start avahi-daemon
systemctl status avahi-daemon

出现如下提示则安装成功:

● avahi-daemon.service - Avahi mDNS/DNS-SD Stack
   Loaded: loaded (/usr/lib/systemd/system/avahi-daemon.service; enabled; vendor preset: enabled)
   Active: active (running) since 四 2019-06-13 22:53:05 CST; 18h ago
 Main PID: 2884 (avahi-daemon)
   Status: "avahi-daemon 0.6.31 starting up."
    Tasks: 2
   Memory: 992.0K
   CGroup: /system.slice/avahi-daemon.service
           ├─2884 avahi-daemon: running [master-kubernetes.local]
           └─2890 avahi-daemon: chroot helper

安装成功后,我们可以尝试在自己的主机上查看配置是否生效:

ping master-kubernetes.local

如果域名被成功解析,且ping正常,则说明avahi安装完成,可以进行下一步的操作。

3. 配置防火墙

如果是初学kubernetes,我的建议是暂时先关闭防火墙,命令如下所示:

systemctl stop firewalld
systemctl disable firewalld

但注意,不推荐直接卸载firewalld甚至是其依赖的iptables,因为后续的配置还需要该防火墙实现虚拟路由。

如果服务部署在外网,不得不配置防火墙,请在Master与Node上执行如下命令:

firewall-cmd --zone=public --add-port=2379-2380/tcp --permanent     # etcd所使用的API端口
firewall-cmd --zone=public --add-port=6443/tcp --permanent      # apiserver所使用的API端口
firewall-cmd --zone=public --add-port=10250-10253/tcp --permanent       # kubelet/kube-scheduler/kube-controller-manager所使用的API端口
firewall-cmd --zone=public --add-port=30000-32767/tcp --permanent       # nodeport服务所使用的API端口
firewall-cmd --reload
firewall-cmd --zone=public --list-ports

随着时间与版本改变,以上端口配置可能与实际情况不相符,如果配置有Service或者LoadBalancer,则需要打开更多的端口,请灵活处理,本机测试阶段依旧推荐直接关闭防火墙,以避免因防火墙造成的诸多困惑。

4. 关闭SELinux

事实上如果直接采用默认配置,无需关闭SELinux也可正常运行,但如果要进行apiserver端口修改、配置文件编辑甚至修改存储目录等操作,配置SELinux将成为一个巨大负担。而通常情况下,SELinux的关闭并不会造成服务器安全受到极大影响,建议关闭:

sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config && setenforce 0

5. 同步系统时间,并修改时区为北京时区

如果使用海外的云服务器,经常会因为忘记修改时区,造成日志信息等时间出现错乱,导致安装过程中的困惑,此处一并对系统时间进行同步、且修改时区。

rm -rf /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
yum install -y ntpdate && ntpdate asia.pool.ntp.org

6. 注册所有服务器的DNS信息

由于kubeadm在init/join时会对域名的DNS进行查询(不通过mDNS,直接查询上游DNS服务器),如果查询失败则停止初始化进程。该问题截止到2019年仍然没有得到彻底解决,因此有两种方案可以解决该问题。

6.1 直接修改每台服务器的hosts配置

该方式适用于服务器数量较少或固定的情况,直接修改每个服务器的/etc/hosts文件。以上文提到的配置为例,需要添加如下内容在每台服务器的hosts配置中:

192.168.1.40 master-kubernetes.local
192.168.1.41 worker-01-kubernetes.local
192.168.1.42 worker-02-kubernetes.local
192.168.1.43 worker-03-kubernetes.local
192.168.1.44 worker-04-kubernetes.local

6.2 配置一个新的DNS服务器

如果服务器数量较多,或经常变动,我的建议是搭建一个DNS服务器。该部分较为复杂,且与本文主题无关,因此只留一个教程链接以供参考:链接

7. 关闭SWAP分区

按照CentOS 7的默认配置,安装时会划分与物理内存大小相同(或相关联)的一块磁盘作为SWAP分区,但Kubernetes与SWAP兼容性较差(为了避免内存交换带来的性能降低),如果不是服务器资源稀缺,通常直接关闭SWAP分区即可。

swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

重启后执行free -m检查SWAP分区是否已关闭,如果SWAP信息显示如下,说明SWAP已经关闭:

Swap:             0           0           0

至此服务器基础配置完成,可以开始相关软件的安装。

0x03 基础环境安装

1. 安装Docker

事实上,Kubernetes支持的容器化引擎绝不止Docker一款,目前(2019年)支持的就有Docker、Containerd、LXD、Rkt四种之多。但介于Docker的影响力及其使用价值与易用性,该教程依旧以Docker为例,讲解安装Kubernetes的方法,其他容器化引擎事实上大同小异。

注意:该部分依旧需要在所有服务器上进行相同操作

1.1 配置Docker仓库

wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo

1.2 修改Docker源,加快下载速度

sed -i '[email protected]@mirrors.tuna.tsinghua.edu.cn/docker-ce@g' /etc/yum.repos.d/docker-ce.repo

1.3 下载安装Docker

yum -y install docker-ce

1.4 启动Docker并配置开机自启动

systemctl start docker
systemctl enable docker

2. 安装kubeadm

2.1 配置kubeadm仓库

在终端粘贴下面的命令:

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF

这里使用的是Linux中知名的Heredoc,可以在我写过的一篇文章『浅谈Heredoc及其使用』中学习。

需要注意的是,kubernetes.repo文件的最后一行使用了exclude=kube*配置,这使得默认不带参数的的yum install无法安装kubeadm组件,但也避免了无脑yum update不小心造成kubeadm意外关闭或升级到不兼容的版本。

2.2 安装kubeadm组件

yum -y install kubeadm kubelet kubectl --disableexcludes=kubernetes

2.3 启动相关服务

systemctl start docker
systemctl enable docker
systemctl enable kubelet        # 此处先配置开机自启,稍后初始化时会自动启动,不用手动start

编辑/etc/sysconfig/kubelet文件,写入如下配置,避免因为swap问题导致无法成功安装:

KUBELET_EXTRA_ARGS="--fail-swap-on=false"

2.4 检测iptables相关桥接配置是否启动

cat /proc/sys/net/bridge/bridge-nf-call-ip6tables
cat /proc/sys/net/bridge/bridge-nf-call-iptables

如果都为1,则相关配置启动
若为0,需要编辑/etc/sysctl.conf,并输入以下配置:

net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1

然后执行sysctl -p应用配置,再重复以上过程检查是否桥接配置已经启动。

0x04 Master配置

以上配置完成后,就可以开始对Master进行单独配置。

0. 提前安装所需镜像

由于前文提到不可言说的原因,在初始化阶段所需要下载的Docker镜像无法在国内访问,若无法获得理想的网络环境,可以提前安装所需镜像,地址前文也已经提供。
安装方式很简单,在服务器上应用docker load 文件名即可安装。
所有镜像安装完成后,使用docker images命令查看镜像列表,应该如图所示:

1. 初始化Master

kubeadm init --ignore-preflight-errors=Swap

初始化结束后,kubeadm会返回所需的token和ca-cert-hash,但如果遗失也没关系,接下来的过程就假设我们遗失了token,以带领读者解决更复杂的问题,迅速了解kubeadm。

2. 拷贝默认配置文件,以便在本机使用kubectl

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

3. 安装网络插件flannel

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

过几分钟会在docker images中看到安装完成的flannel镜像,届时可进行下一步操作。

3. 验证安装状态

yum install -y net-tools
netstat -nlp | grep 6443

如果返回如下所示,则说明kube-apiserver成功启动:

tcp6       0      0 :::6443                 :::*                    LISTEN      4451/kube-apiserver 

然后执行kubectl get cs查看组件状态信息,理想结果应该如下所示:

NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok                  
scheduler            Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   

最后执行kubectl get nodes检查节点状态,理想状态应该为Ready:

NAME                         STATUS   ROLES    AGE   VERSION
master-kubernetes.local      Ready    master   45h   v1.14.3

如果不是Ready,请检查组件是否完全安装,见第0步的截图所示。

0x05 Node配置

0. 提前安装所需镜像

该步骤同上,不再赘述。

1. 获取token与ca-cert-hash

如果还有保存Master初始化时的token与ca-cert-hash,直接复制即可,此处以遗失token和ca-cert-hash为例。

1.1 获取token

在Master下执行如下操作:

kubeadm token list

展示出来的就是Master节点存储的token列表,TTL则为剩余有效时间,初始为24h。
若token过期,可使用kubeadm token create命令新建一个token。

1.2 获取ca-cert-hash

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

返回值则是本地ca的ca-cert-hash。

2. 加入Master

kubeadm join master-kubernetes.local:6443 --token `你的Token` --discovery-token-ca-cert-hash sha256:`你的ca-cert-hash`--ignore-preflight-errors=Swap

3. 验证安装状态

回到Master,使用kubectl get nodes命令查看Node状态,若Node状态为Ready,则说明安装成功。

0x06 结语

至此,kubernetes集群已经搭建安装完成,kubeadm帮助我们在后台完成了Master初始化与Node连接Master背后的所有操作。

如有不明白的地方,欢迎给我发邮件,我会耐心回答。我的邮件是loli#lurenjia.in(替换掉#为@避免spam)。

如果这篇文章帮到了你,不妨请我喝一杯咖啡: