Kubernetes 是 docker 容器編排系統(tǒng), 用于協(xié)調(diào)高可用的計(jì)算機(jī)集群蚂且,并在這個(gè)集群上以更有效的方式自動(dòng)分發(fā)和調(diào)度應(yīng)用程序。由于kubernetes本地安裝比較復(fù)雜幅恋,所以社區(qū)推出了Minikube杏死。Minikube 是在本地的虛擬機(jī)中運(yùn)行一個(gè)單節(jié)點(diǎn)的kubernetes集群。
本文將會(huì)介紹Minikube的安裝佳遣,在kubernetes集群上部署一個(gè)應(yīng)用识埋,并且簡(jiǎn)單擴(kuò)容以及通過(guò)rolling update更新鏡像。最后會(huì)簡(jiǎn)單介紹一下 kubernetes dashboard的簡(jiǎn)單使用零渐。
搭建kubernetes環(huán)境
安裝Minikube
Minikube 可以安裝在linux窒舟、mac和windows上。我們只介紹在mac 以及 ubuntu 14.04上的安裝诵盼。更多關(guān)于安裝Minikube請(qǐng)參考官方教程惠豺。
Minikube是使用go開(kāi)發(fā)生成的二進(jìn)制文件,下載并放到/usr/local/bin
即可风宁。
// linux 下安裝
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
// mac
brew cask install minikube //可能不是最新
// 也可以下面的方式
curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.21.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
驗(yàn)證安裝成功洁墙。
$ minikube version
minikube version: v0.21.0
安裝vm
因?yàn)镸inikube是在host上啟動(dòng)一個(gè)VM來(lái)運(yùn)行Kubernetes集群的,所以還要安裝一個(gè)VM戒财。
下面介紹mac下安裝xhyve
和 linux下安裝virtual box
热监。更多關(guān)于vm的安裝,請(qǐng)參考下面的安裝指導(dǎo)饮寞。
// linux virtualbox
sudo apt-get install virtualbox
// macos xhyxhyve
brew install docker-machine-driver-xhyve
sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
安裝kubectl
Kubectl是kubernetes的命令行工具孝扛,用來(lái) 管理部署在kubernetes上的應(yīng)用∮谋溃可以根據(jù)自己的操作系統(tǒng)苦始,按照官網(wǎng)教程安裝kubectl。
// 1. 下載
// linux
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
// mac
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
或者
$ brew install kubectl
// 2. 更改執(zhí)行權(quán)限 并移到指定位置慌申。
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl
驗(yàn)證kubectl是否安裝成功陌选。
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-06-29T23:15:59Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-07-26T00:12:31Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
這里有可能會(huì)出現(xiàn)下面的錯(cuò)誤狀況。
Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.2", GitCommit:"922a86cfcd65915a9b2f69f3f193b8907d741d9c", GitTreeState:"clean", BuildDate:"2017-07-21T19:06:19Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"darwin/amd64"}
The connection to the server localhost:8080 was refused - did you specify the right host or port?
這里只有客戶(hù)端的信息,沒(méi)有服務(wù)端的信息咨油,那是因?yàn)槲覀兊腗inikube還沒(méi)有啟動(dòng)您炉,下面我們就啟動(dòng)Minikube。
啟動(dòng)Minikube
安裝上面的工具之后臼勉,就可以通過(guò)minikube start
來(lái)啟動(dòng)邻吭。
$ minikube start
Starting local Kubernetes v1.7.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Starting cluster components...
Connecting to cluster...
Setting up kubeconfig...
Kubectl is now configured to use the cluster.
也可以通過(guò)--vm-driver
指定虛擬機(jī)啟動(dòng)。
minikube start --vm-driver xhyve
這樣minikube就啟動(dòng)了宴霸。可以通過(guò)kubectl cluster-info
查看集群的信息膏蚓。
$ kubectl cluster-info
Kubernetes master is running at https://192.168.99.100:8443
可以看到一個(gè)運(yùn)行的master瓢谢。
也可以通過(guò)kubectl get nodes
查看運(yùn)行的node(目前只有一個(gè))。
$kubectl get nodes
NAME STATUS AGE VERSION
minikube Ready 13m v1.7.0
這里還要介紹個(gè)概念就是context
驮瞧。context決定kubectl與哪個(gè)cluster交互氓扛。可以在~/.kube/config
中查看论笔。通過(guò)以下指令指定context采郎。
kubectl config use-context minikube
默認(rèn)就是minikube。
部署應(yīng)用
啟動(dòng)kubernetes cluster之后狂魔,就可以部署應(yīng)用到集群上蒜埋。部署一個(gè)應(yīng)用需要?jiǎng)?chuàng)建一個(gè)Deployment
。Deployment 負(fù)責(zé)創(chuàng)建和更新應(yīng)用程序?qū)嵗羁?chuàng)建Deployment之后整份,kubernetes master 會(huì)將創(chuàng)建的應(yīng)用程序調(diào)度到各個(gè)node上。
創(chuàng)建應(yīng)用實(shí)例后籽孙,kubernetes deploymentController 會(huì)監(jiān)視這些實(shí)例烈评,如果某個(gè)節(jié)點(diǎn)不可用或者刪除,會(huì)自動(dòng)替換實(shí)例犯建。
創(chuàng)建部署時(shí)讲冠,通常需要指定應(yīng)用程序的鏡像
和副本數(shù)
。以下部署一個(gè)簡(jiǎn)單的node應(yīng)用适瓦。
const express = require('express');
const http = require('http');
const app = express();
app.get('/', (req, res) => {
return res.send({ success: true, msg: 'hello kubernetes'});
});
http.createServer(app).listen(1226, () => {
console.log('Server is listening on port 1226');
});
這個(gè)鏡像我push到了docker hub竿开。
這里因?yàn)閯傞_(kāi)始試的時(shí)候,Minikube里一直拉取不了鏡像犹菇。正確的方式應(yīng)該是搭建一個(gè)private docker registry德迹。但折騰中還有點(diǎn)不明白之處,所以這里先不做具體介紹揭芍,直接push到docker hub胳搞。后續(xù)會(huì)介紹更多關(guān)于docker registry的搭建,到時(shí)候順便再一起解釋。
也可以使用minikube VM的docker來(lái)拉鏡像肌毅。
$ eval $(minikube docker-env)
如果不需要使用minikube的docker筷转,可以再恢復(fù)磅摹。
$ eval $(minikube docker-env -u)
使用kubectl run
創(chuàng)建一個(gè)部署转质。
$ kubectl run docker-demo --image=docker_demo --port=1226
image指定鏡像,port指定端口荣月。這里要注意的是笨奠,啟動(dòng)的容器名docker-demo
,只能是小寫(xiě)字母袭蝗、數(shù)字和加 - 橫線。
這樣我們就部署了一個(gè)應(yīng)用到node上般婆。通過(guò)kubectl get deployments
查看到腥。
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
docker-demo 1 1 1 0 22s
如果pods一直處于ContainerCreating
階段,可能還是還不能拉取鏡像蔚袍。
可以通過(guò)minikube ssh
進(jìn)入vm乡范,然后拉取對(duì)應(yīng)鏡像。
$ minikube ssh
$ docker pull dennisge/docker_demo
這時(shí)啤咽,可以看到我們的pod的狀態(tài)是running
晋辆。到此,我們就成功部署了我們的應(yīng)用宇整。
基本概念和指令
Kubernetes 集群由兩種類(lèi)型的資源組成:master
和 Nodes
瓶佳。 master是集群的調(diào)度節(jié)點(diǎn),nodes則是應(yīng)用程序?qū)嶋H運(yùn)行的工作節(jié)點(diǎn)没陡。類(lèi)似于nginx的 master 和 worker涩哟。
部署應(yīng)用時(shí)需要?jiǎng)?chuàng)建deployment
。每個(gè)deployment 會(huì)根據(jù)指定的副本數(shù)
盼玄,創(chuàng)建相應(yīng)的pod
來(lái)托管我們的應(yīng)用實(shí)例贴彼。Pod可以理解為應(yīng)用實(shí)例特定的邏輯主機(jī),表示一個(gè)或多個(gè)容器組和這些容器的共享資源埃儿,包共用卷器仗、唯一的集群IP和容器運(yùn)行的信息,如端口等童番。
而Node
是kubernetes的工作機(jī)器(物理機(jī)或虛擬機(jī))精钮。Node由master管理,可以在一個(gè)node上部署多個(gè)pod剃斧。每個(gè)node至少需要兩種組件轨香,kubelet
和 容器運(yùn)行時(shí)(docker)
。kubelet是負(fù)責(zé)master和所有節(jié)點(diǎn)間的通信進(jìn)程幼东,管理機(jī)器上運(yùn)行的pod和容器臂容。容器運(yùn)行時(shí)負(fù)責(zé)從registry拉取鏡像科雳,解包鏡像并運(yùn)行應(yīng)用實(shí)例。
kubectl 有一系列指令管理實(shí)例的運(yùn)行情況脓杉。
// 查看deployment
kubectl get deployments
// 刪除deployment糟秘,會(huì)自動(dòng)刪除相應(yīng)pods
kubectl delete deployment <部署名>
// 查看pods
// 查看當(dāng)前namespace下的pods
kubectl get pods
// 查看所有pods
kubectl get pods --all-namespaces
// 查看pods的具體信息
kubectl describe pod <pod name>
//特定namespace下的,需要指定namespace
kubectl describe pod <pod name> --namespace=kube-system
// 查看pod日志
kubectl logs pod <pod name>
// 進(jìn)入pod
kubectl exec -it <pod name> bash
發(fā)布應(yīng)用
通過(guò)上面部署的應(yīng)用球散,在主機(jī)外訪問(wèn)不了(可以通過(guò)kubectl proxy的方式訪問(wèn))尿赚。還要需要將其發(fā)布為service
。 service是一組相同邏輯的pods和一個(gè)訪問(wèn)它們的策略蕉堰。一組pods通常由label選擇器
確定凌净。可以在ServiceSpec 中指定類(lèi)型以不同的方式暴露服務(wù)嘁灯。
- Cluster IP(默認(rèn)): 只有集群內(nèi)部訪問(wèn)泻蚊。
- NodePort: 使用NAT方式,在集群中每個(gè)選定的節(jié)點(diǎn)的同一端口上暴露服務(wù)丑婿。可以在集群外部訪問(wèn)服務(wù)羹奉。
- LoadBalancer:創(chuàng)建外部負(fù)載均衡。
- ExternalName:使用任意名稱(chēng)顯示服務(wù)耕挨。
可以通過(guò)kubectl expose
命令來(lái)發(fā)布服務(wù)。
$ kubectl expose deployment/<deployment name> --type=NodePort --port 1226
這樣就expose了一個(gè)服務(wù)翰苫,就可以外部訪問(wèn)了这橙∽嘁ぃ可以通過(guò)一下指令得到url。
$ minikube service <service name> --url
http://192.168.64.2:32354
$ curl http://192.168.64.2:32354
{"success":true,"msg":"hello kubernetes"}
擴(kuò)容和更新
根據(jù)線上需求屈扎,擴(kuò)容和縮容是常會(huì)遇到的問(wèn)題埃唯。Scaling
是通過(guò)更改 Deployment 中的副本數(shù)量實(shí)現(xiàn)的止毕。一旦您有應(yīng)用程序的多個(gè)實(shí)例,您將能夠滾動(dòng)更新巍实,而不會(huì)停止服務(wù)滓技。通過(guò)kubectl scale
指令來(lái)擴(kuò)容和縮容叠必。
// 擴(kuò)充到3個(gè)實(shí)例
kubectl scale deployments/docker-demo --replicas=3
// 縮小到1個(gè)實(shí)例
kubectl scale deployments/docker-demo --replicas=1
我們都是期望應(yīng)用24/7運(yùn)行,但又需要頻繁部署嫉沽。這我們就需要rolling update(滾動(dòng)更新)
。 Rolling updates 允許通過(guò)使用新的 Pods 實(shí)例逐個(gè)更新來(lái)實(shí)現(xiàn)零停機(jī)的部署更新。新的 Pods 會(huì)被調(diào)度到可用資源的 Node 節(jié)點(diǎn)上丸升×朐恚可以通過(guò)set image
修改鏡像。
$ kubectl set image deployments/<部署名> <部署名>=鏡像名:tag
如我們的第二版鏡像猾昆。
kubectl set image deployments/docker-demo docker-demo=dennisge/docker_demo:v2
重新設(shè)置鏡像之后陶因,就會(huì)執(zhí)行滾動(dòng)更新垂蜗。
以上我們就成功部署了自己的應(yīng)用。但是都是通過(guò)指令來(lái)進(jìn)行的毅否,下面我們將介紹一下部署kubernetes dashboard,并通過(guò)web ui的方式部署吞琐、刪除和修改相關(guān)應(yīng)用等。
kubenetes dashboard
Kubernetes dashboard是一個(gè)基于web UI的用戶(hù)接口然爆,可以再界面上完成上面的部署應(yīng)用站粟、擴(kuò)容縮容和滾動(dòng)更新等一系列操作,也可以查看cluster的運(yùn)行情況曾雕。
如果沒(méi)GFW的原因奴烙,minikube會(huì)下載和部署一些組件的,運(yùn)行在 kube-system namespace 下剖张∏芯鳎可以查看鏡像看看這些組件。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gcr.io/google_containers/k8s-dns-kube-dns-amd64 1.14.4 a8e00546bcf3 5 weeks ago 49.4MB
gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64 1.14.4 f7f45b9cb733 5 weeks ago 41.4MB
gcr.io/google-containers/kube-addon-manager v6.4-beta.2 0a951668696f 7 weeks ago 79.2MB
gcr.io/google_containers/kubernetes-dashboard-amd64 v1.6.1 71dfe833ce74 2 months ago 134MB
gcr.io/google_containers/pause-amd64 3.0 99e59f495ffa 15 months ago 747kB
安裝好之后搔弄,就可以通過(guò)以下指令獲得dashboard的訪問(wèn)地址幅虑。
$ minikube dashboard --url
這樣就可以訪問(wèn)dashboard,并進(jìn)行相關(guān)的操作顾犹。
但這里通常會(huì)遇到dashboard 和 kube-addon-manager出現(xiàn)ImagePullBackOff
的情況倒庵。這個(gè)問(wèn)題就是我們無(wú)法拉取google的鏡像褒墨。可以參考這個(gè)方法來(lái)解決擎宝。
這個(gè)方法主要是冒充原來(lái)的鏡像郁妈。可以查看對(duì)應(yīng)deployment的鏡像绍申,然后在別的地方如阿里鏡像等拉取對(duì)應(yīng)鏡像噩咪,或者拉取鏡像放到docker hub。再登陸Minikube失晴,拉取該鏡像剧腻,再重新tag為原deployment需要的鏡像。
以kube-addon-manager 為例涂屁。
$ minikube ssh
$ docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/kube-addon-manager-amd64:v6.1
$ docker tag registry.cn-hangzhou.aliyuncs.com/google-containers/kube-addon-manager-amd64:v6.1 gcr.io/google-containers/kube-addon-manager:v6.1
這樣就可以看到這些組件的狀態(tài)變?yōu)閞unning书在。
這樣的dashboard還是很樸素,如下圖:
這就需要安裝heapster插件〔鹩郑可以查看現(xiàn)在的addons 列表儒旬。
$ minikube addons list
- registry: disabled
- dashboard: enabled
- kube-dns: enabled
- heapster: disabled
- ingress: disabled
- addon-manager: enabled
- default-storageclass: enabled
- registry-creds: disabled
發(fā)現(xiàn)heapster是關(guān)閉的√澹可以把它開(kāi)啟栈源。
$ minikube addons enable heapter
我們會(huì)看到已經(jīng)部署了相關(guān)的pod。
$ kubectl get pods --namespace=kube-system
NAME READY STATUS RESTARTS AGE
heapster-jgzf2 1/1 Running 0 12h
influxdb-grafana-lqdtk 2/2 Running 0 12h
這通常會(huì)遇到ImagePullBackOff 問(wèn)題竖般,無(wú)法拉取鏡像甚垦。這里需要以下幾個(gè)鏡像。
gcr.io/google_containers/heapster_influxdb:v0.6
gcr.io/google_containers/heapster_grafana:v2.6.0-2
gcr.io/google_containers/heapster_influxdb:v0.6
可以安裝上面介紹的鏡像冒充的方法解決這個(gè)問(wèn)題涣雕。我是在我的aws上下載相應(yīng)鏡像push到我的docker hub艰亮。然后下載docker hub的鏡像,再重命名需要的鏡像挣郭。這樣我們的heapster就正常運(yùn)行了迄埃,可以看到漂亮的圖表。
就可以愉快的使用dashboard了兑障。
總結(jié)
Kubernetes是docker的重要編排工具侄非。我們通過(guò)Minikube來(lái)部署一個(gè)應(yīng)用,來(lái)了解kubernetes的一些基本使用流译。
本文介紹了在mac和linux的Minikube安裝逞怨、kubectl安裝,以及基于VM來(lái)啟動(dòng)minikube集群先蒋。然后通過(guò)部署一個(gè)node應(yīng)用骇钦,并成功地伸縮擴(kuò)容并通過(guò)rolling update更新鏡像。在這個(gè)過(guò)程中竞漾,我們也了解了node眯搭、deployment窥翩、pod、service等概念鳞仙。最后我們介紹了一下kubernetes dashboard的安裝寇蚊、heapster插件安裝以及可能遇到的問(wèn)題及解決方案。
參考
[1] kubernetes tutorial
[2] 利用 Minikube 運(yùn)行 Kubernetes
[3] Driver plugin installation
[4] minikube github
[5] mac安裝kubernetes并運(yùn)行echoserver
[6]Heapster Addon