软件工程师到运维的 Docker 初体验

2017/05/01 21:54
阅读数 106

起因

对于各种凌乱的电脑问题,其它行业的人以为程序员们什么都会;程序员中,女程序以为男程序员什么都会;男程序员中,一般程序员以为技术好的程序员什么都会;技术好的程序员,每次都在网上苦苦搜寻答案……

我会做一点公司服务器运维方面的工作,虽然不专业,但是日常维护还是问题不大。不过有一天,代码服务器被我搞坏了,我只是简单地想装个 Git 服务,然后被要求升级,然后升级过程中出现失败,然后服务器就不能用了——不过还好,我偶然发现从启动菜单中不带 “Server” 的那一项启动系统,除了 SSH 不能用之外,其它服务还能照常运行。又经过一翻尝试之后决定放弃,免得把事情搞得更糟——现在最多就是需要操作的时候搬台显示器去机房,麻烦一点。

又过了一段时间,公司停电,UPS 也耗尽了最后一点能量——重启的时候发现 Raid 卡报警,硬盘坏了。拆下来一测试,三块硬盘坏了两块,差点全洗白。这事很严重,所以马上买新硬盘顺便重做系统,毕竟没有 SSH 是件很不方便的事情。

目的

老实说我是真心想装 Windows Server,但是授权问题真的很难解决。如果说用 Linux,有两件事情让我很踌躇,一件事就是上面提到的为了装 Git 更新各种库把服务器系统搞坏;另一件事是在这之后,我专门找了一台旧机器准备玩玩 Linux,结果装好的第二天,对系统进行自动升级之后它就再也启动不起来了。所以我担心以后系统升级和扩展服务内容又会大费周章。

为了解决这个问题,立刻能想到的就是使用虚拟化技术,虚拟机当然是玩过的,除了本身慢得要死之外,把宿主也拉来慢得要死——在遍网都在说 Docker 的年代,我当然会去了解一下,顺便做做尝试。

最后基本上就这么决定了,安装 Linux,配置 Raid 卡,再装个 Docker 环境,上 Docker Hub 搜点现成的映像做成服务,似乎就已经解决了我们目前的问题……然后就开始了为期两周的服务搭建之旅

这两周都在干啥

两周!!!对于专业运维来说,这个时间都可以进行星际旅行了,但是考虑下我的背景,16 年前使用过 Linux,那时候只是在 Linux 下用 Emacs 和 javac 进行开发;没有运维知识栈,所知到关于运维的一切都来自 Internet 上的技术新闻,当然在软件开发和设计过程中会有一些涉及,但涉及不深。在目标确定之后接下来要做的一切事情,都是一边搜索一边试验的情况下完成的,所以两周,似乎可以理解了。

第一周

说起来第一周算是浪费掉了,因为我想继续使用 Raid 卡,但又不想延用原来那个古老版本的 Linux 系统。所以先尝试了 Ubuntu Server 16。各种搜索也没找到驱动,本来想向 Raid 供应商提个服务单,看到一大堆要填写的英文信息,还是放弃了。

然后换 CentOS。驱动倒是很快找到了,就是各种装不上……

最后在朋友的朋友的提示下,决定放弃 Raid 卡,在 Linux 里做软 Raid,不过这时候一周已经过去了

第二周

做软 Raid 配置的过程还算顺序,基本上都是按网上的贴子一步步来。就是配置完之后一直不能用,错误信息现在已经不记得了,也是各种找原因,最后在 /proc/mdstat 里发现了一个百分比,而且还是变化着的,英文看得似懂非懂,大概是在同步两步硬盘吧。所以耐心等着这个百分比走到头。有惊无险,可以装 Docker 了。

装 Docker 是很容易的,不过拉映像还是踩了些坑,大把的时间都花在找映像去了。

Docker 服务环境

当然我们要搭的服务还是有一些,不过最主要的就是 Subversion 服务、Mantis 和 Gogs,以及后面两个都会用到的 MySQL。

一开始我是直接写命令的,但是很快我就意识到这是个非常不靠谱的方式。Docker 命令参数那么多,直接写命令很容易写错,这都不算,大部分命令都是从网络上来的,总还得尝试,如果不对还需要修改……而且似乎也应该为后期维护留下点什么,所以开个了文件叫 INSTALL.md 来记录每一步操作。

MySQL 服务

首先是从 MySQL 开始,这个有官方映像,所以没什么好选的,直接拉官方映像。

从以前的了解,知道 Docker 容器相对封闭,需要通过卷(volume)来指定数据在宿主中的存储位置。这个从命令行很容易查到是 -v 参数,它会为容器内某个目录和宿主某个目录建议映射关系,这两个目录在参数中用一个冒号来分隔,但问题是谁在左谁在右?

-v <宿主中的路径>:<容器内的路径>

创建容器之后,发现用 HeidiSQL 连不上,又查了半天,发现原来是没有做端口映射。在用 -p 参数做端口映射的时候又把参数搞反了,所以又折腾了半天——好吧,其实根据 -v 参数中的顺序都可以猜到这个顺序

-p <映射到宿主的端口>:<容器内的端口>

MySQL 服务似乎没有问题了,不过我很担心重启服务器之后容器不会自动重启,所以决定实验一下。

我担心的事情出现了,MySQL 容器果然没有重启。于是继续搜,发现了 --restart 参数。所以又重新创建了一次容器,加上了 --restart=always 解决问题。

好吧,现在还有最后一个问题——为什么创建容器之后终端会阻塞在那里,我需要另开一个终端来进行其它操作?继续求助于强大的搜索引擎,最后搞明白,需要在 docker run 的时候加个 -d 参数。

Mantis 服务

Mantis 服务需要 MySQL,还需要 PHP5 以上版本。在 Docker Hub 上并没找到现成的,所以退而求其次,找了个带 PHP 的 Apache:nimmis/apache-php7。

有了之前的经验,这个配置起来很简单,Mantis 很快就运行起来了,但是问题也来了。

首先就是怎么访问数据库?借助搜索引擎的力量,我找到了 --link 参数。当然还有 Docker Compose 技术,不过这个 Compose 看起来有点深奥,以后再研究吧。

--link 似乎是以类似域名解析的方式将指定的容器绑定到指定的名称(域名),所以当前容器内部就可以通过这个名称来访问另一个容器了,而且另一个容器的端口是不需要映射到宿主的。当然,--link 参数的冒号左右分别是什么这个问题也需要搞清楚,根据之前的经验,左边接近宿主,右边接近容器内部,所以

--link <另一个容器名称>:<当前容器内部可用的域名>

现在还有第二个问题,Mantis 提示需要安装 PHP 的插件 mbstring。怎么办?继续搜!最后搜出来有两个办法:

  1. 基于原有映像创建自己的映像,安装 mbstring,然后使用这个新映像创建容器

  2. 直接进入容器安装 mbstring

我选用了第二种办法,使用 docker exec 进入容器——它居然是通过运行容器的 bash 命令来进入的,别忘了 -i -t 参数

docker exec -it httpd bash

这里 httpd 是创建的 Apache with PHP7 容器的名称,-it 是合并了 -i-tbash 就是执行的命令。

安装 mbstring 的过程很顺利,最后是恢复 Mantis 的数据库,一开始是直接把 MySQL 数据库文件拷贝过来的,很遗憾,提示找不到表。所以不能偷懒,还是老实的 mysqldump 出来再通过 mysql 命令导入。

Gogs 和 Subversion

安装 Gogs 几乎没遇到什么困难,因为前面已经遇到并解决了所有它可能遇到的问题。

到是 Subversion 装起来比较费事。一开始找了两个 Subversion 的 Docker,Subversion 都是 1.8 版本,而宿主上偏偏又装不了 1.8 版本的 Subversion,只能装 1.9 的(我搞不懂为什么,也懒得去搞懂了)。这么一来,我担心在宿主上通过 svnadmin 创建的库不能被容器内运行的 svn 服务兼容。如果在容器内去创建库又比较麻烦。

原本以为很简单的 Subversion 却在寻找映像这里卡住了。最好尝试了好久,总算找了个 Subversion Edge 的映像,Web 界面管理库,虽然功能并不是很强大,但是简单的管理是没有问题了。说起来,还是很想念 Windows 下的 VirtualSVN Server。

Nginx 反向代理

Docker 服务的端口只要不映射出来,就只能内部访问,这看起来还是增强了安全性的,然并卵,因为不映射出来外面就不能使用这些服务。早就听说过 Nginx 的大名,所以干脆用 Nginx 映像来做个反向代理容器,然后以 HTTPS 协议来代理后面的 HTTP 服务。

配置都在从网上抄的,所以就不贴出来了,不过对于 SVN,后来是遇到 svn copy 总是 502 错误的问题,又在网上去搜索了一番,发现需要在 location 配置里加这么一段

# 解决 svn copy 报 502 错误的问题set $fixedDescination $http_destination;if ($http_destination ~* ^https(.*)$) {    set $fixedDescination http$1;
}
proxy_set_header    Destination $fixedDescination;

然后又遇到提交数据过大的问题,于是又加了一项

client_max_body_size    48m;

最后完整的配置如下,基本上可以代表所有 location 的反向代理配置了

# svn server - svn
location /svn/ {    proxy_set_header    Host                $host;    proxy_set_header    X-Forwarded-Host    $host;    proxy_set_header    X-Forwarded-Server  $host;    proxy_set_header    X-Real-IP           $proxy_protocol_addr;    proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;    proxy_buffering     on;    # 解决 svn copy 报 502 错误的问题    set $fixedDescination $http_destination;
   if ($http_destination ~* ^https(.*)$) {
       set $fixedDescination http$1;    }    proxy_set_header    Destination $fixedDescination;    proxy_pass              http://svn-server:18080/svn/;    client_max_body_size    48m; }

还是假装总结一下吧

  1. 文档和记录很重要,就是前面提到的 INSTALL.md

  2. 搜索引擎很重要,如果中文搜不到就搜英文

  3. Docker 是个好东西

  4. Nginx 也是个好东西

  5. 有没有想在成都或者绵阳找工作的运维?




与原文相比,本文略有缩减,敬请阅读原文 ↓

本文分享自微信公众号 - 边城客栈(fancyidea-full)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部