docker单机编排docker-compose

docker单机编排docker-compose

简介

官方文档介绍

​ docker-compose为单机版的容器编排工具。

​ 在容器较多的情况下,手动一个个docker run就比较繁琐,且命令行方式无法复用,此时就需要用docker-compse这种编排工具管理多个容器,

​ docker-compse为单机版管理,即只能管理一台docker host上的容器,跨主机即集群级别的编排容器,就需要用到docker-swarm,或kubernetes;

​ docker-compse采用yml文件定义容器的状态,然后dokcer-compose解析文件,并依据其定义运行容器,相比于命令行,可重用性好;

​ habor的组件容器,就是通过docker-compose以及一个yml文件定义的;

安装

https://docs.docker.com/compose/install/

yum安装

​ 配置epel源,yum直接安装即可;

[root@host2 ~]# yum install -y docker-compose
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Package docker-compose-1.18.0-4.el7.noarch already installed and latest version
Nothing to do

[root@host2 ~]# rpm -ql docker-compose


[root@host2 ~]# 
[root@host2 ~]# docker-compose --version
docker-compose version 1.18.0, build 8dd22a9

docker-compose管理容器

语法格式

[root@host3 ~]# docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name (default: directory name)
  --verbose                   Show more output
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to
......

# 一般创建一个单独目录,docker-compose会寻找该目录下的docker-compose.yml进行解析处理;-f选项可以指定其他文件名
# 项目名,默认为目录名

docker-compose管理单个容器

  1. 定义docker-compose文件

    [root@host3 compose-test]# cat docker-compose.yml 
    web1:
     image: nginx
     expose:
      - 80
      - 443
     ports:
      - "80:80"
      - "443:443"
       
    web1为标识符,标识定义一个容器的配置段;
    一个yml文件中,可以有多个;
    
  2. 前台运行

    [root@host3 compose-test]# docker-compose up
    Pulling web1 (nginx:latest)...
    latest: Pulling from library/nginx
    bb79b6b2107f: Pulling fs layer
    ...
       
    默认在前台运行
       
    
  3. 后台运行

    [root@host3 compose-test]# docker-compose up -d
    Creating composetest_web1_1 ... done
       
    # -d选项,后台运行;
    
  4. 访问测试

    # 80和443端口也被映射到宿主机
    [root@host3 ~]# ss -nlt
    State      Recv-Q Send-Q Local Address:Port                Peer Address:Port              
    LISTEN     0      128                *:22                             *:*                  
    LISTEN     0      100        127.0.0.1:25                             *:*                  
    LISTEN     0      128               :::80                            :::*                  
    LISTEN     0      128               :::22                            :::*                  
    LISTEN     0      100              ::1:25                            :::*                  
    LISTEN     0      128               :::443                           :::*    
    

    image-20201104160130881

  5. 查看容器进程

    [root@host3 compose-test]# docker-compose ps
           Name                     Command               State               Ports             
    --------------------------------------------------------------------------------------------
    composetest_web1_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:443->443/tcp,         
                                                                  0.0.0.0:80->80/tcp   
    

docker-compose管理多个容器

  1. 编辑docker-compse文件

    [root@host3 compose-test]# cat docker-compose.yml 
    web1:
     image: nginx
     expose:
      - 80
      - 443
     ports:
      - "80:80"
      - "443:443"
       
    web2:
     image: nginx
     expose:
      - 80
      - 443
     ports:
      - "81:80"
      - "8443:443"
    # 再继续定义容器即可
    
  2. 运行

    [root@host3 compose-test]# docker-compose up -d
    Starting composetest_web1_1 ... 
    Starting composetest_web2_1 ... done
    [root@host3 compose-test]# docker-compose ps
           Name                     Command               State               Ports             
    --------------------------------------------------------------------------------------------
    composetest_web1_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:443->443/tcp,         
                                                                  0.0.0.0:80->80/tcp            
    composetest_web2_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8443->443/tcp,        
                                                                  0.0.0.0:81->80/tcp     
    

docker-compose定义存储卷

  1. 准备本地存储卷目录

    [root@host3 compose-test]# mkdir /data/nginx -pv
    mkdir: created directory ‘/data’
    mkdir: created directory ‘/data/nginx’
    [root@host3 compose-test]# echo volume-test > /data/nginx/index.html
    
  2. 编辑docker-compose文件,用volumes字段定义存储卷

    [root@host3 compose-test]# cat docker-compose.yml 
    web1:
     image: nginx
     expose:
      - 80
      - 443
     ports:
      - "80:80"
      - "443:443"
       
    web2:
     image: nginx
     expose:
      - 80
      - 443
     volumes:
      - /data/nginx:/usr/share/nginx/html
     ports:
      - "81:80"
      - "8443:443"
       
    
  3. 运行

       
       
    [root@host3 compose-test]# curl 192.168.80.102:81
    volume-test
       
    

docker-compose常用命令

  1. 停止

    [root@host3 compose-test]# docker-compose stop
    
  2. 启动

    [root@host3 compose-test]# docker-compose start
    # 必须是已经启动的容器,若是第一次需要用up
    
  3. 重启

    [root@host3 compose-test]# docker-compose restart
    
  4. 指定某个容器启停

    # 命令行中,指定需要启停的容器名称即可,
    不加,默认是docker-compose文件中所有容器
    [root@host3 compose-test]# docker-compose ps
           Name                     Command               State               Ports             
    --------------------------------------------------------------------------------------------
    composetest_web1_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:443->443/tcp,         
                                                                  0.0.0.0:80->80/tcp            
    composetest_web2_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8443->443/tcp,        
                                                                  0.0.0.0:81->80/tcp            
    [root@host3 compose-test]# docker-compose stop web2
    Stopping composetest_web2_1 ... done
    
  5. up和down,start和stop的区别

    [root@host3 compose-test]# docker-compose up -d
    Creating composetest_web1_1 ... done
    [root@host3 compose-test]# docker-compose ps
           Name                     Command               State               Ports             
    --------------------------------------------------------------------------------------------
    composetest_web1_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:443->443/tcp,         
                                                                  0.0.0.0:80->80/tcp            
    [root@host3 compose-test]# docker-compose stop
    Stopping composetest_web1_1 ... done
    [root@host3 compose-test]# docker-compose ps
           Name                     Command               State    Ports
    --------------------------------------------------------------------
    composetest_web1_1   /docker-entrypoint.sh ngin ...   Exit 0        
    [root@host3 compose-test]# docker-compose start
    Starting web1 ... done
    [root@host3 compose-test]# docker-compose ps
           Name                     Command               State               Ports             
    --------------------------------------------------------------------------------------------
    composetest_web1_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:443->443/tcp,         
                                                                  0.0.0.0:80->80/tcp            
    [root@host3 compose-test]# docker-compose down
    Stopping composetest_web1_1 ... done
    Removing composetest_web1_1 ... done
    [root@host3 compose-test]# docker-compose ps
    Name   Command   State   Ports
    ------------------------------
       
    up会创建并运行容器,适合第一次运行的docker-compoes.yaml文件
    down与up相反,停止容器,并彻底删除
       
    start和stop只是启停已经创建好的容器;
    start是启动处于exited状态的容器,尚未创建的容器无法start,必须先up
    stop是停止正在运行中的容器;
    

docker-compose实现单机ha+nginx+tomcat

准备镜像

haproxy镜像

  1. 准备dockerfile工作目录

  2. 编辑haproxy镜像的dokcerfile文件

  3. 准备haproxy.cfg,源码包,容器入口脚本

  4. 构建镜像

  5. 准备dockerfile工作目录

    [root@host3 ~]# mkdir /dockerfile/web -pv
    mkdir: created directory ‘/dockerfile’
    mkdir: created directory ‘/dockerfile/web’
    [root@host3 ~]# cd /dockerfile/web/
    [root@host3 web]# mkdir nginx
    [root@host3 web]# mkdir tomcat
    [root@host3 web]# mkdir haproxy
    [root@host3 web]# ll
    total 0
    drwxr-xr-x 2 root root 6 Nov  5 10:47 haproxy
    drwxr-xr-x 2 root root 6 Nov  5 10:47 nginx
    drwxr-xr-x 2 root root 6 Nov  5 10:47 tomcat
    
  6. 编辑haproxy镜像的dokcerfile文件

    [root@host3 haproxy]# cat Dockerfile 
    # haproxy image build
    from centos:7.2.1511
    maintainer wang@gmail.com
       
    add haproxy-1.7.12.tar.gz /usr/local/src
    run rm -rf /etc/yum.repos.d/*
    run curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    run yum install -y gcc gcc++ pcre pcre-devel
       
    run rpm --rebuilddb && yum install -y systemd-devel zlib-devel openssl-devel
    run rpm --rebuilddb && yum install -y make
    run cd /usr/local/src/haproxy-1.7.12/ && make TARGET=linux2628 USE_PCRE=1 USE_ZLIB=1 USE_SYSTEMD=1 ARCh=x86_64 prefix=/usr/local/haproxy && make install PREFIX=/usr/local/haproxy
       
    add haproxy.cfg  /etc/haproxy/
    run mkdir /var/lib/haproxy && touch /var/lib/haproxy
    copy run_ha.sh /etc/haproxy/
    expose 80 9999
       
    cmd /etc/haproxy/run_ha.sh
    
  7. 准备haproxy.cfg,源码包,容器入口脚本

    [root@host3 haproxy]# wget https://www.haproxy.org/download/1.7/src/haproxy-1.7.12.tar.gz
       
    [root@host3 haproxy]# pwd
    /dockerfile/web/haproxy
    [root@host3 haproxy]# ll
    total 1732
    -rw-r--r-- 1 root root     735 Nov  5 10:54 Dockerfile
    -rw-r--r-- 1 root root 1760527 Oct 25  2019 haproxy-1.7.12.tar.gz
    -rw-r--r-- 1 root root    1988 Nov  5 10:55 haproxy.cfg
    -rw-r--r-- 1 root root      80 Nov  5 10:54 run_ha.sh
    [root@host3 haproxy]# cat run_ha.sh 
       
    /usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
    tail -f /etc/hosts
    [root@host3 haproxy]
       
    ---
    [root@host3 haproxy]# cat haproxy.cfg 
    #---------------------------------------------------------------------
    # Global settings
    #---------------------------------------------------------------------
    global
        # to have these messages end up in /var/log/haproxy.log you will
        # need to:
        #
        # 1) configure syslog to accept network log events.  This is done
        #    by adding the '-r' option to the SYSLOGD_OPTIONS in
        #    /etc/sysconfig/syslog
        #
        # 2) configure local2 events to go to the /var/log/haproxy.log
        #   file. A line like the following can be added to
        #   /etc/sysconfig/syslog
        #
        #    local2.*                       /var/log/haproxy.log
        #
        log         127.0.0.1 local2
         
        chroot      /var/lib/haproxy
       
        pidfile     /var/run/haproxy.pid
       
        maxconn     4000
        
     uid 99
     gid 99
       
     daemon
        # turn on stats unix socket
        stats socket /var/lib/haproxy/stats
       
       
    #---------------------------------------------------------------------
    # common defaults that all the 'listen' and 'backend' sections will
    # use if not designated in their block
    #---------------------------------------------------------------------
    defaults
        mode                    http
        log                     global
        option                  httplog
        option                  dontlognull
        option http-server-close
        option forwardfor       except 127.0.0.0/8
        option                  redispatch
        retries                 3
        timeout http-request    10s
        timeout queue           1m
        timeout connect         10s
        timeout client          1m
        timeout server          1m
        timeout http-keep-alive 10s
        timeout check           10s
        maxconn                 3000
       
       
    listen stats
     mode http
     bind *:9999
     stats enable
     log global
     stats uri /ha-status
     stats auth admin:admin
       
    listen web1
     bind *:80
     mode http
     log global
     balance roundrobin
     server web1 192.168.80.101:8080 check inter 3000 fall 2 rise 5
     server web2 192.168.80.101:8081 check inter 3000 fall 2 rise 5
    
  8. 构建镜像

    [root@host3 haproxy]# docker build -t notechbb/haproxy:centos7.2 .
       
    [root@host3 haproxy]# docker image ls
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    notechbb/haproxy    centos7.2           3dd465ba4172        39 seconds ago      606MB
    

nginx镜像

  1. 编辑nginx的dockerfile文件

  2. 准备nginx源码包,配置文件

  3. 构建镜像

  4. 编辑nginx的dockerfile文件

    [root@host3 nginx]# cat Dockerfile 
    # 将编译安装nginx的步骤,写为dockerfile指令即可;
    # Dockerfile需要D大写
    # 创建目录,用于dockerfile的编写
       
       
    # dockerfile compile nginx
    From centos:7.2.1511
    maintainer wang@qq.com
    # 基础镜像为centos,作者信息;
       
       
    run rm -rf /etc/yum.repos.d/*
    run curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
       
    run yum install -y lrzsz gcc gcc-c++ pcre-devel openssl-devel zlib-devel
    # 配置yum源,安装基础包
       
    run rpm --rebuilddb &&  yum install -y make
       
    add nginx-1.14.2.tar.gz /usr/local/src
    # run tar -xf /usr/local/src/nginx-1.14.2.tar.gz -C /usr/local/src
    # 将源码包,复制到容器内的文件系统目录中,注意:不需要解压,会自动解压!
       
       
    run useradd nginx
    run cd /usr/local/src/nginx-1.14.2/ && ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio --with-stream_realip_module --with-stream_ssl_module --with-stream --with-pcre --with-http_gzip_static_module --with-http_realip_module
    # 添加用户,进入目录,configure
       
       
    run cd /usr/local/src/nginx-1.14.2/ && make && make install
    # 根据实验中报错,再安装make包,编译,和安装
       
       
    add nginx.conf /usr/local/nginx/conf
    run ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx
    run echo "dockerfile bianyi nginx" > /usr/local/nginx/html/index.html
    # 复制配置文件、做主程序软链接,自定义主页文件
       
    expose 80
    cmd ["/usr/sbin/nginx"]
    # 暴露80端口,定义运行为容器时,执行的命令
    
  5. 准备nginx源码包,配置文件

    [root@host3 nginx]# wget http://nginx.org/download/nginx-1.14.2.tar.gz
       
    [root@host3 nginx]# tar -xf nginx-1.14.2.tar.gz -C /root/
       
    [root@host3 nginx]# cp /root/nginx-1.14.2/conf/nginx.conf .
    [root@host3 nginx]# ll
    total 1000
    -rw-r--r-- 1 root root    1604 Nov  5 11:17 Dockerfile
    -rw-r--r-- 1 root root 1015384 Dec  4  2018 nginx-1.14.2.tar.gz
    -rw-r--r-- 1 root root    2656 Nov  5 11:19 nginx.conf
       
    # 修改为前台运行
    [root@host3 nginx]# vim nginx.conf 
       
    [root@host3 nginx]# grep dae nginx.conf 
    daemon off;
    
  6. 构建镜像

    [root@host3 nginx]# docker build -t notechbb/nginx:v1.14.2 .
       
    [root@host3 nginx]# docker image ls
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    notechbb/nginx      v1.14.2             6d3c38cfd4f1        10 minutes ago      555MB
    

编辑docker-compose.yml

1、编写yml文件

[root@host3 compose]# cat docker-compose.yml 

nginx1:
 image: notechbb/nginx:v1.14.2
 container_name: n1
 expose:
  - 80
 volumes:
  - /data/n1.html:/usr/local/nginx/html/index.html
nginx2:
 image: notechbb/nginx:v1.14.2
 container_name: n2
 expose:
  - 80
 volumes:
  - /data/n2.html:/usr/local/nginx/html/index.html
haproxy:
 image: notechbb/haproxy:centos7.2
 ports:
  - "9999:9999"
  - "80:80"
 container_name: ha1
 links:
  - nginx1
  - nginx2
 volumes:
  - /data/haproxy.cfg:/etc/haproxy/haproxy.cfg

2、准备要挂载的数据卷文件;

[root@host3 compose]# echo n1-index > /data/n1.html
[root@host3 compose]# echo n2-index > /data/n2.html

[root@host3 compose]# ll /data/
total 12
-rw-r--r-- 1 root root 1960 Nov  5 16:57 haproxy.cfg
-rw-r--r-- 1 root root    9 Nov  5 16:54 n1.html
-rw-r--r-- 1 root root    9 Nov  5 16:54 n2.html

启动并验证

1、启动,查看容器进程

[root@host3 compose]# docker-compose up -d

[root@host3 compose]# docker-compose ps
Name              Command               State                     Ports                   
------------------------------------------------------------------------------------------
ha1    /bin/sh -c /etc/haproxy/ru ...   Up      0.0.0.0:80->80/tcp, 0.0.0.0:9999->9999/tcp
n1     /usr/sbin/nginx                  Up      80/tcp                                    
n2     /usr/sbin/nginx                  Up      80/tcp   

---
[root@host3 compose]# ss -nlt
State      Recv-Q Send-Q Local Address:Port                Peer Address:Port              
LISTEN     0      128                *:22                             *:*                  
LISTEN     0      100        127.0.0.1:25                             *:*                  
LISTEN     0      128               :::9999                          :::*                  
LISTEN     0      128               :::80                            :::*                  
LISTEN     0      128               :::22                            :::*                  
LISTEN     0      100              ::1:25                            :::*   

2、浏览器访问

image-20201105170406977

image-20201105170356963

遇到的问题

  • haproxy容器启动后即退出;原因:入口脚本,执行权限没加,docker-compose前台调试发现
  • docker-compose.yml中定义顺序问题,haproxy用links引用了nginx的名称,因此nginx定义需要在前;
updatedupdated2020-11-052020-11-05
加载评论