轉自:CloudMan老師公衆號《天天5分鐘玩轉Kubernetes》https://item.jd.com/26225745440.htmlhtml
Cluster 是計算、存儲和網絡資源的集合,Kubernetes 利用這些資源運行各類基於容器的應用。前端
Master 是 Cluster 的大腦,它的主要職責是調度,即決定將應用放在哪裏運行。Master 運行 Linux 操做系統,能夠是物理機或者虛擬機。爲了實現高可用,能夠運行多個 Master。node
Node 的職責是運行容器應用。Node 由 Master 管理,Node 負責監控並彙報容器的狀態,並根據 Master 的要求管理容器的生命週期。Node 運行在 Linux 操做系統,能夠是物理機或者是虛擬機。linux
Pod 是 Kubernetes 的最小工做單元。每一個 Pod 包含一個或多個容器。Pod 中的容器會做爲一個總體被 Master 調度到一個 Node 上運行。web
Kubernetes 引入 Pod 主要基於下面兩個目的:docker
可管理性。
有些容器天生就是須要緊密聯繫,一塊兒工做。Pod 提供了比容器更高層次的抽象,將它們封裝到一個部署單元中。Kubernetes 以 Pod 爲最小單位進行調度、擴展、共享資源、管理生命週期。數據庫
通訊和資源共享。
Pod 中的全部容器使用同一個網絡 namespace,即相同的 IP 地址和 Port 空間。它們能夠直接用 localhost 通訊。一樣的,這些容器能夠共享存儲,當 Kubernetes 掛載 volume 到 Pod,本質上是將 volume 掛載到 Pod 中的每個容器。json
Pods 有兩種使用方式:vim
運行單一容器。one-container-per-Pod
是 Kubernetes 最多見的模型,這種狀況下,只是將單個容器簡單封裝成 Pod。即使是隻有一個容器,Kubernetes 管理的也是 Pod 而不是直接管理容器。後端
運行多個容器。
但問題在於:哪些容器應該放到一個 Pod 中?
答案是:這些容器聯繫必須 很是緊密,並且須要 直接共享資源。
舉個例子。
下面這個 Pod 包含兩個容器:一個 File Puller,一個是 Web Server。
File Puller 會按期從外部的 Content Manager 中拉取最新的文件,將其存放在共享的 volume 中。Web Server 從 volume 讀取文件,響應 Consumer 的請求。
這兩個容器是緊密協做的,它們一塊兒爲 Consumer 提供最新的數據;同時它們也經過 volume 共享數據。因此放到一個 Pod 是合適的。
再來看一個反例:是否須要將 Tomcat 和 MySQL 放到一個 Pod 中?
Tomcat 從 MySQL 讀取數據,它們之間須要協做,但還不至於須要放到一個 Pod 中一塊兒部署,一塊兒啓動,一塊兒中止。同時它們是之間經過 JDBC 交換數據,並非直接共享存儲,因此放到各自的 Pod 中更合適。
Kubernetes 一般不會直接建立 Pod,而是經過 Controller 來管理 Pod 的。Controller 中定義了 Pod 的部署特性,好比有幾個副本,在什麼樣的 Node 上運行等。爲了知足不一樣的業務場景,Kubernetes 提供了多種 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等,咱們逐一討論。
Deployment 是最經常使用的 Controller,好比前面在線教程中就是經過建立 Deployment 來部署應用的。Deployment 能夠管理 Pod 的多個副本,並確保 Pod 按照指望的狀態運行。
ReplicaSet 實現了 Pod 的多副本管理。使用 Deployment 時會自動建立 ReplicaSet,也就是說 Deployment 是經過 ReplicaSet 來管理 Pod 的多個副本,咱們一般不須要直接使用 ReplicaSet。
DaemonSet 用於每一個 Node 最多隻運行一個 Pod 副本的場景。正如其名稱所揭示的,DaemonSet 一般用於運行 daemon。
StatefuleSet 可以保證 Pod 的每一個副本在整個生命週期中名稱是不變的。而其餘 Controller 不提供這個功能,當某個 Pod 發生故障須要刪除並從新啓動時,Pod 的名稱會發生變化。同時 StatefuleSet 會保證副本按照固定的順序啓動、更新或者刪除。
Job 用於運行結束就刪除的應用。而其餘 Controller 中的 Pod 一般是長期持續運行。
Deployment 能夠部署多個副本,每一個 Pod 都有本身的 IP,外界如何訪問這些副本呢?
經過 Pod 的 IP 嗎?
要知道 Pod 極可能會被頻繁地銷燬和重啓,它們的 IP 會發生變化,用 IP 來訪問不太現實。
答案是 Service。
Kubernetes Service 定義了外界訪問一組特定 Pod 的方式。Service 有本身的 IP 和端口,Service 爲 Pod 提供了負載均衡。
Kubernetes 運行容器(Pod)與訪問容器(Pod)這兩項任務分別由 Controller 和 Service 執行。
若是有多個用戶或項目組使用同一個 Kubernetes Cluster,如何將他們建立的 Controller、Pod 等資源分開呢?
答案就是 Namespace。
Namespace 能夠將一個物理的 Cluster 邏輯上劃分紅多個虛擬 Cluster,每一個 Cluster 就是一個 Namespace。不一樣 Namespace 裏的資源是徹底隔離的。
Kubernetes 默認建立了兩個 Namespace。
[root@linux-node1 ~]# kubectl get namespace
NAME STATUS AGE
default Active 1d
kube-system Active 1d
default
-- 建立資源時若是不指定,將被放到這個 Namespace 中。
kube-system
-- Kubernetes 本身建立的系統資源將放到這個 Namespace 中。
K8S Master
節點
從上圖能夠看到,Master是K8S集羣的核心部分,主要運行着如下的服務:kube-apiserver、kube-scheduler、kube-controller-manager、etcd和Pod網絡(如:flannel)
API Server:K8S對外的惟一接口,提供HTTP/HTTPS RESTful API,即kubernetes API。全部的請求都須要通過這個接口進行通訊。主要處理REST操做以及更新ETCD中的對象。是全部資源增刪改查的惟一入口。
Scheduler:資源調度,負責決定將Pod放到哪一個Node上運行。Scheduler在調度時會對集羣的結構進行分析,當前各個節點的負載,以及應用對高可用、性能等方面的需求。
Controller Manager:負責管理集羣各類資源,保證資源處於預期的狀態。Controller Manager由多種controller組成,包括replication controller、endpoints controller、namespace controller、serviceaccounts controller等
ETCD:負責保存k8s 集羣的配置信息和各類資源的狀態信息,當數據發生變化時,etcd會快速地通知k8s相關組件。
Pod網絡:Pod要可以相互間通訊,K8S集羣必須部署Pod網絡,flannel是其中一種的可選方案。
K8S Node
節點
Node是Pod運行的地方,Kubernetes支持Docker、rkt等容器Runtime。Node上運行的K8S組件包括kubelet、kube-proxy和Pod網絡。
Kubelet:kubelet是node的agent,當Scheduler肯定在某個Node上運行Pod後,會將Pod的具體配置信息(image、volume等)發送給該節點的kubelet,kubelet會根據這些信息建立和運行容器,並向master報告運行狀態。
Kube-proxy:service在邏輯上表明瞭後端的多個Pod,外借經過service訪問Pod。service接收到請求就須要kube-proxy完成轉發到Pod的。每一個Node都會運行kube-proxy服務,負責將訪問的service的TCP/UDP數據流轉發到後端的容器,若是有多個副本,kube-proxy會實現負載均衡,有2種方式:LVS或者Iptables
Docker Engine:負責節點的容器的管理工做
Kubernetes中pod建立流程
Pod是Kubernetes中最基本的部署調度單元,能夠包含container,邏輯上表示某種應用的一個實例。例如一個web站點應用由前端、後端及數據庫構建而成,這三個組件將運行在各自的容器中,那麼咱們能夠建立包含三個container的pod。
具體的建立步驟包括:
(1)客戶端提交建立請求,能夠經過API Server的Restful API,也可使用kubectl命令行工具。支持的數據類型包括JSON和YAML。
(2)API Server處理用戶請求,存儲Pod數據到etcd。
(3)調度器經過API Server查看未綁定的Pod。嘗試爲Pod分配主機。
(4)過濾主機 (調度預選):調度器用一組規則過濾掉不符合要求的主機。好比Pod指定了所須要的資源量,那麼可用資源比Pod須要的資源量少的主機會被過濾掉。
(5)主機打分(調度優選):對第一步篩選出的符合要求的主機進行打分,在主機打分階段,調度器會考慮一些總體優化策略,好比把容一個Replication Controller的副本分佈到不一樣的主機上,使用最低負載的主機等。
(6)選擇主機:選擇打分最高的主機,進行binding操做,結果存儲到etcd中。
(7)kubelet根據調度結果執行Pod建立操做: 綁定成功後,scheduler會調用APIServer的API在etcd中建立一個boundpod對象,描述在一個工做節點上綁定運行的全部pod信息。運行在每一個工做節點上的kubelet也會按期與etcd同步boundpod信息,一旦發現應該在該工做節點上運行的boundpod對象沒有更新,則調用Docker API建立並啓動pod內的容器。
主機名 IP地址 描述 linux-node1.example.com eth0:192.168.56.110 K8S Master節點/ETCD節點 linux-node2.example.com eth0:192.168.56.120 K8S Node節點/ETCD節點 linux-node3.example.com eth0:192.168.56.130 K8S Node節點/ETCD節點
第一步:使用國內Docker源
[root@linux-node1 ~]# cd /etc/yum.repos.d/ [root@linux-node1 yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo [root@linux-node2 ~]# cd /etc/yum.repos.d/ [root@linux-node2 yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo [root@linux-node3 ~]# cd /etc/yum.repos.d/ [root@linux-node3 yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
第二步:Docker安裝:
[root@linux-node1 ~]# yum install -y docker-ce [root@linux-node2 ~]# yum install -y docker-ce [root@linux-node3 ~]# yum install -y docker-ce
第三步:啓動後臺進程:
[root@linux-node1 ~]# systemctl start docker [root@linux-node2 ~]# systemctl start docker [root@linux-node3 ~]# systemctl start docker
[root@linux-node1 ~]# mkdir -p /opt/kubernetes/{cfg,bin,ssl,log} [root@linux-node2 ~]# mkdir -p /opt/kubernetes/{cfg,bin,ssl,log} [root@linux-node3 ~]# mkdir -p /opt/kubernetes/{cfg,bin,ssl,log}
3.準備軟件包
百度網盤下載地址:
https://pan.baidu.com/s/1zs8sCouDeCQJ9lghH1BPiw
[root@linux-node1 src]# tar zxf kubernetes.tar.gz [root@linux-node1 src]# tar zxf kubernetes-server-linux-amd64.tar.gz [root@linux-node1 src]# tar zxf kubernetes-client-linux-amd64.tar.gz [root@linux-node1 src]# tar zxf kubernetes-node-linux-amd64.tar.gz
[root@linux-node1 src]# cd kubernetes #解壓的server、client、node都會解壓到kubernetes目錄下 [root@linux-node1 kubernetes]# ll total 29536 drwxr-xr-x 2 root root 6 Apr 12 23:16 addons drwxr-xr-x 3 root root 31 Apr 12 23:16 client drwxr-xr-x 13 root root 4096 Apr 12 23:24 cluster drwxr-xr-x 7 root root 131 Apr 12 23:25 docs drwxr-xr-x 34 root root 4096 Apr 12 23:25 examples drwxr-xr-x 3 root root 17 Apr 12 23:24 hack -rw-r--r-- 1 root root 24710771 Apr 12 23:16 kubernetes-src.tar.gz -rw-r--r-- 1 root root 5516760 Apr 12 23:16 LICENSES drwxr-xr-x 3 root root 17 Apr 12 23:16 node -rw-r--r-- 1 root root 3329 Apr 12 23:25 README.md drwxr-xr-x 3 root root 66 Apr 12 23:16 server drwxr-xr-x 3 root root 22 Apr 12 23:24 third_party -rw-r--r-- 1 root root 8 Apr 12 23:25 version
各個節點增長kubernetes的環境變量
[root@linux-node1 ~]# vim .bash_profile PATH=$PATH:$HOME/bin:/opt/kubernetes/bin [root@linux-node1 ~]# source .bash_profile
[root@linux-node2 ~]# vim .bash_profile PATH=$PATH:$HOME/bin:/opt/kubernetes/bin [root@linux-node2 ~]# source .bash_profile
[root@linux-node3 ~]# vim .bash_profile PATH=$PATH:$HOME/bin:/opt/kubernetes/bin [root@linux-node3 ~]# source .bash_profile
從k8s的1.8版本開始,K8S系統各組件須要使用TLS證書對通訊進行加密。每個K8S集羣都須要獨立的CA證書體系。CA證書有如下三種:easyrsa、openssl、cfssl。這裏使用cfssl證書,也是目前使用最多的,相對來講配置簡單一些,經過json的格式,把證書相關的東西配置進去便可。這裏使用cfssl的版本爲1.2版本。
[root@linux-node1 ~]# cd /usr/local/src [root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 [root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 [root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 [root@linux-node1 src]# chmod +x cfssl* #增長執行權限 [root@linux-node1 src]# mv cfssl-certinfo_linux-amd64 /opt/kubernetes/bin/cfssl-certinfo [root@linux-node1 src]# mv cfssljson_linux-amd64 /opt/kubernetes/bin/cfssljson [root@linux-node1 src]# mv cfssl_linux-amd64 /opt/kubernetes/bin/cfssl
複製cfssl命令文件到k8s-node1和k8s-node2節點。若是實際中多個節點,就都須要同步複製。 [root@linux-node1 ~]# ssh-copy-id linux-node1 [root@linux-node1 ~]# ssh-copy-id linux-node2 [root@linux-node1 ~]# ssh-copy-id linux-node3 [root@linux-node1 ~]# scp /opt/kubernetes/bin/cfssl* 192.168.56.120:/opt/kubernetes/bin cfssl 100% 10MB 18.1MB/s 00:00 cfssl-certinfo 100% 6441KB 21.3MB/s 00:00 cfssljson 100% 2224KB 13.3MB/s 00:00 [root@linux-node1 ~]# scp /opt/kubernetes/bin/cfssl* 192.168.56.130:/opt/kubernetes/bin cfssl 100% 10MB 22.5MB/s 00:00 cfssl-certinfo 100% 6441KB 40.7MB/s 00:00 cfssljson 100% 2224KB 43.1MB/s 00:00
[root@linux-node1 src]# mkdir ssl && cd ssl #建立臨時證書存放目錄 [root@linux-node1 ssl]# pwd /usr/local/src/ssl [root@linux-node1 ssl]# vim ca-config.json { "signing": { "default": { "expiry": "8760h" }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "8760h" } } } }
(3)建立用來生成 CA 證書籤名請求(CSR)的 JSON 配置文件
[root@linux-node1 ssl]# vim ca-csr.json { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ] }
[root@linux-node1 ssl]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca #生成證書和密鑰 2018/05/30 14:11:02 [INFO] generating a new CA key and certificate from CSR 2018/05/30 14:11:02 [INFO] generate received request 2018/05/30 14:11:02 [INFO] received CSR 2018/05/30 14:11:02 [INFO] generating key: rsa-2048 2018/05/30 14:11:02 [INFO] encoded CSR 2018/05/30 14:11:02 [INFO] signed certificate with serial number 167714418220584190953978332616641264281080483250 [root@linux-node1 ssl]# ll total 20 -rw-r--r-- 1 root root 290 May 30 14:09 ca-config.json -rw-r--r-- 1 root root 1001 May 30 14:11 ca.csr -rw-r--r-- 1 root root 208 May 30 14:10 ca-csr.json -rw------- 1 root root 1675 May 30 14:11 ca-key.pem -rw-r--r-- 1 root root 1359 May 30 14:11 ca.pem
[root@linux-node1 ssl]# cp ca.csr ca.pem ca-key.pem ca-config.json /opt/kubernetes/ssl SCP證書到k8s-node1和k8s-node2節點,之後增長節點也是須要將這些證書進行分發 [root@linux-node1 ssl]# scp ca.csr ca.pem ca-key.pem ca-config.json 192.168.56.120:/opt/kubernetes/ssl ca.csr 100% 1001 350.2KB/s 00:00 ca.pem 100% 1359 891.4KB/s 00:00 ca-key.pem 100% 1675 1.0MB/s 00:00 ca-config.json 100% 290 180.7KB/s 00:00 [root@linux-node1 ssl]# scp ca.csr ca.pem ca-key.pem ca-config.json 192.168.56.130:/opt/kubernetes/ssl ca.csr 100% 1001 350.2KB/s 00:00 ca.pem 100% 1359 891.4KB/s 00:00 ca-key.pem 100% 1675 1.0MB/s 00:00 ca-config.json 100% 290 180.7KB/s 00:00