從零開始搭建Kubernetes集群(三、搭建K8S集群)

一、前言

在上一篇文章 從零開始搭建Kubernetes 1.10.0 集群(二、搭建虛擬機(jī)環(huán)境)中,我們已經(jīng)搭建好了基礎(chǔ)的虛擬機(jī)環(huán)境。現(xiàn)在,我們可以開啟我們真正的K8S之旅。

我們將現(xiàn)有的虛擬機(jī)稱之為Node1,用作主節(jié)點(diǎn)。為了減少工作量,在Node1安裝Kubernetes后,我們利用VirtualBox的虛擬機(jī)復(fù)制功能,復(fù)制出兩個(gè)完全一樣的虛擬機(jī)作為工作節(jié)點(diǎn)。三者角色為:

  • Node1:Master
  • Node2:Woker
  • Node3:Woker

二、安裝Kubernetes

還是那句話,官方文檔永遠(yuǎn)是最好的參考資料:https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/

但是,僅供參考,因?yàn)閴Φ脑颍⒉煌耆m用于我們天朝子民。下面將詳細(xì)介紹在Node1上安裝Kubernetes的過程,安裝完畢后,再進(jìn)行虛擬機(jī)的復(fù)制出Node2、Node3即可。

配置K8S的yum源

官方倉庫無法使用,建議使用阿里源的倉庫,執(zhí)行以下命令添加kubernetes.repo倉庫:


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

關(guān)閉swap、防火墻

上一篇文章已介紹關(guān)閉

關(guān)閉SeLinux

執(zhí)行:setenforce 0

安裝K8S組件

執(zhí)行以下命令安裝kubelet、kubeadm、kubectl:

yum install -y kubelet kubeadm kubectl

如下圖所示:


image.png

配置kubelet的cgroup drive

確保docker 的cgroup drive 和kubelet的cgroup drive一樣:


docker info | grep -i cgroup

cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

若顯示不一樣,則執(zhí)行:

sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
systemctl daemon-reload

如圖:


image.png

啟動(dòng)kubelet

注意,根據(jù)官方文檔描述,安裝kubelet、kubeadm、kubectl三者后,要求啟動(dòng)kubelet:
systemctl enable kubelet && systemctl start kubelet
但實(shí)際測(cè)試發(fā)現(xiàn),無法啟動(dòng),報(bào)如下錯(cuò)誤:

image.png

查看日志發(fā)現(xiàn)是沒有證書:

unable to load client CA file /etc/kubernetes/pki/ca.crt: open /etc/kubernetes/pki/ca.crt: no such file or directory
image.png

我在網(wǎng)上沒有找到解決方法,但無意測(cè)試中發(fā)現(xiàn),后面的kubeadm init操作會(huì)創(chuàng)建證書。也就是說,現(xiàn)在無法啟動(dòng)并不影響后續(xù)操作,繼續(xù)!

下載K8S的Docker鏡像

本文使用的是K8S官方提供的kubeadm工具來初始化K8S集群,而初始化操作kubeadm init會(huì)默認(rèn)去訪問谷歌的服務(wù)器,以下載集群所依賴的Docker鏡像,因此也會(huì)超時(shí)失敗,你懂得。

但是,只要我們可以提前導(dǎo)入這些鏡像,kubeadm init操作就會(huì)發(fā)現(xiàn)這些鏡像已經(jīng)存在,就不會(huì)再去訪問谷歌。網(wǎng)上有一些方法可以獲得這些鏡像,如利用Docker Hub制作鏡像等,但稍顯繁瑣。

這里,我已將初始化時(shí)用到的所有Docker鏡像整理好了,鏡像版本是V1.10.0。推薦大家使用。

  • 地址:https://pan.baidu.com/s/11AheivJxFzc4X6Q5_qCw8A
  • 密碼:2zov

準(zhǔn)備好的鏡像如下圖所示:


image.png

K8S更新速度很快,截止目前最新版本是V1.10.2。本人提供的鏡像會(huì)越來越舊,需要最新版本的讀者可以根據(jù)網(wǎng)上教材自行制作

腳本docker_images_load.sh用于導(dǎo)入鏡像:


docker load < quay.io#calico#node.tar

docker load < quay.io#calico#cni.tar

docker load < quay.io#calico#kube-controllers.tar

docker load < k8s.gcr.io#kube-proxy-amd64.tar

docker load < k8s.gcr.io#kube-scheduler-amd64.tar

docker load < k8s.gcr.io#kube-controller-manager-amd64.tar

docker load < k8s.gcr.io#kube-apiserver-amd64.tar

docker load < k8s.gcr.io#etcd-amd64.tar

docker load < k8s.gcr.io#k8s-dns-dnsmasq-nanny-amd64.tar

docker load < k8s.gcr.io#k8s-dns-sidecar-amd64.tar

docker load < k8s.gcr.io#k8s-dns-kube-dns-amd64.tar

docker load < k8s.gcr.io#pause-amd64.tar

docker load < quay.io#coreos#etcd.tar

docker load < quay.io#calico#node.tar

docker load < quay.io#calico#cni.tar

docker load < quay.io#calico#kube-policy-controller.tar

docker load < gcr.io#google_containers#etcd.tar

將鏡像與該腳本放置同一目錄,執(zhí)行即可導(dǎo)入Docker鏡像。運(yùn)行docker images,如下圖所示,即表示鏡像導(dǎo)入成功:

image.png

三、復(fù)制虛擬機(jī)

前言中提到,當(dāng)Node1的Kubernetes安裝完畢后,就需要進(jìn)行虛擬機(jī)的復(fù)制了。

復(fù)制

復(fù)制前需要退出虛擬機(jī),我們選擇“正常關(guān)機(jī)”。右鍵虛擬機(jī)點(diǎn)擊復(fù)制:


image.png

如上,新的節(jié)點(diǎn)命名為CentOS-Node2,注意一定要勾選"重新初始化網(wǎng)卡Mac地址"。點(diǎn)擊“復(fù)制”,稍等幾分鐘,即可完成復(fù)制:

image.png

依此法再復(fù)制一個(gè)節(jié)點(diǎn)命名為CentOS-Node3。

添加網(wǎng)卡

復(fù)制結(jié)束后,如果直接啟動(dòng)三個(gè)虛擬機(jī),你會(huì)發(fā)現(xiàn)每個(gè)機(jī)子的IP地址(網(wǎng)卡enp0s3)都是一樣的:


image.png

這是因?yàn)閺?fù)制虛擬機(jī)時(shí)連同網(wǎng)卡的地址也復(fù)制了,這樣的話,三個(gè)節(jié)點(diǎn)之間是無法訪問的。因此,我建議復(fù)制結(jié)束后,不要馬上啟動(dòng)虛擬機(jī),而先要為每一個(gè)虛擬機(jī)添加一個(gè)網(wǎng)卡,用于節(jié)點(diǎn)間的互通訪問。

如下圖所示,連接方式選擇“Host-Only”模式:


image.png

網(wǎng)卡添加結(jié)束后,啟動(dòng)三個(gè)虛擬機(jī),查看各個(gè)IP。以主節(jié)點(diǎn)Node1為例,運(yùn)行ip addr

image.png

可以看到,網(wǎng)卡enp0s8為新添加的網(wǎng)卡2,IP地址為192.168.56.101。三個(gè)節(jié)點(diǎn)IP分別為:

  • Node1:192.168.56.101
  • Node2:192.168.56.102
  • Node3:192.168.56.103

在這三個(gè)節(jié)點(diǎn)中,可以使用這些IP互相ping一下,確保網(wǎng)絡(luò)連通正常。

另外,同上一節(jié)所述,建議啟用端口轉(zhuǎn)發(fā)功能,使用Xshell連接到Node1和Node2的終端。

設(shè)置虛擬機(jī)

網(wǎng)卡添加結(jié)束后,即可啟動(dòng)三個(gè)虛擬機(jī),我們需要進(jìn)行一些簡(jiǎn)單的設(shè)置,以主節(jié)點(diǎn)Node1為例:

  • 編輯/etc/hostname,將hostname修改為k8s-node1
  • 編輯/etc/hosts,追加內(nèi)容 IP k8s-node1

以上IP為網(wǎng)卡2的IP地址,修改后重啟生效。另外兩個(gè)節(jié)點(diǎn)修改同理,主機(jī)名分別為k8s-node2、k8s-node3。

四、創(chuàng)建集群

kubeadm介紹

前面的工作都準(zhǔn)備好后,我們就可以真正的創(chuàng)建集群了。這里使用的是官方提供的kubeadm工具,它可以快速、方便的創(chuàng)建一個(gè)K8S集群。kubeadm的具體介紹大家可以參考官方文檔:https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/。

截止目前,kubeadm尚處于beta狀態(tài),官方暫時(shí)不推薦在生產(chǎn)環(huán)境使用,但是預(yù)計(jì)今年會(huì)推出GA版本。這里,我建議大家盡量使用kubeadm,相對(duì)于純手動(dòng)部署效率更高,也不容易出錯(cuò)。

創(chuàng)建集群

在Master主節(jié)點(diǎn)(k8s-node1)上執(zhí)行:
kubeadm init --pod-network-cidr=192.168.0.0/16 --kubernetes-version=v1.10.0 --apiserver-advertise-address=192.168.56.101

含義:
1.選項(xiàng)--pod-network-cidr=192.168.0.0/16表示集群將使用Calico網(wǎng)絡(luò),這里需要提前指定Calico的子網(wǎng)范圍
2.選項(xiàng)--kubernetes-version=v1.10.0指定K8S版本,這里必須與之前導(dǎo)入到Docker鏡像版本v1.10.0一致,否則會(huì)訪問谷歌去重新下載K8S最新版的Docker鏡像
3.選項(xiàng)--apiserver-advertise-address表示綁定的網(wǎng)卡IP,這里一定要綁定前面提到的enp0s8網(wǎng)卡,否則會(huì)默認(rèn)使用enp0s3網(wǎng)卡
4.若執(zhí)行kubeadm init出錯(cuò)或強(qiáng)制終止,則再需要執(zhí)行該命令時(shí),需要先執(zhí)行kubeadm reset重置

執(zhí)行結(jié)果:


[root@k8s-node1 ~]# kubeadm init --pod-network-cidr=192.168.0.0/16 --kubernetes-version=v1.10.0 --apiserver-advertise-address=192.168.56.101
[init] Using Kubernetes version: v1.10.0
[init] Using Authorization modes: [Node RBAC]
[preflight] Running pre-flight checks.
    [WARNING SystemVerification]: docker version is greater than the most recently validated version. Docker version: 18.03.1-ce. Max validated version: 17.03
    [WARNING FileExisting-crictl]: crictl not found in system path
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
[certificates] Generated ca certificate and key.
[certificates] Generated apiserver certificate and key.
[certificates] apiserver serving cert is signed for DNS names [k8s-node1 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.56.101]
[certificates] Generated apiserver-kubelet-client certificate and key.
[certificates] Generated etcd/ca certificate and key.
[certificates] Generated etcd/server certificate and key.
[certificates] etcd/server serving cert is signed for DNS names [localhost] and IPs [127.0.0.1]
[certificates] Generated etcd/peer certificate and key.
[certificates] etcd/peer serving cert is signed for DNS names [k8s-node1] and IPs [192.168.56.101]
[certificates] Generated etcd/healthcheck-client certificate and key.
[certificates] Generated apiserver-etcd-client certificate and key.
[certificates] Generated sa key and public key.
[certificates] Generated front-proxy-ca certificate and key.
[certificates] Generated front-proxy-client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[controlplane] Wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"
[controlplane] Wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
[controlplane] Wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"
[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"
[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests".
[init] This might take a minute or longer if the control plane images have to be pulled.
[apiclient] All control plane components are healthy after 24.006116 seconds
[uploadconfig] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[markmaster] Will mark node k8s-node1 as master by adding a label and a taint
[markmaster] Master k8s-node1 tainted and labelled with key/value: node-role.kubernetes.io/master=""
[bootstraptoken] Using token: kt62dw.q99dfynu1kuf4wgy
[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstraptoken] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: kube-dns
[addons] Applied essential addon: kube-proxy

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join 192.168.56.101:6443 --token kt62dw.q99dfynu1kuf4wgy --discovery-token-ca-cert-hash sha256:5404bcccc1ade37e9d80831ce82590e6079c1a3ea52a941f3077b40ba19f2c68

可以看到,提示集群成功初始化,并且我們需要執(zhí)行以下命令:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

另外, 提示我們還需要?jiǎng)?chuàng)建網(wǎng)絡(luò),并且讓其他節(jié)點(diǎn)執(zhí)行kubeadm join...加入集群。

創(chuàng)建網(wǎng)絡(luò)

如果不創(chuàng)建網(wǎng)絡(luò),查看pod狀態(tài)時(shí),可以看到kube-dns組件是阻塞狀態(tài),集群時(shí)不可用的:


image.png

大家可以參考官方文檔,根據(jù)需求選擇適合的網(wǎng)絡(luò),這里,我們使用Calico(在前面初始化集群的時(shí)候就已經(jīng)確定了)。

根據(jù)官方文檔,在主節(jié)點(diǎn)上,需要執(zhí)行如下命令:
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml

但需要注意的是:

本文實(shí)驗(yàn)時(shí)所使用的calico的docker鏡像版本為v3.1.0,如下圖所示

image.png

但截至本文撰寫時(shí),calico.yaml文件中版本已升級(jí)為v3.1.1。因此我們需要下載calico.yaml,手動(dòng)編輯文件修改為v3.1.0并重新創(chuàng)建網(wǎng)絡(luò)。否則,執(zhí)行kubectl apply命令時(shí),會(huì)重新拉取v3.1.1的鏡像導(dǎo)致超時(shí)失敗。同時(shí),kube-dns模塊也會(huì)因?yàn)榫W(wǎng)絡(luò)無法創(chuàng)建而Pending:
image.png

確保版本一致后,執(zhí)行成功則提示:


image.png
image.png

五、集群設(shè)置

將Master作為工作節(jié)點(diǎn)

K8S集群默認(rèn)不會(huì)將Pod調(diào)度到Master上,這樣Master的資源就浪費(fèi)了。在Master(即k8s-node1)上,可以運(yùn)行以下命令使其作為一個(gè)工作節(jié)點(diǎn):
kubectl taint nodes --all node-role.kubernetes.io/master-

利用該方法,我們可以不使用minikube而創(chuàng)建一個(gè)單節(jié)點(diǎn)的K8S集群

執(zhí)行成功后提示:


image.png

將其他節(jié)點(diǎn)加入集群

在其他兩個(gè)節(jié)點(diǎn)k8s-node2和k8s-node3上,執(zhí)行主節(jié)點(diǎn)生成的kubeadm join命令即可加入集群:
kubeadm join 192.168.56.101:6443 --token kt62dw.q99dfynu1kuf4wgy --discovery-token-ca-cert-hash sha256:5404bcccc1ade37e9d80831ce82590e6079c1a3ea52a941f3077b40ba19f2c68

加入成功后,提示:


image.png

驗(yàn)證集群是否正常

當(dāng)所有節(jié)點(diǎn)加入集群后,稍等片刻,在主節(jié)點(diǎn)上運(yùn)行kubectl get nodes可以看到:

image.png

如上,若提示notReady則表示節(jié)點(diǎn)尚未準(zhǔn)備好,可能正在進(jìn)行其他初始化操作,等待全部變?yōu)镽eady即可。

大家可能會(huì)好奇,我們前面使用的是v1.10.0,為何這里版本是v1.10.2。實(shí)際上,這里顯示是每個(gè)節(jié)點(diǎn)上kubelet程序的版本,即先前使用yum安裝時(shí)的默認(rèn)版本,是向下兼容的。而v.1.10.0指的是K8S依賴的Docker鏡像版本,與kubeadm init命令中一定要保持一致。

另外,建議查看所有pod狀態(tài),運(yùn)行kubectl get pods -n kube-system

image.png

如上,全部Running則表示集群正常。至此,我們的K8S集群就搭建成功了。走!去按摩一下頸椎,放松一下,真累啊!

八、廢話

到目前為止,我們的K8S就真正搭建完畢了,下一章節(jié)《從零開始搭建Kubernetes集群(四、搭建K8S Dashboard)》敬請(qǐng)期待。

本人水平有限,難免有錯(cuò)誤或遺漏之處,望大家指正和諒解,歡迎評(píng)論留言。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容