kubeadm HA master(v1.12.1)集群搭建指南(离线包 + 自动化脚本 + ipvs + keepalived + calico + helm) For Centos/Fedora

0x00 文章楔子

本文停止后续维护,请转至:

kubeadm HA master(v1.14.0)离线包 + 自动化脚本 + 常用插件 For Centos/Fedora

本文旨在通过最简易的方式指导读者搭建HA kubernetes 1.12.1集群

通过部署脚本驱动kubeadm工具进行自动化部署,自动启动keepalived负载均衡,calico网络插件,并且开启kube-proxy的IPVS模式。

本文中的自动化部署脚本可以在Lentil1016/kubeadm-ha找到,欢迎Star/Fork/提issue和PR。

在我的环境上进行示例自动化部署的录像可以在该链接查看

0x01 Kubernetes集群搭建

集群结构摘要

集群结构摘要

Master是集群的管理者,负责监控应用运行状态,维护应用运行,如发布工作任务、重启应用、部署升级应用等

Worker(节点),也被称为Minion,即从属主机,是Kubernetes集群中的一台工作机器。每一个节点都包含了Pod运行所需的必要服务,例如docker/kubelet/kube-proxy。

Kubernetes集群的基本部署步骤:

  1. 所有节点安装docker
  2. harbor节点安装harbor
  3. 所有master和minion节点安装kubelet kubeadm kubectl
  4. 初始化master节点,并启动Calico容器
  5. 将worker节点join到集群中

各个机器的主机信息以及IP分布如下:

  • Distribute: CentOS 7
  • Docker: 17.03.2-ce
  • Kernel: 4.18.12-1.el7.elrepo.x86_64
  • Kubernetes: 1.12.1
  • NetPlugin: Calico
  • Proxy-Mode: IPVS
  • Master-Mode: HA Master
  • DNS: CoreDNS
Host Name Role IP
harbor image registry 10.130.38.80
centos-7-x86-64-29-80 master-1 10.130.29.80
centos-7-x86-64-29-81 master-2 10.130.29.81
centos-7-x86-64-29-82 master-3 10.130.29.82
Virtual IP 10.130.29.83
node1 worker 10.130.38.105
node2 worker 10.130.38.106
node3 worker 10.130.38.107

进行系统配置

在所有机器上下载内核rpm包,并且执行下面的脚本,配置注记:

  • 关闭防火墙、selinux
  • 关闭系统的Swap,Kubernetes 1.8开始要求。
  • 关闭linux swap空间的swappiness
  • 配置L2网桥在转发包时会被iptables的FORWARD规则所过滤,该配置被CNI插件需要,更多信息请参考Network Plugin Requirements
  • 开启IPVS
# 所有主机:基本系统配置

# 关闭Selinux/firewalld
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
 
# 关闭交换分区
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab
 
# 设置网桥包经IPTables,core文件生成路径
echo """
vm.swappiness = 0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
""" > /etc/sysctl.conf
sysctl -p
 
# 同步时间
yum install -y ntpdate
ntpdate -u ntp.api.bz
 
# 安装4.18版本内核
# 由于最新稳定版4.19内核将nf_conntrack_ipv4更名为nf_conntrack,目前的kube-proxy不支持在4.19版本内核下开启ipvs
# 详情可以查看:https://github.com/kubernetes/kubernetes/issues/70304
# 对于该问题的修复10月30日刚刚合并到代码主干,所以目前还没有包含此修复的kubernetes版本发出
# 读者可以选择安装我提供的4.18版本内核,或者不开启IPVS
# 4.18版本内核RPM下载链接:https://pan.baidu.com/s/1dCeozuMRQ96MBBjGpf0cjA 提取码:3nqg
cd /path/to/kernel-ml.tgz/
tar -xzvf kernel-ml.tgz
rpm -Uvh kernel-ml/*
 
# 检查默认内核版本是否为4.18,否则请调整默认启动参数
grub2-editenv list
 
#重启以更换内核
reboot
 
# 确认内核版本
uname -a
 
# 确认内核版本为4.18后,开启IPVS
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
 
#!/bin/bash
ipvs_modules="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 nf_conntrack_ipv4"
for kernel_module in \${ipvs_modules}; do
 /sbin/modinfo -F filename \${kernel_module} > /dev/null 2>&1
 if [ $? -eq 0 ]; then
 /sbin/modprobe \${kernel_module}
 fi
done
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs

执行sysctl -p报错请参考centos7添加bridge-nf-call-ip6tables出现No such file or directory

Kubernetes要求集群中所有机器具有不同的Mac地址、产品uuid、Hostname。可以使用如下命令查看Mac和uuid

# 所有主机:检查UUID和Mac

cat /sys/class/dmi/id/product_uuid
ip link

安装配置Docker

Docker从1.13版本开始调整了默认的防火墙规则,禁用了iptables filter表中FOWARD链,这样会引起Kubernetes集群中跨Node的Pod无法通信,因此docker安装完成后,还需要手动修改iptables规则。

安装私有镜像库

如果不能翻墙,需要使用本文提供的私有镜像源,则还需要为docker做如下配置,将K8s官方镜像库的几个域名设置为insecure-registry,然后设置hosts使它们指向私有源。

# 所有主机:http私有源配置

# 为Docker配置一下私有源
mkdir -p /etc/docker
echo -e '{\n"insecure-registries":["k8s.gcr.io", "gcr.io", "quay.io"]\n}' > /etc/docker/daemon.json
systemctl restart docker
 
# 此处应当修改为harbor所在机器的IP
HARBOR_HOST="10.130.38.80"
# 设置Hosts
yes | cp /etc/hosts /etc/hosts_bak
cat /etc/hosts_bak|grep -vE '(gcr.io|harbor.io|quay.io)' > /etc/hosts
echo """
$HARBOR_HOST gcr.io harbor.io k8s.gcr.io quay.io """ >> /etc/hosts

下载链接:链接:https://pan.baidu.com/s/10qwKtvVCeCRHccLrN-zQHg 提取码:ip4z,随后将该文件放置到harbor机器上,并在harbor主机上加载、启动该镜像

# harbor:启动私有镜像库

docker load -i /path/to/k8s-repo-1.12.1
docker run --restart=always -d -p 80:5000 --name repo harbor.io:1180/system/k8s-repo:v1.12.1

该镜像库中包含如下镜像,全部来源于官方镜像站。

1.12.1版本镜像列表

安装配置kubernetes

基本安装

首先下载链接:链接:https://pan.baidu.com/s/1ETQoH6RmcZ34n5IscR9RLQ 提取码:ntc6,并放置在k8s各个master和worker主机上

# master & worker:安装kubernetes

yum install -y socat keepalived ipvsadm
cd /path/to/downloaded/file
tar -xzvf k8s-v1.12.1-rpms.tgz
cd k8s-v1.12.1
rpm -Uvh *
systemctl enable kubelet
kubeadm version -o short

配置免密码登陆

# master-1:生成ssh密钥对

ssh-keygen
# 三次回车后,密钥生成完成
cat ~/.ssh/id_rsa.pub
# 得到该机器的公钥如下图

将该公钥复制,并分别登陆到master-1 master-2 master-3的root用户,将它令起一行粘贴到 ~/.ssh/authorized_keys 文件中,包括master-1自己

复制完成后,从master-1上分别登陆master-1 master-2 master-3测试是否可以免密码登陆(请不要跳过这一步),可以的话便可以继续执行下一步

部署HA Master

HA Master的部署过程已经自动化,请在master-1上执行如下命令,并注意修改IP和Hostname

# 部署HA master

cd ~/
 
# 创建集群信息文件
echo """
CP0_IP=10.130.29.80
CP0_HOSTNAME=centos-7-x86-64-29-80
CP1_IP=10.130.29.81
CP1_HOSTNAME=centos-7-x86-64-29-81
CP2_IP=10.130.29.82
CP2_HOSTNAME=centos-7-x86-64-29-82
VIP=10.130.29.83
NET_IF=eth0
CIDR=10.244.0.0/16
""" > ./cluster-info
 
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Lentil1016/kubeadm-ha/1.12.1/kubeha-gen.sh)"
# 该步骤将可能持续2到10分钟,在该脚本进行安装部署前,将有一次对安装信息进行检查确认的机会

可以在该链接查看我在自己的环境上安装全过程的录像,安装结束后会打印出如下的信息,最后一行为加入集群的命令,其中加入集群的IP已经被更换为了高可用的VIP。

访问dashboard

如果需要访问kubernetes dashboard或traefik dashboard,只需要在浏览器所在机器上配置到任意master的hosts解析,然后访问对应域名即可。

echo """
10.130.29.80 dashboard.multi.io ingress.multi.io""" >> /etc/hosts

测试发现有时kubernetes dashboard容器会不响应请求,如果出现该情况请尝试删除dashboard的pod以重新启动该pod,即可解决该问题。

安装helm

如果需要安装helm,请先下载离线包链接:https://pan.baidu.com/s/1RZ8WOHQHQ951h2qlna85ig 提取码:02ni

cd /path/to/helm-v2.11.0-linux-amd64.tar/
tar -xzvf helm-v2.11.0-linux-amd64.tar
cd linux-amd64
cp helm /usr/local/bin
helm init --service-account=kubernetes-dashboard-admin --skip-refresh --upgrade
helm version

加入work node

现在可以将各节点入编到集群中。join command是由kubeadm动态生成的,其基本形式如下

# worker:将worker编入集群
kubeadm join 10.130.29.83:6443 --token 4n3hvt.sb8qjmno6l47tsww --discovery-token-ca-cert-hash sha256:a7f1de577bd8677a5d7fe4d765993645ae25d8b52a63a1133b74a595a7bb2e0f

其中包含了节点入编集群所需要携带的验证token,以防止外部恶意的节点进入集群。每个token自生成起24小时后过期。届时如果需要加入新的节点,则需要重新生成新的join token,请使用下面的命令生成,注意改写IP:

# master-1:生成指向VIP的Join Command
kubeadm token create --print-join-command|sed 's/${LOCAL_IP}/${VIP}/g'

随后到worker节点执行刚刚生成的join command即可将该节点编入集群。

至此,HA master Kubernetes 集群搭建完毕

K8S中文社区微信公众号

评论 57

登录后评论

立即登录  

  1. #16

    问一问,Hyperkube 组件是用在哪里? 1.12.1对比以前1.11.0的大版本有哪里不一样?

    译风6年前 (2018-10-26)
    • hyperkube是Prometheus部署会用到
      kubeadm的配置文件api版本变成v1alpha3了,结构和以前大不一样了,目前影响到我的只有这个。证书轮换功能以前我挺需要的,现在不用了,所以。。。
      其他都是些小变化,大多数在我的能力和视野之外。

      lentil10166年前 (2018-10-26)
  2. #15

    vip可以绑定域名吗

    15年前 (2018-10-29)
    • 不太可能,VIP这一配置主要是给keepalived用的,首先我没找到这样配置keepalived的文档。其次keepalived要拿这个IP在多个机器间争抢,如果经过一层DNS,keepalived很难知道这个过程中有没有做过DNS负载均衡,导致两次拿的IP不同。所以keepalived不太可能支持配置hostanem为VIP。

      lentil10165年前 (2018-10-29)
  3. #14

    [root@localhost ~]# /sbin/modinfo -F filename nf_conntrack_ipv4
    modinfo: ERROR: Module nf_conntrack_ipv4 not found.
    [root@localhost ~]#

    bhj_dysf5年前 (2018-11-04)
    • 我也遇到了这个问题 内核更新到 4.19 没有 nf_conntrack_ipv4

      annda5年前 (2018-11-07)
      • 我写这篇的时候kernel-ml分支还在4.18版本,可能是4.19已经把nf_conntrack_ipv4.ko这个模块内置到内核里了,应该把最后那项去掉就可以了,我一会试一下,如果可以的话我会更新一下文章。

        lentil10165年前 (2018-11-08)
      • 由于4.19版本内核将nf_conntrack_ipv4更名为nf_conntrack,目前的kube-proxy不支持在4.19版本内核下开启ipvs,详情可以查看:https://github.com/kubernetes/kubernetes/issues/70304
        对于该问题,由于修复9天前刚刚合并,所以还没有包含此修复的版本
        目前读者可以选择安装4.18版本内核,或者不开启IPVS

        lentil10165年前 (2018-11-08)
  4. #13

    nf_conntrack_ipv4这个模块没有 ,怎么办啊

    bhj_dysf5年前 (2018-11-04)
    • 我不清楚你遇到的是什么问题
      ls /lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko
      建议先执行这个命令查看那个内核模块存不存在,这个文件通常是直接包含在内核的本体RPM包中,例如kernel-ml-4.18.12-1.el7.elrepo.x86_64.rpm。所以它会和内核一起安装,不存在漏装或安装失败的情况,如果没有的话可能说明你的rpm源有问题。

      lentil10165年前 (2018-11-06)
      • 就是按照文档添加的源啊

        annda5年前 (2018-11-07)
      • 我试了一下 kernel-ml-4.18.12-1.el7.elrepo.x86_64.rpm 这个版本,确实是有 nf_conntrack_ipv4 的。现在 elrepo 源提供的 kernel-ml-4.19.1-1.el7.elrepo.x86_64 确实没有 nf_conntrack_ipv4,谷歌了以下 coreos 那边用了 4.19 内核好像也存在类似问题

        annda5年前 (2018-11-07)
        • 由于4.19版本内核将nf_conntrack_ipv4更名为nf_conntrack,目前的kube-proxy不支持在4.19版本内核下开启ipvs,详情可以查看:https://github.com/kubernetes/kubernetes/issues/70304
          对于该问题,由于修复9天前刚刚合并,所以还没有包含此修复的版本
          目前读者可以选择安装4.18版本内核,或者不开启IPVS

          lentil10165年前 (2018-11-08)
        • 你是怎么把内核版本升特定到4.28的,貌似有点复杂啊

          雾非雾5年前 (2018-11-12)
        • 4.18

          雾非雾5年前 (2018-11-12)
  5. #12

    4.19.1-1.el7这个内核版本确实没有nf_conntrack_ipv4

    雾非雾5年前 (2018-11-08)
    • 由于4.19版本内核将nf_conntrack_ipv4更名为nf_conntrack,目前的kube-proxy不支持在4.19版本内核下开启ipvs,详情可以查看:https://github.com/kubernetes/kubernetes/issues/70304
      对于该问题,由于修复9天前刚刚合并,所以还没有包含此修复的版本
      目前读者可以选择安装4.18版本内核,或者不开启IPVS

      lentil10165年前 (2018-11-08)
  6. #11

    centos-7-x86-64-29-80 master-1 10.130.29.80
    centos-7-x86-64-29-81 master-2 10.130.29.81
    centos-7-x86-64-29-82 master-3 10.130.29.82
    – Virtual IP 10.130.29.83
    这几个IP地址在29段,其他在38段,这是有意要做成这样吗?29段和38段怎么互通呢?

    laozhang5年前 (2018-11-09)
    • 这是无意的,公司的内网网段是10.130.0.0/16,这几个38网段的只是恰巧开在了这个网段而已。Kubernetes对网络的要求是不太高的,只要两台机器之间的网络是平整的,不经过NAT就可以路由就可以。具体使用哪个网段,可以由读者个人的网络环境决定。

      lentil10165年前 (2018-11-09)
  7. #10

    使用脚本是出现如下错误:
    [init] this might take a minute or longer if the control plane images have to be pulled

    Unfortunately, an error has occurred:
    timed out waiting for the condition

    This error is likely caused by:
    – The kubelet is not running
    – The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)

    If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
    – ‘systemctl status kubelet’
    – ‘journalctl -xeu kubelet’

    Additionally, a control plane component may have crashed or exited when started by the container runtime.
    To troubleshoot, list all containers using your preferred container runtimes CLI, e.g. docker.
    Here is one example how you may list all Kubernetes containers running in docker:
    – ‘docker ps -a | grep kube | grep -v pause’
    Once you have found the failing container, you can inspect its logs with:
    – ‘docker logs CONTAINERID’
    couldn’t initialize a Kubernetes cluster
    Waiting for etcd bootup…

    怀疑是harbor机器那边出现问题导致的。怎么检查harbor那边是正常的?
    谢谢!

    laozhang5年前 (2018-11-10)
  8. #9

    [root@centos7-h1 ~]# docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    3123ffe6479d harbor.io:1180/system/k8s-repo:v1.12.1 “/entrypoint.sh /e…” 9 minutes ago Up 9 minutes 0.0.0.0:80->5000/tcp repo
    [root@centos7-h1 ~]# netstat -na |grep LIST
    tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
    tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
    tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN
    tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
    tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
    tcp6 0 0 ::1:25 :::* LISTEN
    tcp6 0 0 :::111 :::* LISTEN
    tcp6 0 0 :::80 :::* LISTEN
    tcp6 0 0 :::22 :::* LISTEN
    tcp6 0 0 ::1:631 :::* LISTEN

    发现不知道为何harbor的80端口是没有监听。

    laozhang5年前 (2018-11-10)
    • 你的kubelet启动失败了,建议首先执行journalctl -uf kubelet,随后另开一个终端执行systemctl restart kubelet查看kubelet启动的过程中报了什么错误

      lentil10165年前 (2018-11-11)
      • k8s-vip kubelet[6297]: E1208 03:16:48.497954 6297 kubelet.go:2236] node “k8s-vip” not found
        我也出现这样的问题

        Steven5年前 (2018-12-08)
        • Unable to update cni config: No networks found in /etc/cni/net.d

          Steven5年前 (2018-12-08)
          • 这个问题我没有见过,不太眼熟,如果可以的话,烦请在我的github issue区提issue,提供更加详细的信息,也比较方便我们交流

            lentil10165年前 (2018-12-11)
  9. #8

    1.12搭建完了。三个master里,coredns的podip用docker0,没有用calico。。。这个遇到过没有

    weeknd5年前 (2018-11-13)
  10. #7

    master2、master3设置–cluster-cidr=10.244.0.0/16,但是部署到master2和master3上时,pod分配的ip确实172.17.0.0/16(docker的所属的网段),不知是什么原因

    nika5年前 (2018-11-13)
    • 大兄弟,装的什么版本1.12.1还是1.12.2

      weeknd5年前 (2018-11-14)
      • 解决了master2和master3没有启用calico网络

        nika5年前 (2018-11-14)
        • 不是daemonset吗。为何没有启动啊。你改了啥地方

          weeknd5年前 (2018-11-15)
    • 您好,这是由一个Kubeadm的已知问题造成的,我昨天更新了脚本,对该问题进行了修复,重新执行脚本进行部署后该问题应当不会再出现了

      lentil10165年前 (2018-11-16)
      • 开启ipvs一定要升级内核吗,3.10的内核可以吗

        shy5年前 (2018-11-21)
        • 建议升级内核,3.10内核有多个Cgroup内存泄漏的bug,且至少在3.10.0-327版本中还缺少ip_vs_fo.ko模块,将导致kube-proxy无法开启ipvs模式

          lentil10165年前 (2018-11-22)
          • 非常感谢,我升级试一下,因为目前一测试DNS,coredns总是OOMKilled

            shy5年前 (2018-11-22)
          • 并且ipvsadm -Ln查看发现不了vip的转发

            shy5年前 (2018-11-22)
  11. #6

    大神你好,如果我想在云服务器上自己搭建k8s集群,怎么解决vip漂移这个问题

    捶捶5年前 (2018-11-22)
    • 您好,公有云上一般会限制VIP的使用,并要求使用厂商的SLB,如果不想开启VIP的话可以手动停止各个机器上的keepalived,并将~/.kube/config中的IP替换成某一个master的IP即可,但这样也会造成kubectl并不能严格意义上的高可用。

      lentil10165年前 (2018-11-24)
  12. #5

    大神,视频里用的Linux terminal theme 是什么呀?看着很酷炫?分享下呗

    若枫5年前 (2018-11-22)
    • shell是安装了oh-my-zsh插件的zsh,主题是我自己写的,可以在这里找到:https://github.com/Lentil1016/lent-dotfile/blob/master/.zshrc

      lentil10165年前 (2018-11-24)
  13. #4

    请问,目前 kubeadm 能用于生产吗?

    Jasontom5年前 (2018-11-25)
    • kubeadm目前是BETA测试阶段,社区不再阻止使用者在生产环境使用该工具,但也没有明确推荐。我目前还没有遇到什么由Kubeadm引发的问题,但具体是否要在生产上使用应该由读者自行判断。

      lentil10165年前 (2018-11-29)
  14. #3

    楼主你好,卡在这里20分钟左右Waiting for all pods into ‘Running’ statu. You can press ‘Ctrl + c’ to terminate this waiting any time you like.
    安装过程没有报错提示,请问是哪里出问题。

    unicorn5年前 (2018-11-29)
    • 说明有一些容器一直没有启动成功,Ctrl + c后执行kubectl get pods -n kube-system查看有哪些容器启动失败

      lentil10165年前 (2018-11-29)
      • 显示 calico-node-7lb9x calico-node-z45xj kube-proxy-8rnr6 kube-proxy-wwvt4 为 nodelost状态 其他正常 可能是什么原因

        nuaa10015年前 (2018-11-30)
        • 您好,从当前的描述我不太能判断出原因,该问题可能与集群中的特定节点有关,请运行kubectl get pods -n kube-system -o wide查看是哪些节点上的pod运行出错。尝试在有故障pod的节点上运行kubectl describe node {包含nodelost状态的节点}, jourctl -u kubelet -f, kubectl get pods -n kube-system calico-node-7lb9x尝试获得更多线索

          lentil10165年前 (2018-12-02)
  15. #2

    Docker 18.09.0 在K8s 1.12.1 上面不支持。后面没法继续了。

    szxdyx5年前 (2018-12-06)
    • yum install -y docker-ce-18.06.1.ce

      Steven5年前 (2018-12-08)
  16. #1

    dashboard ui使用token无法登陆,页面没反应 pod日志正常,跳过token可以进入dashboard ui界面 请问该如何排查

    肉啃肉5年前 (2018-12-10)
    • 我也一样,请问怎样获取token?

      Steven5年前 (2018-12-11)
      • token 可以通过`kubectl get secret -o yaml`获得,至于使用token无法登陆的问题,其实是由于dashboard为了安全性禁止了http和未经验证的https登陆。如果想使用token登陆,首先需要保证通过https进入网页,其次浏览器需要信任dashboard下发的证书。不登陆将使用默认权限,我在部署时将默认权限设为最大,所以不登陆也不影响使用。如果想通过登陆进入dashboard,请参考dashboard wiki: https://github.com/kubernetes/dashboard/wiki/Access-control

        lentil10165年前 (2018-12-11)
      • 并且注意去掉deployment中的serviceAccount以禁用免登录的默认权限,否则登陆就没有意义了

        lentil10165年前 (2018-12-11)