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 --