尝试将正式服务迁移至docker中并管理的一次实践

3次阅读

共计 2147 个字符,预计需要花费 6 分钟才能阅读完成。

一、前言

我自己都对我自己博客记录的次数太少感到无语了~…

目前公司是没有使用 docker 的,因而自己希望对此作出改变,将服务都部署到 docker 容器中。

在这里是有几个方面是要考虑的:
1. 怎么去部署 docker 容器?
2. 对于镜像和容器该怎么去统一管理?
3. 使用 docker 发生线上故障该如何排查处理?
4. 使用 docker 的时候有哪些方面需要注意的?

因为以前的公司也没有使用过 docker,所以这次算是摸石头过河~

二、怎么去部署 docker 容器

部署 docker 容器有多种方式:

1. 使用 jenkins + git 自动化部署(当然了我们公司运维都没有。。只能靠自己打包放服务器部署了)2. 使用 maven 的 docker 插件打包成镜像(大致是这样。。)3. 创建好一个包含 java 环境的镜像,将某个文件夹挂载到容器上,后续更新服务的时候直接丢 jar 包到这个文件夹中重启容器就可以了

在这里我采用第三种方式。

在这里我编写了一个较简单的 Dockerfile 去构建镜像:

FROM java:8

VOLUME /tmp

WORKDIR /app

RUN bash -c "touch /app/app.jar"

EXPOSE 9110

ENTRYPOINT ["java", "-jar", "/app/bigdata-1.0.jar", "&"]

编写后使用构建镜像命令:docker build -t xxx .(XXX 为要构建的镜像名 注意最后的一个 . 要加上)

如果需要暴露多个端口,比如开放 JMX 端口,则加在 EXPOSE 中

然后启动容器:docker run –name docker-bigdata -d -v /mnt/bigdata/docker-bigdata:/app -p 9110:9110 bad1deaec0b1

将 jar 包和外置配置的 Config 目录一起放在 docker-bigdata 目录里,挂载到容器的 /app 目录上,容器启动的时候会自己执行 Dockerfile 中的命令。

到这里的时候服务已经启动成功了。

三、怎么去管理 docker 中的容器或镜像

使用可视化的 UI 界面管理。这里有几个选择:

1.k8s
2.swarm
3.portainer

当然了还有其他工具可以选择。

在这里我们首选 k8s,因为它可以做到一些更精细化的操作。但是因为学习成本太高,以及服务太少,这里我们略过选择。
swarm 是最贴合 docker 的,服务比较少的时候选择 swarm 是不错的选择,但是因为自己了解的比较少,所以不作选择。
选择 portainer 是因为朋友公司在使用,部署以及管理都很方便,所以参考了他的推荐选择了 portainer。

portainer 的使用非常简单:

1.docker 上面有 portainer 的镜像,可以直接拉取下来

2. 使用命令:docker run -d -p 9000:9000 –restart=always -v /var/run/docker.sock:/var/run/docker.sock –name portainer docker.io/portainer/portainer

这里 –restart=always 设置关闭后总是会自动重启,至于挂载 /var/run/docker.sock:/var/run/docker.sock 是必须的,不然进入 UI 界面的时候会提示你挂载。

3. 启动成功后,使用 http://ip:port 直接登录,第一次登录会设置账号和密码。
在这里应该注册个域名,将 ip+port 的访问方式屏蔽掉。

这是 portainer 的管理界面,可以很方便的管理镜像和容器,可以看到容器的运行状况 (是否运行以及 CPU 等状况),实时日志,容器信息,甚至还可以以命令行方式进入容器,具体一些管理操作等待后面熟悉。

在查看容器运行的日志时,发现容器和宿主机的时间不一致,有刚使用 docker 的朋友应该注意一下。在 Dockerfile 中补上这段配置:

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

四、使用 docker 发生线上故障该如何排查处理或有哪些方面需要注意的?

其实我也不是很清楚。。。因为也是第一次尝试将服务迁到 docker。
如果发生问题,如容器挂掉,则关注容器日志以及及时重启。
要更新服务,则到挂载的宿主机目录里面更新 jar 包然后重启容器就可以了。

在这里遇到问题:
1. 容器时间与宿主机问题不一致,在上面已经写了怎么解决。

2. 不能像之前一样指定输出控制台日志到某个文件中, 如 java -jar xxx.jar >log 2>&1 & 是不行的。在 Dockerfile 中用 ENTRYPOINT 重定向输出日志文件是不行的。原因:容器并不认为这个文件是它自己的,严格来说这个文件应该是属于宿主机的。

我觉得可以通过将启动命令放置在脚本中,如:java -jar xxx.jar >log 2>&1 &,将脚本挂载进容器,在 Dockerfile 中运行脚本文件,这样子 jar 包启动的时候就会将控制台输出到 log 文件中,然后通过挂载显示出来到宿主机中,方便问题排查。

现在正处于初步使用阶段,如有后续问题我会继续关注写出来。如有在使用 docker 中遇到那些坑的朋友,欢迎留言讨论~

正文完
 0