如何将容器融入你的日常工作
本周我们将稍微回避一下。
我原本计划将一个 Docker-Compose 项目转换为 Kubernetes 项目,但这周突然冒出一个小项目。这个项目需要我搭建一个容器来模拟生产环境,这样我就可以在不干扰任何客户端的情况下测试我的脚本。
我认为一个容器如何拯救世界的实际例子会是一个比我只是为了学习而学习的东西更好的话题。
偶尔我会接到一个任务,一旦解释清楚,就会觉得要花很多时间。每次遇到这种工作,我都要花上好几个小时的注意力。
我通常会问这个任务在一个季度内出现的频率。如果一个季度的总时间超过一两天,我通常会把 XKCD 上关于自动化的漫画扔到一边,直接去做。
编写和维护自动化脚本比让我在团队其他成员处理生产问题时离开“战斗”几个小时去处理一些琐碎的事情更值得。
这周我接到一个任务,需要我登录服务器,用编程的方式清理一些文件。有时候只需要循环遍历一个列表,用一些简单的*
匹配来删除一些文件。有时候则需要一些 sed 的技巧才能完成。
当我决定值得自动化这项任务时,我把 Confluence 的步骤概述复制到了 VS Code 的一个新文档中。我根据所需完成的类似工作对任务进行了分组,尝试了一些 Bash 脚本,哭了一会儿,最终想出了一个更复杂的版本,如下所示:
项目代码:Release The Hounds <-- GitHub 链接
现在让我们深入了解一下那里到底发生了什么。
README 主要只是告诉您如何启动容器并运行./code/
目录中的脚本:
$ docker pull centos:5.11
$ docker run -v `pwd`/code/:/var/theHounds/ --name DogHouse -it centos:5.11 /bin/bash
$ cd /var/theHounds/
$ ./SetUpEnv.sh
$ ./ReleaseTheHounds.sh
“但是亨利,你为什么要用容器来做这个呢?”
好问题!目前我有三个答案:
-
我们和许多公司一样,在生产环境中运行 Red Hat Enterprise Linux。启动 CentOS(RHEL 的下游项目)服务器可以让我更接近我想要的脚本运行环境。这为我提供了一个比 Windows 更相似的测试环境。
-
容器本应是虚空的。 中的一个脚本
./code/
会SetUpEnv.sh
创建目录和文件供我测试。如果需要再次测试,我可以重启容器,我的设置脚本每次都会创建相同的环境。 -
容器无法访问任何你未明确授予其访问权限的本地存储。这样,如果我弄乱了脚本,就不会意外删除我想要保留的本地目录。
# EXCERPT FROM SETUPENV.SH:
#!/bin/bash
mkdir -p /opt/hoodlums
touch /opt/hoodlums/2019-03-07_Thief.zip
touch /opt/hoodlums/2019-06-12_Ruffian.zip
touch /opt/hoodlums/2019-07-25_Vandal.zip
所以,一旦我启动容器并运行这个脚本,我就能始终在相同的环境中测试我的脚本。这就是它./code/ReleaseTheHounds.sh
发挥作用的地方。
这个脚本的存在只是为了帮我清理一些文件。有时候,这很简单,只需循环遍历一个变量,然后粉碎所有匹配的文件即可。
#!/bin/bash
# Set up vars
HOODLUMTYPES="Thief Ruffian Hooligan Delinquent Vandal"
...
# A HOODLUMS
cd /opt/hoodlums/
for i in $HOODLUMTYPES; do shred -n 7 -u -v *$i.zip; done;
...
echo "------------------------------";
echo "LEFTOVER FILES IN /opt/Hoodlums/";
ls /opt/hoodlums/;
我可以在我的 Docker 容器内运行此脚本,以确保它能够捕获我设置的任何边缘情况,SetUpEnv.sh
而不必担心意外触碰我/opt/
的 MacBook Pro 上的本地目录。
这很好,因为我不想意外毁掉 Gradle 或 Vagrant!
有时我需要先通过清理程序运行我的数据,然后才能使用它来查找文件。
例如,我们的输入之一是 ,163Killer
而我们要测试的文件是0277_Killer.yaml
。我们需要提取Killer
以匹配该 yaml 文件。这很容易做到,只需一个额外的循环和一些 sed 魔法:
#!/bin/bash
WHALETYPES="123Fin 456_Gray 495Beluga 385_Livyatan 012_Blue 978Bowhead 149_Humpback 163Killer"
SANITIZEDWHALES=""
function whaleSanitizer {
input=$1
input=`echo $input | sed 's/^[0-9]*//'`
input=`echo $input | sed 's/^_*//'`
echo $input
}
# B WHALES
for i in $WHALETYPES; do
SANITIZEDWHALES="$SANITIZEDWHALES $(whaleSanitizer $i)"
done;
echo "------------------------------";
echo "LEFTOVER FILES IN /var/lib/docker/";
ls /var/lib/docker/;
我们不需要将其转换为 Bash 帖子,只需将WHALETYPES
变量传入whaleSanitizer
函数,再传入新的SANITIZEDWHALES
变量即可。然后,我们用这个新的变量来查找需要粉碎的文件。
然后,在脚本的最后,我ls
检查了所有接触过的目录,以确保我想要删除的文件不再存在。
为了与大家分享,我稍微简化了它,最终它成为了一个非常简单的例子。
我正在启动一个容器,创建一个临时的测试环境,然后针对该测试环境运行我的清理脚本。如果运行不正常,我可以进行一些更改,快速恢复环境,然后再试一次。
另一个好处是,这很容易重复。README.md
包含设置和运行测试环境说明的文件只有 176 字节。没错,就是 176 字节。
当我不可避免地需要更新这个脚本时,拉取 GitHub 仓库只需几秒钟。我可以在几分钟内完成修改,并创建一个容器用于测试。如果我已经将镜像centos:5.11
拉取到本地,则时间会更短。
希望以上内容能让大家更真切地感受到容器的优势。如果你们当中有人读到这里,并且曾经在类似的项目(工作或个人项目)中使用过容器,欢迎在评论区留言。让我们一起讨论,帮助新人了解何时应该使用容器!
另外,在我撰写 Compose -> Kubernetes 项目/文章的同时,我也在等待亚马逊推出一些有趣的玩具。这肯定会是一篇独立的文章,但我还是想加入 Raspberry Pi Kubernetes 集群的潮流。
在那之前,请保持冷静。
https://henryneeds.coffee
博客
LinkedIn
Twitter