安装docker-compose,这里采用pip install的方式
yum install -y epel-release
yum install -y python-pip
pip install -U pip
pip install docker-compose
查看docker-compose版本
docker-compose -v
docker-compose version 1.24.1, build 4667896
添加 bash 补全命令 :
curl -L https://raw.githubusercontent.com/docker/compose/1.24.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
命令 | 功能 |
---|---|
build | 指定Dockerfile所在文件夹的路径 |
cap_add cap_drop | 指定窗口的内核能力 |
command | 覆盖容器启动后默认执行的命令 |
cgroup_parent | 指定父 cgroup 组,意味着将继承该组的资源限制 。 目前不支持 Swarm 模式 |
container_name | 指定容非名称。 目前不支持 Swarm 模式 |
devices | 指定设备映射关系,不支持 Swarm 模式 |
depends_on | 指定多个服务之间的依赖关系 |
dns | 自定义 DNS 服务器 |
dns_search | 配置DNS搜索域 |
dockfile | 指定额外的编译镜像的 Docke file 文件 |
entrypoint | 覆盖容器中默认的人口命令 |
env_file | 从文件中获取环境变量 |
environment | 设置环境变量 |
expose | 暴露端口,但不映射到宿主机,只被连接的服务访问 |
exetends | 基于其他模板文件进行扩展 |
external_links | 链接到docker-compose.yml外部的容器 |
extra_hosts | 指定额外的 host 名称映射信息 |
healthcheck | 指定检测应用健康状态的机制 |
image | 指定为镜像名称或镜像id |
isolation | 配置容器隔离的机制 v |
lables | 为容器添加Docker无数据信息 |
links | 连接到其他服务中的容器 |
logging | 与日志相关的配置 |
network_mode | 设置网络模式 |
networks | 所加入的网络 |
pid | 跟主机系统共享进程命名空间 |
ports | 暴露端口信息 |
secrets | 配置应用的秘密数据 |
security_opt | 指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等) |
stop_grace_period | 指定应用停止时,容器的优雅停止期限。过期后则通过SIGKILL强制退出,默认值为10s |
stop_signal | 指定停止容器的信号 |
sysctls | 配置容器内的内核参数。 目前不支持 Swarm 模式 |
ulimits | 指定容器的 ulimits 限制值 |
userns_mode | 指定用户命名空间模式。 目前不支持 Swarm模式 |
volumes | 数据卷所挂载路径设置 |
restart | 指定重启策略 |
deploy | 指定部署和运行时的容器相关配置。 该命令只在 Swarm 模式下生效,且只支持 docker stack deploy 命令部署 |
应用案例: Web负载均衡
首先创建一个haprox_web目录,作为项目工作目录,并在其中分别创建两个子目
录: web和haproxy。
- web子目录
在web子目录下将放置所需Web应用代码和Dockerle, 一会将生成需要的Web镜像。
这里用Python程序来实现一个简单的Web应用,该应用能响应HTTP请求,返回的页
面将打印出访问者的 IP 和响应请求的后端容器的 IP。
编写一个index.py作为服务器文件,代码为:
import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import socket
import fcntl
import struct
import pickle
from datetime import datetime
from collections import OrderedDict
class HandlerClass(SimpleHTTPRequestHandler):
def get_ip_address(self, ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
def log_message(self, format, *args):
if len(args) < 3 or "200" not in args[1]:
return
try:
request = pickle.load(open("pickle_data.txt", "r"))
except:
request = OrderedDict()
time_now = datetime.now()
ts = time_now.strftime('%Y-%m-%d %H:%M:%S')
server = self.get_ip_address('eth0')
host = self.address_string()
addr_pair = (host, server)
if addr_pair not in request:
request[addr_pair] = [1, ts]
else:
num = request[addr_pair][0] + 1
del request[addr_pair]
request[addr_pair] = [num, ts]
file = open("index.html", "w")
file.write(
"<!DOCTYPE html> <html> <body><center><hl><font color=\"blue\"face=\"Georgia, Arial\" size=8><em>HA</em></font> Webpage Visit Results</hl></center>")
for pair in request:
if pair[0] == host:
guest = "LOCAL: " + pair[0]
else:
guest = pair[0]
if (time_now - datetime.strptime(request[pair][1], '%Y-%m-%d %H:%M:%S')).seconds < 3:
file.write("<p style=\"font-size:150%\" >#" + str(request[pair][1]) + ": <font color=\"red\">" + str(
request[pair][
0]) + " </font>request " + "from <<font color=\"blue\">" + guest + "</font>> to WebServer <<font color=\"blue\">" +
pair[1] + "</font>></p>")
else:
file.write("<p style=\"font-size:150%\" >#" + str(request[pair][1]) + ": <font color=\"maroon\">" + str(
request[pair][
0]) + " </font>request " + "from <<font color=\"navy\">" + guest + "</font>> to WebServer <<font color=\"navy\">" +
pair[1] + "</font>></p>")
file.write("</body> </html>")
file.close()
pickle.dump(request, open("pickle_data.txt", "w"))
if __name__ == '__main__':
try:
ServerClass = BaseHTTPServer.HTTPServer
Protocol = "HTTP/1.0"
addr = len(sys.argv) < 2 and "0.0.0.0" or sys.argv[1]
port = len(sys.argv) < 3 and 80 or int(sys.argv[2])
HandlerClass.protocol_version = Protocol
httpd = ServerClass((addr, port), HandlerClass)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], " ..."
httpd.serve_forever()
except:
exit()
生成一个index.html
编辑一个Dockerfile,内容如下:
FROM python:2.7
WORKDIR /code
ADD . /code
EXPOSE 80
CMD python index.py
- haproxy目录
该目录将配置haproxy镜像。 在其中生成一个haproxy.cfg文件, 内容为:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen stats
bind 0.0.0.0:70
mode http
stats enable
stats hide-version
stats scope .
stats realm Haproxy\ Statistics
stats uri /
stats auth user:pass
frontend balancer
bind 0.0.0.0:80
mode http
default_backend web_backends
backend web_backends
mode http
option forwardfor
balance roundrobin
server weba weba:80 check
server webb webb:80 check
server webc webc:80 check
#option httpchk
#option httpchk GET /
http-check expect status 200
- docker-compose.yml
在haproxy_web目录下编写一个docker-compose.yml文件, 该文件是Compose
使用的主模板文件。 其 中, 指定启动3个Web容 器(weba、 webb、 webc), 以及1个
haproxy容器:
weba:
build: ./web
expose:
- 80
webb:
build: ./web
expose:
- 80
webc:
build: ./web
expose:
- 80
haproxy:
image: haproxy:1.6
volumes:
- ./haproxy:/haproxy-override
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
links:
- weba
- webb
- webc
ports:
- "80:80"
- "70:70"
在haproxy_web目录下运行
docker-compose up --build 命令,控制台会整合打印出所有容器的
输出信息:
Successfully built baab8924db96
Successfully tagged haproxy_web_weba:latest
Starting haproxy_web_weba_1 ... done
Starting haproxy_web_webb_1 ... done
Starting haproxy_web_webc_1 ... done
Starting haproxy_web_haproxy_1 ... done
Attaching to haproxy_web_webc_1, haproxy_web_weba_1, haproxy_web_webb_1, haproxy_web_haproxy_1
通过浏览器访问本地的 80 端口,会获取到页面信息
访问本地 70 端口,可以查看到 haproxy 的统计信息