博主简介:
云计算领域优质创作者
2022年CSDN新星计划python赛道第一名2022年CSDN原力计划优质作者
阿里云ACE认证高级工程师
阿里云开发者社区专家博主交流社区:CSDN云计算交流社区欢迎您的加入!
目录
1.web子目录
1.1index.py
1.2index.html
1.3Dockerfile
2.haproxy子目录
3.docker-compose.yml文件
4.运行compose项目
结束语
负载均衡器+Web应用是十分经典的应用结构。下面,博主将创建一个该结构的Web项目:将Haproxy作为负载均衡器,后端挂载三个Web容器。 |
首先创建一个haproxy_web目录,作为项目工作目录,并在其中分别创建两个子目录:web和haproxy。 |
1.web子目录
在web子目录下将放置所需Web应用代码和Dockerfile,下面将生成需要的Web镜像。 |
这里用Python程序来实现一个简单的Web应用,该应用能响应HTTP请求,返回的页面将打印出访问者的IP和响应请求的后端容器的IP。 |
1.1index.py
编写一个index.py作为服务器文件,代码为: |
#!/usr/bin/python#authors: yeasy.github.com#date: 2013-07-05import sysimport BaseHTTPServerfrom SimpleHTTPServer import SimpleHTTPRequestHandlerimport socketimport fcntlimport structimport picklefrom datetime import datetimefrom collections import OrderedDictclass 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, # SIOCGIFADDRstruct.pack('256s', ifname[:15]))[20:24])def log_message(self, format, *args):if len(args) < 3 or "200" not in args[1]:returntry: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]+1del request[addr_pair]request[addr_pair]=[num,ts]file=open("index.html", "w")file.write(" HA Webpage VisitResults
");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.HTTPServerProtocol = "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 = Protocolhttpd = ServerClass((addr, port), HandlerClass)sa = httpd.socket.getsockname()print "Serving HTTP on", sa[0], "port", sa[1], "..."httpd.serve_forever()except:exit()
1.2index.html
生成一个临时的index.html文件,其内容会由index.py来更新:模板文件 |
$ touch index.html
1.3Dockerfile
生成一个Dockerfile,部署该Web应用,内容为: |
FROM python:2.7WORKDIR /codeADD . /codeEXPOSE 80CMD python index.py
2.haproxy子目录
该目录将配置haproxy镜像。 在其中生成一个haproxy.cfg文件,内容为: |
globallog 127.0.0.1 local0log 127.0.0.1 local1 noticemaxconn 4096defaultslog globalmode httpoption httplogoption dontlognulltimeout connect 5000mstimeout client 50000mstimeout server 50000mslisten statsbind 0.0.0.0:70mode httpstats enablestats hide-versionstats scope .stats realm Haproxy\ Statisticsstats uri /stats auth user:passfrontend balancerbind 0.0.0.0:80mode httpdefault_backend web_backendsbackend web_backendsmode httpoption forwardforbalance roundrobinserver weba weba:80 checkserver webb webb:80 checkserver webc webc:80 checkoption httpchk GET /http-check expect status 200
3.docker-compose.yml文件
在haproxy_web目录下编写一个docker-compose.yml文件,该文件是Compose使用的主模板文件。其中,指定启动3个Web容器(weba、webb、webc),以及1个Haproxy容器: |
# This will start a haproxy and three web services. haproxy will act as aloadbalancer.# Authors: yeasy.github.com# Date: 2015-11-15weba:build: ./webexpose:- 80webb:build: ./webexpose:- 80webc:build: ./webexpose:- 80haproxy:image: haproxy:1.6volumes:- ./haproxy:/haproxy-override- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:rolinks:- weba- webb- webcports:- "80:80"- "70:70"
4.运行compose项目
现在haproxy_web目录应该长成下面的样子: |
haproxy_web├── docker-compose.yml├── haproxy│ └── haproxy.cfg└── web├── Dockerfile├── index.html└── index.py
在该目录下执行sudo docker-compose up命令,控制台会整合显示出所有容器的输出信息: |
$ sudo docker-compose upRecreating haproxyweb_webb_1...Recreating haproxyweb_webc_1...Recreating composehaproxyweb_weba_1...Recreating composehaproxyweb_haproxy_1...Attaching to composehaproxyweb_webb_1, composehaproxyweb_webc_1, composehaproxyweb_weba_1, composehaproxyweb_haproxy_1
此时通过浏览器访问本地的80端口,会获取到页面信息,如图所示。 |
经过Haproxy自动转发到后端的某个Web容器上,刷新页面,可以观察到访问的容器地址的变化。 |
访问本地70端口,可以查看到Haproxy的统计信息,如下图所示。 查看本地的镜像,会发现Compose自动创建的haproxyweb_weba、 haproxyweb_webb、haproxyweb_webc镜像: |
$ docker imagesREPOSITORYTAG IMAGE ID CREATED VIRTUAL SIZEhaproxyweb_webb latest33d5e6f5e20b 44 minutes ago675.2 MBhaproxyweb_weba latest33d5e6f5e20b 44 minutes ago675.2 MBhaproxyweb_webc latest33d5e6f5e20b 44 minutes ago675.2 MB
当然,还可以进一步使用Consul等方案来实现服务自动发现,这样就可以不用手动指定后端的web容器了,更为灵活。 |
结束语