1委煤、單機(jī)多容器部署
在之前的章節(jié)中我們已經(jīng)對(duì)Docker有了初步的認(rèn)知,知道如何去部署項(xiàng)目修档,如何實(shí)現(xiàn)多容器的通信碧绞。但是大家應(yīng)該也體會(huì)到了部署容器時(shí)的繁瑣。每部署一個(gè)容器都需要很多的命令去操作吱窝,容器多了之后我們都不記得這個(gè)容器是加了什么參數(shù)了讥邻,而且也需要花費(fèi)較多的時(shí)間去部署,如果能像寫配置文件一樣去維護(hù)多個(gè)容器院峡,那一定很方便兴使。
接下來要說的 Docker Compose 就是用來解放我們的雙手的,通過配置 yaml 文件去實(shí)現(xiàn)容器的部署照激,只需要配幾個(gè)參數(shù)就能做到多容器的配置发魄、通信和維護(hù)了。
-
Docker Compose
-
安裝
如果是Mac或者Windows系統(tǒng)实抡,在安裝了Docker的時(shí)候就已經(jīng)內(nèi)置了Docker Compose了欠母,如果是Linux系統(tǒng),則需要手動(dòng)安裝。
-
# 第一步 sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 第二步 sudo chmod +x /usr/local/bin/docker-compose
-
示例
-
創(chuàng)建目錄
$ mkdir composetest $ cd composetest
-
創(chuàng)建 app.py 文件
import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\n'.format(count)
-
創(chuàng)建 requirements.txt 文件
flask redis
-
編寫Dockerfile
FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . CMD ["flask", "run"]
-
編寫docker-compose.yml
version: '3' # docker-compose的版本 services: web: # 構(gòu)建一個(gè)容器,名為 web build: . # 使用本地Dockerfile構(gòu)建 ports: # 端口映射 - "5000:5000" redis: # 構(gòu)建一個(gè)容器,名為 redis image: "redis:alpine" # 從遠(yuǎn)端倉(cāng)庫(kù)拉取
-
運(yùn)行docker-compose
- 默認(rèn)會(huì)尋找當(dāng)前目錄下的 docker-compose.yml
- 如果要指定名稱則加
-f xxx.yml
參數(shù)
[root@10 composetest]# docker-compose up -d
-
測(cè)試功能
每訪問一次頁(yè)面捻勉,都會(huì)調(diào)用 Redis 的 increment 遞增訪問次數(shù)柒莉。
image.png
-
-
docker-compose.yml文件 參數(shù)介紹
-
version: '3'
- 表示docker-compose的版本
-
services
- 一個(gè)service表示一個(gè)container
-
networks
- 相當(dāng)于docker network create app-net
-
volumes
- 相當(dāng)于
-v v1:/var/lib/mysql
- 相當(dāng)于
-
image
- 表示使用哪個(gè)鏡像,要從遠(yuǎn)端拉取
-
build
- 表示使用本地Dockerfile構(gòu)建鏡像
-
ports
- 相當(dāng)于 -p 8080:8080
-
environment
- 相當(dāng)于 -e
-
-
docker-compose常見操作
- 查看版本
- docker-compose version
- 根據(jù) yml 創(chuàng)建service
- docker-compose up
- 指定 yaml:docker-compose up -f xxx.yaml
- 后臺(tái)運(yùn)行:docker-compose up -d
- 查看啟動(dòng)成功的service
- docker-compose ps
- 也可以使用 docker ps
- 查看images
- docker-compose images
- 停止/啟動(dòng)service
- docker-compose stop/start
- 刪除service[同時(shí)會(huì)刪除掉network和volume]
- docker-compose down
- 進(jìn)入到某個(gè)service
- docker-compose exec redis sh
- 查看版本
-
scale擴(kuò)縮容
-
準(zhǔn)備 docker-compose.yml 文件饶米,注意去除 ports 參數(shù),防止端口沖突
version: '3' services: web: build: . networks: - app-net redis: image: "redis:alpine" networks: - app-net networks: app-net: driver: bridge
-
創(chuàng)建 service 容器
- docker-compose up -d
-
對(duì) web 容器進(jìn)行擴(kuò)縮容
- docker-compose up --scale web=5 -d
- 表示增加 web 容器數(shù)量到 5
-
查看容器
- docker-compose ps
-
2凰盔、多機(jī)多容器部署
Docker Compose只是能在單機(jī)下對(duì)容器進(jìn)行管理辣卒,如果涉及到多臺(tái)宿主機(jī)它就沒辦法了掷贾,這時(shí)就需要另一個(gè)技術(shù)Docker Swarm。
Docker Swarm可以實(shí)現(xiàn)多機(jī)下的容器管理荣茫、通信與編排想帅,不過這里也是不會(huì)講太多,因?yàn)楝F(xiàn)在的容器編排主流是 Kubernetes啡莉!
-
Docker Swarm
-
安裝
任意平臺(tái)下安裝過Docker就已經(jīng)內(nèi)置了Docker Swarm了港准,所以無需安裝
但是我們需要準(zhǔn)備多臺(tái)機(jī)器去測(cè)試多機(jī)部署,這里我們用虛擬機(jī)代替
-
使用vagrantfile來安裝多臺(tái)虛擬機(jī)
boxes = [ { :name => "manager-node", :eth1 => "192.168.50.111", :mem => "1024", :cpu => "1" }, { :name => "worker01-node", :eth1 => "192.168.50.112", :mem => "1024", :cpu => "1" }, { :name => "worker02-node", :eth1 => "192.168.50.113", :mem => "1024", :cpu => "1" } ] Vagrant.configure(2) do |config| config.vm.box = "centos/7" boxes.each do |opts| config.vm.define opts[:name] do |config| config.vm.hostname = opts[:name] config.vm.provider "vmware_fusion" do |v| v.vmx["memsize"] = opts[:mem] v.vmx["numvcpus"] = opts[:cpu] end config.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--memory", opts[:mem]] v.customize ["modifyvm", :id, "--cpus", opts[:cpu]] v.customize ["modifyvm", :id, "--name", opts[:name]] end config.vm.network :public_network, ip: opts[:eth1] end end end
-
一次構(gòu)建多節(jié)點(diǎn)的情況下咧欣,通過vagrant ssh [node name]進(jìn)入虛擬機(jī)
vagrant ssh [manager-node / worker01-node / worker02-node]
初始化步驟浅缸、配置xshell連接與第一章節(jié)一致,這里不細(xì)講了
在每臺(tái)虛擬機(jī)中安裝Docker
-
搭建Swarm集群
-
在 manager 節(jié)點(diǎn)中初始化集群配置
[root@10 ~]# docker swarm init --advertise-addr=192.168.50.111 Swarm initialized: current node (rf5m8pyx7w7i2tutxumspn3ph) is now a manager. To add a worker to this swarm, run the following command: # 這段命令是需要到worker節(jié)點(diǎn)執(zhí)行,表示加入集群 docker swarm join --token SWMTKN-1-3wwhsp6boxd5damm9f549v21eshj5cdkuu97xmz6vo1pkvuhrr-6wtpwh1ewl3ib3ryr9j5dayzc 192.168.50.111:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
-
worker 節(jié)點(diǎn)加入集群
[root@10 ~]# docker swarm join --token SWMTKN-1-3wwhsp6boxd5damm9f549v21eshj5cdkuu97xmz6vo1pkvuhrr-6wtpwh1ewl3ib3ryr9j5dayzc 192.168.50.111:2377 This node joined a swarm as a worker.
-
在manager節(jié)點(diǎn)查看集群狀態(tài)
hostname 需要手動(dòng)修改魄咕,默認(rèn)是展示網(wǎng)卡ip的衩椒,比如:hostnamectl set-hostname manager-node
[root@manager-node ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION rf5m8pyx7w7i2tutxumspn3ph * manager-node Ready Active Leader 19.03.7 ncgr8mqhhz47itjqcyhamtn62 worker01-node Ready Active 19.03.7
-
成員節(jié)點(diǎn)類型轉(zhuǎn)換
可以將worker提升成manager,從而保證manager的高可用哮兰,但這個(gè)提升只是讓worker有成為manager的資格毛萌,沒有提升的worker節(jié)點(diǎn)無權(quán)成為manager
[root@manager-node ~]# docker node promote ncgr8mqhhz47itjqcyhamtn62 Node ncgr8mqhhz47itjqcyhamtn62 promoted to a manager in the swarm. # 現(xiàn)在worker節(jié)點(diǎn)的 manager status變成 Reachable,表示擁有變成Leader的權(quán)限了 [root@manager-node ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION ncgr8mqhhz47itjqcyhamtn62 10.0.2.15 Ready Active Reachable 19.03.7 rf5m8pyx7w7i2tutxumspn3ph * 10.0.2.15 Ready Active Leader 19.03.7 #降級(jí)可以用demote [root@manager-node ~]# docker node demote ncgr8mqhhz47itjqcyhamtn62 Manager ncgr8mqhhz47itjqcyhamtn62 demoted in the swarm. [root@manager-node ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION rf5m8pyx7w7i2tutxumspn3ph * manager-node Ready Active Leader 19.03.7 ncgr8mqhhz47itjqcyhamtn62 worker01-node Ready Active 19.03.7
-
-
-
Docker Swarm常用操作
-
創(chuàng)建一個(gè)tomcat的service
-
docker service create --name my-tomcat tomcat
[root@manager-node ~]# docker service create --name my-tomcat tomcat h9xki026ivexy28r3242izu5g overall progress: 1 out of 1 tasks 1/1: running [==================================================>] # 創(chuàng)建完成后會(huì)使用5秒時(shí)間對(duì)容器的可用性進(jìn)行驗(yàn)證 verify: Waiting 5 seconds to verify that tasks are stable... # 5秒結(jié)束會(huì)變成 Service converged verify: Service converged
-
-
刪除容器
- docker service rm my-tomcat
-
查看當(dāng)前Swarm的service
-
docker service ls
[root@manager-node ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zdf8vgmay2hx my-tomcat replicated 1/1 tomcat:latest
-
-
查看service的啟動(dòng)日志
- docker service logs my-tomcat
-
查看service的詳情
- docker service inspect my-tomcat
-
查看my-tomcat運(yùn)行在哪個(gè)node上
-
docker service ps my-tomcat
# 可以看到容器是創(chuàng)建在manager節(jié)點(diǎn)的 [root@manager-node ~]# docker service ps my-tomcat ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS s83wnalw3xx0 my-tomcat.1 tomcat:latest manager-node Running Running 3 minutes ago
-
-
水平擴(kuò)容service
[root@manager-node ~]# docker service scale my-tomcat=3 my-tomcat scaled to 3 overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged # 可以發(fā)現(xiàn),my-tomcat的service會(huì)分別部署到不同宿主機(jī)中 [root@manager-node ~]# docker service ps my-tomcat ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS s83wnalw3xx0 my-tomcat.1 tomcat:latest manager-node Running Running 7 minutes ago qs8qfoo7ge0n my-tomcat.2 tomcat:latest worker01-node Running Running 28 seconds ago 4m661e5msju9 my-tomcat.3 tomcat:latest worker01-node Running Running 28 seconds ago
如果不用docker service ps喝滞,執(zhí)行docker ps朝聋,會(huì)發(fā)現(xiàn)container的name和service名稱不一樣,這是正常的囤躁,也要注意別搞混了
[root@worker01-node ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 59ea2502ede4 tomcat:latest "catalina.sh run" 10 minutes ago Up 10 minutes 8080/tcp my-tomcat.1.u6o4mz4tj3969a1p3mquagxok
-
如果某個(gè)node上的my-tomcat掛掉了冀痕,這時(shí)候會(huì)自動(dòng)擴(kuò)展
[root@worker01-node ~]# docker rm -f 0e9b5d804c25 # 現(xiàn)在manager上運(yùn)行2個(gè)容器了 [root@manager-node ~]# docker service ps my-tomcat ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS s83wnalw3xx0 my-tomcat.1 tomcat:latest manager-node Running Running 10 minutes ago 1qbunkr1fs5j my-tomcat.2 tomcat:latest manager-node Running Running 6 seconds ago qs8qfoo7ge0n \_ my-tomcat.2 tomcat:latest worker01-node Shutdown Failed 12 seconds ago "task: non-zero exit (137)" 4m661e5msju9 my-tomcat.3 tomcat:latest worker01-node Running Running 3 minutes ago
-
-
多機(jī)通信 overlay 網(wǎng)絡(luò)
-
使用swarm創(chuàng)建容器后,會(huì)自動(dòng)生成一個(gè)overlay的網(wǎng)絡(luò)模式
[root@manager-node ~]# docker network ls NETWORK ID NAME DRIVER SCOPE f707fc44e537 bridge bridge local d2f72fb35175 host host local w5p8g8c4z5sk ingress overlay swarm a2f09c4b5e89 none null local
+ 創(chuàng)建一個(gè)overlay網(wǎng)絡(luò)狸演,用于docker swarm中多機(jī)通信 ```ruby # -d 表示指定網(wǎng)絡(luò)模式類型 [root@manager-node ~]# docker network create -d overlay my-overlay-net wekfq4m34mc5welq5d7xvc6d0 # 此時(shí)worker node查看不到言蛇,只有創(chuàng)建容器且分配到該宿主機(jī)之后才可以看到 [root@worker01-node ~]# docker network ls NETWORK ID NAME DRIVER SCOPE c7f42990d130 bridge bridge local 81a19f795c7e host host local w5p8g8c4z5sk ingress overlay swarm 7356babbeab8 none null local [root@manager-node ~]# docker service create --name my-tomcat --network my-overlay-net tomcat gl90f1frfeae9cutnz0uc7i72 overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged # 擴(kuò)容 [root@10 ~]# docker service scale my-tomcat=3 my-tomcat scaled to 3 overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged # 現(xiàn)在worker節(jié)點(diǎn)可以看到之前在manager節(jié)點(diǎn)創(chuàng)建的overlay網(wǎng)絡(luò)模式了 [root@worker01-node ~]# docker network ls NETWORK ID NAME DRIVER SCOPE c7f42990d130 bridge bridge local 81a19f795c7e host host local w5p8g8c4z5sk ingress overlay swarm wekfq4m34mc5 my-overlay-net overlay swarm 7356babbeab8 none null local
overlay網(wǎng)絡(luò)與brige網(wǎng)絡(luò)模式的區(qū)別就是overlay是多機(jī)多容器之間通信的,brige是單機(jī)多容器通信
通過docker swarm創(chuàng)建的容器宵距,無論訪問哪臺(tái)宿主機(jī)的ip地址腊尚,最終都可以訪問到正確的容器中的項(xiàng)目。如果是使用容器名稱進(jìn)行通信满哪,還會(huì)自動(dòng)做到負(fù)載均衡婿斥。
-
-
docker stack
docker stack與docker-compose其實(shí)是一樣的,compose是單機(jī)容器管理哨鸭,stack是多機(jī)容器管理民宿。
-
新建service.yml文件
version: '3' services: wordpress: image: wordpress ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: exampleuser WORDPRESS_DB_PASSWORD: examplepass WORDPRESS_DB_NAME: exampledb networks: - ol-net volumes: - wordpress:/var/www/html deploy: mode: replicated replicas: 3 restart_policy: condition: on-failure delay: 5s max_attempts: 3 update_config: parallelism: 1 delay: 10s db: image: mysql:5.7 environment: MYSQL_DATABASE: exampledb MYSQL_USER: exampleuser MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - db:/var/lib/mysql networks: - ol-net deploy: mode: global placement: constraints: - node.role == manager volumes: wordpress: db: networks: ol-net: driver: overlay
-
根據(jù)service.yml創(chuàng)建service
# -c 指定配置文件 [root@manager-node swarmtest]# docker stack deploy -c service.yml my-service Creating network my-service_ol-net Creating service my-service_db Creating service my-service_wordpress
-
測(cè)試
- 瀏覽器訪問 [任意節(jié)點(diǎn)的ip]:8080
-
> 可以確認(rèn),無論訪問集群中哪個(gè)節(jié)點(diǎn)的ip像鸡,docker都可以幫助自動(dòng)指向正確的容器
-
docker stack常用操作
- 根據(jù)service.yml創(chuàng)建service
-
docker stack deploy -c service.yml my-service
-
查看stack具體信息
-
docker stack ls
[root@manager-node swarmtest]# docker stack ls NAME SERVICES ORCHESTRATOR my-service 2 Swarm
-
-
查看具體的service
-
docker stack services my-service
[root@manager-node swarmtest]# docker stack services my-service ID NAME MODE REPLICAS IMAGE PORTS 6h3ipjnx32sc my-service_wordpress replicated 0/3 wordpress:latest *:8080->80/tcp cwo60mztuoou my-service_db global 1/1 mysql:5.7
-
-
查看某個(gè)service詳情
- docker service inspect my-service_db
-