上篇文章我们进行了Docker的快速入门,基本命令的讲解,以及简单的实战,那么本篇我们就来实战一个真实的项目,看看怎么在产线上来通过容器技术来运行我们的项目,来达到学会容器间通信以及docker-compose学习以及docker网络模型学习的目的。
二、项目描述
-
创建Todo应用,功能很简单,实现创建Task关联Task分类,以及更新Task的完成状态的功能。
-
项目运行后的主界面如下:
三、启动项目
-
因为是使用git管理的maven java项目,所以需要首先在服务器上安装java、maven、git 三大件
传送门:
-
Git入门教程传送门:
-
接着把github上的项目源码clone到本地
git clone https://github.com/hafizzhang/mysql-spring-boot-todo.git
-
进入到项目根目录
cd mysql-spring-boot-todo
-
使用maven命令进行打包项目并且使用docker命令进行build镜像
mvn clean package docker:build
-
用容器启动mysql 5.6版本
docker run --name mysql -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=tododb -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -d mysql:5.6
-
查看mysql日志输出,确保mysql服务启动没有问题
docker logs mysql (因为上步中我们已经指定了运行mysql容器的名称为mysql,所以这里可以直接用容器名查看日志)
-
用容器启动todo镜像
docker run -p 8080:8080 --name todo -d hafiz/todo-demo:1.0.0
-
查看todo容器的日志,观察容器是否启动成功
docker logs todo
我们会发现出现了以下错误:
这就说明了,同一个主机上的各个容器之间是相互隔离的,也就是他们直接不能直接相互访问,那我们怎么解决这个问题呢?最简单的办法我们可以直接在启动容器的时候指定--link参数把该容器链接到mysql容器上(虽说这种方式已经官方已经不推荐,但是对于同一个主机的不同容器间的通信却是最简单的,后面会介绍别的方式实现),这样我们的目标容器todo就可以跟mysql源容器进行通信了,来,说干就干
docker rm -f todo 首先删除已经存在的容器tododocker run -p 8080:8080 --name todo --link mysql -d hafiz/todo-demo:1.0.0
再查看todo容器启动的日志,发现可以成功启动了,然后打开浏览器输入主机ip:8080可以看到todo的运行主界面
-
我们在todo主界面上添加一条记录,然后通过mysql容器进行查看已经添加的记录,如下:
docker exec -t -i mysql bash 进入到mysql容器mysql -uuser -ppass 用户名为user,密码为passselect category, IF(complete,'true','false') complete, name from todo_item;
可以看到我们保存的记录已经进到mysql中了
四、使用link实现Docker容器间的通信的原理
todo项目和mysql项目的启动后通信模型如下:
那我们上面已经通过link方式实现了todo容器可以访问相同主机的mysql容器,那么这种方式如何实现的呢?
我们查看todo容器的/etc/hosts文件就会明白了,如下:
可以看出link的工作原理是在todo的hosts文件中写入mysql容器的地址信息
使用容器连接的好处
-
运行在同一主机的独立容器间可以相互通讯
-
容器间建立一个安全通讯隧道而不需要暴露容器的任何端口
五、使用Docker Compose管理多个容器
为什么需要使用Docker Compose管理多个容器
答:当多个容器相互之间需要通讯时,手动配置容器间连接变得非常复杂,而且官方也已经不推荐使用了。
什么是Docker Compose
-
Docker Compose是一个定义和管理多个Docker容器的工具
-
它通过YAML文件定义Docker应用运行时的信息,如:端口、网络等。
-
使用Docker Compose,一个简单命令可以管理多个容器应用。
Docker Compose使用场景
-
快速构建开发环境
-
自动化测试环境
-
单一主机部署多个容器
安装Docker Compose
-
传送门:
如何使用Docker Compose
-
定义构建各个镜像所需的Dockerfile文件
-
定义docker-compose.yml文件
-
在docker-compose.yml和Dockerfile文件所在的目录下,通过
docker-compose up [-d]
启动docker-compose.yml 所定义的多个Docker应用
深入了解Docker Compose
-
几个重要的Docker Compose命令
-
docker-compose up
启动YAML中定义的所有容器 -
docker-compose ps [-a]
查看[所有的]运行的容器 -
docker-compose logs containerId/containerName
查看运行的容器的日志 -
docker-compose stop containerId/containerName
停止运行的容器 -
docker-compose rm containerId/containername
删除已停止的容器 -
docker-compose build
重新创建所有的镜像
-
-
Tips
-
docker-compose只有在Docker镜像不存在的时候才创建镜像
-
更新Dockerfile后一定要执行docker-compose build重新创建镜像才能生效
-
六、Docker网络模型
docker daemon启动以后,会默认创建一个名称为docker0的网桥,容器默认情况下是通过这个docker0网桥来和主机进行通信的。
docker网络模型有以下几种分类:
1. None网络模型
-
实现了最大限度的网络隔离
-
容器间不能通过网络通讯提供服务或者提供网络服务
-
尽管None网络模型可以提供非常好的安全隔离,但其适用场景非常有限
2. Bridge网络模型(默认)
-
Bridge网络模型下默认有两个网络接口:loopback和eth0
-
同一主机上相同bridge网络的所有容器可以相互间通信
-
同一主机上不同bridge网络上所有容器间不能直接通讯
-
不同主机间bridge网络的容器不能直接通讯
-
演示:
docker run --rm -d --net bridge --name c1 imageName:imageTag sleep 1000docker run --rm -d --net bridge --name c2 imageName:imageTag sleep 1000docker exec -ti c1 ping c2 ip 显示网络访问成功
3. Host网络模型(和主机共享网络)
-
Host网络安全性相对于其他网络模型如:None、Bridge较低
-
Host网络跟主机共享网络栈
-
所有主机可见的网络接口对以Host网络模型运行的容器均可见
-
容器间网络不具有隔离性
-
由于使用Host网络容器的请求无需经过docker0和Iptable的处理,它提供非常好的性能
-
演示:
docker run --rm -d --net host --name c1 imageName:imageTag sleep 1000docker exec -ti c1 ping 主机ip
4. Overlay网络模型
-
支持多主机间容器直接通讯
-
Swarm模式下使用overlay网络模型无需外部键值存储系统
-
非Swarm模式下使用overlay网络模型需要外部键值存储系统,如Consul等
-
docker network ls
产看当前所有的docker网络 -
docker network create [-d] network-name
创建指定驱动的网络-
-d选项可选,用来指定创建网络使用的驱动类型,但好像只能创建bridge驱动的网络
-
-
docker network rm network-name
删除自定义网络 -
docker network inspect network-name
查看指定docker网络的信息 -
docker network connect network-name containerId/containerName
把指定的容器链接到指定的网络上
七、使用Docker Compose管理网络
-
默认执行docker-compose时将创建新网络
-
新网络名字以docker-compose.yml当前所在目录名字跟默认driver的组合,比如当前目录为test,则docker-compose.yml不指定具体网络的时候,创建的网络名称为:test_default
-
可以创建自定义的网络,在docker-compose.yml中自定义networks,如下图的标注1
-
指定service使用特定的网络,如下图的标注2
八、如何在产线运行容器化的服务
我们要想在产线去运行容器集群,那我们首先需要COE(Container Orchestration Engine)工具。
1. COE的主要功能如下:
-
主机配置(Provisioning)
-
容器编排
-
自我修复
-
Scale up/down 容器
-
暴露服务给外界
-
服务发现
2. COE工具:
-
Docker Swarm Mode
-
原生集成Docker Engine的集群管理
-
去中心化的设计
-
声明式服务模型
-
Scale up/down 服务
-
支持多主机网络
-
服务发现
-
负载均衡
-
安全性高
-
支持滚动升级
-
-
Kubernates
-
Mesos/Marathon
-
高可用
-
支持有状态服务
-
支持多种容器引擎
-
服务发现和负载均衡
-
健康检测
-
事件订阅
-
丰富的API支持
-
容器调度约束
-
-
Hashicorp Nomad
-
简单且轻量级
-
多云支持
-
维护简单
-
支持混合工作负载
-
高可用
-
支持多区域多数据中心
-
3. COE选择的准则
-
抽象程度(Level of abstraction):支持混合还是只支持基于容器的工作负载(Hybrid Workloads)
-
工具链(Tooling):编排工具相关生态圈,工具的集成程度
-
架构(Architecture): 是否支持高可用、高稳定性以及灾难恢复
4. 如何选择COE工具
-
是否支持企业DevOps框架和编排
-
是否提供丰富的API
-
集群支持主机数量大小
-
容器运行在什么平台?物理机、私有云还是公有云?
-
是否具有自我修复功能
-
是否提供服务负载均衡
-
如何Provision容器
-
运维复杂性高低
-
是否支持混合工作负载
-
生态圈发展是否成熟
-
社区是否活跃
5. 监控及指标
常用监控工具
-
Sensu
-
Prometheus
-
Grafana
-
Influxdb
-
Telegraf
-
Zabbix
-
cAdvisor
-
Sysdig
6. 日志
-
EFK(Elasticsearch Fluentd Kibana)
-
ELK (Elasticsearch Logstash Kibana)
-
Graylog
九、总结
通过本文,我们就知道如何让同一主机上的不同容器进行通讯,如何进行docker 网络的管理,Docker的网络模型都有哪几种?如何在docker-compose.yml文件中自定义docker网络,如何给其中定义的service指定使用自定义的网络?如何在产线运行容器化服务?如何选择COE工具?以及容器化以后我们要注意的地方。对于不同主机间的容器通讯,本文没有设计,以后有机会,我们再来慢慢谈起。