研究K8S有一段時間了,最開始學習K8S時,根據網上的教程安裝K8S環境老是報錯。因此,我就改變了學習策略,先不搞環境搭建了。先經過官網學習了K8S的總體架構,底層原理,又硬啃了一遍K8S源碼。別問我爲哈這樣學,只是我以爲對我我的來講,這樣學能讓我更好的理解整套雲原生體系。這不,此次,我總結了如何一次性成功安裝K8S集羣的方法。咱們今天先來講說如何基於一主兩從模式搭建K8S集羣。後面,咱們再上如何徹底無坑搭建K8S高可用集羣的方案。文章和搭建環境所須要的yml文件已收錄到:https://github.com/sunshinelyz/technology-binghe 和 https://gitee.com/binghe001/technology-binghe 。若是文件對你有點幫助,別忘記給個Star哦!node
IP | 主機名 | 節點 | 操做系統版本 |
---|---|---|---|
192.168.175.101 | binghe101 | Master | CentOS 8.0.1905 |
192.168.175.102 | binghe102 | Worker | CentOS 8.0.1905 |
192.168.175.103 | binghe103 | Worker | CentOS 8.0.1905 |
在三臺服務器上的/etc/hosts文件中添加以下配置項。linux
192.168.175.101 binghe101 192.168.175.102 binghe102 192.168.175.103 binghe103
分別在三臺服務器上檢查系統的環境。git
cat /etc/redhat-release
安裝Docker和K8S集羣的服務器操做系統版本須要在CentOS 7以上。程序員
hostname
注意:集羣中服務器的主機名不能是localhost。
lscpu
注意:集羣中服務器的CPU核數不能少於2個。
以binghe101(Master)服務器爲例。在服務器上執行 ip route show
命令來查看服務器的默認網卡,以下所示。github
[root@binghe101 ~]# ip route show default via 192.168.175.2 dev ens33 proto static metric 100 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 192.168.175.0/24 dev ens33 proto kernel scope link src 192.168.175.101 metric 100
在上面的輸出信息中有以下一行標註了binghe101服務器所使用的默認網卡。面試
default via 192.168.175.2 dev ens33 proto static metric 100
能夠看到,binghe101服務器使用的默認網卡爲ens33。docker
接下來,使用ip address
命令查看服務器的IP地址,以下所示。shell
[root@binghe101 ~]# ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:0c:29:68:06:63 brd ff:ff:ff:ff:ff:ff inet 192.168.175.101/24 brd 192.168.175.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::890f:5a92:4171:2a11/64 scope link noprefixroute valid_lft forever preferred_lft forever
能夠看到,binghe101服務器上的默認網卡的IP地址爲192.168.175.101
,K8S將使用此 IP 地址與集羣內的其餘節點通訊。集羣中全部K8S所使用的IP地址必須能夠互通。json
分別在三臺服務器上安裝Docker並配置阿里雲鏡像加速器。vim
新建auto_install_docker.sh腳本文件
vim auto_install_docker.sh
文件的內容以下所示。
export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com dnf install yum* yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo dnf install https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm yum install docker-ce docker-ce-cli -y systemctl enable docker.service systemctl start docker.service docker version
或者指定Docker的版本進行安裝,此時auto_install_docker.sh腳本文件的內容以下所示。
export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com dnf install yum* yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8 containerd.io systemctl enable docker.service systemctl start docker.service docker version
使用以下命令賦予auto_install_docker.sh文件可執行權限。
chmod a+x ./auto_install_docker.sh
接下來,直接運行auto_install_docker.sh腳本文件安裝Docker便可。
./auto_install_docker.sh
新建腳本文件aliyun_docker_images.sh。
vim aliyun_docker_images.sh
文件內容以下所示。
mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker
爲aliyun_docker_images.sh腳本文件賦予可執行權限,以下所示。
chmod a+x ./aliyun_docker_images.sh
執行aliyun_docker_images.sh腳本文件配置阿里雲鏡像加速器。
./aliyun_docker_images.sh
分別在三臺服務器上進行系統設置。
yum install -y nfs-utils yum install -y wget
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
新建sys_config.sh腳本文件。
vim sys_config.sh
sys_config.sh腳本文件的內容以下所示,
# 若是有配置,則修改 sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g" /etc/sysctl.conf # 可能沒有,追加 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf # 執行命令以應用 sysctl -p
執行以下命令賦予sys_config.sh文件可執行權限。
chmod a+x ./sys_config.sh
執行sys_config.sh腳本文件。
./sys_config.sh
分別在三臺服務器上安裝K8S。
新建k8s_yum.sh腳本文件。
vim k8s_yum.sh
文件的內容以下所示。
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
賦予k8s_yum.sh腳本文件的可執行權限。
chmod a+x ./k8s_yum.sh
執行k8s_yum.sh文件。
./k8s_yum.sh
yum remove -y kubelet kubeadm kubectl
yum install -y kubelet-1.18.2 kubeadm-1.18.2 kubectl-1.18.2
sed -i "s#^ExecStart=/usr/bin/dockerd.*#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd#g" /usr/lib/systemd/system/docker.service
systemctl daemon-reload systemctl restart docker systemctl enable kubelet && systemctl start kubelet
綜上,上述安裝Docker、進行系統設置,安裝K8S的操做能夠統一成auto_install_docker_k8s.sh腳本。腳本的內容以下所示。
#安裝Docker 19.03.8 export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com dnf install yum* yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8 containerd.io systemctl enable docker.service systemctl start docker.service docker version #配置阿里雲鏡像加速器 mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker #安裝nfs-utils yum install -y nfs-utils yum install -y wget #關閉防火牆 systemctl stop firewalld systemctl disable firewalld #關閉SeLinux setenforce 0 sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config # 關閉 swap swapoff -a yes | cp /etc/fstab /etc/fstab_bak cat /etc/fstab_bak |grep -v swap > /etc/fstab #修改 /etc/sysctl.conf # 若是有配置,則修改 sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g" /etc/sysctl.conf sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g" /etc/sysctl.conf # 可能沒有,追加 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf # 執行命令以應用 sysctl -p # 配置K8S的yum源 cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF # 卸載舊版本K8S yum remove -y kubelet kubeadm kubectl # 安裝kubelet、kubeadm、kubectl,這裏我安裝的是1.18.2版本,你也能夠安裝1.17.2版本 yum install -y kubelet-1.18.2 kubeadm-1.18.2 kubectl-1.18.2 # 修改docker Cgroup Driver爲systemd # # 將/usr/lib/systemd/system/docker.service文件中的這一行 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock # # 修改成 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd # 若是不修改,在添加 worker 節點時可能會碰到以下錯誤 # [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". # Please follow the guide at https://kubernetes.io/docs/setup/cri/ sed -i "s#^ExecStart=/usr/bin/dockerd.*#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd#g" /usr/lib/systemd/system/docker.service # 設置 docker 鏡像,提升 docker 鏡像下載速度和穩定性 # 若是您訪問 https://hub.docker.io 速度很是穩定,亦能夠跳過這個步驟 # curl -sSL https://kuboard.cn/install-script/set_mirror.sh | sh -s ${REGISTRY_MIRROR} # 重啓 docker,並啓動 kubelet systemctl daemon-reload systemctl restart docker systemctl enable kubelet && systemctl start kubelet docker version
注意:我安裝的K8S版本是1.18.2,你們在安裝K8S時,也能夠選擇其餘版本進行安裝
賦予auto_install_docker_k8s.sh腳本文件可執行權限。
chmod a+x ./auto_install_docker_k8s.sh
執行auto_install_docker_k8s.sh腳本文件。
./auto_install_docker_k8s.sh
注意:須要在每臺服務器上執行auto_install_docker_k8s.sh腳本文件。
只在binghe101服務器上執行的操做。
# 只在 master 節點執行 # export 命令只在當前 shell 會話中有效,開啓新的 shell 窗口後,若是要繼續安裝過程,請從新執行此處的 export 命令 export MASTER_IP=192.168.175.101 # 替換 k8s.master 爲 您想要的 dnsName export APISERVER_NAME=k8s.master # Kubernetes 容器組所在的網段,該網段安裝完成後,由 kubernetes 建立,事先並不存在於您的物理網絡中 export POD_SUBNET=172.18.0.1/16 echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
在binghe101服務器上建立init_master.sh腳本文件,文件內容以下所示。
#!/bin/bash # 腳本出錯時終止執行 set -e if [ ${#POD_SUBNET} -eq 0 ] || [ ${#APISERVER_NAME} -eq 0 ]; then echo -e "\033[31;1m請確保您已經設置了環境變量 POD_SUBNET 和 APISERVER_NAME \033[0m" echo 當前POD_SUBNET=$POD_SUBNET echo 當前APISERVER_NAME=$APISERVER_NAME exit 1 fi # 查看完整配置選項 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2 rm -f ./kubeadm-config.yaml cat <<EOF > ./kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.18.2 imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers controlPlaneEndpoint: "${APISERVER_NAME}:6443" networking: serviceSubnet: "10.96.0.0/16" podSubnet: "${POD_SUBNET}" dnsDomain: "cluster.local" EOF # kubeadm init # 根據您服務器網速的狀況,您須要等候 3 - 10 分鐘 kubeadm init --config=kubeadm-config.yaml --upload-certs # 配置 kubectl rm -rf /root/.kube/ mkdir /root/.kube/ cp -i /etc/kubernetes/admin.conf /root/.kube/config # 安裝 calico 網絡插件 # 參考文檔 https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises echo "安裝calico-3.13.1" rm -f calico-3.13.1.yaml wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml kubectl apply -f calico-3.13.1.yaml
賦予init_master.sh腳本文件可執行權限。
chmod a+x ./init_master.sh
執行init_master.sh腳本文件。
./init_master.sh
(1)確保全部容器組處於Running狀態
# 執行以下命令,等待 3-10 分鐘,直到全部的容器組處於 Running 狀態 watch kubectl get pod -n kube-system -o wide
以下所示。
[root@binghe101 ~]# watch kubectl get pod -n kube-system -o wide Every 2.0s: kubectl get pod -n kube-system -o wide binghe101: Sat May 2 23:40:33 2020 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES calico-kube-controllers-5b8b769fcd-l2tmm 1/1 Running 0 3m59s 172.18.203.67 binghe101 <none> <none> calico-node-8krsl 1/1 Running 0 3m59s 192.168.175.101 binghe101 <none> <none> coredns-546565776c-rd2zr 1/1 Running 0 3m59s 172.18.203.66 binghe101 <none> <none> coredns-546565776c-x8r7l 1/1 Running 0 3m59s 172.18.203.65 binghe101 <none> <none> etcd-binghe101 1/1 Running 0 4m14s 192.168.175.101 binghe101 <none> <none> kube-apiserver-binghe101 1/1 Running 0 4m14s 192.168.175.101 binghe101 <none> <none> kube-controller-manager-binghe101 1/1 Running 0 4m14s 192.168.175.101 binghe101 <none> <none> kube-proxy-qnffb 1/1 Running 0 3m59s 192.168.175.101 binghe101 <none> <none> kube-scheduler-binghe101 1/1 Running 0 4m14s 192.168.175.101 binghe101 <none> <none>
(2) 查看 Master 節點初始化結果
kubectl get nodes -o wide
以下所示。
[root@binghe101 ~]# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME binghe101 Ready master 5m43s v1.18.2 192.168.175.101 <none> CentOS Linux 8 (Core) 4.18.0-80.el8.x86_64 docker://19.3.8
在Master節點上執行以下命令獲取join命令參數。
kubeadm token create --print-join-command
具體執行以下所示。
[root@binghe101 ~]# kubeadm token create --print-join-command W0502 23:44:55.218947 59318 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io] kubeadm join k8s.master:6443 --token s0hoh1.2cwyf1fyyjl2h04a --discovery-token-ca-cert-hash sha256:6d78e360dc64d84762611ac6beec8ac0f0fe9f72a5c2cca008df949e07827c19
其中,有以下一行輸出。
kubeadm join k8s.master:6443 --token s0hoh1.2cwyf1fyyjl2h04a --discovery-token-ca-cert-hash sha256:6d78e360dc64d84762611ac6beec8ac0f0fe9f72a5c2cca008df949e07827c19
這行代碼就是獲取到的join命令。
注意:join命令中的token的有效時間爲 2 個小時,2小時內,可使用此 token 初始化任意數量的 worker 節點。
針對全部的 worker 節點執行,在這裏,就是在binghe102服務器和binghe103服務器上執行。
建立init_worker.sh腳本文件,文件內容以下所示。
# 只在 worker 節點執行 # 192.168.175.101 爲 master 節點的內網 IP export MASTER_IP=192.168.175.101 # 替換 k8s.master 爲初始化 master 節點時所使用的 APISERVER_NAME export APISERVER_NAME=k8s.master echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts # 替換爲 master 節點上 kubeadm token create 命令輸出的join kubeadm join k8s.master:6443 --token s0hoh1.2cwyf1fyyjl2h04a --discovery-token-ca-cert-hash sha256:6d78e360dc64d84762611ac6beec8ac0f0fe9f72a5c2cca008df949e07827c19
其中,kubeadm join...就是master 節點上 kubeadm token create 命令輸出的join。
賦予init_worker.sh腳本文件文件可執行權限,並執行init_worker.sh腳本文件。
chmod a+x ./init_worker.sh ./init_worker.sh
在Master節點執行以下命令查看初始化結果。
kubectl get nodes -o wide
以下所示。
[root@binghe101 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION binghe101 Ready master 20m v1.18.2 binghe102 Ready <none> 2m46s v1.18.2 binghe103 Ready <none> 2m46s v1.18.2
注意:kubectl get nodes命令後面加上-o wide參數能夠輸出更多的信息。
Master 節點的 IP 地址發生變化,致使 worker 節點不能啓動。須要從新安裝K8S集羣,並確保全部節點都有固定的內網 IP 地址。
重啓服務器後使用以下命令查看Pod的運行狀態。
kubectl get pods --all-namespaces
發現不少 Pod 不在 Running 狀態,此時,須要使用以下命令刪除運行不正常的Pod。
kubectl delete pod <pod-name> -n <pod-namespece>
注意:若是Pod 是使用 Deployment、StatefulSet 等控制器建立的,K8S 將建立新的 Pod 做爲替代,從新啓動的 Pod 一般可以正常工做。
微信搜一搜【冰河技術】微信公衆號,關注這個有深度的程序員,天天閱讀超硬核技術乾貨,公衆號內回覆【PDF】有我準備的一線大廠面試資料和我原創的超硬核PDF技術文檔,以及我爲你們精心準備的多套簡歷模板(不斷更新中),但願你們都能找到心儀的工做,學習是一條時而鬱鬱寡歡,時而開懷大笑的路,加油。若是你經過努力成功進入到了心儀的公司,必定不要懈怠放鬆,職場成長和新技術學習同樣,不進則退。若是有幸咱們江湖再見!
另外,我開源的各個PDF,後續我都會持續更新和維護,感謝你們長期以來對冰河的支持!!