DevOps第二讲:用Docker部署你的环境

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

我用Docker的前世今生

集成环境

在开发中,集成环境是最快捷的环境搭建方式,可以说是开箱即用。并且扩展方便????让人欲罢不能。

DevOps第二讲:用Docker部署你的环境_第1张图片

虚拟机

后来因为生产环境是Linux系统,而开发环境是Win系统,两者差距较大,常常引爆开发与运维大战。

DevOps第二讲:用Docker部署你的环境_第2张图片

最终为了世界和平,我就使用了虚拟机来进行开发,模拟生产环境,同时走上了运维之路???

Vagrant

又过了五百年,开发人员急增,开发环境各异,每个开发工程师都需要针对不同的项目进行环境搭建,1个人消耗1个工时,100个人就消耗100个工时。同时开发和运维大战更加激烈了。所以引入了Vagrant来维护世界和平,减少重复工作。

st=>start: 开始:>
e=>end: 结束:>
op1=>operation: 制作开发镜像包
op2=>operation: 所有开发者拉起镜像
op3=>operation: 开发
st->op1->op2->op3->e

DevOps第二讲:用Docker部署你的环境_第3张图片

完美维护了世界和平

容器技术

针对中大型项目,往往为了性能负载等方面,需要对业务进行分布式及集群部署,一旦出现问题,开发就说运维的问题,运维就说开发的问题。而运维没法对代码进行调试,而开发没法对生产环境进行调试,最终导致困难重重。而Docker很好的模拟了生产环境,甚至一模一样。

DevOps第二讲:用Docker部署你的环境_第4张图片

后来越来越多的问题出现了:

大型应用分布式的需要多虚拟机来测试,宿主机承受不了。
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镜像

DevOps第二讲:用Docker部署你的环境_第5张图片

  • 网页模式搜索

    官网的hub :https://hub.docker.com/
    daocloud : http://www.daocloud.io/

DevOps第二讲:用Docker部署你的环境_第6张图片

下载容器镜像

根据上面搜索出来的镜像,你可以pull下来,比如下载nginx镜像:

docker pull nginx

这里的一个镜像是由3层组成:e6e142a99202、b6268bec1a4d、677a76dde9c6

  • docker 的层级结构】

DevOps第二讲:用Docker部署你的环境_第7张图片

  • 什么是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

DevOps第二讲:用Docker部署你的环境_第8张图片

保存新的镜像

docker commit 02b xierikai/alpine

发布自己的镜像

  1. docker images命令可以列出所有安装过的镜像。
    DevOps第二讲:用Docker部署你的环境_第9张图片

  2. docker push命令可以将某一个镜像发布到官方网站。

可以是docker hub官网,也可以是阿里云容器镜像平台,也可以是自己搭建的Docker Registry

Dockerfile

DevOps第二讲:用Docker部署你的环境_第10张图片
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项目编排示例

DevOps第二讲:用Docker部署你的环境_第11张图片

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集群负载均衡

DevOps第二讲:用Docker部署你的环境_第12张图片

docker实现集群横向扩展(一个scale命令即可)

活动高峰,需要扩展服务器性能
DevOps第二讲:用Docker部署你的环境_第13张图片
图片可以看出已经实现自动反向代理
DevOps第二讲:用Docker部署你的环境_第14张图片

活动结束,节约性能用于其它系统

扩展知识

通过docker-compose编排我们可以实现容器的控制,搭建分布式系统。但是都是基于单台物理机器的。当单台物理机器出现性能瓶颈时,我们往往需要多台物理机器组建集群,来实现更高的性能。

使用 swarm 实现集群

1、如下拓扑:
DevOps第二讲:用Docker部署你的环境_第15张图片

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:
DevOps第二讲:用Docker部署你的环境_第16张图片

DevOps第二讲:用Docker部署你的环境_第17张图片

DevOps第二讲:用Docker部署你的环境_第18张图片

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上,再次访问也是不影响的:
DevOps第二讲:用Docker部署你的环境_第19张图片

配合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界面看一下服务是否正常:
DevOps第二讲:用Docker部署你的环境_第20张图片

使用kubernetes实现集群

kubernetes在docker集群管理中也是目前非常?的一个工具,有兴趣的同学可以自己去进行了解。

转载于:https://my.oschina.net/596868636/blog/1480069

你可能感兴趣的:(DevOps第二讲:用Docker部署你的环境)