docker-compose实战


Docker-Compose是Docker的一种编排服务,是一个用于在Docker上定义并运行复杂应用的工具,可以让用户在集群中部署分布式应用。

通过Docker-Compose用户可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose解决了容器与容器之间如何管理编排的问题。

如Docker-Compose文件格式为2.0,Docker Engine版本必须大于1.10.0
如Docker-Compose文件格式为1.0,Docker Engine版本必须大于1.9.1

安装Docker-Compose

直接使用二进制文件安装:

# curl -L https://github.com/docker/compose/releases/download/1.17.0-rc1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose

验证安装成功
# docker-compose --version

Docker-Compose常用命令,可以查看docker-compose的用法,里面有详细的解释。

Docker-Compose YAML语法使用说明
默认的模板文件是 docker-compose.yml,其中定义的每个服务都必须通过image指令指定镜像或build指令(需要 Dockerfile)来自动构建。其它大部分指令都跟docker run中的类似。

如果使用build指令,在Dockerfile中设置的选项(例如:CMD, EXPOSE, VOLUME, ENV 等) 将会自动被获取,无需在docker-compose.yml中再次设置。

  • build

这个是创建docker镜像时的选项,通过本地的dockerfile来创建,而不是通过image id来pull。
其中build还有一些小选项。

build:
  context: ./nginx
  dockerfile: Dockerfile
  args:
    - buildno=1
    - user=someuser

dockerfile选项是备选的dockerfile。args是一些提供的参数。

  • image: 

生成镜像的ID,指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉去这个镜像。

image: ubuntu
image: orchardup/postgresql
  • links

链接到其它服务中的容器,使一个容器可以主动的去和另外一个容器通讯。使用服务名称(同时作为别名)或服务名称:服务别名 (SERVICE:ALIAS) 格式都可以。

links:
 - db
 - db:database
 - redis

使用的别名将会自动在服务容器中的 /etc/hosts 里创建,相应的环境变量也将被创建。例如

172.17.2.186  db
172.17.2.186  database
172.17.2.187  redis
  • external_links

链接到 docker-compose.yml 外部的容器,甚至 并非 Compose 管理的容器。参数格式跟 links 类似。

external_links:
 - redis_1
 - project_db_1:mysql
 - project_db_1:postgresql
  • expose

这个是给link用的,将一些端口暴露给link到这个container上的containers。暴露端口,但不映射到宿主机,只被连接的服务访问

expose:
    - "3000"
    - "8000"
  • ports

暴露端口信息,这个是将端口和本机端口映射的选项,写法如下,其实跟docker -p一样。使用宿主:容器 (HOST:CONTAINER)格式或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

ports:
    - "3000"
    - "3000-3005"
    - "80:80"
    - "9090-9091:8080-8081"
    - "49100:22"
    - "127.0.0.1:8001:8001"
    - "127.0.0.1:5000-5010:5000-5010"

注:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 你可能会得到错误得结果,因为 YAML 将会解析 xx:yy 这种数字格式为 60 进制。所以建议采用字符串格式。

  • environment:

设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取它在 Compose 主机上的值,可以用来防止泄露不必要的数据。

environment:
  RACK_ENV: development
  SESSION_SECRET:

environment:
  - RACK_ENV=development
  - SESSION_SECRET
  • env_file

从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过 docker-compose -f FILE 指定了模板文件,则 env_file 中路径会基于模板文件路径。
如果有变量名称与 environment 指令冲突,则以后者为准。

env_file: .env

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env
  • volumes

将本机的文件夹挂载到container中。

volumes:
    # Just specify a path and let the Engine create a volume
        - /var/lib/mysql
    # Specify an absolute path mapping
        - /opt/data:/var/lib/mysql
    # User-relative path
        - ~/configs:/etc/configs/:ro
    # Named volume
        - datavolume:/var/lib/mysql

卷挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)

volumes:
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro
  • volumes_from

从另一个服务或容器挂载它的所有卷。

volumes_from:
 - service_name
 - container_name
  • extends

基于已有的服务进行扩展。例如我们已经有了一个webapp服务,模板文件为 common.yml。

# common.yml
webapp:
  build: ./webapp
  environment:
    - DEBUG=false
    - SEND_EMAILS=false

编写一个新的 development.yml 文件,使用 common.yml 中的 webapp 服务进行扩展。

# development.yml
web:
  extends:
    file: common.yml
    service: webapp
  ports:
    - "8000:8000"
  links:
    - db
  environment:
    - DEBUG=true
db:
  image: postgres

后者会自动继承 common.yml 中的 webapp 服务及相关环节变量。

  • net

设置网络模式。使用和 docker client 的 –net 参数一样的值。

net: "bridge"
net: "none"
net: "container:[name or id]"
  • pid

跟主机系统共享进程命名空间。打开该选项的容器可以相互通过进程 ID 来访问和操作。

pid: "host"
  • dns

配置 DNS 服务器。可以是一个值,也可以是一个列表。

dns: 8.8.8.8
dns:
  - 8.8.8.8
  - 9.9.9.9
  • cap_add, cap_drop

添加或放弃容器的 Linux 能力(Capabiliity)。

cap_add:
  - ALL

cap_drop:
  - NET_ADMIN
  - SYS_ADMIN
  • dns_search

配置 DNS 搜索域。可以是一个值,也可以是一个列表。

dns_search: example.com
dns_search:
  - domain1.example.com
  - domain2.example.com
  • command

覆盖容器启动后默认执行的命令。

command: bundle exec thin -p 3000

其它选项

working_dir, entrypoint, user, hostname, domainname, mem_limit, privileged, restart, stdin_open, tty, cpu_sharesv 这些都是和 docker run 支持的选项类似。

cpu_shares: 73
working_dir: /code
entrypoint: /code/entrypoint.sh
user: postgresql
hostname: foo
domainname: foo.com
mem_limit: 1000000000
privileged: true
restart: always
stdin_open: true
tty: true

---------------------------

Docker-Compose使用实例:

Docker-compose搭建tomcat服务

# cat docker-compose.yml 
version: '3.1'
services:
  tomcat:
    restart: always
    image: tomcat
    container_name: tomcat
    ports:
      - 8080:8080
    volumes:
      - ./webapps:/usr/local/tomcat/webapps
    environment:
      TZ: Asia/Shanghai

Docker-compose搭建Redis Sentinel

Redis Sentinel是针对原始Master/Slave模型而衍生的高可用模型。我们为便于灵活部署,先易后难,先搭建Redis Master/Slave模型,再搭建Redis Sentinel模型。

文件目录结构如下:

docker
├── redis
│   └── docker-compose.yml
└── sentinel
    ├── docker-compose.yml
    ├── sentinel1.conf
    ├── sentinel2.conf
    ├── sentinel3.conf
    └── sentinel.conf

一、搭建Redis Master/Slave模型

下面的Compose文件设置了redis的 一主两从(Master-Slave)

1.创建并进入redis文件夹,并创建如下docker-compose.yml文件。

[root@localhost ~]# mkdir -p docker/redis
[root@localhost ~]# cd docker/redis
[root@localhost redis]# touch docker-compose.yml
docker-compose.yml文件内容如下:
 
version: '3'
services:
  master:
    image: redis
    container_name: redis-master
    command: redis-server --requirepass redis_pwd  --masterauth redis_pwd
    ports:
      - 6379:6379
  slave1:
    image: redis
    container_name: redis-slave-1
    ports:
      - 6380:6379
    command:  redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd
  slave2:
    image: redis
    container_name: redis-slave-2
    ports:
      - 6381:6379
    command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd

注意,如果设置了Redis客户端访问密码requirepass, 那么也要设置相同的副本集同步密码masterauth。
另外我们后面使用哨兵模式能够完成故障转移,现有的Master可能会变成Slave,故在当前Master容器中也要携带masterauth参数。

2. 执行 docker-compose up -d 会产生3个Redis容器,分别映射到宿主机6379、6380、6381端口, 默认连接在redis-default网桥。

[root@localhost redis]# docker-compose -f docker-compose.yml up -d
WARNING: IPv4 forwarding is disabled. Networking will not work.
Creating network "redis_default" with the default driver
Pulling master (redis:)...
Trying to pull repository docker.io/library/redis ... 
latest: Pulling from docker.io/library/redis
54fec2fa59d0: Pull complete
9c94e11103d9: Pull complete
04ab1bfc453f: Pull complete
a22fde870392: Pull complete
def16cac9f02: Pull complete
1604f5999542: Pull complete
Creating redis-slave-1 ... done
Creating redis-master  ... done
Creating redis-slave-2 ... done

3. 使用docker ps查看redis输出:

[root@localhost redis]# docker ps -a
CONTAINER ID    IMAGE    COMMAND          CREATED              STATUS              PORTS                    NAMES
262b42fb0c9f    redis    "docker-en..."   About a minute ago   Up About a minute   0.0.0.0:6381->6379/tcp   redis-slave-2
a2243df4965d    redis    "docker-en..."   About a minute ago   Up About a minute   0.0.0.0:6379->6379/tcp   redis-master
e6d40f337118    redis    "docker-en..."   About a minute ago   Up About a minute   0.0.0.0:6380->6379/tcp   redis-slave-1

查看redis容器使用的网桥信息:

[root@localhost ~]# docker inspect -f {{.HostConfig.NetworkMode}} 262b42fb0c9f
redis_default

4. 验证
Master/Slave副本集,进入Master容器,确认两个Slave容器已经连接。

 二、docker-compose 部署Redis Sentinel

我们即将搭建的Sentinel容器需要能访问到以上3个容器,故需要在形成Sentinel容器时使用外置的redis-default网桥(Redis Master/Slave docker-compose 已经创建).

[root@localhost ~]# mkdir -p docker/sentinel
[root@localhost ~]# cd docker/sentinel/

1 进入sentinel文件夹,创建docker-compose.yml

version: '3'
services:
  sentinel1:
    image: redis
    container_name: redis-sentinel-1
    ports:
      - 26379:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf
  sentinel2:
    image: redis
    container_name: redis-sentinel-2
    ports:
    - 26380:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
  sentinel3:
    image: redis
    container_name: redis-sentinel-3
    ports:
      - 26381:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:
  default:
    external:
      name: redis_default

2 创建哨兵文件sentinel.conf,将如下内容拷贝进去:

port 26379
dir /tmp
sentinel monitor mymaster 172.18.0.4 6379 2
sentinel auth-pass mymaster redis_pwd
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

注意,以上 172.18.0.4是之前Redis Master/slave启动之后Master节点的IP,通过docker inspect [container]获取, 这里我们要配合设置Master/Slave访问密码。

3 将哨兵文件复制三份,Volume进Sentinel容器。

[root@localhost sentinel]# cp sentinel.conf sentinel1.conf
[root@localhost sentinel]# cp sentinel.conf sentinel2.conf
[root@localhost sentinel]# cp sentinel.conf sentinel3.conf

4 docker-compose up -d生成3个Sentinel容器。

[root@localhost sentinel]# docker-compose -f docker-compose.yml up -d

5 此时docker ps显示如下:

[root@localhost sentinel]# docker ps -a
CONTAINER ID    IMAGE     COMMAND          CREATED       STATUS         PORTS                                NAMES
33473b024a55    redis     "docker-en..."   12 hours ago  Up 12 hours    6379/tcp, 0.0.0.0:26380->26379/tcp   redis-sentinel-2
65ed9d4032a4    redis     "docker-en..."   12 hours ago  Up 12 hours    6379/tcp, 0.0.0.0:26379->26379/tcp   redis-sentinel-1
02ae36076592    redis     "docker-en..."   12 hours ago  Up 12 hours    6379/tcp, 0.0.0.0:26381->26379/tcp   redis-sentinel-3
262b42fb0c9f    redis     "docker-en..."   17 hours ago  Up 11 hours    0.0.0.0:6379->6379/tcp               redis-master
a2243df4965d    redis     "docker-en..."   17 hours ago  Up 11 hours    0.0.0.0:6381->6379/tcp               redis-slave-2
e6d40f337118    redis     "docker-en..."   17 hours ago  Up 11 hours    0.0.0.0:6380->6379/tcp               redis-slave-1

6 验证

进入其中一个redis-sentinel容器,确认Master、2个Slave、另外2个Sentinel.

[root@localhost sentinel]# docker exec -it redis-sentinel-1 /bin/bash
root@65ed9d4032a4:/data# redis-cli -p 26379
127.0.0.1:26379> sentinel master mymaster

flags: master表明master正常运作,异常情况会显示s-down,o-down
num-slaves:侦测到2个Slave副本集
num-other-sentinels:除此之外,还有2个哨兵

3.Redis Sentinel高可用
停止 redis-master容器,等待10s,进入任意sentinel容器,使用sentinel master mymaster命令观察主节点发生变化,观察外挂的Sentinel*.conf 主节点IP发生变化,然后重新启动master节点,检查集群状态.

Docker-compose搭建Redis-jenkins

1、创建docker在主机的jenkins数据映射目录

mkdir -p /data/jenkins_home
chown -R 1000 /data/jenkins_home

2、用docker-compose安装,当然你也可以用docker run的方式,创建一个docker-jenkins-compose.yml文件。

version: "3"
services:
  jenkins:
    image: jenkins/jenkins:lts
    ports:
      - 8080:8080
      - 50000:50000
    restart: "always"
    container_name: jenkins
    environment:
      JAVA_OPTS: -Duser.timezone=Asia/Shanghai
    volumes:
      - /opt/jenkins/home:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/bin/docker:/usr/bin/docker
    privileged: true
    user: root

3、启动Jenkins容器

docker-compose -f docker-jenkins-compose.yml up -d

 

参考文档:https://www.cnblogs.com/JulianHuang/p/12650721.html


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM