轉:https://mritd.me/2016/10/29/set-up-kubernetes-cluster-by-kubeadm/#23鏡像版本怎么整
一、環境准備
首先環境還是三台虛擬機,虛擬機地址如下然后每台機器安裝好 docker,至於 rpm 安裝包版本下面介紹
IP 地址 節點
192.168.1.167 master
192.168.1.189 node1
192.168.1.176 node2
二、說點正經事
2.1、安裝包從哪來
官方的文檔頁面更新並不及時,同時他的 yum 源更新也很慢,再者…那他媽可是 Google 的服務器,能特么連上嗎?以前總是在國外服務器使用 yumdownloader
下載,然后 scp
到本地,雖然能解決問題,但是蛋碎一地…最后找到了源頭,如下
Kubernetes 編譯的各種發行版安裝包來源於 Github 上的另一個叫 release 的項目,地址 點這里,把這個項目 clone
下來,由於本人是 Centos 用戶,所以進入 rpm 目錄,在安裝好 docker 的機器上執行那個 docker-build.sh
腳本即可編譯 rpm 包,最后會生成到當前目錄的 output
目錄下,截圖如下
2.2、鏡像從哪來
對的,沒錯,gcr.io 就是 Google 的域名,服務器更不用提,所以在進行 kubeadm init
操作時如果不先把這些鏡像 load 進去絕對會卡死不動,以下列出了所需鏡像,但是版本號根據 rpm 版本不同可能略有不同,具體怎么看下面介紹
鏡像名稱 版本號
gcr.io/google_containers/kube-discovery-amd64 1.0
gcr.io/google_containers/kubedns-amd64 1.7
gcr.io/google_containers/kube-proxy-amd64 v1.4.1
gcr.io/google_containers/kube-scheduler-amd64 v1.4.1
gcr.io/google_containers/kube-controller-manager-amd64 v1.4.1
gcr.io/google_containers/kube-apiserver-amd64 v1.4.1
gcr.io/google_containers/etcd-amd64 2.2.5
gcr.io/google_containers/kube-dnsmasq-amd64 1.3
gcr.io/google_containers/exechealthz-amd64 1.1
gcr.io/google_containers/pause-amd64 3.0
這些鏡像有兩種辦法可以獲取,第一種是利用一台國外的服務器,在上面 pull 下來,然后再 save 成 tar 文件,最后 scp 到本地 load 進去;相對於第一種方式比較坑的是取決於服務器速度,每次搞起來也很蛋疼,第二種方式就是利用 docker hub 做中轉,簡單的說就是利用 docker hub 的自動構建功能,在 Github 中創建一個 Dockerfile,里面只需要 FROM xxxx
這些 gcr.io 的鏡像即可,最后 pull 到本地,然后再 tag 一下
首先創建一個 github 項目,可以直接 fork 我的即可
其中每個 Dockerfile 只需要 FROM
一下即可
最后在 Docker Hub 上創建自動構建項目
最后要手動觸發一下,然后 Docker Hub 才會開始給你編譯
等待完成即可直接 pull 了
2.3、鏡像版本怎么整
上面已經解決了鏡像獲取問題,但是一大心病就是 “我特么怎么知道是哪個版本的”,為了發揚 “刨根問底” 的精神,先進行一遍 kubeadm init
,這時候絕對卡死,此時進入 /etc/kubernetes/manifests
可以看到許多 json 文件,這些文件中定義了需要哪些基礎鏡像
從上圖中基本可以看到 kubeadm init
的時候會拉取哪些基礎鏡像了,但是還有一些鏡像,仍然無法找到,比如kubedns
、pause
等,至於其他的鏡像版本,可以從源碼中找到,源碼位置是 kubernetes/cmd/kubeadm/app/images/images.go
這個文件中,如下所示:
剩余的一些鏡像,比如 kube-proxy-amd64
、kube-discovery-amd64
兩個鏡像,其中 kube-discovery-amd64
現在一直是 1.0 版本,源碼如下所示
kube-proxy-amd64
則是一直跟隨基礎組件的主版本,也就是說如果從 manifests
中看到 controller 等版本是 v.1.4.4
,那么 kube-proxy-amd64
也是這個版本,源碼如下
最后根據這些版本去 github 上准備相應的 Dockerfile,在利用 Docker Hub 的自動構建 build 一下,再 pull 下來 tag 成對應的鏡像名稱即可
三、搭建集群
3.1、主機名處理
經過親測,節點主機名最好為 xxx.xxx
這種域名格式,否則在某些情況下,POD 中跑的程序使用域名解析時可能出現問題,所以先要處理一下主機名
# 寫入 hostname(node 節點后綴改成 .node) echo "192-168-1-167.master" > /etc/hostname # 加入 hosts echo "127.0.0.1 192-168-1-167.master" >> /etc/hosts # 不重啟情況下使內核生效 sysctl kernel.hostname=192-168-1-167.master # 驗證是否修改成功 ➜ ~ hostname 192-168-1-167.master
3.2、load 鏡像
由於本人已經在 Docker Hub 上處理好了相關鏡像,所以直接 pull 下來 tag 一下即可,
images=(kube-proxy-amd64:v1.4.4 kube-discovery-amd64:1.0 kubedns-amd64:1.7 kube-scheduler-amd64:v1.4.4 kube-controller-manager-amd64:v1.4.4 kube-apiserver-amd64:v1.4.4 etcd-amd64:2.2.5 kube-dnsmasq-amd64:1.3 exechealthz-amd64:1.1 pause-amd64:3.0 kubernetes-dashboard-amd64:v1.4.1) for imageName in ${images[@]} ; do docker pull mritd/$imageName docker tag mritd/$imageName gcr.io/google_containers/$imageName docker rmi mritd/$imageName done
3.3、安裝 rpm
rpm 獲取辦法上文已經提到,可以自己編譯,這里我已經編譯好並維護了一個 yum 源,直接yum install 即可(懶)
# 添加 yum 源 tee /etc/yum.repos.d/mritd.repo << EOF [mritdrepo] name=Mritd Repository baseurl=https://rpm.mritd.me/centos/7/x86_64 enabled=1 gpgcheck=1 gpgkey=https://mritd.b0.upaiyun.com/keys/rpm.public.key EOF # 刷新cache yum makecache # 安裝 yum install -y kubelet kubectl kubernetes-cni kubeadm
3.4、初始化 master
等會有個坑,kubeadm 等相關 rpm 安裝后會生成 /etc/kubernetes
目錄,而 kubeadm init 時候又會檢測這些目錄是否存在,如果存在則停止初始化,所以要先清理一下,以下清理腳本來源於 官方文檔 Tear down 部分,該腳本同樣適用於初始化失敗進行重置
systemctl stop kubelet;
# 注意: 下面這條命令會干掉所有正在運行的 docker 容器, # 如果要進行重置操作,最好先確定當前運行的所有容器都能干掉(干掉不影響業務), # 否則的話最好手動刪除 kubeadm 創建的相關容器(gcr.io 相關的) docker rm -f -v $(docker ps -q); find /var/lib/kubelet | xargs -n 1 findmnt -n -t tmpfs -o TARGET -T | uniq | xargs -r umount -v; rm -r -f /etc/kubernetes /var/lib/kubelet /var/lib/etcd;
還有個坑,初始化以前記得一定要啟動 kubelet,雖然你 systemctl status kubelet
看着他是啟動失敗,但是也得啟動,否則絕壁卡死
systemctl enable kubelet systemctl start kubelet
等會等會,還有坑,新版本直接 init 會提示 ebtables not found in system path
錯誤,所以還得先安裝一下這個包在初始化
# 安裝 ebtables yum install -y ebtables
最后見證奇跡的時刻
# 初始化並指定 apiserver 監聽地址 kubeadm init --api-advertise-addresses 192.168.1.167
完美截圖如下
這里再爆料一個坑,底下的 kubeadm join --token=b17964.5d8a3c14e99cf6aa 192.168.1.167
這條命令一定保存好,因為后期沒法重現的,你們老大再讓你添加機器的時候如果沒這個你會哭的
3.5、加入 node
上面所有坑大約說的差不多了,直接上命令了
# 處理主機名 echo "192-168-1-189.node" > /etc/hostname echo "127.0.0.1 192-168-1-189.node" >> /etc/hosts sysctl kernel.hostname=192-168-1-189.node # 拉取鏡像 images=(kube-proxy-amd64:v1.4.4 kube-discovery-amd64:1.0 kubedns-amd64:1.7 kube-scheduler-amd64:v1.4.4 kube-controller-manager-amd64:v1.4.4 kube-apiserver-amd64:v1.4.4 etcd-amd64:2.2.5 kube-dnsmasq-amd64:1.3 exechealthz-amd64:1.1 pause-amd64:3.0 kubernetes-dashboard-amd64:v1.4.1) for imageName in ${images[@]} ; do docker pull mritd/$imageName docker tag mritd/$imageName gcr.io/google_containers/$imageName docker rmi mritd/$imageName done # 裝 rpm tee /etc/yum.repos.d/mritd.repo << EOF [mritdrepo] name=Mritd Repository baseurl=https://rpm.mritd.me/centos/7/x86_64 enabled=1 gpgcheck=1 gpgkey=https://mritd.b0.upaiyun.com/keys/rpm.public.key EOF yum makecache yum install -y kubelet kubectl kubernetes-cni kubeadm ebtables # 清理目錄(沒初始化過只需要刪目錄) rm -r -f /etc/kubernetes /var/lib/kubelet /var/lib/etcd; # 啟動 kubelet systemctl enable kubelet systemctl start kubelet # 初始化加入集群 kubeadm join --token=b17964.5d8a3c14e99cf6aa 192.168.1.167
同樣完美截圖
3.6、部署 weave 網絡
再沒部署 weave 時,dns 是啟動不了的,如下
官方給出的命令是這樣的
kubectl create -f https://git.io/weave-kube
本着 “刨根問底挖祖墳” 的精神,先把這個 yaml 搞下來
wget https://git.io/weave-kube -O weave-kube.yaml
然后同樣的套路,打開看一下鏡像,利用 Docker Hub 做中轉,搞下來再 load 進去,然后 create -f
就行了
docker pull mritd/weave-kube:1.7.2
docker tag mritd/weave-kube:1.7.2 weaveworks/weave-kube:1.7.2
docker rmi mritd/weave-kube:1.7.2
kubectl create -f weave-kube.yaml
完美截圖
3.7、部署 dashboard
dashboard 的命令也跟 weave 的一樣,不過有個大坑,默認的 yaml 文件中對於 image 拉取策略的定義是 無論何時都會去拉取鏡像,導致即使你 load 進去也無卵用,所以還得先把 yaml 搞下來然后改一下鏡像拉取策略,最后再 create -f
即可
wget https://rawgit.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml -O kubernetes-dashboard.yaml
編輯 yaml 改一下 imagePullPolicy
,把 Always
改成 IfNotPresent
(本地沒有再去拉取) 或者 Never
(從不去拉取) 即可
最后再利用 Dokcer Hub 中轉,然后創建(實際上 dashboard 已經有了 v1.4.1,我這里已經改了)
kubectl create -f kubernetes-dashboard.yaml
截圖如下
通過 describe 命令我們可以查看其暴露出的 NodePoint
,然后便可訪問
四、其他的一些坑
還有一些其他的坑等着大家去摸索,其中有一個是 DNS 解析錯誤,表現形式為 POD 內的程序通過域名訪問解析不了,cat 一下容器的 /etc/resolv.conf
發現指向的 dns 服務器與 kubectl get svc --namespace=kube-system
中的 kube-dsn 地址不符;解決辦法就是 編輯節點的 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
文件,更改 KUBELET_DNS_ARGS
地址為 get svc
中的 kube-dns 地址,然后重啟 kubelet 服務,重新殺掉 POD 讓 kubernetes 重建即可
其他坑歡迎大家補充