用了 Docker 快一个月了,不过都是用别人的镜像。正好看到 github 上有趣的 nyancat 项目便构建一个镜像玩玩。
这个就是我要做的东西:「Nyan Cat Telnet Server」。
目前 DockerHub 上有一些 nyancat 的镜像。不过支持 telnet 的很多都是 node 版本的而且镜像体积都得几十兆,运行时一直 100% 内存 :(
我就想用 alpine:3.5 [3.99MB] 镜像做个特别轻、特别干净的镜像。
0x00 - 准备工作
Docker 环境都在 「Docker 学习笔记(一) - 搭建 Firekylin 博客」时设置好了。
0x01 - 编写镜像的 Dockerfile
读了很多文章后总结出来的结论就是一定要用 Dockerfile
写镜像而不是用 docker commit
功能。主要优势就是易维护,易分享,易集成。
试了半天写出了下面这坨:
Dockerfile
FROM alpine:3.5
LABEL maintainer="Wei He <[email protected]>"
RUN \
apk upgrade --update && \
apk add g++ make git autoconf automake
RUN \
cd /tmp && git clone https://github.com/klange/nyancat.git && \
cd /tmp/nyancat && make && \
cp ./src/nyancat /usr/local/bin/ && \
cd / && rm -rf /tmp/nyancat
RUN \
cd /tmp && git clone https://github.com/ddhhz/onenetd.git && \
cd /tmp/onenetd && autoreconf -vfi && ./configure && make && \
cp ./onenetd /usr/local/bin && \
cd / && rm -rf /tmp/onenetd
RUN \
apk del --purge g++ make git autoconf automake
EXPOSE 23
ENTRYPOINT ["onenetd", "-v1", "0", "23", "nyancat", "--telnet"]
我把 RUN 部分分为了 4 个步骤,安装 dependencies、安装 nyancat、安装 onenetd、清理 dependencies,应该是比较清晰明了的。
0x02 - 构建镜像
这一步我写 Dockerfile 测试时重复了好多遍。
$ docker build -f Dockerfile . -t ddhhz/nyancat-server
Output 长这样:
Sending build context to Docker daemon 4.099 MB Step 1/8 : FROM alpine:3.5 3.5: Pulling from library/alpine Digest: sha256:58e1a1bb75db1b5a24a462dd5e2915277ea06438c3f105138f97eb53149673c4 Status: Downloaded newer image for alpine:3.5 ---> 4a415e366388 Step 2/8 : LABEL maintainer "Wei He" ---> Running in 6dcfd2925e26 ---> d5045af5f75e Removing intermediate container 6dcfd2925e26 Step 3/8 : RUN apk upgrade --update && apk add g++ make git autoconf automake ---> Running in 31c4a3cc086b ... ---> f2a2dd1731d8 Removing intermediate container 31c4a3cc086b Step 4/8 : RUN cd /tmp && git clone https://github.com/klange/nyancat.git && cd /tmp/nyancat && make && cp ./src/nyancat /usr/local/bin/ && cd / && rm -rf /tmp/nyancat ---> Running in e4446629a4fd ... ---> c349461e3fc7 Removing intermediate container e4446629a4fd Step 5/8 : RUN cd /tmp && git clone https://github.com/ddhhz/onenetd.git && cd /tmp/onenetd && autoreconf -vfi && ./configure && make && cp ./onenetd /usr/local/bin && cd / && rm -rf /tmp/onenetd ---> Running in 5c8198ecc381 ... ---> e2a1d37466f6 Removing intermediate container 5c8198ecc381 Step 6/8 : RUN apk del --purge g++ make git autoconf automake ---> Running in f8b3c1a8c33c ... ---> 794d44a3ae67 Removing intermediate container f8b3c1a8c33c Step 7/8 : EXPOSE 23 ---> Running in 9264e44de3be ---> 09a57d263cc7 Removing intermediate container 9264e44de3be Step 8/8 : ENTRYPOINT onenetd -v1 0 23 nyancat --telnet ---> Running in fb9d7ccc00a5 ---> 0e0b79a8b21e Removing intermediate container fb9d7ccc00a5 Successfully built 0e0b79a8b21e
看起来总共有 8 层。多层的优势就是更改了一层的代码不需要重构所有的层,比如:更改了 nyancat 构建代码重新 build 就不需要重新运行 apk add
安装命令了。
0x03 - 运行容器
运行
$ docker run -d --name nyancat-server --restart=always -p 23:23 ddhhz/nyancat-server
然后
$ telnet localhost
就可以看到美丽的 nyancat 了!
0x04 - 镜像瘦身法
惊吓!容器太大了!
突然发现镜像大小。。。有。。。221 MB。。
REPOSITORY TAG IMAGE ID CREATED SIZE
ddhhz/nyancat-server latest 0e0b79a8b21e 13 minutes ago 221 MB
alpine 3.5 4a415e366388 7 weeks ago 3.99 MB
joshgordon/nyancat-telnet latest ea00a2adcc4b 11 months ago 42 MB
我是怎么做到的!!!给 alpine 美女喂了点东西就从 3.99 MB 涨到了 221 MB ?!
优化方法
其实就是刚才的层的问题。Docker 会保存下来每一层。安装了一堆包后保存了一下,删除包后也有保存,但是,并不会删除之前保存的层。
多层在开发过程中是很有优势的,但是在发布时候应该尽可能用最少的层。
于是新的 Dockerfile
诞生了:
FROM alpine:3.5
LABEL \
maintainer="Wei He <[email protected]>" \
verion="1.0" \
description="Nyancat Telnet Server"
RUN \
apk upgrade --update && \
apk add g++ make git autoconf automake && \
cd /tmp && git clone https://github.com/klange/nyancat.git && \
cd /tmp/nyancat && make && \
cp ./src/nyancat /usr/local/bin/ && \
cd / && rm -rf /tmp/nyancat && \
cd /tmp && git clone https://github.com/ddhhz/onenetd.git && \
cd /tmp/onenetd && autoreconf -vfi && ./configure && make && \
cp ./onenetd /usr/local/bin && \
cd / && rm -rf /tmp/onenetd && \
apk del --purge g++ make git autoconf automake && \
:
EXPOSE 23
ENTRYPOINT ["onenetd", "-v1", "0", "23", "nyancat", "--telnet"]
重新 docker build
:
$ docker build -f Dockerfile . -t ddhhz/nyancat-server
Sending build context to Docker daemon 65.54 kB Step 1/5 : FROM alpine:3.5 ---> 4a415e366388 Step 2/5 : LABEL maintainer "Wei He" verion "1.0" description "Nyancat Telnet Server" ---> Running in cec170bdbdab ---> b903ab18f6ab Removing intermediate container cec170bdbdab Step 3/5 : RUN apk upgrade --update && apk add g++ make git autoconf automake && cd /tmp && git clone https://github.com/klange/nyancat.git && cd /tmp/nyancat && make && cp ./src/nyancat /usr/local/bin/ && cd / && rm -rf /tmp/nyancat && cd /tmp && git clone https://github.com/ddhhz/onenetd.git && cd /tmp/onenetd && autoreconf -vfi && ./configure && make && cp ./onenetd /usr/local/bin && cd / && rm -rf /tmp/onenetd && apk del --purge g++ make git autoconf automake && : ---> Running in 05acf0bbca6a ... ---> a47c97ca49c9 Removing intermediate container 05acf0bbca6a Step 4/5 : EXPOSE 23 ---> Running in a7e6e77354c9 ---> 1b1c44e12b84 Removing intermediate container a7e6e77354c9 Step 5/5 : ENTRYPOINT onenetd -v1 0 23 nyancat --telnet ---> Running in cf5a7f3f1a6a ---> 5ffd3f6b5393 Removing intermediate container cf5a7f3f1a6a Successfully built 5ffd3f6b5393
已经从刚才的 8 层减少到了 5 层。Docker 保存 RUN 这层的时候我已经把多余的包都删掉了。
看看效果:
REPOSITORY TAG IMAGE ID CREATED SIZE
ddhhz/nyancat-server latest 5ffd3f6b5393 3 minutes ago 5.15 MB
<none> <none> 0e0b79a8b21e 24 minutes ago 221 MB
alpine 3.5 4a415e366388 7 weeks ago 3.99 MB
joshgordon/nyancat-telnet latest ea00a2adcc4b 11 months ago 42 MB
简直了 从刚才的 221 MB 减肥到了 5.15 MB。
Source:
0x05 - 发布到 DockerHub
流程简单列一下:
- 建立 Github repo 并把 Dockerfile 放进去。
- 登陆 https://hub.docker.com
- 链接 Github 账户
- Create Automated Build
- 手动 POST 或 Github push 触发 build
0x06 - 服务器 nyancat telnet 服务上线
服务器防火墙打开 23 端口,运行:
$ docker run -d --name nyancat-server --restart=always -p 23:23 ddhhz/nyancat-server
Unable to find image 'ddhhz/nyancat-server:latest' locally
latest: Pulling from ddhhz/nyancat-server
627beaf3eaaf: Already exists
cf86dd0cc659: Pull complete
Digest: sha256:cd147440427e8fa15aaf10d0832d0491ad70eb416eaa2a9854d349533c8d32fc
Status: Downloaded newer image for ddhhz/nyancat-server:latest
3b13880ed9b1272427eca4fcab8cb206c2060d956a206d0e6fbab18693012632
成功!Demo:把 terminal 拉大一些然后 一分钟 3 兆流量,我看看就好。已经 CNAME 到原作者的:telnet nyancat.whe.me
telnet nyancat.dakko.us
;或者本地测试吧。
乞丐版谷歌云从 Node 版 joshgordon/nyancat-telnet:latest
切换到 ddhhz/nyancat-server:latest
系统资源占用对比:
Comments
注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。