本文面向具有基本K8s使用經驗的讀者
項目作者在業餘時間看心情維護,不求你用,愛用不用。
建議那些有錢的,懶得動腦子的,有甲方病的,出門左轉找個收費的裝,花點,不丟人。
關於kubernetes v1.14.0:
- kubeadm開始建議使用systemd作爲節點的cgroup控制器,因此建議讀者參考本文流程配置docker爲使用systemd,而非默認的Cgroupfs。
- kubelet額外的引入了對conntrack的依賴。
- Linux 5.0.x版內核已被支持。
關於其他plugins:
- 本次release集成的是calico3.5.3版本,使用host-local模式ipam。最新版的calico(3.6.0)中,calico-ipam功能已經成熟並在官方manifest中默認啓用,然而3.6.0存在一些問題因而沒能通過我的部署測試。
- 本次release集成的traefik是最新的穩定版本1.7.9,traefik:2.0已經發布,但尚處於alpha2測試階段。
- 我在項目的feature-prom-rook分支添加了Rook和Prometheus的測試yaml,讀者有興趣的話可以試用一下。
理論上升級內核並不是必要的,爲私有倉庫單獨準備一臺機器也並不是必要的,但本指導爲了簡化步驟,將假設讀者會按照本文步驟升級內核,併爲私有倉庫準備了一臺單獨的機器。如果讀者跳過這些步驟後出現問題,本文不會提供解決這些問題所需要進行的額外配置。
本文中出現的全部下載連接見下表:
文件名 | 下載鏈接 | 提取碼 | MD5 |
---|---|---|---|
helm-v2.13.1-linux-amd64.tar.gz | 百度盤 | crv5 | ffbe37fe328d99156d14a950bbd8107c |
k8s-v1.14.0-rpms.tgz | 百度盤 | okdg | 7cccc6b10e17a6c640baced768aab274 |
k8s-repo-v1.14.0 | 百度盤 | 88ua | 96af3a2da51460f8e51321e15094fdd2 |
kernel-ml-5.0.4.tgz | 百度盤 | twl3 | 8e546a243f6fd5ca3ebe1d30079d2bac |
本文中的自動化部署腳本可以在Lentil1016/kubeadm-ha找到,歡迎Star/Fork/提issue和PR。
升級過程的錄像可以在本鏈接查看
集羣方案:
- 發行版:CentOS 7 & Fedora 29
- 容器運行時:Docker-18.09.3-ce
- 內核: 5.0.3-200.fc29.x86_64
- 版本:Kubernetes: 1.14.0
- 網絡方案: Calico v3.5.3
- kube-proxy mode: IPVS
- master高可用方案:keepalived LVS
- DNS插件: CoreDNS 1.3.1
- metrics插件:metrics-server v0.3.1
- dashboard:kubernetes-dashboard v1.10.1
- ingress控制器:traefik 1.7.9
- helm & tiller:v2.13.1
0x01 Kubernetes集羣搭建
集羣結構摘要
此處爲舉列說明,假定各個機器的主機信息以及IP分佈如下,需要額外說明的是,由於私有倉庫需要佔用80端口,與ingress controller衝突,因此爲私有倉庫單獨準備一臺機器是必要的:
Host Name | Role | IP |
---|---|---|
registry | 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
- 升級內核到最新,原因見issue#19
- 開啓IPVS
如果發現elrepo-kernel源中的內核版本過高或過低,無法滿足要求,可以使用下面測試過的5.0.4版本rpm包:
kernel-ml-5.0.4.tgz | 百度盤 | twl3 | 8e546a243f6fd5ca3ebe1d30079d2bac |
# 所有主機:基本系統配置 # 關閉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-iptables = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 """ > /etc/sysctl.conf 執行下面加載bridge命令,不然可能會報(
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: 沒有那個文件或目錄)
modprobe br_netfilter modprobe bridge sysctl -p# 同步時間 yum install -y ntpdate ntpdate -u ntp.api.bz # 升級內核 rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm ;yum --enablerepo=elrepo-kernel install kernel-ml-devel kernel-ml -y # 檢查默認內核版本是否大於4.14,否則請調整默認啓動參數 hostnamectl
grub2-editenv list #重啓以更換內核(需要手工選擇升級後的內核) reboot
將新內核設置爲默認引導內核並創建新內核的配置文件。默認啓動的順序應該爲1,升級以後內核是往前面插入,值爲0[root@localhost ~]# grub2-set-default 0 [root@localhost ~]# grub2-mkconfig -o /etc/grub2.cfg Generating grub configuration file ... Found linux image: /boot/vmlinuz-5.1.15-1.el7.elrepo.x86_64 Found initrd image: /boot/initramfs-5.1.15-1.el7.elrepo.x86_64.img Found linux image: /boot/vmlinuz-3.10.0-862.14.4.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-862.14.4.el7.x86_64.img Found linux image: /boot/vmlinuz-3.10.0-327.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-327.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-b64aa70a2eef8444a209edf175e3bcce Found initrd image: /boot/initramfs-0-rescue-b64aa70a2eef8444a209edf175e3bcce.img done # 確認內核版本後,開啓IPVS uname -a 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" 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
# 安裝docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
yum makecache fast
yum install -y docker-ce
# 編輯systemctl的Docker啓動文件和配置文件
sed -i "13i ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT" /usr/lib/systemd/system/docker.service
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
# 啓動docker
systemctl daemon-reload
systemctl enable docker
systemctl start docker
安裝私有鏡像庫
如果不能翻牆,需要使用本文提供的私有鏡像源,則還需要爲docker做如下配置,將K8s官方鏡像庫的幾個域名設置爲insecure-registry,然後設置hosts使它們指向私有源。
# 所有主機:http私有源配置
# 額外爲Docker配置私有源
cat > /etc/docker/daemon.json <<EOF
{
"insecure-registries":["harbor.io", "k8s.gcr.io", "gcr.io", "quay.io"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
systemctl restart docker
# 此處應當修改爲registry所在機器的IP
REGISTRY_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 """
$REGISTRY_HOST gcr.io harbor.io k8s.gcr.io quay.io """ >> /etc/hosts
下載地址:
k8s-repo-v1.14.0 | 百度盤 | 88ua | 96af3a2da51460f8e51321e15094fdd2 |
隨後將該文件放置到registry機器上,並在registry主機上加載、啓動該鏡像
# registry:啓動私有鏡像庫
docker load -i /path/to/k8s-repo-1.14.0
docker run --restart=always -d -p 80:5000 --name repo harbor.io:1180/system/k8s-repo:v1.14.0
該鏡像庫中包含如下鏡像,全部來源於官方鏡像站。
鏡像列表
安裝配置kubernetes
基本安裝
下載文件:
k8s-v1.14.0-rpms.tgz | 百度盤 | okdg | 7cccc6b10e17a6c640baced768aab274 |
並放置在k8s各個master和worker主機上
# master & worker:安裝kubernetes
yum install -y socat keepalived ipvsadm conntrack
cd /path/to/downloaded/file
tar -xzvf k8s-v1.14.0-rpms.tgz
cd k8s-v1.14.0
rpm -Uvh * --force
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
# 部署HA master
cd ~/
# 創建集羣信息文件
echo """
CP0_IP=10.130.29.80
CP1_IP=10.130.29.81
CP2_IP=10.130.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.14.0/kubeha-gen.sh)"
# 該步驟將可能持續2到10分鐘,在該腳本進行安裝部署前,將有一次對安裝信息進行檢查確認的機會
可以在本鏈接查看我在自己的環境上安裝全過程的錄像,安裝結束後會打印出如下的信息,最後一行爲加入集羣的命令。
訪問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,請先下載離線包:
helm-v2.13.1-linux-amd64.tar.gz | 百度盤 | crv5 | ffbe37fe328d99156d14a950bbd8107c |
cd /path/to/helm-v2.13.1-linux-amd64.tar.gz/
tar -xzvf helm-v2.13.1-linux-amd64.tar.gz
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
隨後到worker節點執行剛剛生成的join command即可將該節點編入集羣。
至此,HA master Kubernetes 集羣搭建完畢