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 | 
 
        