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