首先,準備機器。最直接的辦法,天然是到公有云上申請幾個虛擬機。固然,若是條件容許的話,拿幾臺本地的物理服務器來組集羣是最好不過了。這些機器只要知足以下幾個條件便可:html
安裝 kubeadm 和 Docker node
《Kubernetes 一鍵部署利器:kubeadm》它的一鍵安裝很是方便,咱們只須要添加 kubeadm 的源,而後直接使用 apt-get 安裝便可,具體流程以下所示:linux
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
把官方源列表加入到k8s節點本地源列表配置目錄中git
vi /etc/apt/sources.list.d/kubernetes.list
輸入如下內容github
deb http://apt.kubernetes.io/ kubernetes-xenial main
更新包索引 docker
apt-get update
安裝docker 這裏我用的是docker 17.03.3-ce版本ubuntu
添加Docker的官方GPG密鑰:後端
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
添加官方源倉庫 centos
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
更新包索引api
apt-get update
安裝17.03版本
apt-get install docker-ce=17.03.3~ce-0~ubuntu-xenial
安裝 kubelet kubctl kubeadm
apt install kubelet=1.11.1-00 apt install kubectl=1.11.1-00 apt install kubeadm=1.11.1-00
kubeadm 能夠一鍵部署 Master 節點。不過,在本篇文章中既然要部署一個「完整」的 Kubernetes 集羣,那咱們不妨稍微提升一下難度:經過配置文件來開啓一些實驗性功能。
因此,這裏我編寫了一個給 kubeadm 用的 YAML 文件(名叫: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: "v1.11.1"
這個配置中,我給+kube-controller-manager+設置了
horizontal-pod-autoscaler-use-rest-clients: "true"
這意味着,未來部署的 kube-controller-manager 可以使用自定義資源(Custom Metrics)進行自動水平擴展。
其中,「stable-1.11」就是 kubeadm 幫咱們部署的 Kubernetes 版本號,即:Kubernetes release 1.11 最新的穩定版,在個人環境下,它是 v1.11.1。你也能夠直接指定這個版本,好比:kubernetesVersion:「v1.11.1」。而後,咱們只須要執行一句指令:
kubeadm init --config kubeadm.yaml
就能夠完成 Kubernetes+Master 的部署了,這個過程只須要幾分鐘。部署完成後,kubeadm 會生成一行指令
kubeadm join 209.250.244.253:6443 --token 4srvlc.6ug9t7ikb3ao0m06 --discovery-token-ca-cert-hash sha256:b71d09fee04a19c53787b44bd18df39b50256de6beeee90f3acc2665948d18b8
這個 kubeadm join 命令,就是用來給這個 Master 節點添加更多工做節點(Worker)的命令。咱們在後面部署 Worker 節點的時候立刻會用到它,因此找一個地方把這條命令記錄下來。此外,kubeadm 還會提示咱們第一次使用 Kubernetes 集羣所須要的配置命令
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
而須要這些配置命令的緣由是:Kubernetes 集羣默認須要加密方式訪問。因此,這幾條命令,就是將剛剛部署生成的 Kubernetes 集羣的安全配置文件,保存到當前用戶的.kube 目錄下,kubectl 默認會使用這個目錄下的受權信息訪問 Kubernetes 集羣。
若是不這麼作的話,咱們每次都須要經過 export+KUBECONFIG 環境變量告訴 kubectl 這個安全配置文件的位置。
如今,咱們就可使用 kubectl get 命令來查看當前惟一一個節點的狀態了:
kubectl get nodes
能夠看到,這個 get 指令輸出的結果裏,Master 節點的狀態是 NotReady,這是爲何呢?
在調試 Kubernetes 集羣時,最重要的手段就是用 kubectl describe 來查看這個節點(Node)對象的詳細信息、狀態和事件(Event),咱們來試一下:
kubectl describe node master
經過 kubectl describe 指令的輸出,咱們能夠看到 NodeNotReady 的緣由在於,咱們還沒有部署任何網絡插件。
另外,咱們還能夠經過+kubectl+檢查這個節點上各個系統 Pod 的狀態,其中,kube-system 是 Kubernetes 項目預留的系統 Pod 的工做空間(Namepsace,注意它並非 Linux Namespace,它只是 Kubernetes 劃分不一樣工做空間的單位):
kubectl get pods -n kube-system
能夠看到,CoreDNS 等依賴於網絡的 Pod 都處於 Pending 狀態,即調度失敗。這固然是符合預期的:由於這個 Master 節點的網絡還沒有就緒
在 Kubernetes 項目「一切皆容器」的設計理念指導下,部署網絡插件很是簡單,只須要執行一句 kubectl apply 指令,
kubectl apply -f https://git.io/weave-kube-1.6
部署完成後,咱們能夠經過 kubectl get 從新檢查 Pod 的狀態:
能夠看到,全部的系統 Pod 都成功啓動了,而剛剛部署的 Weave 網絡插件則在 kube-system 下面新建了一個名叫 weave-net-cmk27 的+Pod,通常來講,這些 Pod 就是容器網絡插件在每一個節點上的控制組件。 Kubernetes 支持容器網絡插件,使用的是一個名叫 CNI 的通用接口,它也是當前容器網絡的事實標準,市面上的全部容器網絡開源項目均可以經過 CNI 接入 Kubernetes,好比 Flannel、Calico、Canal、Romana 等等,它們的部署方式也都是相似的「一鍵部署」。
至此,Kubernetes 的 Master 節點就部署完成了。若是你只須要一個單節點的 Kubernetes,如今你就可使用了。不過,在默認狀況下,Kubernetes 的 Master 節點是不能運行用戶 Pod 的,因此還須要額外作一個小操做。在本篇的最後部分,我會介紹到它。
Kubernetes 的 Worker 節點跟 Master 節點幾乎是相同的,它們運行着的都是一個 kubelet 組件。惟一的區別在於,在 kubeadm init 的過程當中,kubelet 啓動後,Master 節點上還會自動運行 kube-apiserver、kube-scheduler、kube-controller-manger 這三個系統 Pod。 因此,相比之下,部署 Worker 節點反而是最簡單的,只須要兩步便可完成。
第一步,在全部 Worker 節點上執行「安裝 kubeadm 和 Docker」一節的全部步驟
第二步,執行部署 Master 節點時生成的 kubeadm join 指令:
kubeadm join 209.250.244.253:6443 --token 4srvlc.6ug9t7ikb3ao0m06 --discovery-token-ca-cert-hash sha256:b71d09fee04a19c53787b44bd18df39b50256de6beeee90f3acc2665948d18b8
在這裏我想master中加入了2個Worker節點
默認狀況下 Master 節點是不容許運行用戶 Pod 的。而 Kubernetes 作到這一點,依靠的是 Kubernetes 的 Taint/Toleration 機制。它的原理很是簡單:一旦某個節點被加上了一個 Taint,即被「打上了污點」,那麼全部 Pod 就都不能在這個節點上運行,由於 Kubernetes 的 Pod 都有「潔癖」。
除非,有個別的 Pod 聲明本身能「容忍」這個「污點」,即聲明瞭 Toleration,它才能夠在這個節點上運行。
其中,爲節點打上「污點」(Taint)的命令是(master節點默認就有Taint,因此master上默認不能運行用戶的pod)
kubectl taint nodes node1 foo=bar:NoSchedule
這時,該 node1 節點上就會增長一個鍵值對格式的 Taint,即:foo=ANoSchedule。其中值裏面的 NoSchedule,意味着這個 Taint 只會在調度新 Pod 時產生做用,而不會影響已經在 node1 上運行的 Pod,哪怕它們沒有 Toleration。 那麼 Pod 又如何聲明 Toleration 呢?
咱們只要在 Pod 的.yaml 文件中的 spec 部分,加入 tolerations 字段便可:
apiVersion: v1 kind: Pod ... spec: tolerations: - key: "foo" operator: "Equal" value: "bar" effect: "NoSchedule"
這個 Toleration 的含義是,這個 Pod 能「容忍」全部鍵值對爲 foo=bar 的 Taint( operator:「Equal」,「等於」操做)。
如今回到咱們已經搭建的集羣上來。這時,若是你經過 kubectl describe 檢查一下master 節點的 Taint 字段,就會有所發現了:
kubectl describe node master
能夠看到,master 節點默認被加上了node-role.kubernetes.io/ANoSchedule這樣一個「污點」,其中「鍵」是node-role.kubernetes.io/Fmaster,而沒有提供「值」。
此時,你就須要像下面這樣用「Exists」操做符(operator:「Exists」,「存在」便可)來講明,該 Pod 可以容忍全部以 foo 爲鍵的 Taint,才能讓這個 Pod 運行在該 Master 節點上:
apiVersion: v1 kind: Pod ... spec: tolerations: - key: "foo" operator: "Exists" effect: "NoSchedule"
固然,若是你就是想要一個單節點的 Kubernetes,刪除這個 Taint 纔是正確的選擇:
kubectl taint nodes --all node-role.kubernetes.io/master-
如上所示,咱們在「node-role.kubernetes.io/master」這個鍵後面加上了一個短橫線「-」,這個格式就意味着移除全部以「node-role.kubernetes.io/master」爲鍵的 Taint。
到了這一步,一個基本完整的 Kubernetes 集羣就部署完畢了。是否是很簡單呢?
有了 kubeadm 這樣的原生管理工具,Kubernetes 的部署已經被大大簡化。更重要的是,像證書、受權、各個組件的配置等部署中最麻煩的操做,kubeadm 都已經幫你完成了。
接下來,咱們再在這個 Kubernetes 集羣上安裝一些其餘的輔助插件,好比 Dashboard 和存儲插件。
在 Kubernetes 社區中,有一個很受歡迎的 Dashboard 項目,它能夠給用戶提供一個可視化的 Web 界面來查看當前集羣的各類信息。絕不意外,它的部署也至關簡單:
wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.0/src/deploy/recommended/kubernetes-dashboard.yaml
爲了便於本地訪問,修改yaml文件,將service改成NodePort 類型:
部署
kubectl apply -f kubernetes-dashboard.yaml
部署完成以後,咱們就能夠查看 Dashboard 對應的 Pod 的狀態了:
kubectl get pods -n kube-system
須要注意的是,因爲 Dashboard 是一個 Web Server,不少人常常會在本身的公有云上無心地暴露 Dashboard 的端口,從而形成安全隱患。因此,1.7 版本以後的 Dashboard 項目部署完成後,默認只能經過 Proxy 的方式在本地訪問。具體的操做,你能夠查看 Dashboard 項目的官方文檔。
而若是你想從集羣外訪問這個 Dashboard 的話,就須要用到 Ingress,我會在後面的文章中專門介紹這部份內容。
接下來,讓咱們完成這個 Kubernetes 集羣的最後一塊拼圖:容器持久化存儲。
我在前面介紹容器原理時已經提到過,不少時候咱們須要用數據卷(Volume)把外面宿主機上的目錄或者文件掛載進容器的 Mount Namespace 中,從而達到容器和宿主機共享這些目錄或者文件的目的。容器裏的應用,也就能夠在這些數據卷中新建和寫入文件。
但是,若是你在某一臺機器上啓動的一個容器,顯然沒法看到其餘機器上的容器在它們的數據卷裏寫入的文件。這是容器最典型的特徵之一:無狀態。
而容器的持久化存儲,就是用來保存容器存儲狀態的重要手段:存儲插件會在容器裏掛載一個基於網絡或者其餘機制的遠程數據卷,使得在容器裏建立的文件,其實是保存在遠程存儲服務器上,或者以分佈式的方式保存在多個節點上,而與當前宿主機沒有任何綁定關係。這樣,不管你在其餘哪一個宿主機上啓動新的容器,均可以請求掛載指定的持久化存儲卷,從而訪問到數據卷裏保存的內容。這就是「持久化」的含義。
因爲 Kubernetes 自己的鬆耦合設計,絕大多數存儲項目,好比 Ceph、GlusterFS、NFS 等,均可覺得 Kubernetes 提供持久化存儲能力。在此次的部署實戰中,我會選擇部署一個很重要的 Kubernetes 存儲插件項目:Rook。
Rook 項目是一個基於 Ceph 的 Kubernetes 存儲插件(它後期也在加入對更多存儲實現的支持)。不過,不一樣於對 Ceph 的簡單封裝,Rook 在本身的實現中加入了水平擴展、遷移、災難備份、監控等大量的企業級功能,使得這個項目變成了一個完整的、生產級別可用的容器存儲插件。
得益於容器化技術,用兩條指令,Rook 就能夠把複雜的 Ceph 存儲後端部署起來:
kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/operator.yaml kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/cluster.yaml
查詢全部pods 的namespace
kubectl get pods --all-namespaces
查看 pod rook-ceph-operator-5496d44d7c-nw5hz 詳細信息
kubectl describe pod rook-ceph-operator-5496d44d7c-nw5hz -n rook-ceph-system
在部署完成後,你就能夠看到 Rook 項目會將本身的 Pod 放置在由它本身管理的兩個 Namespace 當中:
kubectl get pods -n rook-ceph-system
kubectl get pods -n rook-ceph
這樣,一個基於 Rook 持久化存儲集羣就以容器的方式運行起來了,而接下來在 Kubernetes 項目上建立的全部 Pod 就可以經過 Persistent Volume(PV)和 Persistent Volume Claim(PVC)的方式,在容器裏掛載由 Ceph 提供的數據捲了。
而 Rook 項目,則會負責這些數據卷的生命週期管理、災難備份等運維工做。關於這些容器持久化存儲的知識,我會在後續章節中專門講解。
這時候,你可能會有個疑問:爲何我要選擇 Rook 項目呢?
其實,是由於這個項目頗有前途。 若是你去研究一下 Rook 項目的實現,就會發現它巧妙地依賴了 Kubernetes 提供的編排能力,合理的使用了不少諸如 Operator、CRD 等重要的擴展特性(這些特性我都會在後面的文章中逐一講解到)。這使得 Rook 項目,成爲了目前社區中基於 Kubernetes API 構建的最完善也最成熟的容器存儲插件。我相信,這樣的發展路線,很快就會獲得整個社區的推崇。
其實,在不少時候,你們說的所謂「雲原生」,就是「Kubernetes 原生」的意思。而像 Rook、Istio 這樣的項目,正是貫徹這個思路的典範。在咱們後面講解了聲明式 API 以後,相信你對這些項目的設計思想會有更深入的體會。
備忘:
查看所有節點
kubectl get pods --all-namespaces
查看pods
kubectl describe pod -n kube-system
查看具體問題
kubectl describe pod kubernetes-dashboard-767dc7d4d-mg5gw -n kube-system
查看pod日誌
kubectl logs -f podname -n cotainname
若是初始化過程出現問題,使用以下命令重置:
kubeadm reset
根據 kubeadm 版本查看其所需鏡像
kubeadm config images list --kubernetes-version v1.11.1
centos安裝步奏
systemctl stop firewalld systemctl disable firewalld
官方安裝地址
https://docs.docker.com/install/linux/docker-ce/centos/
安裝docker
yum install -y --setopt=obsoletes=0 \ docker-ce-17.03.2.ce-1.el7.centos.x86_64 \ docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch
參考:
https://www.datayang.com/article/45 https://www.cnblogs.com/hongdada/p/9761336.html https://www.liyang.pro/archives/134 https://blog.csdn.net/huangjun0210/column/info/32515