准備:
網上教如何編譯與安裝kubernetes的教程很多,需要提前准備的也很多,比如關閉selinux,防火牆啦....但有一點一定要注意,編譯kubernetes源碼時要求有2G內存,這個可是實打實的2G內存!所以要求你的機器至少是3G,4G最好了。
如果你手頭不是那么寬裕比如我只買得起2G內存的計算雲,那么只好利用交換分區了...
增加1GB大小的交換分區,則命令寫法如下,其中的count等於想要的塊的數量(bs*count=文件大小)
dd if=/dev/zero of=/root/swapfile bs=1M count=2048
mkswap /root/swapfile
swapon /root/swapfile
使系統開機時自啟用,在文件/etc/fstab中添加一行
vi /etc/fstab
添加/root/swapfile swap swap defaults 0 0
擴大或修改 swap 大小 其實和增加一樣的,只是必須先停止交換分區
swapoff /root/swapfile
然后按上面的增加方法即可
一,源碼編譯
#KUBE_BUILD_PLATFORMS=linux/amd64 make all GOFLAGS=-v GOGCFLAGS="-N -l"
注:這個過程如果編譯出錯,基本是內存不夠了,那就一個一個模塊的編,比較耗內存的有kubelet, kube-controller-manager...,單獨一個木塊的編譯命令例如
#KUBE_BUILD_PLATFORMS=linux/amd64 make all WHAT=cmd/kubelet GOFLAGS=-v GOGCFLAGS="-N -l"
二,生成鏡像:
推薦參考此博客:https://www.kubernetes.org.cn/5033.html
三,node/minion節點的安裝(直接yum安裝方式)
節點vip: 106.y.y.3
node節點需要安裝的組件有:kubelet,kube-proxy,flannel,etcd(可選)
【安裝】:現如今,yum源中已經支持安裝k8s了,所以一個kubernetes-node選項,就可以將當前節點作為node角色進行必要的安裝。
#yum install kubernetes-node etcd flannel -y
說明:其實和其他centos系統下的二進制安裝是一樣的:
- 二進制可執行文件放到/usr/bin中
- 統一的系統配置文件:/usr/lib/systemd/system/kubelet.service.
- 專屬配置文件:例如/etc/kubernetes/*, /etc/etcd/etcd.conf
專屬配置文件如/etc/kubernetes/目錄下的配置文件為系統配置文件xx.service文件提供參數 ,所以要改參數需要兩個文件結合修改,這里需要改的無非兩點:集群master節點地址,etcd的地址
【配置etcd】
vi /etc/etcd/etcd.conf
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ---表示開啟的本地監聽:用來提供服務的接口 ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380" ---表示開啟的本地監聽:用來和perr交流的接口 --以下是用來廣播出去給peer們,告訴大家怎么能找到我,包括:我與peer通信的接口和我服務的接口 ETCD_INITIAL_ADVERTISE_PEER_URLS="http://188.x.x.113:2380" ETCD_ADVERTISE_CLIENT_URLS="http://188.x.x.113:2379" ETCD_INITIAL_CLUSTER="etcd0=http://188.x.x.113:2380,etcd1=http://106.y.y.3:2380" ETCD_INITIAL_CLUSTER_STATE="new"
vi /usr/lib/systemd/system/etcd.service
--advertise-client-urls=\"${ETCD_ADVERTISE_CLIENT_URLS}\" --initial-cluster=\"${ETCD_INITIAL_CLUSTER}\" --initial-advertise-peer-urls=\"${ETCD_INITIAL_ADVERTISE_PEER_URLS}\" --initial-cluster-state=\"${ETCD_INITIAL_CLUSTER_STATE}\" --listen-peer-urls=\"${ETCD_LISTEN_PEER_URLS}\" --listen-client-urls=\"${ETCD_LISTEN_CLIENT_URLS}\""
最后:
systemctl daemon-reload
systemctl restart etcd.service
systemctl enable etcd.service
驗證:
etcdctl member list
etcdctl cluster-health
【坑1】
場景1:報錯:rafthttp: request sent was ignored (cluster ID mismatch: peer[b6568aca930d28d4]=cdf818194e3a8c32, local=9c8b920197d88342)
場景2:當某個peer掛了,或者減少etcd集群的成員等,你變更了配置之后,發現重啟失敗等等之類的錯誤,都可以嘗試如下的解決辦法
解決:
cd /var/lib/etcd/
rm ./* -rf //清緩存
【配置flannel】
0,為什么需要etcd
etcd是一個key-value形式的存儲系統,所以關於網絡方面的數據,要首先為其指定一個key,那么這個key下的數據都屬於網絡方面的。
1,配置flannel,包括 1)etcd的地址; 2)存儲數據到etcd中使用的key
#vi /etc/sysconfig/flanneld FLANNEL_ETCD_ENDPOINTS="http://106.13.146.3:2379,http://188.131.210.113:2379" FLANNEL_ETCD_PREFIX="/k8s/network" //這個key是 "/k8s/network"
FLANNEL_OPTIONS="--log_dir=/var/log/k8s/flannel/ --public-ip=188.x.x.113" //這個public-ip一定是網絡可達的,比如我的環境中,必須配置成host的vip
2,在etcd中為flannel添加初始配置,表示之后為k8s集群分配ip的時候,取如下地址空間
# 在master上etcd執行
etcdctl mk /k8s/network/config '{"Network": "10.0.0.0/16"}'
# 若要重新建,先刪除
etcdctl rm /k8s/network/ --recursive
3,重啟flannel
systemctl daemon-reload
systemctl restart flanneld.service
systemctl enable flanneld.service
4,重啟docker
說明:flannel之所以能夠掌控pod的流向轉發,其實是和docker配合着來做的,flannel的安裝會偷偷修改docker的啟動參數或環境變量,所以要重啟下docker以生效。詳見深入解讀docker網絡與kubernetes網絡
四,master節點的安裝(鏡像 + 二進制)
節點Vip:188.x.x.113
0,之前我們已經編譯好了三大鏡像,加載之
[root@master _output]# find ./release-stage/ -name "*.tar"
./release-stage/server/linux-amd64/kubernetes/server/bin/kube-controller-manager.tar
./release-stage/server/linux-amd64/kubernetes/server/bin/kube-apiserver.tar
./release-stage/server/linux-amd64/kubernetes/server/bin/kube-scheduler.tar
docker load < kube-scheduler.tar
...
k8s.gcr.io/kube-scheduler v1.13.6-beta.0.39_ddd2add0dd3dbc 0ee023810183 22 minutes ago 79.5MB
k8s.gcr.io/kube-apiserver v1.13.6-beta.0.39_ddd2add0dd3dbc 7666a559eee8 22 minutes ago 181MB
k8s.gcr.io/kube-controller-manager v1.13.6-beta.0.39_ddd2add0dd3dbc ac910ff4cca1 22 minutes ago 146MB
1,安裝etcd
步驟同node節點,需要注意的是,要先安裝etcd,再安裝k8s的組件
2,安裝flanel
步驟同node節點
3,三大組件的最基本安裝:
//wxy:注意,對於綁定vip的雲上機器, insecure-bind-address的地址不能是vip,而應該是自己本地的ip,這里就用了0.0.0.0代替 docker run -d --name=apiserver --net=host k8s.gcr.io/kube-apiserver:v1.13.6-beta.0.39_ddd2add0dd3dbc kube-apiserver --insecure-bind-address=0.0.0.0 --service-cluster-ip-range=11.0.0.0/16 --etcd-servers=http://188.x.x.113:2379 docker run -d --name=controllermanager --net=host k8s.gcr.io/kube-controller-manager:v1.13.6-beta.0.39_ddd2add0dd3dbc kube-controller-manager --master=188.x.x.113:8080 docker run -d --name=scheduler --net=host k8s.gcr.io/kube-scheduler:v1.13.6-beta.0.39_ddd2add0dd3dbc kube-scheduler --master=188.x.x.113:8080
至此,k8s的集群已經起來了,驗證下:
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 12h
kube-public Active 12h
kube-system Active 12h
但是,創建pod的時候會出現如下錯誤:
[root@master ~]# kubectl create -f ./centos.yaml
Error from server (ServerTimeout): error when creating "./centos.yaml": No API token found for service account "default", retry after the token is automatically created and added to the service account
那是認證的問題,下一步就展示了如何配置認證
3,升級安裝:帶證書配置
說明:與k8s集群的交流是通過調用api-server組件提供的各種api,比如創建pod,service等,這種訪問可能是來自人類例如某人執行kuectl命令,也可能是pod中的某進程想要訪問api,都需要認證,api-server可不是隨隨便便就能被任何人訪問的,那么就需要有一套認證機制,詳細的見 【爬坑系列】之解讀kubernetes的認證原理&實踐,否則只需要做如下操作即可:
0)生成需要的證書
使用CFSSL工具或者openssl都可以,網上也有很多教程,詳細的也可以看這里,反正這里我就需要一個根證書,以下的是已經生成好的一些證書
[root@master ~]# ll /etc/kubernetes/apiserver/
total 36
-rw-rw-rw- 1 root root 997 May 22 10:46 ca.csr
-rw-rw-rw- 1 root root 1679 May 22 10:46 ca-key.pem
-rw-rw-rw- 1 root root 1350 May 22 10:46 ca.pem ---我所需要的
-rw-rw-rw- 1 root root 1338 May 22 11:59 server.csr
-rw-rw-rw- 1 root root 1679 May 22 11:59 server-key.pem
-rw-rw-rw- 1 root root 1704 May 22 11:59 server.pem
1)重新安裝controller manage,只配置service-account-private-key-file這一個認證相關的參數
[root@master ~]# docker run -d --name=cm --net=host \ -v /etc/kubernetes/apiserver:/run/ssl \ k8s.gcr.io/kube-controller-manager:v1.13.6-beta.0.39_ddd2add0dd3dbc \ kube-controller-manager \ --master=0.0.0.0:8080 \ --service-account-private-key-file=/run/ssl/ca-key.pem
2),重啟所有節點的kublete (重要)
[root@master ~]# systemctl restart kubelet.service
k8s會做兩件事
1)自動給生成一個secret:屬於服務賬號的,用來給pod提供一個缺省的身份(名字 和 token),讓他得以訪問apiserver,具體怎么給pod用的,看這里
2)在/var/run/kubernetes/目錄下生成一對證書,由配置的CA證書簽發的 ---干什么用的?目前沒時間研究,在說....
3),此時創建pod,可以成功
[root@master ~]# kubectl create -f centos.yaml pod/myapp-centos created [root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE myapp-centos 1/1 Running 0 6s
【坑2】
配置了證書啟動kube-controller-manager后還是報同樣的錯誤,secret也沒生成,為什么?
定位過程:
- kube-controller-manager的日志顯示文件不存在,命名在的啊:
#docker logs -f cm ... F0529 10:18:21.535516 1 controllermanager.go:213] error starting controllers: error reading key for service account token controller: open /etc/kubernetes/apiserver/ca-key.pem: no such file or directory
- 看了源碼,根據源碼我還本地寫了個小程序,發現是可以順利讀取的,那說明文件是沒問題,為什么到了容器里就有問題了。突然,我意識到這可是容器啊,代碼讀取的可是容器內的路徑,而我的配置是host上的路徑。於是
- 於是增加了卷掛載,即把host中的證書掛載到容器中,結果:OK
docker run -d --name=cm --net=host \ -v /etc/kubernetes/apiserver:/run/ssl \ k8s.gcr.io/kube-controller-manager:v1.13.6-beta.0.39_ddd2add0dd3dbc \ kube-controller-manager \ --master=0.0.0.0:8080 \ --root-ca-file=/run/ssl/ca.pem \ --service-account-private-key-file=/run/ssl/ca-key.pem
水鬼子:這是一個很low的錯誤,很無語啊,只是希望萬一你也有這個問題,也許這是一個提示...