Docker 是一个开放源代码软件项目,让应用程序布署在软件货柜下的工作可以自动化进行,借此在 Linux 操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制。
这里使用 Docker 将 BlogReaper 和 MySQL 进行容器化
安装和使用
安装过程官方文档说的非常清楚
https://docs.docker.com/install/linux/docker-ce/centos/#install-docker-ce
1 | # 清理旧版本 |
MYSQL 容器化
首先拉取 MySQL 镜像
1 | $ docker pull mysql |
需要注意的是这里默认的TAG
为latest
,而 MySQL 最新的版本为8.0
,并不是常用的5.7
使用docker images
可以查看已有的镜像
1 | $ docker images |
然后启动服务器
1 | $ sudo docker run -p 3306:3306 --name mysql_reaper -e MYSQL_ROOT_PASSWORD=password -d mysql |
使用 docker ps
可以查看正在运行的容器
启动 MySQL 客户端
1 | $ docker run -it --net host mysql "sh" |
然后为数据库添加用户和权限
1 | # 新建数据库 |
PS: 在 8.0 及以上的版本,有些客户端不支持新的默认身份验证插件(caching_sha2_password),我们可以将其换成原来的(mysql_native_password)
1 | use mysql; |
Dockerfile
使用 Dockerfile,我们可以创建我们专属的 Docker 镜像,这里以一个简单的 Go 应用(BlogReaper)为例子
1 | FROM scratch |
FROM
FROM scratch
表示从一个空的镜像上创建
如果我们需要专门的编译环境的话,可以使用FROM golang:1.11.3-stretch
从镜像库中获取文件
我们可以从https://hub.docker.com/上找到我们需要的镜像,并且基于已经做好的镜像上创建我们的镜像
COPY
COPY
表示复制文件,这里用来复制配置文件到 docker 镜像里面
格式:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
ADD
ADD
是一种高级的 COPY,不但可以从本地复制文件,而且还可以从互联网上获取文件
对于本次运行的程序,由于存在 https 对外的请求,因此运行的时候遇到了以下的问题
1 | x509: failed to load system roots and no roots provided |
这是一个非常常见的问题:为了进行 SSL 请求,我们需要 SSL 根证书。
因此需要在 Dockerfile 中加入这一句
1 | ADD https://curl.haxx.se/ca/cacert.pem /etc/ssl/certs/ |
添加根证书到镜像的指定目录中
CMD
一个 Dockerfile 里面只能存在一个 CMD,为镜像创建完成之后执行的命令
EXPOSE
表示需要暴露的端口
使用
静态编译
因为是我们的 main 文件生成的时候依赖的一些库如 libc 还是动态链接的,但是 scratch 镜像完全是空的,什么东西也不包含,所以生成 main 时候要按照下面的方式生成,使生成的 main 静态链接所有的库:
1 | $ CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o main . |
打包镜像
1 | # 将当前目录的项目打包成docker镜像,并命名为reaper |
通过docker ps
可以看到,两个 Docker 进行已经成功运行
Stack
Stack 中包含一系列的 service,这些 service 组成了应用。stack 通过一个 YAML 文件定义每个 service,并描述 service 使用的资源和各种依赖。
有了 Stack,就可以把我们的服务端和数据库打包一起运行咯
定义
首先,定义一个yml
文件
1 | version: '3.1' |
首先在开头用version
声明版本,这里使用3.1
然后声明服务service
首先是数据库db
使用image
表示使用的 docker 镜像为mysql:latest
由于这里使用的是 8.0 的 mysql,因此需要使用command
指定默认密码认证组件为mysql_native_password
使用volumes
指定挂载的数据库位置。可以将“数据卷”理解为容器中的一个目录,类似于 Linux 中 mount 的概念。创建容器时,可以一并创建数据卷,并且能够挂载一个主机目录为数据卷。
使用docker inspect
命令可以查看到,数据库文件挂载在指定的目录上,这样我们每次使用的时候就可以复用之前的数据库
1 | "Mounts": [ |
然后使用environment
指明一些参数,比如数据库密码、用户之类的
用户和密码被存储在docker secrets
里面,通过secrets
从本地文件中创建,然后运行之后会被映射到/run/secrets
下面,使用secrets
表示这个容器使用这些秘密文件
最后指明端口
对于服务端,使用depends_on
表示所依赖的服务,可以保证数据库运行之后才运行服务器,同样可以通过secrets
把密码传递到环境变量中
使用
使用docker stack deploy
命令使用预先写好的配置文件
1 | $ docker swarm init # 初始化服务 |
然后查看其运行状态
1 | $ docker stack service ls # 查看服务信息 |
如果不能正常运行可以通过docker logs
查看其日志
更新配置之后只需要重新运行一次 docker stack deploy -c docker-compse.yml reaperstack
即可
使用rm
可以停止当前 stack 并清除
1 | $ docker stack rm reaperstack |