docker-compose 搭建 consul, registrator, consul-template,nginx环境。

为了真实近似模拟线上,下面的配置都是一个服务一个docker-compose.yml文件。


consul

version: '3.3'
services:
  consul:
    image: consul
    container_name: consul_server
    network_mode: bridge 
    ports:
      - 8300:8300
      - 8301:8301
      - 8301:8301/udp
      - 8302:8302
      - 8302:8302/udp
      - 8400:8400
      - 8500:8500
      - 53:53/udp
    command: consul agent -data-dir=/tmp/consul -server -bootstrap -domain=zhenhe.li -client=0.0.0.0
 
 

2018-04-22 23:06 做出更改:

1.镜像image由原来的progrium/consul 修改为官方的consul, 原因是原来的镜像中consul版本过低没有新特性。官方目前是1.0.7

2.参数变更为 consul agent 开头,同时新版本中要求参数要加入 -client=x.x.x.x 否则默认127.0.0.1 不允许外部ip 访问

新特性包含critical服务定时清除,允许Tags定义覆盖,增加Meta属性(非常有用,在后面的 template 中使用):

请求示例:

{
  "ID": "redis1",
  "Name": "redis",
  "Tags": [
    "primary",
    "v1"
  ],
  "Address": "127.0.0.1",
  "Port": 8000,
  "Meta": {
    "redis_version": "4.0"
  },
  "EnableTagOverride": false,
  "Check": {
    "DeregisterCriticalServiceAfter": "90m",
    "HTTP": "http://localhost:5000/health",
    "Interval": "10s"
  }
}

响应示例:

{
	"redis1": {
		"ID": "redis1",
		"Service": "redis",
		"Tags": ["primary", "v1"],
		"Address": "127.0.0.1",
		"Meta": {
			"redis_version": "4.0"
		},
		"Port": 8000,
		"EnableTagOverride": false,
		"CreateIndex": 0,
		"ModifyIndex": 0
	}
}



registrator

version: '3.3'
services:
  registrator:
    image: gliderlabs/registrator
    container_name: docker_consul_registrator 
    network_mode: bridge
    external_links:
      - consul_server:consul
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    command: consul://consul:8500
    

上述配置文件中。 network_mode 使用的bridge ,这其中也踩过坑。网上有很多示例是host, 意思是docker 可以与宿主机共有一网套络,就是说进入容器执行ifconfig与宿主机看到的可能是一样的,暴露的端口也占用宿主机端口。后来反复测试发现在mac os中,network_mode=host 这个配置不能达到上述要求。最终在一篇讨论看到结论:Should docker run –net=host work?

讨论中说network_mode=host在linux中可以正常运行,有时间我验证一下。




nginx+consul-template, 这个网上或docker hub上有别人已经做好了,但是模板ctmpl文件都是根据自己的环境编写的,有可能不符合自己的要求,所以这一步还是要自己去pull nginx镜像,加入最新版consul-template,然后commit, push到hub上或自己的仓库中使用。

之所以要用自己的镜像,一个非常重要的原因是consul-template版本还是变更非常快的,它要随着consul版本的变更而变更Struct,用来解析最新的nodes, services等等json结构。 举例,我们本例中会用到的Meta属性就是目前网上现有的consul-template-nginx镜像中包含的consul-template所不能解析的。


自己基于官方nginx 镜像加入最新版的 consul-template,加入自己的ctmpl 模板文件

自定义consul-template-nginx

Dockerfile  

FROM nginx
MAINTAINER LiZhenhe <zhenhe.li@vcg.com>

RUN apt-get update && \
    apt-get install --no-install-recommends --no-install-suggests -y unzip && \
    rm -r /var/lib/apt/lists/*


ENV CONSUL_TEMPLATE_VERSION 0.19.4
ADD https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/consul-template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.zip /tmp/consul-template.zip

RUN unzip /tmp/consul-template.zip -d /usr/bin && \
    chmod +x /usr/bin/consul-template && \
    rm /tmp/consul-template.zip
RUN mkdir /etc/ctmpl
COPY ctmpl /etc/ctmpl
WORKDIR /etc/ctmpl

ENTRYPOINT ["/usr/bin/consul-template"]


ctmpl模板文件, 内容还需要改造。这个模板来自网上,稍后,我基于这个模板加入Meta进行多域名解析的改造,适应我们现在线上环境的需求


{{range services}}
  upstream {{.Name}} {
    least_conn;{{range service .Name}}
    server {{.Address}}:{{.Port}};{{end}}
  }
{{end}}

server {
    listen 80;
    proxy_set_header            Host $host;
    proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
    {{range services}}
          location {{.Name}} {
            proxy_read_timeout 180;
            proxy_pass http://{{.Name}}/{{.Name}};
          }
    {{end}}
}

线上使用Tags,但不严谨, 应该使用Meta最为严谨安全

{{range services}} 
	{{$name := .Name}} 
	{{$service := service .Name}} 
	{{$tags := .Tags}}
	
	upstream {{$name}} {
		zone upstream-{{$name}} 64k;
		{{range $service}}
			server {{.Address}}:{{.Port}}  max_fails=3 fail_timeout=60 weight=1;
		{{else}}
			server 127.0.0.1:65535;
		{{end}}
	} 
	server {
		listen 80;
		listen 443;
		charset utf-8;
		server_name {{range $tags }} {{.}} {{else}}localhost{{end}};	
		access_log  /var/log/nginx/{{$name}}.log;
		location / {
			proxy_pass http://{{$name}};
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
			client_max_body_size    1000m;
			proxy_buffering off;
		}
	} 
{{end}}

注意这个ctmpl文件要与上面的Dockerfile放在同上目录下。


执行docker build -t="zhenheli/consul-template-nginx" -f Dockfile .来构建镜像


consul-template-nginx

version: '3'
services:
  consul-template:
    container_name: consul-template-nginx
    image: zhenheli/consul-template-nginx
    network_mode: bridge
    external_links:
      - consul_server:consul
    command: -consul-addr=consul:8500 -wait=5s -template="/etc/ctmpl/ctmpl:/etc/nginx/conf.d/app.conf:nginx -s reload"
    ports:
      - 80:80


最终由于spring-cloud-consul-client版本过低也无法提供nodeMeta, 退回到使用tags, 不过为了安全起见, 制定了一个规则,

以vcg_domain:开头的才看作是要获取的域名的tag,具体实现如下:


{{range services}} {{$name := .Name}} {{$service := service .Name}} {{$tags := .Tags}}
upstream {{$name}} {
zone upstream-{{$name}} 64k;
{{range $service}}server {{.Address}}:{{.Port}}  max_fails=3 fail_timeout=60 weight=1;
{{else}}server 127.0.0.1:65535;{{end}}
}
server {
        listen 80;
        listen 443;
        charset utf-8;
        access_log  /var/log/nginx/{{.Name}}.log;
        server_name {{range $tag := .Tags}} {{if $tag|contains "vcg_domain:"}} {{$tag|replaceAll "vcg_domain:" ""}}{{else}}localhost{{end}}{{else}}localhost{{end}};
        location / {
                proxy_pass http://{{.Name}};
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                client_max_body_size    1000m;
                proxy_buffering off;
        }
} {{end}}






未完。更新日期:2018年04年24日 13:12

----------------------------------------

原创作品,版权归zhenhe.li@vcg.com所有,转载请标记出处。

阅读更多

没有更多推荐了,返回首页