1. 程式人生 > >Kubernetes管理Docker叢集之部署篇

Kubernetes管理Docker叢集之部署篇

什麼是Kubernetes?

Kubernetes是Google開源的容器叢集管理系統,實現基於Docker構建容器,利用Kubernetes能很方面管理多臺Docker主機中的容器。

主要功能如下:

1)將多臺Docker主機抽象為一個資源,以叢集方式管理容器,包括任務排程、資源管理、彈性伸縮、滾動升級等功能。

2)使用編排系統(YAML File)快速構建容器叢集,提供負載均衡,解決容器直接關聯及通訊問題

3)自動管理和修復容器,簡單說,比如建立一個叢集,裡面有十個容器,如果某個容器異常關閉,那麼,會嘗試重啟或重新分配容器,始終保證會有十個容器在執行,反而殺死多餘的。

kubernetes角色組成:

1)Pod

Pod是kubernetes的最小操作單元,一個Pod可以由一個或多個容器組成;

同一個Pod只能執行在同一個主機上,共享相同的volumes、network、namespace;

2)ReplicationController(RC)

RC用來管理Pod,一個RC可以由一個或多個Pod組成,在RC被建立後,系統會根據定義好的副本數來建立Pod數量。在執行過程中,如果Pod數量小於定義的,就會重啟停止的或重新分配Pod,反之則殺死多餘的。當然,也可以動態伸縮執行的Pods規模或熟悉。

RC通過label關聯對應的Pods,在滾動升級中,RC採用一個一個替換要更新的整個Pods中的Pod。

3)Service

Service定義了一個Pod邏輯集合的抽象資源,Pod集合中的容器提供相同的功能。集合根據定義的Label和selector完成,當建立一個Service後,會分配一個Cluster IP,這個IP與定義的埠提供這個集合一個統一的訪問介面,並且實現負載均衡。

4)Label

Label是用於區分Pod、Service、RC的key/value鍵值對; 

Pod、Service、RC可以有多個label,但是每個label的key只能對應一個;

主要是將Service的請求通過lable轉發給後端提供服務的Pod集合;

kubernetes元件組成:

1)kubectl

客戶端命令列工具,將接受的命令格式化後傳送給kube-apiserver,作為整個系統的操作入口。

2)kube-apiserver

作為整個系統的控制入口,以REST API服務提供介面。

3)kube-controller-manager

用來執行整個系統中的後臺任務,包括節點狀態狀況、Pod個數、Pods和Service的關聯等。

4)kube-scheduler

負責節點資源管理,接受來自kube-apiserver建立Pods任務,並分配到某個節點。

5)etcd

負責節點間的服務發現和配置共享。

6)kube-proxy

執行在每個計算節點上,負責Pod網路代理。定時從etcd獲取到service資訊來做相應的策略。

7)kubelet

執行在每個計算節點上,作為agent,接受分配該節點的Pods任務及管理容器,週期性獲取容器狀態,反饋給kube-apiserver。

8)DNS

一個可選的DNS服務,用於為每個Service物件建立DNS記錄,這樣所有的Pod就可以通過DNS訪問服務了。

基本部署步驟:

1)minion節點安裝docker

2)minion節點配置跨主機容器通訊

3)master節點部署etcd、kube-apiserver、kube-controller-manager和kube-scheduler元件

4)minion節點部署kubelet、kube-proxy元件

注意:如果minion主機沒有安裝docker,啟動kubelet時會報如下錯誤:

W0116 23:36:24.205672    2589 server.go:585] Could not load kubeconfig file /var/lib/kubelet/kubeconfig: stat /var/lib/kubelet/kubeconfig: no such file or directory. Trying auth path instead.
W0116 23:36:24.205751    2589 server.go:547] Could not load kubernetes auth path /var/lib/kubelet/kubernetes_auth: stat /var/lib/kubelet/kubernetes_auth: no such file or directory. Continuing with defaults.
I0116 23:36:24.205817    2589 plugins.go:71] No cloud provider specified.

實驗環境:

作業系統:ubuntu14.04_x64

master:192.168.18.15

minion01 : 192.168.18.16  容器網段:172.17.1.0/24

minion02 : 192.168.18.17  容器網段:172.17.2.0/24

一、minion節點安裝docker

1、新增祕鑰

$ sudo apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

2、新增docker源

$ sudo vi /etc/apt/sources.list.d/docker.list

# Ubuntu Precise 

deb https://apt.dockerproject.org/repo ubuntu-precise main 

# Ubuntu Trusty 

deb https://apt.dockerproject.org/repo ubuntu-trusty main 

# Ubuntu Vivid 

deb https://apt.dockerproject.org/repo ubuntu-vivid main 

# Ubuntu Wily 

deb https://apt.dockerproject.org/repo ubuntu-wily main

注意:通過命令lsb_release -cs檢視上面對應的版本,不要都新增上

3、更新索引

$ sudo apt-get update

4、安裝docker

$ sudo apt-get install docker-engine -y

二、minion節點配置跨主機容器互聯(也可以使用自帶的flannel元件)

由於docker自身還未支援跨主機容器通訊,需要藉助docker網路開源解決方案實現。這裡利用OpenVSwich即開放式虛擬交換機實現容器跨主機通訊。

什麼是OpenVSwich?

OpenVSwich是一種開源軟體,通過軟體的方式實現二層交換機功能,專門管理多租賃雲端計算網路環境,提供虛擬網路中的訪問策略、網路隔離、流量監控等。

既然是虛擬交換機,自然與傳統的物理交換機有著相同的特性,操作中可以按照理解物理交換機的方式去操作,有助於對虛擬交換機的認識。

開始建立網路環境(兩臺宿主機做相同的操作,部分要適當修改,已註明):

1、安裝openvswitch

$ sudo apt-get install openvswitch-switch bridge-utils

2、新增網橋obr0(理解為添加了一個交換機)

$ sudo ovs-vsctl add-br obr0

3、將gre0介面加入到網橋obr0, 遠端IP寫對端IP(建立一個GRE隧道並新增到網橋中)

$ sudo ovs-vsctl add-port obr0 gre0 -- set Interface gre0 type=gre options:remote_ip=192.168.18.17

4、檢視ovs資訊

$ sudo ovs-vsctl show

5、新增docker網橋

$ sudo brctl addbr kbr0

6、將obr0網橋加入kbr0網橋,並啟動

$ sudo brctl addif kbr0 obr0

$ sudo ip link dev kbr0 up

$ sudo ip link set dev kbr0 up

7、檢視網橋資訊

$ sudo brctl show

8、新增docker網橋配置資訊(18.17宿主機按照這種方式配置自己)

$ vi /etc/network/interfaces

auto eth0
iface eth0 inet static
    address 192.168.18.16
    netmask 255.255.255.0
    gateway 192.168.18.1
    dns-nameservers 192.168.18.1
auto kbr0
iface kbr0 inet static        
    address 172.17.1.1
    netmask 255.255.255.0
    gateway 172.17.1.0

9、刪除預設docker網橋

$ sudo ip link set dev docker0 down

$ sudo ip link delete dev docker0

10、關鍵一點,新增路由條目,否則無法通訊(同樣在18.17上面這樣新增路由,寫對端IP)

# via從哪個網關出去,寫對端IP。dev由哪個裝置出去

$ sudo ip route add 172.17.2.0/24 via 192.168.18.17 dev eth0

跨主機容器互聯配置完成,並可以相互通訊,接下來部署kubernetes叢集!

先下載好相關的二進位制包:

三、master節點部署etcd、kube-apiserver、kube-controller-manager和kube-scheduler元件

1、安裝配置k8s儲存系統etcd

etcd是一個開源的用於配置共享和服務發現的高效能的鍵值儲存系統。

# tar zxvf etcd-v2.2.2-linux-amd64.tar.gz

# cd etcd-v2.2.2-linux-amd64

注意: 建立存放所有元件二進位制檔案目錄,最好是/opt/bin目錄,因為啟動腳本里面寫的就是這個目錄。

# mkdir /opt/bin

# cp etcd etcdctl /opt/bin

配置etcd啟動選項:

# vi /etc/default/etcd

ETCD_OPTS="\

--listen-client-urls http://0.0.0.0:4001 \

--advertise-client-urls http://0.0.0.0:4001 \

--data-dir /var/lib/etcd/default.etcd"

選項說明:

--listen-peer-urls :etcd作為分散式節點通訊埠,預設指定埠7001,我們這裡做的是單節點,這個引數可以不寫,需要知道的是v2版本中改變為2380,7001仍可用

--listen-client-urls :客戶端操作etcd API的埠,預設指定埠4001,v2中改變為2379,在k8s中我們要使用4001埠

--data-dir :指定資料存放目錄

--advertise-client-urls :作為分散式的客戶端連線埠,如果不寫這個引數會出現以下報錯。

2016-01-15 16:04:20.469486 E | etcdmain: error verifying flags, -advertise-client-urls is required when -listen-client-urls is set explicitly. See 'etcd --help'.
2016-01-15 16:04:20.469717 E | etcdmain: When listening on specific address(es), this etcd process must advertise accessible url(s) to each connected client.

etcd服務配置好後先不啟動,待會用下面kubernetes提供的啟動指令碼啟動!~             

2、啟動etcd,安裝配置kube-apiserver、kube-scheduler和kube-controller-manager

# tar zxvf kubernetes.tar.gz

# cd kubernetes/server

# tar zxvf kubernetes-server-linux-amd64.tar.gz

拷貝master端相關元件到/opt/bin目錄:

# cd kubernetes/server/kubernetes/server/bin

# cp kube-apiserver kube-scheduler kube-controller-manager /opt/bin/

拷貝相關元件啟動指令碼到/etc/init.d目錄:

# cd kubernetes/cluster/ubuntu/master/init_scripts

# cp etcd kube-* /etc/init.d/

配置apiserver啟動選項:

# vi /etc/default/kube-apiserver 

KUBE_APISERVER_OPTS="\

--insecure-bind-address=0.0.0.0 \

--insecure-port=8080 \

--service-cluster-ip-range=10.0.0.0/16 \

--etcd_servers=http://127.0.0.1:4001 \

--logtostderr=true"

選項說明:

--insecure-bind-address:api監聽地址

--insecure-port:api監聽埠

--service-cluster-ip-range:上面說到service角色是定義叢集中一個pod集合,這個pod中容器提供一種服務,當建立service時會分配一個CLUSTER_IP提供統一的訪問入口,那麼,這個選項就是指定分配的IP範圍

--etcd_servers:指定etcd連線地址

配置controller-manager啟動選項:

# vi /etc/default/kube-controller-manager 

KUBE_CONTROLLER_MANAGER_OPTS="\

--master=127.0.0.1:8080 \

--logtostderr=true"

配置scheduler啟動選項:

# vi /etc/default/kube-scheduler 

KUBE_SCHEDULER_OPTS="\

--master=127.0.0.1:8080 \

--logtostderr=true"

配置完成後,啟動元件:

# service etcd start

etcd start/running, process 30585

# service kube-apiserver start

* Kube-Apiserver is managed via upstart, try using service kube-apiserver start

啟動方式不對!為啥呢?

先看下指令碼這段怎麼執行的,可以看到兩個條件都是成立的,當然會輸出這句話了,看下其他啟動指令碼也一樣,為啥etcd能啟動呢?再看下etcd的啟動指令碼,原來壓根都沒執行這個判斷,難道是kubernetes漏寫了,先不管了,其他指令碼都改為etcd這樣吧!

再啟動就成功了,呵呵!

# service kube-apiserver start
 * Starting Kube-Apiserver: kube-apiserver               [ OK ]
# service kube-scheduler start
 * Starting Kube-Scheduler: kube-scheduler                      [ OK ] 
# service kube-controller-manager start
  * Starting Kube-Controller-Manager: kube-controller-manager     [ OK ]

可以通過etcdctl檢視到etcd儲存著關於叢集的各種資訊:

# /opt/bin/etcdctl ls /registry

/registry/controllers

/registry/pods

/registry/ranges

/registry/namespaces

/registry/services

/registry/serviceaccounts

/registry/events

/registry/minions

四、minion節點部署kubelet、kube-proxy元件

在master端將minion相關元件拷貝到minion:

# cd kubernetes/server/kubernetes/server/bin

# scp kubelet kube-proxy [email protected]:/opt/bin

# scp kubelet kube-proxy [email protected]:/opt/bin

注意: ubuntu預設禁止root遠端登入,需要配置允許ssh登入,也可以先將二進位制包拷貝到minion伺服器能ssh登入的使用者,然後再sudo移動到/opt/bin目錄

拷貝相關元件啟動指令碼到/etc/init.d目錄:

# cd kubernetes/cluster/ubuntu/minion/init_scripts

# scp kubelet kube-proxy [email protected]:/etc/init.d/

# scp kubelet kube-proxy [email protected]:/etc/init.d/

配置kubelet啟動選項:

# vi /etc/default/kubelet

KUBELET_OPTS="\

--address=0.0.0.0 \

--port=10250 \

--hostname_override=192.168.18.16 \           

--api_servers=http://192.168.18.15:8080 \

--pod-infra-container-image=docker.io/kubernetes/pause:latest \

--logtostderr=true"

重要選項說明:

--hostname_override:在master端顯示的節點名稱,對應的minion主機修改對應的IP

--pod-infra-container-image:建立pod時下載映象地址,預設是gcr.io/google_containers/pause:0.8.0,需要翻牆才能訪問,所以指定了官方映象下載源

配置kube-proxy啟動選項:

# vi /etc/default/kube-proxy

KUBE_PROXY_OPTS="\

--master=http://192.168.18.15:8080 \

--proxy-mode=iptables \

--logtostderr=true"

重要選項說明:--proxy-mode,代理模式,預設使用userspace,會如下報錯,我們需要修改為iptables做網路轉發

# tail /var/log/kube-proxy.log 

E1230 19:33:33.171758   24488 server.go:357] Not trying iptables proxy: can't get Node "minion2": node "minion2" not found
E1230 19:33:33.203271   24488 proxier.go:193] Error removing pure-iptables proxy rule: error checking rule: exit status 2: iptables v1.4.21: Couldn't load target `KUBE-SERVICES':No such file or directory
Try `iptables -h' or 'iptables --