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

释放双眼,带上耳机,听听看~!

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

consul


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1version: '3.3'
2services:
3  consul:
4    image: consul
5    container_name: consul_server
6    network_mode: bridge 
7    ports:
8      - 8300:8300
9      - 8301:8301
10      - 8301:8301/udp
11      - 8302:8302
12      - 8302:8302/udp
13      - 8400:8400
14      - 8500:8500
15      - 53:53/udp
16    command: consul agent -data-dir=/tmp/consul -server -bootstrap -domain=zhenhe.li -client=0.0.0.0
17 
18
19

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 中使用):

请求示例:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1{
2  "ID": "redis1",
3  "Name": "redis",
4  "Tags": [
5    "primary",
6    "v1"
7  ],
8  "Address": "127.0.0.1",
9  "Port": 8000,
10  "Meta": {
11    "redis_version": "4.0"
12  },
13  "EnableTagOverride": false,
14  "Check": {
15    "DeregisterCriticalServiceAfter": "90m",
16    "HTTP": "http://localhost:5000/health",
17    "Interval": "10s"
18  }
19}
20

响应示例:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1{
2   "redis1": {
3       "ID": "redis1",
4       "Service": "redis",
5       "Tags": ["primary", "v1"],
6       "Address": "127.0.0.1",
7       "Meta": {
8           "redis_version": "4.0"
9       },
10      "Port": 8000,
11      "EnableTagOverride": false,
12      "CreateIndex": 0,
13      "ModifyIndex": 0
14  }
15}
16

**

registrator


1
2
3
4
5
6
7
8
9
10
11
12
13
1version: '3.3'
2services:
3  registrator:
4    image: gliderlabs/registrator
5    container_name: docker_consul_registrator
6    network_mode: bridge
7    external_links:
8      - consul_server:consul
9    volumes:
10      - /var/run/docker.sock:/tmp/docker.sock
11    command: consul://consul:8500
12    
13

上述配置文件中。 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  


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1FROM nginx
2MAINTAINER LiZhenhe <zhenhe.li@vcg.com>
3
4RUN apt-get update && \
5    apt-get install --no-install-recommends --no-install-suggests -y unzip && \
6    rm -r /var/lib/apt/lists/*
7
8
9ENV CONSUL_TEMPLATE_VERSION 0.19.4
10ADD https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/consul-template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.zip /tmp/consul-template.zip
11
12RUN unzip /tmp/consul-template.zip -d /usr/bin && \
13    chmod +x /usr/bin/consul-template && \
14    rm /tmp/consul-template.zip
15RUN mkdir /etc/ctmpl
16COPY ctmpl /etc/ctmpl
17WORKDIR /etc/ctmpl
18
19ENTRYPOINT ["/usr/bin/consul-template"]
20

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1{{range services}}
2  upstream {{.Name}} {
3    least_conn;{{range service .Name}}
4    server {{.Address}}:{{.Port}};{{end}}
5  }
6{{end}}
7
8server {
9    listen 80;
10    proxy_set_header            Host $host;
11    proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
12    {{range services}}
13          location {{.Name}} {
14            proxy_read_timeout 180;
15            proxy_pass http://{{.Name}}/{{.Name}};
16          }
17    {{end}}
18}
19

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1{{range services}}
2   {{$name := .Name}}
3   {{$service := service .Name}}
4   {{$tags := .Tags}}
5  
6   upstream {{$name}} {
7       zone upstream-{{$name}} 64k;
8       {{range $service}}
9           server {{.Address}}:{{.Port}}  max_fails=3 fail_timeout=60 weight=1;
10      {{else}}
11          server 127.0.0.1:65535;
12      {{end}}
13  }
14  server {
15      listen 80;
16      listen 443;
17      charset utf-8;
18      server_name {{range $tags }} {{.}} {{else}}localhost{{end}};   
19      access_log  /var/log/nginx/{{$name}}.log;
20      location / {
21          proxy_pass http://{{$name}};
22          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
23          proxy_set_header Host $host;
24          proxy_set_header X-Real-IP $remote_addr;
25          client_max_body_size    1000m;
26          proxy_buffering off;
27      }
28  }
29{{end}}
30

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

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

consul-template-nginx


1
2
3
4
5
6
7
8
9
10
11
12
1version: '3'
2services:
3  consul-template:
4    container_name: consul-template-nginx
5    image: zhenheli/consul-template-nginx
6    network_mode: bridge
7    external_links:
8      - consul_server:consul
9    command: -consul-addr=consul:8500 -wait=5s -template="/etc/ctmpl/ctmpl:/etc/nginx/conf.d/app.conf:nginx -s reload"
10    ports:
11      - 80:80
12

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1{{range services}} {{$name := .Name}} {{$service := service .Name}} {{$tags := .Tags}}
2upstream {{$name}} {
3zone upstream-{{$name}} 64k;
4{{range $service}}server {{.Address}}:{{.Port}}  max_fails=3 fail_timeout=60 weight=1;
5{{else}}server 127.0.0.1:65535;{{end}}
6}
7server {
8        listen 80;
9        listen 443;
10        charset utf-8;
11        access_log  /var/log/nginx/{{.Name}}.log;
12        server_name {{range $tag := .Tags}} {{if $tag|contains "vcg_domain:"}} {{$tag|replaceAll "vcg_domain:" ""}}{{else}}localhost{{end}}{{else}}localhost{{end}};
13        location / {
14                proxy_pass http://{{.Name}};
15                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
16                proxy_set_header Host $host;
17                proxy_set_header X-Real-IP $remote_addr;
18                client_max_body_size    1000m;
19                proxy_buffering off;
20        }
21} {{end}}
22

给TA打赏
共{{data.count}}人
人已打赏
安全运维

基于spring boot和mongodb打造一套完整的权限架构(一)

2021-12-11 11:36:11

安全运维

Ubuntu上NFS的安装配置

2021-12-19 17:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索