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