0. 回顧Kubernetes架構
kubeadm使用簡介
- apt-get install kubeadm( 宿主機上安裝kubeadm,kubelet,kubectl)
- Kubeadm init
- 做一些列的檢查工作,確認是否可以部署k8s,被稱爲Preflight checks
- 生成k8s對外提供服務所需的各種證書和對應的目錄,注意,我們可以選擇不讓kubeadm生成這些證書,而是拷貝現有證書到/etc/kubernetes/pki/目錄下
- 爲其他組件生成訪問kube-apiserver所需的配置文件,存儲路徑是/etc/kubernets/xxx.conf
- 爲master組件,kube-apiserver,kube-controller-manager,kube-scheduler,生成pod配置文件(yaml文件),被保存在/etc/kubernetes/mainfests下
- 在4中節點上的kubelet啓動後,通過static pod的方式加載4中目錄下的pod yaml文件,並啓動kube-apiserver這些master組件
- kubeadm會生成一個etcd的pod yaml文件,同樣通過static pod的方式啓動etcd,所以master組件的pod yaml文件如下
$ ls /etc/kubernetes/manifests/
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml- 檢查Locallhost:6443/healthz 這個健康檢查url,等待master組件完全運行起來
- 爲集羣生成bootstrap token,爲之後kubeadm join命令做驗證
- 將master節點的重要信息,通過configmap的方式保存在etcd中,共後續安裝Node節點使用
- 安裝默認插件,k8s默認安裝kube-proxy和dns,提供集羣發現和dns功能。
- Kubeadm join
- 新的worker節點上kubeadm發起一次“不安全的”請求道kube-apiserver獲取etcd中存儲的cluster-info中的地址,端口,證書,bootstrap token扮演了安全驗證的角色
- 通過證書建立起worker節點和master節點的 關係
1. 在所有節點上安裝Docker和kubeadm
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF > /etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ apt-get update
$ apt-get install -y docker.io kubeadm
通過這個步驟,kubeadm、kubelet、kubectl、kubernetes-cni這幾個二進制文件都會被自動安裝好。
2. 部署Kubernetes Master
2.1 編寫kubeadm.yaml配置文件
示例如下:
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
controllerManagerExtraArgs:
horizontal-pod-autoscaler-use-rest-clients: "true"
horizontal-pod-autoscaler-sync-period: "10s"
node-monitor-grace-period: "10s"
apiServerExtraArgs:
runtime-config: "api/all=true"
kubernetesVersion: "stable-1.11"
執行kubeadm init --config kubeadm.yaml, 稍等一會兒,部署完成後,kubeadm會生成一條指令,如下
kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711
記錄下來上面這條指令,這是用來給這個master節點添加更多工作節點(worker)的命令。
通過kubectl describe node master和kubectl get pods -n kube-system查看到的是因爲網絡相關的配置沒有進行導致nodenotready
2.2 安全文件配置
此外,Kubernetes默認需要加密方式訪問。所以,需要把剛剛部署生成的Kubernetes集羣的安全配置文件,保存到當前用戶的.kube目錄下,kubectl默認會使用這個目錄下信息授權訪問Kubernetes集羣。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
2.3 檢查節點狀態
- kubectl describe node master
$ kubectl describe node master
...
Conditions:
...
Ready False ... KubeletNotReady runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
- kubectl get pods -n kube-system
$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-78fcdf6894-j9s52 0/1 Pending 0 1h
coredns-78fcdf6894-jm4wf 0/1 Pending 0 1h
etcd-master 1/1 Running 0 2s
kube-apiserver-master 1/1 Running 0 1s
kube-controller-manager-master 0/1 Pending 0 1s
kube-proxy-xbd47 1/1 NodeLost 0 1h
kube-scheduler-master 1/1 Running 0 1s
可以看出,是CoreDNS、kube-controller-manager等依賴網絡的Pod都處於Pending狀態,即調度失敗。
3. 部署容器網絡插件
部署網絡插件,以Weave爲例,
$ kubectl apply -f https://git.io/weave-kube-1.6
部署完成後,重新kubectl get pods -n kube-system檢查Pod的狀態,全部都啓動成功,保持running狀態。
目前,Kubernetes支持容器網絡插件,使用的是CNI的通用接口,也是當前容器網絡的實施標準,市面上Flannel、Calico、Canal、Romana等一鍵部署項目都是通過CNI接口Kubernetes。
至此,Master節點部署完成,如果只需要一個Kubernetes,現在就可以使用了,但是默認情況下,Kubernetes的Master節點是不能運行用戶Pod的,所以還需要額外做一個小操作,最後介紹。
4. 部署Kubernetes Worker節點
master節點和worker節點幾乎是相同的,都運行着一個kubulet的組件。唯一的區別是Master節點會額外在kubeadm init過程中自動運行kube-apiserver, kube-scheduler, kube-controller-manager。
分兩步執行部署:
- 在所有節點上執行第一小節“安裝kubeadm和Docker”
- 執行部署Master節點是生成的kubeadm join指令
$ kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711
5. 通過Taint/Toleration調整Master執行Pod的策略
[規定]默認情況下Master節點是不運行Pod。
[實現方式]Taint/Toleration機制
Taint(污點):通過命令給node節點加上Taint之後,所有的Pod就不能再在這個node上運行了。---Pod有潔癖
Toleration(容忍):個別Pod可以特別聲明自己可以容忍這個污點,那麼就可以在對應打了污點的節點上運行。
[Taint使用方法]
$ kubectl taint nodes node1 foo=bar:NoSchedule
這樣在node1上上城了一個鍵值對格式的Taint,其中裏面的NoSchedule字段,意味着這個污點只會在調度新的Pod的時候產生作用,不會影響已經運行在Node1上的POD。
這麼看來,給Node打上Taint的內容即foo=bar:NoSchedule部分還是有多種使用方法,這個還是要再研究下。
[Toleration使用方法]
在Pod對應的Yaml文件中加入字段:
apiVersion: v1
kind: Pod
...
spec:
tolerations:
- key: "foo"
operator: "Equal"
value: "bar"
effect: "NoSchedule"
6. 部署Dashboard可視化插件
安裝可視化插件並查看對應Pod詳情
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
$ kubectl get pods -n kube-system
kubernetes-dashboard-6948bdb78-f67xk 1/1 Running 0 1m
注意,dashboard是一個web service,1.7 版本之後dashboard項目部署完成後,只能通過Proxy在本地訪問,需要用到Ingress。
7. 部署容器存儲插件
容器持久化存儲是解決容器的典型特徵“無狀態”的。
通過網絡或者其他機制的遠程數據卷,將其和容器中某個目錄進行綁定掛載,進而使得在容器中創建的文件能夠保存在遠程存儲服務器上、或以分佈式的方式保存在多個節點上。
可用的,如Ceph,NFS,GlusterFS等,都可以爲Kubernetes提供持久化存儲能力。
8. 踩坑
- 離線安裝kubelet
systemctl daemon-reload
systemctl start kubelet.service //啓動失敗,通過journalctl查看具體原因(systemctl起服務失敗時候可以採用該日誌定位方式)