一种生产环境Docker Overlay Network的配置方案

原文地址介绍一种生产环境Docker overlay network的配置方案。概要先讲一下生产环境中的问题:有多个Docker host,希望能够通过Docker swarm连接起来。Docker swarm只适合于无状态应用,不适合有状态应用。因此生产环境中会同时存在无状态应用:利用docker service create/docker stack deploy创建的。有状态应用:利用docker run/docker compose up创建的。希望两种应用能够连接到同一个overlay网络,在网络内部能够通过tasks.<service-name> DNS name 连接到无状态应用(见Container discovery)<container-name> DNS name 连接到有状态应用解决办法:创建attachable的overlay network有状态应用挂到这个overlay network上无状态应用也挂到这个overlay network上步骤到manager节点上创建attachable的overlay network,名字叫做prod-overlay:docker network create -d overlay –attachable prod-overlay在manager节点上查看这个网络是否创建成功:$ docker network lsNETWORK ID NAME DRIVER SCOPEfbfde97ed12a bridge bridge local73ab6bbac970 docker_gwbridge bridge locala2adb3de5f7a host host localnm7pgzuh6ww4 ingress overlay swarm638e550dab67 none null localqqf78g8iio10 prod-overlay overlay swarm在worker节点上查看这个网络,这时你看不到这个网络,不过不要担心,当后面在worker节点上创建工作负载后就能看到了:$ docker network lsNETWORK ID NAME DRIVER SCOPEfbfde97ed12a bridge bridge local73ab6bbac970 docker_gwbridge bridge locala2adb3de5f7a host host localnm7pgzuh6ww4 ingress overlay swarm638e550dab67 none null local在manager上创建容器c1,挂到prod-overlay network上:docker run –name c1 –network prod-overlay -itd busybox在worker上创建容器c2,挂到prod-overlay network上:docker run –name c2 –network prod-overlay -itd busybox在manager上创建service c,挂到prod-overlay network上:docker service create -td –name c –replicas 2 –network prod-overlay busybox验证查看worker节点的network之前在worker节点上没有看到prod-overlay network,现在你应该可以看见了:$ docker network lsNETWORK ID NAME DRIVER SCOPE01180b9d4833 bridge bridge localcd94df435afc docker_gwbridge bridge local74721e7670eb host host localnm7pgzuh6ww4 ingress overlay swarm32e6853ea78d none null localdw8kd2nb2yl3 prod-overlay overlay swarm确认容器可以互ping到manager节点上,让c1 ping c2$ docker exec c1 ping -c 2 c2PING c2 (10.0.2.2): 56 data bytes64 bytes from 10.0.2.2: seq=0 ttl=64 time=0.682 ms64 bytes from 10.0.2.2: seq=1 ttl=64 time=0.652 ms到manager节点上,让c1 ping tasks.c,tasks.c是之前创建的service c的DNS name:$ docker exec c1 ping -c 2 tasks.cPING tasks.c (10.0.2.8): 56 data bytes64 bytes from 10.0.2.8: seq=0 ttl=64 time=2.772 ms64 bytes from 10.0.2.8: seq=1 ttl=64 time=0.694 ms到manager节点上,让c1 查询 tasks.c的DNS name,可以看到tasks.c有两条记录:$ docker exec c1 nslookup -type=a tasks.cServer: 127.0.0.11Address: 127.0.0.11:53Non-authoritative answer:Name: tasks.cAddress: 10.0.2.7Name: tasks.cAddress: 10.0.2.8到manager节点上,查看service c的task,看到有c.1、c.2两个task,分别部署在两个节点上:$ docker service ps cID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTSp5n70vhtnz2f c.1 busybox:latest docker-learn-1 Running Running 17 minutes agobyuoox1t7cve c.2 busybox:latest docker-learn-2 Running Running 17 minutes ago到c.1 task所在的节点上,查看task c.1的容器名:$ docker ps -f name=c.1CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES795a3bd3c20a busybox:latest “sh” 21 minutes ago Up 21 minutes c.1.p5n70vhtnz2f5q8p2pcvbyfmw然后在c1里ping task c.1的容器名:$ docker exec c1 ping -c 2 c.1.p5n70vhtnz2f5q8p2pcvbyfmwPING c.1.p5n70vhtnz2f5q8p2pcvbyfmw (10.0.2.7): 56 data bytes64 bytes from 10.0.2.7: seq=0 ttl=64 time=0.198 ms64 bytes from 10.0.2.7: seq=1 ttl=64 time=0.128 ms你同样可以:在c2里:ping c1ping tasks.cping task c.1、c.2的容器在task c.1、c.2的容器里:ping c1、c2;ping tasks.cping task c.1、c.2的容器注意通过docker run / docker compose up创建的容器的名字,要保证在整个集群里是唯一的。docker 不会帮你检查名称冲突的情况,如果名称冲突了那么会得到错误的DNS结果。参考资料Use overlay networksUse an overlay network for standalone containers ...

January 9, 2019 · 2 min · jiezi

Prometehus自动发现Docker Swarm Overlay网络中的容器

原文地址介绍如何使用Prometheus的dns service discovery机制,自动发现并抓取Docker swarm overlay网络中的容器所提供的指标。使用docker service create/docker stack deploy能够很方便管理多个docker host,并且对应用做扩缩容。那么我们如何抓取这些动态创建的容器应用所提供的指标呢?在《使用Prometheus+Grafana监控JVM》一文里我们使用了static_config静态配置指标抓取目标,这显然在docker swarm环境里是不合适的。我们需要一种动态发现容器的方法。解决思路如下:使用《一种生产环境Docker Overlay Network的配置方案》提到的方法配置overlay网络,并且把docker service、stack、standalone container都挂到这个overlay网络里。把Prometheus也挂到这个overlay网络里。使用Prometheus的DNS service discovery机制,半自动的发现容器。本文所提到的脚本可以在这里下载下面构建一个实验环境以说明方法。第一步:构建overlay network根据《一种生产环境Docker Overlay Network的配置方案》里提到的方法,创建Docker swarm,和一个overlay网络,名字叫做test-overlay:docker network create -d overlay –attachable test-overlay第二步:启动容器为了方便起见,使用prometheus-mock-data来模拟一个提供指标的应用,这样就能够避免繁琐的jmx-exporter。1) 新建一个目录,名字叫做docker-swarm-demo2) 新建一个文件scrape-data.txt,这个文件就是我们要提供的假指标,内容如下:# HELP x mock metric# TYPE x gaugex 1—# HELP x mock metric# TYPE x gaugex 2—# HELP x mock metric# TYPE x gaugex 3—# HELP x mock metric# TYPE x gaugex 43) 为了演示docker service和standalone container都能被采集到,会启动这两种形式的容器:4) 使用docker service create启动一个service,replicas=3(注意–name参数):docker service create \ –name mock \ –replicas 3 \ –network test-overlay \ –limit-memory 96M \ –mount type=bind,src=$(pwd)/scrape-data.txt,dst=/home/java-app/etc/scrape-data.txt \ chanjarster/prometheus-mock-data:latest4) 使用docker run启动一个standalone container(注意–name参数):docker run -d \ -v $(pwd)/scrape-data.txt:/home/java-app/etc/scrape-data.txt \ –network test-overlay \ –name standalone-mock \ chanjarster/prometheus-mock-data:latest第三步:启动Prometheus1) 在之前新建目录docker-swarm-demo里创建文件prom-config.yml,内容如下:scrape_configs: - job_name: ‘swarm-service’ scrape_interval: 30s dns_sd_configs: - names: - tasks.mock - standalone-mock type: A port: 8080 relabel_configs: - source_labels: [’__meta_dns_name’] target_label: ‘service’注意到上面的两个关键配置:设定了两个DNS A记录,tasks.mock和standalone-mock。tasks.mock是Docker自动为docker service mock创建的,而standalone-mock就是容器名。文章最开始说到的半自动就是这个意思,我们得事先知道DNS A记录有哪些,然后让Prometheus去发现这些DNS A记录背后对应的容器有哪些。把__meta_dns_name的值设置到指标的service 这个label里。2) 启动Prometheus:docker run -d \ –name=prometheus \ –network test-overlay \ -p 9090:9090 \ -v $(pwd):/prometheus-config \ -v $(pwd)/prom-data:/prometheus \ prom/prometheus –config.file=/prometheus-config/prom-config.yml3) 访问 http://localhost:9090 看看Prometheus是否启动成功,在输入框里输入x然后执行,应该可以看到如下图的结果:其中3个instance是属于tasks.mock的,还有一个则是standalone container(如果没有看到4个instance,那么等一会儿再试)。 ...

January 9, 2019 · 1 min · jiezi