docker技术很早就开始接触,最开始偷懒的想法是起一个标准的容器,在容器内安装完自己的定制需求然后再把容器转存成一个镜像。可最终开始应用的还是得乖乖的去学习dockerfile的规范,根据自己的情况写自己的dockerfile。
再后来工作中使用就是kubernetes了,不过一直没有魄力上生产;docker-compose只闻其名,没有真正的使用过。
很多时间工作需要才是技术研究的动力,近期工作中开始应用docker-compose,提升不少效率;但受限于docker-compose的单机特性,无法原生支持服务高可用的需要,后来把眼光转向的docker-compose和docker-swarm结合的应用,但时间有限一直没有深入了解swarm模式,想当然的认为是一套轻量化的集群,可以在服务器数量有限的情况下满足我的高可用需求。但是当了解到swarm的集群创建和运行模式后,发现满足高可用最少3个master节点,woker node另算,有这3个master节点就直接上k8s了;研究的结果就是放弃,想其他办法实现一下高可用吧!
自我吐槽完毕,介绍一下docker-compose的内容吧,
我对这个工具的要求就是,轻量、简单、快速部署,目前这几点上使用起来还算不错。
docker是docker-compose的基础,装好docker再来聊docker-compose。 docker的安装这里就不介绍了。
docker-compose最重要的两个组成: docker-compose 命令和docker-compose定义文件。
1. docker-compose命令是python语言实现的命令,绝大部分python包都支持两种安装方式,docker-compose也不例外:
a. yum安装
yum install -y docker-compose
b. pip安装
pip install docker-compose
c. docker-compose常用命令
docerk-compose up 启动预定义的一系统容器,需要在当前目录下存在docker-compose.yml的文件,或者 -f 指定文件路径
docker-compose up -d 后台启动
docker-compose ps 查看当前定义所有容器的状态
docker-compose logs -f --tail 50 contanier_name 查看容器日志,相当于tail -50f filename.txt的效果,持续跟踪容器日志
docker-compose stop 停止服务
docker-compose [stop|start|restart] service-name 可以查看指定服务名的容器操作
docker-compose exec service-name command 在指定的容器执行命令
以上所有操作都需要当前目录下存在一份预设的docker-compose定义文件。
2. docker-compose.yaml
docker-compose定义文件使用yaml格式,文件格式以yaml或yml结尾。 docker-compose命令在执行时会默认到当前文件夹下查找docker-compose.yaml或docker-compose.yml文件,如果不存在,则报错。也可以加-f 指定docker-compose.yml文件的路径。
docker-compose最新的版本是3.8,但是除非使用一些特别的新功能,对一般使用来说3.1以上的版本都是可以通用的,下面聊聊docker-compose文件。
#固定格式,文件开头,声明定义文件版本,最新版本为3.8
version: '3.1'
#顶级字段,声明服务
services:
nginx: #服务名
image: myregister.com/myapp/nginx:v1.12 #镜像地址
environment: #传递给镜像的环境变量
- TZ=Asia/Shanghai #修改容器时区
myapp:
image: myregister.com/myapp/model-myapp:3
ports:
- "8288" #容器暴露的端口
volumes:
- /etc/localtime:/etc/localtime:ro #另一种修改容器时区的实现方式
- /data/myapp/config/application.properties:/myapp/config/application.properties #挂载文件,把配置文件从宿主机映射到容器内
- /data/myapp/logs:/data/logs
depends_on: #依赖服务,在指定的服务成功启动后再启动当前服务
- redis
- mysql
redis:
image: myregister.com/myapp/redis:v2.1
ports: #多端口服务 redis镜像,集群版,带密码;通过自定义启动脚本实现,集群创建,初始化,配置密码
- "7001"
- "7002"
- "7003"
- "7004"
- "7005"
- "7006"
environment:
REDISPASSWD: GROA1qpPoGzPc3M4maeP8Qc
mysql:
image: mysql:5.7 #这处是官方的镜像
command: --default-authentication-plugin=mysql_native_password
environment:
TZ: "Asia/Shanghai" #修改时区
MYSQL_ROOT_PASSWORD: mfrYZXmQeWlRez2F #设置mysql的密码
volumes:
- /data/data/mysql:/var/lib/mysql #映射数据库存储目录
- /data/myapp/sql/:/docker-entrypoint-initdb.d #mysql容器启动过程中初始化的数据
- /data/myapp/config/my.cnf:/etc/my.cnf #映射自定义配置文件
#顶级字段,声明当前docker-compose使用的网络
networks:
default: #在服务中不单独指定网络模式时,使用的默认网络
driver: bridge #网络的驱动
上面这段是一个比较常见的样式,一个前端加上nginx,一个后端java服务,一个Redis集群,一个mysql数据库 组成一个完整的系统;实现快速部署启动时,下面的文件复制到服务器上,在安装完docker和dockerfile之后,直接启动即可
docker-compose up -d
启动后,通过下面命令查看服务组内,各个容器的启动状态
docker-compose ps
注:连接到同一个网络的容器,彼此之间可以通过service name访问,如果应用中连接redis就可以用"redis:7001"这个地址;但是这个地址在redis容器内确不能用,这是一个问题还需要再验证排查一下。
3. 应用场景
2例子中不管是redis 还是mysql都是单点服务,redis也是一个伪集群的状态;所以这种形式不太适合大压力的生产环境,不适用于无法承受任务数据丢失的场景。但对于一些演示类的项目,试用类的服务非常适合,实现无配置启动。