docker-compose
https://docs.docker.com/compose/
两个重要概念:
服务(service): 一个应用的容器,实际上可以包含若干运行相同镜像的容器实例
项目(project): 一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件定义
=====pre=====
install docker
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
=====install=====
curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
$ docker-compose --version
project haproxy_web
haproxy and three web
tree haproxy_web
haproxy_web
├── docker-compose.yml
├── haproxy
│ └── haproxy.cfg
└── web
├── Dockerfile
├── index.html
└── index.py
mkdir /project_home/haproxy_web
mkdir /project_home/haproxy_web/haproxy
mkdir /project_home/haproxy_web/web
=====web=====
cd /project_home/haproxy_web/web
vi Dockerfile
FROM python:2.7
WORKDIR /code
ADD . /code
EXPOSE 80
CMD python index.py
touch index.html
vi index.py
!/usr/bin/env python
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')
hostname = socket.gethostname()
server = socket.gethostbyname(hostname)
#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(" HA Webpage Visit Results
");
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("#"+ str(request[pair][1]) +": "+str(request[pair][0])+ " requests " + "from <"+guest+"> to WebServer <"+pair[1]+">
")
else:
file.write("#"+ str(request[pair][1]) +": "+str(request[pair][0])+ " requests " + "from <"+guest+"> to WebServer <"+pair[1]+">
")
file.write(" ");
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()
======haproxy======
cd /project_home/haproxy_web/haproxy
vi haproxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option dontlognull
timeout connect 5s
timeout client 50s
timeout server 50s
listen stats
bind *:70
stats enable
stats uri /
frontend balancer
bind *:80
mode http
default_backend web_backends
backend web_backends
mode http
option forwardfor
balance roundrobin
server web-1 web-1:80 check
server web-2 web-2:80 check
server web-3 web-3:80 check
option httpchk GET /
http-check expect status 200
========project haproxy_web========
cd /project_home/haproxy_web
vi docker-compose.yml
web-1:
build: ./web
expose:
- 80
web-2:
build: ./web
expose:
- 80
web-3:
build: ./web
expose:
- 80
haproxy:
image: haproxy:1.6
volumes:
- ./haproxy:/haproxy-override
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
links:
- web-1
- web-2
- web-3
ports:
- "80:80"
- "70:70"
=====up stop start====
cd /project_home/haproxy_web
docker-compose up -d
docker-compose stop
docker-compose start
docker ps -a