背景
你是否有过这样的困惑?
常常需要本地电脑安装例如Mysql,Redis,RocketMQ,ES,Zookeeper, Nginx,Nacos 等等软件,耗时又费力。
每当更换电脑,或者重装系统的时候。
每当工作中,需要做些调优或者测试的时候,而这些软件服务一般都是运维或者DBA搭建的,自己甚至没有权限登录到服务器机器上查看,苦恼。
每当想学习,却被搭建基础环境折腾,无情的浪费时间。
所以,为了节约时间,我总结了用本地常用软件docker化,实现一键启动。是不是很香?
特别说明: 本文重点说明如何将软件docker化实战,本地宿主机和Docker服务通信问题,对于docker安装,docker,docker-compose 命令及用法基础知识不会讲解。
目标
各软件docker服务通过固定IP访问,不能每次重启docker服务IP都变化。
本机通过IP直接通信docker容器,而不是通过127.0.0.1 + 端口映射的方式。
支持多个服务一键部署,也支持单个服务一键部署。
实现步骤
创建网桥取名 app-network
docker network create --driver bridge --subnet=172.30.1.0/24 --gateway=172.30.1.1 --opt "com.docker.network.bridge.name"="app-network" app-network
配置docker服务,都桥接到同一网桥app-network上
以mysql为例(其它服务类似)
version: '3.5' services: db: image: hub.c.163.com/library/mysql:5.7 restart: always container_name: "mysql_5_7" restart: always ports: - 3306:3306 environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: root #command: volumes: - ./conf.d:/etc/mysql/mysql.conf.d - ./data:/var/lib/mysql networks: default: ipv4_address: 172.30.1.2 networks: default: external: name: app-network
其中: MYSQL_ROOT_PASSWORD 为root用户登录密码,指定IP: 172.30.1.2
编写docker-compose.yml文件
编写启动脚本 start.sh
#!/usr/bin/env bash # 创建目录 mkdir -p ./conf.d mkdir -p ./data # 设置目录权限 chmod -R 777 ./conf.d chmod -R 777 ./data # 下载并启动容器,且为 后台 自动启动 docker-compose up -d # 显示 mysql 容器 docker ps |grep mysql_5_7
启动mysql
tanyawendeMacBook-Pro:mysql bytearch$ sh ./start.sh mysql_5_7 is up-to-date 1be6fba30c7c hub.c.163.com/library/mysql:5.7 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp mysql_5_7
至此,mysql服务启动成功,一切很顺利,但是,宿主机(MAC电脑)ping不通容器
tanyawendeMacBook-Pro:mysql bytearch$ ping 172.30.1.2 PING 172.30.1.2 (172.30.1.2): 56 data bytes Request timeout for icmp_seq 0 Request timeout for icmp_seq 1 Request timeout for icmp_seq 2 Request timeout for icmp_seq 3 Request timeout for icmp_seq 4 Request timeout for icmp_seq 5 Request timeout for icmp_seq 6 Request timeout for icmp_seq 7 Request timeout for icmp_seq 8 Request timeout for icmp_seq 9
尝试试了下阿里云CentOS系统,是可以ping通的。
[root@VM_0_14_centos ~]# ping 172.30.1.2 PING 172.30.1.2 (172.30.1.2) 56(84) bytes of data. 64 bytes from 172.30.1.2: icmp_seq=1 ttl=64 time=0.028 ms 64 bytes from 172.30.1.2: icmp_seq=2 ttl=64 time=0.021 ms 64 bytes from 172.30.1.2: icmp_seq=3 ttl=64 time=0.017 ms 64 bytes from 172.30.1.2: icmp_seq=4 ttl=64 time=0.027 ms 64 bytes from 172.30.1.2: icmp_seq=5 ttl=64 time=0.023 ms 64 bytes from 172.30.1.2: icmp_seq=6 ttl=64 time=0.023 ms 64 bytes from 172.30.1.2: icmp_seq=7 ttl=64 time=0.020 ms
通过查阅资料,究其原因如下:
Docker在Mac系统架构
docker在OSX的实现方式,是首先创建一个linux的虚拟机,在将docker放入到虚拟机中实现,而对于linux虚拟机,与OSX之间的通信,目前版本采用/var/run/docker.sock
这种socket文件来通信,在OSX宿机中自然ping不通docker容器。
Docker 在Linux系统架构
docker是在linux内核容器基础上实现的,linux安装docker后,会创建一个为docker0的虚拟网卡,linux宿主机与docker容器之间的通信,通过docker0虚拟网卡进行。
所以对于Linux系统,到这就完成了!!!
那Mac怎么办?对于一个追求完美的程序员来说,这不能忍,必须血战到底。
Mac电脑与docker容器通信解决方案
经过多次尝试找到一种解决方案 (若有同学有其它更换办法,欢迎告知!)
Mac 通过 brew 安装 docker-connector
brew install wenjunxiao/brew/docker-connector
执行以下命令把 docker 的所有
bridge
网络都添加到路由中docker network ls --filter driver=bridge --format "{{.ID}}" | xargs docker network inspect --format "route {{range .IPAM.Config}}{{.Subnet}}{{end}}" >> /usr/local/etc/docker-connector.conf
或者修改
/usr/local/etc/docker-connector.conf
添加路由route 172.30.1.0/24
配置完成,重启服务
sudo brew services start docker-connector
使用以下命令在 docker 端运行 wenjunxiao/mac-docker-connector,需要使用
host
网络,并且允许NET_ADMIN,pull connector容器的作用是作为桥接
docker run -it -d --restart always --net host --cap-add NET_ADMIN --name connector wenjunxiao/mac-docker-connector
大功告成
tanyawendeMacBook-Pro:docker-app bytearch$ ping 172.30.1.2 PING 172.30.1.2 (172.30.1.2): 56 data bytes 64 bytes from 172.30.1.2: icmp_seq=0 ttl=63 time=3.019 ms 64 bytes from 172.30.1.2: icmp_seq=1 ttl=63 time=3.751 ms 64 bytes from 172.30.1.2: icmp_seq=2 ttl=63 time=1.850 ms 64 bytes from 172.30.1.2: icmp_seq=3 ttl=63 time=3.992 ms 64 bytes from 172.30.1.2: icmp_seq=4 ttl=63 time=3.695 ms
其它
以上源码已经开源, 感兴趣同学可以移步查看。
Gitee: https://gitee.com/bytearch_admin/docker-app.git
Github: https://github.com/bytearch/docker-app.git
目录结构如下:
.
├── README.md
├── install_network.sh
├── mac_connect_docker.md
├── mysql
│ ├── conf.d //数据库配置文件
│ ├── data //数据库data目录挂载,重启数据不丢失
│ ├── docker-compose.yml
│ ├── start.sh //启动脚本
│ └── stop.sh //关闭脚本
├── redis
│ ├── conf
│ ├── data
│ ├── docker-compose.yml
│ ├── start.sh
│ └── stop.sh
├── rocketmq
│ ├── docker-compose.yml
│ ├── readme.md
│ ├── rmq
│ ├── rmqs
│ ├── start.sh
│ └── stop.sh
├── startAll.sh //启动所有服务
├── stopAll.sh //关闭所有服务
└── zookeeper
├── docker-compose.yml
├── start.sh
├── stop.sh
├── zoo1
├── zoo2
└── zoo3
执行./startAll看看效果:
嗯,真香!要的就是这种效果!以后可以愉快地玩耍了!