2019独角兽企业重金招聘Python工程师标准>>>
我用Docker的前世今生
集成环境
在开发中,集成环境是最快捷的环境搭建方式,可以说是开箱即用。并且扩展方便????让人欲罢不能。
虚拟机
后来因为生产环境是Linux系统,而开发环境是Win系统,两者差距较大,常常引爆开发与运维大战。
最终为了世界和平,我就使用了虚拟机来进行开发,模拟生产环境,同时走上了运维之路???
Vagrant
又过了五百年,开发人员急增,开发环境各异,每个开发工程师都需要针对不同的项目进行环境搭建,1个人消耗1个工时,100个人就消耗100个工时。同时开发和运维大战更加激烈了。所以引入了Vagrant来维护世界和平,减少重复工作。
st=>start: 开始:>
e=>end: 结束:>
op1=>operation: 制作开发镜像包
op2=>operation: 所有开发者拉起镜像
op3=>operation: 开发
st->op1->op2->op3->e
完美维护了世界和平
容器技术
针对中大型项目,往往为了性能负载等方面,需要对业务进行分布式及集群部署,一旦出现问题,开发就说运维的问题,运维就说开发的问题。而运维没法对代码进行调试,而开发没法对生产环境进行调试,最终导致困难重重。而Docker很好的模拟了生产环境,甚至一模一样。
后来越来越多的问题出现了:
大型应用分布式的需要多虚拟机来测试,宿主机承受不了。
Note left of 以前: N台废旧机器或装N个虚拟机
以前-->现在: 测试分布式或集群
Note right of 现在: N个容器
环境需要自己安装编译部署,常因为各种扩展浪费时间。
Note left of 以前: 装系统,逐个安装
以前-->现在: 开发、测试、预发布、生产各种环境
Note right of 现在: 写好编排文件,一个命令
应用都部署在一个虚拟机中,没有很好的隔离,常因一个应用影响到其它应用的环境
Note left of 以前: mysql、redis等等都在一起
以前-->现在: 机器有限
Note right of 现在: 一个服务就是一个容器,可横向扩展
因生产环境的差异性,还是时常出现执行结果不一致的情况
Note left of 以前: 开发者无法保证和生产环境一致
以前-->现在: win上开发 linux上部署
Note right of 现在: 同样的编排,保证了环境的高度一致
安装Docker并安装加速器
Centos安装
#安装Docker
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
#安装加速器
sudo sed -i "s|ExecStart=/usr/bin/dockerd|ExecStart=/usr/bin/dockerd --registry-mirror=https://qxx96o44.mirror.aliyuncs.com|g" /etc/systemd/system/docker.service
sudo systemctl daemon-reload
sudo service docker restart
Ubuntu安装
#安装Docker
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
#安装加速器
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/mirror.conf <<-'EOF'
[Service]
ExecStart=/usr/bin/docker daemon -H fd:// --registry-mirror=https://9il63lzw.mirror.aliyuncs.com
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Mac安装
对于10.10.3以下的用户 推荐使用 Docker Toolbox
Toolbox的介绍和帮助:mirrors.aliyun.com/help/docker-toolbox
Mac系统的安装文件目录:http://mirrors.aliyun.com/docker-toolbox/mac/docker-toolbox/对于10.10.3以上的用户 推荐使用 Docker for Mac
Mac系统的安装文件目录:http://mirrors.aliyun.com/docker-toolbox/mac/docker-for-mac/创建一台安装有Docker环境的Linux虚拟机,指定机器名称为default,同时配置Docker加速器地址。
docker-machine create --engine-registry-mirror=https://9il63lzw.mirror.aliyuncs.com -d virtualbox default
- 查看机器的环境配置,并配置到本地,并通过Docker客户端访问Docker服务。
docker-machine env default
eval "$(docker-machine env default)"
docker info
Windows安装
对于Windows 10以上的用户 推荐使用 Docker for Windows
Windows系统的安装文件下载:http://mirrors.aliyun.com/docker-toolbox/windows/docker-for-windows/对于Windows 10以下的用户 推荐使用 Docker Toolbox
Toolbox的介绍和帮助:mirrors.aliyun.com/help/docker-toolbox
Windows系统的安装文件目录:http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/创建一台安装有Docker环境的Linux虚拟机,指定机器名称为default,同时配置Docker加速器地址。
docker-machine create --engine-registry-mirror=https://9il63lzw.mirror.aliyuncs.com -d virtualbox default
- 查看机器的环境配置,并配置到本地,并通过Docker客户端访问Docker服务。
docker-machine env default
eval "$(docker-machine env default)"
docker info
Docker基础
搜索可用容器镜像
- 命令模式搜索
docker search nginx #搜索nginx镜像
网页模式搜索
官网的hub :https://hub.docker.com/
daocloud : http://www.daocloud.io/
下载容器镜像
根据上面搜索出来的镜像,你可以pull下来,比如下载nginx镜像:
docker pull nginx
这里的一个镜像是由3层组成:e6e142a99202、b6268bec1a4d、677a76dde9c6
- docker 的层级结构】
- 什么是docker的层
kernel镜像(Linxu 核心文件)-> centos基础镜像文件: 通过各种修改编译
centos基础镜像文件->nginx镜像: 安装nginx
nginx镜像-->Proxy镜像: 配置proxy
假设:
kernel镜像:20M
centos镜像:80M
nginx镜像:100M
proxy镜像:120M
那么下载一个proxy镜像的话,其实下载了120M. 下载四个镜像其实还是120M
docker容器中运行hello world!
docker run learn/tutorial echo "hello word"
在容器中安排新的程序
docker run learn/tutorial apt-get install -y ping
保存新的镜像
docker commit 02b xierikai/alpine
发布自己的镜像
可以是docker hub官网,也可以是阿里云容器镜像平台,也可以是自己搭建的Docker Registry
Dockerfile

Dockerfile是制作镜像的利器。它可以帮助我们生成合适自己的镜像。
结构
DockerFile分为四部分组成:基础镜像信、维护者信息、镜像操作指令和容器启动时执行指令
#第一行必须指令基于的基础镜像
From ubutu
#维护者信息
MAINTAINER xierikai [email protected]
#镜像的操作指令
RUN apt-get update && apt-get install -y ngnix
RUN echo "\ndaemon off;">>/etc/ngnix/nignix.conf
#容器启动时执行指令
CMD /usr/sbin/ngnix
指令
From指令
DockerFile第一条必须为From指令。如果同一个DockerFile创建多个镜像时,可使用多个From指令(每个镜像一次)
MAINTAINER
格式为maintainer ,指定维护者的信息
RUN
在docker 一个RUN生成一个镜像层
CMD指令
支持三种格式:
CMD [“executable” ,”Param1”, “param2”]使用exec执行,推荐
CMD command param1 param2,在/bin/sh上执行
CMD [“Param1”, “param2”] 提供给ENTRYPOINT做默认参数。
每个容器只能执行一条CMD命令,多个CMD命令时,只最后一条被执行。
EXPOSE
格式为 EXPOSE […] 。
告诉Docker服务端容器暴露的端口号,供互联系统使用。在启动Docker时,可以通过-P,主机会自动分配一个端口号转发到指定的端口。使用-P,则可以具体指定哪个本地端口映射过来
例如:
EXPOSE 22 80 8443
ENV
格式为 ENV 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。
例如
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
ADD
该命令将文件复制指定的 到容器中的 。 其中 可以是Dockerfile所在目录的一个相对路径;也可以是一个URL;还可以是一个tar文件(自动解压为目录)
COPY
复制本地主机的 (为Dockerfile所在目录的相对路径)到容器中的 。
当使用本地目录为源目录时,推荐使用 COPY 。
ENTRYPOINT
ENTRYPOINT [“executable”, “param1”, “param2”]
ENTRYPOINT command param1 param2 (shell中执行)
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
每个Dockerfile中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。
VOLUME
格式为 VOLUME [“/data”] 。
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
USER
格式为 USER daemon 。
指定运行容器时的用户名或UID,后续的 RUN 也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。要临时获取管理员权限可以使用 gosu ,而不推荐 sudo 。
WORKDIR
格式为 WORKDIR /path/to/workdir 。
为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。
可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为 /a/b/c 。
ONBUILD
格式为 ONBUILD [INSTRUCTION]
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。
例如,Dockerfile使用如下的内容创建了镜像 image-A 。
docker-compose
DockerFile创建了镜像,但是我们要用好这些镜像,自然需要一些方法把这些镜像组合起来,成为分布式部署或者集群部署我们的系统。
docker-compose.yml 语法说明
build
指定 Dockerfile 所在文件夹的路径。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。
build: /path/to/build/dir
command
覆盖容器启动后默认执行的命令。
command: bundle exec thin -p 3000
links
链接到其它服务中的容器。使用服务名称(同时作为别名)或服务名称:服务别名 (SERVICE:ALIAS) 格式都可以。
links:
- db
- db:database
- redis
使用的别名将会自动在服务容器中的 /etc/hosts 里创建。例如:
172.17.2.186 db
相应的环境变量也将被创建。
external_links
链接到 docker-compose.yml 外部的容器,甚至 并非 Compose 管理的容器。参数格式跟 links 类似。
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
ports
暴露端口信息。
使用宿主:容器 (HOST:CONTAINER)格式或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。
ports:
- "3000"
- "8000:8000"
- "127.0.0.1:8001:8001"
注:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 你可能会得到错误得结果,因为 YAML 将会解析 xx:yy 这种数字格式为 60 进制。所以建议采用字符串格式。
expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数
expose:
- "3000"
- "8000"
volumes
卷挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
volumes_from
从另一个服务或容器挂载它的所有卷。
volumes_from:
- service_name
- container_name
environment
设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取它在 Compose 主机上的值,可以用来防止泄露不必要的数据。
environment:
- RACK_ENV=development
- SESSION_SECRET
WSP项目编排示例
version: '2'
services:
### 反向代理 #############################
nginx-proxy:
image: registry.cn-shenzhen.aliyuncs.com/wsp/proxy
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/proxy
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/proxy
restart: always
privileged: true
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx/ssl/:/etc/nginx/certs:ro
- /etc/localtime:/etc/localtime:ro
### 应用工具 ###########################
workspace:
image: registry.cn-shenzhen.aliyuncs.com/wsp/workspace
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/workspace
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/workspace
restart: always
privileged: true
command: bash /var/www/shell/start/docker.sh
volumes:
- ./logs/shell/:/var/log/shell
- ./logs/cron:/var/log/cron/
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
ports:
- "2322:22"
tty: true
### IM ###########################
phpimr:
image: registry.cn-shenzhen.aliyuncs.com/wsp/php-im
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/php-im
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/php-im
restart: always
privileged: true
command: bash /var/www/shell/chat/phpim.sh -r -all
volumes:
- ./logs/imchat/:/var/log/imchat
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
depends_on:
- nginx-proxy
expose:
- "1235"
tty: true
phpimchatg:
image: registry.cn-shenzhen.aliyuncs.com/wsp/php-im
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/php-im
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/php-im
restart: always
privileged: true
command: bash /var/www/shell/chat/phpim.sh -g -all
depends_on:
- phpimr
volumes:
- ./nginx/ssl/:/etc/nginx/ssl
- ./logs/imchat/:/var/log/imchat
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
ports:
- "7172:7172"
expose:
- "2200"
- "2201"
- "2202"
- "2203"
tty: true
environment:
- VIRTUAL_HOST=worker.yiqizuo.xin
phpimchatw:
image: registry.cn-shenzhen.aliyuncs.com/wsp/php-im
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/php-im
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/php-im
restart: always
privileged: true
command: bash /var/www/shell/chat/phpim.sh -w -all
volumes:
- ./logs/imchat/:/var/log/imchat
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
depends_on:
- phpimchatg
tty: true
links:
- mongo:mongodb
### PHP-FPM Container #######################################
php-fpm:
image: registry.cn-shenzhen.aliyuncs.com/wsp/php-fpm
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/php-fpm
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/php-fpm
restart: always
privileged: true
volumes:
- ./php-fpm/php71.ini:/usr/local/etc/php/php.ini
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
expose:
- "9000"
depends_on:
- workspace
environment:
- YII_ENV=docker
### Nginx Server Container ##################################
nginxback:
image: registry.cn-shenzhen.aliyuncs.com/wsp/nginx
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/nginx
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/nginx
restart: always
privileged: true
volumes:
- ./logs/nginxback/:/var/log/nginx
- ./nginx/nginxback/:/etc/nginx/sites-available
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
depends_on:
- nginx-proxy
- php-fpm
environment:
- VIRTUAL_HOST=backend.yiqizuo.xin
- CERT_NAME=yiqizuo.xin
- VIRTUAL_PORT=80
nginxadmin:
image: registry.cn-shenzhen.aliyuncs.com/wsp/nginx
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/nginx
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/nginx
restart: always
privileged: true
volumes:
- ./logs/nginxadmin/:/var/log/nginx
- ./nginx/nginxadmin/:/etc/nginx/sites-available
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
depends_on:
- nginx-proxy
- php-fpm
environment:
- VIRTUAL_HOST=admin.yiqizuo.xin
- CERT_NAME=yiqizuo.xin
- VIRTUAL_PORT=80
nginxfront:
image: registry.cn-shenzhen.aliyuncs.com/wsp/nginx
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/nginx
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/nginx
restart: always
privileged: true
volumes:
- ./logs/nginxfront/:/var/log/nginx
- ./nginx/nginxfront/:/etc/nginx/sites-available
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
ports:
- "12380:80"
depends_on:
- nginx-proxy
- php-fpm
environment:
- VIRTUAL_HOST=frontend.yiqizuo.xin
- CERT_NAME=yiqizuo.xin
- VIRTUAL_PORT=80
nginxres:
image: registry.cn-shenzhen.aliyuncs.com/wsp/nginx
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/nginx
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/nginx
restart: always
privileged: true
volumes:
- ./logs/nginxres/:/var/log/nginx
- ./nginx/nginxres/:/etc/nginx/sites-available
- ../:/var/www
- /etc/localtime:/etc/localtime:ro
depends_on:
- nginx-proxy
- php-fpm
environment:
- VIRTUAL_HOST=resource.yiqizuo.xin
- CERT_NAME=yiqizuo.xin
- VIRTUAL_PORT=80
### MySQL Container #########################################
mysql:
image: registry.cn-shenzhen.aliyuncs.com/wsp/mysql
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/mysql
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/mysql
restart: always
privileged: true
environment:
- MYSQL_DATABASE=数据库名
- MYSQL_USER=新创建用户
- MYSQL_PASSWORD=新用户米娜
- MYSQL_ROOT_PASSWORD=root用户密码
volumes:
- ./data/mysql:/var/lib/mysql
- ./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
### MongoDB Container #######################################
mongo:
image: registry.cn-shenzhen.aliyuncs.com/wsp/mongo
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/mongo
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/mongo
restart: always
privileged: true
ports:
- "27017:27017"
volumes:
- ./data/mongo:/data/db
- ./logs/mongo:/var/log/mongodb/
- /etc/localtime:/etc/localtime:ro
### Redis Container #########################################
redis:
image: registry.cn-shenzhen.aliyuncs.com/wsp/redis
#image: registry-internal.cn-shenzhen.aliyuncs.com/wsp/redis
#image: registry-vpc.cn-shenzhen.aliyuncs.com/wsp/redis
restart: always
privileged: true
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./data/redis:/data
- ./redis/redis:/usr/local/etc/redis
- ./logs/redis:/var/log/redis
- /etc/localtime:/etc/localtime:ro
ports:
- "63790:6379"
environment:
- appendonly=yes
scale实现横向扩展
经典方式实现WEB集群负载均衡
docker实现集群横向扩展(一个scale命令即可)
活动高峰,需要扩展服务器性能
图片可以看出已经实现自动反向代理
扩展知识
通过docker-compose编排我们可以实现容器的控制,搭建分布式系统。但是都是基于单台物理机器的。当单台物理机器出现性能瓶颈时,我们往往需要多台物理机器组建集群,来实现更高的性能。
使用 swarm 实现集群
2、环境说明:
Master/nfs服务器:192.168.63.217
Worker:192.168.63.217
Worker:192.168.63.216
3、创建一个nfs挂载目录,用于存放wordpress代码(63.217):
[root@master ~]#yum install -y nfs-utils
[root@master ~]## cat /etc/exports
/web 192.168.63.0/24(rw,sync,fsid=0)
[root@master ~]#systemctl enable rpcbind.service
[root@master ~]#systemctl enable nfs-server.service
[root@master ~]#systemctl start rpcbind.service
[root@master ~]#systemctl start nfs-server.service
4、挂载/web目录(worker):
[root@node2 ~]#yum install -y nfs-utils
[root@node2 ~]#systemctl enable rpcbind.service
[root@node2 ~]#systemctl start rpcbind.service
[root@webstatus ~]# mount192.168.63.217:/web /web
5、构建Docker swarm集群63.217操作:
[root@master~]# docker swarm init --advertise-addr 192.168.63.217
To add a worker to this swarm, run the following command:
docker swarm join \
--tokenSWMTKN-1-37fe5tarzcy50mazbe1e3ewyblkfk7xf9kx9ncanz0wx3q70e1-a7wn9tiepd114if6smuiqlez3\
192.168.63.217:2377
6、在worker节点上面操作,加入这个集群:
[root@node2 ~]#docker swarm join --token SWMTKN-1-37fe5tarzcy50mazbe1e3ewyblkfk7xf9kx9ncanz0wx3q70e1-a7wn9tiepd114if6smuiqlez3 192.168.63.217:2377
7、查看集群的节点状态:
[root@master wordpress]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
e9naz0ctzaaer4bwleruo34x6 * master Ready Active Leader
rfcbavxd8yrixximm9e1i6dsn node1 Ready Active
shrzku0k3xx87526lkkkyrxsi node2 Ready Active
8、为了使得Docker swarm集群容器互相通讯,我们先创建一个overlay网络:
[root@master docker]# docker network create --driver overlaynginx_network
9、随机创建调度一个9000端口的Php service运行Docker容器:
[root@masterwordpress]# docker service create --mount type=bind,source=/web/,target=/web/--network nginx_network --name php -p 9000:9000192.168.63.217:5000/lnmp/php:1.0
[root@masterwordpress]# docker service ls
ID NAME MODE REPLICAS IMAGE
ira3ezabroai php replicated 1/1 192.168.63.217:5000/lnmp/php:1.0
10、启动nginx service:
[root@masterwordpress]#docker service create --mount type=bind,source=/web/,target=/web/ --network nginx_network --name web -p 80:80 192.168.63.217:5000/lnmp/nginx:1.0
11、再启动mysql service:
[root@masterwordpress]# docker service create --mounttype=bind,source=/data/,target=/var/lib/mysql/ --network nginx_network --namemysql -p 3306:3306 192.168.63.217:5000/lnmp/mysql:1.0
12、我们也可以在复制出一个web service:
[root@master wordpress]# docker servicescale web=2
web scaled to 2
13、看一下我们的容器到底运行在哪个linux主机上呢:
[root@master wordpress]# docker service ls
ID NAME MODE REPLICAS IMAGE
ira3ezabroai php replicated 1/1 192.168.63.217:5000/lnmp/php:1.0
kcxqzxwe0dzb mysql replicated 1/1 192.168.63.217:5000/lnmp/mysql:1.0
ufn1n5phtsqn web replicated 2/2 192.168.63.217:5000/lnmp/nginx:1.0
[root@master wordpress]# docker service ps php
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ptxokpvq1b7s php.1 192.168.63.217:5000/lnmp/php:1.0 master Running Running 5 minutes ago
[root@master wordpress]# docker service ps mysql
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zowbxqnr9toi mysql.1 192.168.63.217:5000/lnmp/mysql:1.0 node2 Running Running 2 minutes ago
[root@master wordpress]# docker service ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
vhk44hij7gnu web.1 192.168.63.217:5000/lnmp/nginx:1.0 node1 Running Running 3 minutes ago
u1vdnr0ujzl7 web.2 192.168.63.217:5000/lnmp/nginx:1.0 node2 Running Running about a minute ago
14、我们已经确认所有的容器都已经起起来并且正常运行了,访问一下web就可以进行80端口的访问了,192.168.63.217:
15、为了测试高可用性,我们把node1节点关闭掉,看容器是否转移:
我们在node1执行关闭docker:
[root@node1 web]# systemctl stop docker
16、在master节点上查看一下状态:
[root@master web]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
e9naz0ctzaaer4bwleruo34x6 * master Ready Active Leader
rfcbavxd8yrixximm9e1i6dsn node1 Down Active
shrzku0k3xx87526lkkkyrxsi node2 Ready Active
17、我们可以看到node1节点已经Down,然后我们的Docker 容器也已经转移到了别的worker节点上:
[root@master web]# docker service ps php
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ptxokpvq1b7s php.1 192.168.63.217:5000/lnmp/php:1.0 master Running Running 18 minutes ago
[root@master web]# docker service ps mysql
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zowbxqnr9toi mysql.1 192.168.63.217:5000/lnmp/mysql:1.0 node2 Running Running 15 minutes ago
[root@master web]# docker service ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
jqcuqzjdgi9y web.1 192.168.63.217:5000/lnmp/nginx:1.0 master Running Running 2 minutes ago
vhk44hij7gnu \_web.1 192.168.63.217:5000/lnmp/nginx:1.0 node1 Shutdown Running 2 minutes ago
u1vdnr0ujzl7 web.2 192.168.63.217:5000/lnmp/nginx:1.0 node2 Running Running 14 minutes ago
我们可以看到在node1节点上之前运行的容器已经shutdown了,然后转移到了master和node2上,再次访问也是不影响的:
配合Docker compose v3实现集群
1、存在了Docker swarm集群:
[root@master ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
e9naz0ctzaaer4bwleruo34x6 * master Ready Active Reachable
rfcbavxd8yrixximm9e1i6dsn node1 Ready Active Leader
shrzku0k3xx87526lkkkyrxsi node2 Ready Active Reachable
2、Docker 版本要求是1.13以上的版本
[root@master ~]# docker version
Client:
Version: 17.04.0-ce
API version: 1.28
Go version: go1.7.5
Git commit: 4845c56
Built: Mon Apr 3 18:01:50 2017
OS/Arch: linux/amd64
Server:
Version: 17.04.0-ce
API version: 1.28 (minimum version 1.12)
Go version: go1.7.5
Git commit: 4845c56
Built: Mon Apr 3 18:01:50 2017
OS/Arch: linux/amd64
Experimental: false
3、基于之前的镜像我们构建时候非常简单,直接编写compose文件即可
[root@master stack]# cat compose_wordpress.yml
version: '3'
services:
php:
image: 192.168.63.217:5000/lnmp/php:1.0
volumes:
- /web:/web
ports:
- 9000:9000
nginx:
image: 192.168.63.217:5000/lnmp/nginx:1.0
ports:
- 80:80
volumes:
- /web:/web
depends_on:
- mysql
deploy:
replicas: 3
restart_policy:
condition: on-failure
mysql:
image: 192.168.63.217:5000/lnmp/nginx:1.0
ports:
- 3306:3306
volumes:
- /data:/var/lib/mysql
restrat_policy:表示重启条件,我们定义是错误重启。
4、开始构建
[root@master stack]# docker stack deploy -c compose_wordpress.yml wordpress
Creating network wordpress_default
Creating service wordpress_php
Creating service wordpress_nginx
Creating service wordpress_mysql
##构建时候可以看到创建一个wordpress_default这样一个overlay网络:
[root@master stack]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e1608d2e6f7d bridge bridge local
5de3863d8bf9 docker_gwbridge bridge local
c97de54d6fcc dockercompose_default bridge local
080a6647873b host host local
wdqd0cye6t5h wordpress_default overlay swarm
5、我们查看一下相关的stack状态
[root@master stack]# docker stack services wordpress
ID NAME MODE REPLICAS IMAGE
hx5zabzybbny wordpress_php replicated 1/1 192.168.63.217:5000/lnmp/php:1.0
me5s3v37tzsw wordpress_nginx replicated 3/3 192.168.63.217:5000/lnmp/nginx:1.0
txz5xzgnkjbc wordpress_mysql replicated 1/1 192.168.63.217:5000/lnmp/nginx:1.0
6、可以看到worepress 这个调度的stack已经起起来了,因为是与Docker swarm结合,所以我们也可以用Docker swarm 形式来查看和管理
[root@master stack]# docker service ls
ID NAME MODE REPLICAS IMAGE
hx5zabzybbny wordpress_php replicated 1/1 192.168.63.217:5000/lnmp/php:1.0
me5s3v37tzsw wordpress_nginx replicated 3/3 192.168.63.217:5000/lnmp/nginx:1.0
txz5xzgnkjbc wordpress_mysql replicated 1/1 192.168.63.217:5000/lnmp/nginx:1.0
[root@master stack]# docker service ps wordpress_nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
9pcbe6zvjoa5 wordpress_nginx.1 192.168.63.217:5000/lnmp/nginx:1.0 master Running Running 4 minutes ago
ode397gc036g wordpress_nginx.2 192.168.63.217:5000/lnmp/nginx:1.0 node2 Running Running 4 minutes ago
76tznesy3bm8 wordpress_nginx.3 192.168.63.217:5000/lnmp/nginx:1.0 node1 Running Running 4 minutes ago
7、都起起来了,我们访问一下web界面看一下服务是否正常:
使用kubernetes实现集群
kubernetes在docker集群管理中也是目前非常?的一个工具,有兴趣的同学可以自己去进行了解。