Docker1.12+swrmkit
docker1.12集成了swarmkit, 使你可以不用安裝額外的軟件包, 使用簡單的命令啓動創建docker swarm集羣。
如果你在運行 Docker 1.12時,你就可以原生創建一個 Swarm 集羣 .
集成了swarm集羣的安全特性, 集成了K-V存儲, 你現在不需要額外部署etcd或者consul。
在Docker1.12版本中,一個大的功能點是swarm集羣(基於swarmkit項目),通過Docker命令可以直接實現docker-engine相互發現,並組建成爲一個容器集羣。
SwarmKit將節點分爲兩類:
工作節點(Worker):負責通過執行器運行任務。SwarmKit的默認執行器爲Docker容器執行器(Docker Container Executor)。
(1)內建分佈式存儲,不要額外的數據庫
(2)支持Rolling update
(3容器高可用
(4)通過TLS保證了節點之間通訊的安全
管理節點(Manager):負責接收和響應用戶請求,將集羣狀態調節到最終狀態。在SwarmKit中,用戶可以動態調整節點的角色,即在Manager和Worker之間轉換。
如下圖所示,這是一個典型的master-slave的架構。每個節點都是運行着Docker Engine的Docker主機。一些節點有更高的權限,被稱爲Manager。下面的節點是worker節點,接收來自manager組的任務指示。
部署docker.12 Swarm
實驗環境:
1 )這裏選擇三臺主機運行Swarm,依次爲:
Vim /etc/hostname (更改好執行bash使其生效)
node1192.168.1.104
node2192.168.1.105
node3192.168.1.113
2) 基本環境配置
3臺主機確保時間一致
三臺主機以實現時間同步
3臺主機均關閉selinux,開啓路由轉發。
3 )系統環境準備
準備系統環境, 配置host列表
3臺主機均修改/etc/hosts文件,添加所有主機的ip地址和主機名的映射記錄
4 ) 3臺主機開啓宿主機之間的端口
TCP端口2377集羣管理端口
TCP與UDP端口7946節點之間通訊端口
TCP與UDP端口4789 overlay網絡通訊端口
(以host1 爲例,)
5 )配置所有節點密鑰登錄.
配置所以節密鑰互信, 在node1可以免密碼登錄各節點,只在node1上執行:
生成sshkey
發佈sshkey到各個節點
把/root/.ssh目錄下的id_rsa.pub公鑰發佈給其它兩臺node主機上,發佈給那臺主機,就在那臺主機的/root/.ssh目錄下生產authorized.key文件,其內容和node1的id_rsa.pub一樣
測試密鑰登錄
6 )在所有節點上安裝docker 1.12(如果沒有docker 1.12軟件包,按照docs.docker.com官網安裝)
添加docker repo文件
rm -rf /etc/yum.repos.d/*
tee /etc/yum.repos.d/docker.repo<<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
安裝docker package
yum -y install docker-engine
我這裏已經有下載好的docker1.12軟件包,所以不適用上面提供的方法,直接使用rpm在三臺主機上都安裝
(以host1 爲例)
檢查docker版本
docker1.12 Swarm 模式簡介
Docker Engine 1.12 集成了Swarm集羣工具.
主要使用三個新的命令行工具創建一個swarm集羣:
docker swarm 開啓swarm模式; 加入Swarm集羣; 配置集羣參數
docker node 查詢集羣節點信息; 提升/移除一個管理節點; 管理swarm節點主機
docker service 創建管理 service
可以查看docker --help
創建 Swarm集羣
在node1上初始化swram集羣:
注意 你只需要在一個node1上初始化swarm集羣, 其他node加入這個集羣就行了, 所以以下命令只需要在node1上運行.
解釋:根據如上命令的提示:
我們的其他節點服務器,以worker角色加入swarm集羣需要登錄到服務器運行如下命令:
以manager角色加入swarm集羣:
--advertise-addr參數, 後面跟你swarm集羣的通訊地址, 也就是node1的地址.
查看端口號監聽情況
檢查node1 docker swarm mode信息:
查看swarm集羣node列表
可以看到,我們的swarm集羣中只有一個節點.現在我們把其他節點加入我們的集羣中:
把其他節點加入集羣中:
注: 如果你不記得上面提示的加入swarm集羣的命令和密鑰可以使用如下方式查看worker節點和manager節點的加入命令
在node1通過ssh, 在node2-node3上執行上面的加入集羣命令:
再次檢查集羣節點列表, 我們可以看到所有的服務器都已經加入swarm集羣了
不過現在集羣只有一個manager節點node1, 爲了swarm集羣的高可用,和避免單點故障. 我們希望建立多個manager節點集羣.
只需要通過如下命令, 提升worker節點成manager節點:並
查看node2的docker info
現在我們可以看到, 已經有2個manager節點了, 一個Leader節點, 一個Reachable節點. 現在你也可以在node2上面管理整個swarm集羣.
我們的swarm集羣就搭建完畢了.
習慣使用docker命令幫助:docker<command> --help
總結:
docker swarm:集羣管理,子命令主要有下面幾個。
dockerswarm init命令用於初始化一個集羣
dockerswarm join命令用於加入一個現有集羣
dockerswarm leave命令由於離開集羣
附:node下線
有些時候需要維護一個節點,此時此節點可能會網絡斷開或者需要關機,造成節點上服務可用。使用docker node update --availability drain <NODE-ID>將節點下線,swarm會將當前節點上的容器關閉並在其他節點上啓動。當維護完成,需要上線是,將節點狀態修改爲active狀態即可,命令如下:docker node update --availability active <NODE-ID>
有了Docker Swarm集羣我們如何把我們的應用跑在Swarm集羣上呢?
很簡單, 基本上原來我們使用docker run的命令創建容器, 把前面替換成docker service create就行了.
建議搭建一個registry,爲所的docker主機提供鏡像下載,否則你需要在每個docker主機本地存在容器鏡像。
所以搭建一個私有倉庫,由私有倉庫提供所需要的鏡像,
本實驗環境中用node2同時作爲registry。
拉取本地私有倉庫registry,查看registry鏡像
1開啓路由轉發
vi /etc/sysctl.cof
添加net.ipv4.ip_forward=1
執行sysctl -p使修改生效
2 將registry2.tar導入到本地,並查看
Registry1和registry2版本的區別
1 registry1是python語言寫的,而現在registry2版本即docker distribution更加安全和快速,並且是用go語言寫的。
基於私有倉庫鏡像運行容器
2默認情況下,registry2會將倉庫存放於容器的/var/lib/registry目錄下,這樣如果容器被刪除,則存放於容器中的鏡像也會丟失,所以我們一般情況下會指定本地一個目錄掛載到容器的/var/lib/registry下,兩個目錄下都有!
·registry的默認存儲路徑是/var/lib/registry,只是個臨時目錄,一段時間之後就會消失
·所以使用-v參數,指定個本地持久的路徑,
返回{"repositories":[]} 說明registry服務工作正常.
注:鏡像信息存放在/var/lib/registry目錄下,因此這裏將宿主機目錄映射到/var/lib/registry
私有倉庫已搭建完畢
所有主機都指向registry服務器:(以node1爲例,其他兩臺主機作相同的配置)
停止docker服務
重載docker服務並啓動docker服務
測試本地鏡像倉庫
有了本地鏡像倉庫registry, 現在我們推送一個測試鏡像到本機鏡像倉庫, 測試下registry服務.
測試:在node1主機上推送鏡像到registry
如果想把鏡像推送到本地registry.
需要先tag這個鏡像的名字成<registry>/<image name>:<tag>,並查看鏡像
將tag後的鏡像上傳到registry.
push成功後, 可以調用registry API查看 registry中的鏡像
在node3主機測試從registry下載鏡像,並查看
overlay網絡
解決了鏡像構建問題, 爲了讓應用跑在swram集羣上,我們還需要解決容器間的網絡訪問問題.
單臺服務器的時候我們應用所有的容器都跑在一臺主機上, 所以容器之間的網絡是互通的. 現在我們的集羣有3臺主機, 所以docker應用的服務會分佈在這3臺主機上.
如何保證不同主機上的容器網絡互通呢?
swarm集羣已經幫我們解決了這個問題了,就是隻用overlay network.
在docker 1.12以前, swarm集羣需要一個額外的key-value存儲(consul, etcdetc). 來同步網絡配置, 保證所有容器在同一個網段中.
在docker 1.12已經內置了這個存儲, 集成了overlay networks的支持.
下面我們演示下如何創建一個 overlay network:
注:swarm上默認已有一個名爲ingress的overlay 網絡, 可以直接使用, 但本文會創建一個新的
爲我們的docker應用創建一個名爲dockercoins的overlay network
查詢docker network 列表
在網絡列表中你可以看到dockercoins網絡的SCOPE是swarm, 表示該網絡在整個swarm集羣生效的, 其他一些網絡是local, 表示本機網絡.
你只需要在manager節點創建network, swarm集羣會自動處理配置到其他的節點,這是你可以查看其他節點的network. dockercoins網絡已經都創建了.:
注:一旦新的任務被指定給這個節點,Overlay網絡就會被按需創建。
在swarm集羣上運行docker應用
概念解釋:service
Docker1.12 swarm引入了服務的概念,一個服務由多個任務組成,一個任務即一個運行的容器。
服務包括兩種類型:
複製服務(replicated services):類似 k8s 中複製集的概念,保持一定數量的相同任務在集羣中運行;
全局服務(global services):類似 k8s 中 daemon 的概念,每個工作節點上運行一個。
發佈服務:
下面我們可以使用之前push到本地鏡像倉庫的鏡像啓動服務, 以centos:http爲例:
以複製服務類型運行服務
在manager上執行如下命令:
docker service create命令創建一個 service.
--name標籤命名service爲web1.
--replicas標籤來聲明1個運行實體(即容器副本數)
注意, 我們啓動的鏡像名字192.168.1.104:5000/centos:http使用我們本地鏡像倉庫的鏡像名稱, 這樣當主機上沒有這個鏡像時, 會自動到本地鏡像倉庫拉取鏡像.
使用docker service ls查看服務
docker service inspect命令用戶查看service詳細信息
使用docker service ps <SERVICE-ID/NAME>查看服務運行在哪個節點上
現在你可以用瀏覽器訪問http://192.168.1.104:8000 就能訪問測試頁
事實上, 你可以訪問swarm集羣中的所有節點 192.168.1.105、192.168.1.113的8000端口, 都可以訪問測試頁。(注:將firewall防火牆默認區域設置爲trusted)
在manager上執行如下命令:
--replicas標籤來聲明2個運行實體
查看服務:(需等待一會,纔會顯示REPLICAS)
從上圖可以看到web2名稱的service有2個副本分別運行在node2和node3節點上。
以全局服務類型運行服務
從下圖可以看到服務web4在每個節點上都運行一個
下面我們擴展舊的服務,從下圖可以看到web1 service目前只有一個副本
擴展已有的服務的副本數,這裏將web1服務擴展到3個副本
縮減已有的服務的副本數,這裏將web1服務縮減到2個副本
Swarm節點是自組織(self-organizing)和自修復(self-healing)的,什麼意思?只要有節點或容器宕掉,swarm engine就會嘗試修復,下面我們來具體看一下
自修復(self-healing)
經過上面的操作之後,我們有以下3個節點:
運行着3個服務共7個任務(容器)
Node2節點上運行着容器3個容器還有一個私有倉庫註冊服務器容器
Node1節點上運行着容器2個容器
Node3節點上運行着容器2個容器
現在我們讓node3上的容器都宕掉或部分宕掉
一旦node3上所有容器停止,Docker就會試圖在相同的節點上啓動2個不同ID的容器。
這就是Docker Swarm Engine的self-healing功能。
在node3節點上執行docker ps查看
Self-Organizing
現在我們讓node3整個宕掉,node3上的容器會自動在其它節點上啓動。
在manager節點上執行docker server ps 服務名
總結:docker swarm 既能實現容器的高可用,也能實現負載均衡