Docker:快速上路

一. 简介

Docker核心是由Linux Namespace 的隔离能力、Linux Cgroups 的限制能力,以及基于 rootfs 的文件系统三个组成,

枯燥的指令集毫无乐趣,所以我借鉴了他人的教学方法,采用一个小demo从头到尾运行一边docker镜像的全生命流程。

二. 构建流程

我们今天采用docker进行一个Flask Web项目的全流程构建,部署和推送等。

相关代码在此链接中:flask_web项目地址

2.1 构建App

这个项目将启动一个Flask项目,暴露一个18080的端口,当访问Web根目录时,将会返回向一个'Hello World!' + hostname的字符串,hostname代表当前容器的hostname。
app.py文件如下:

from flask import Flask
import socket

app = Flask(__name__)


@app.route('/')
def hello_world():
    hostname = socket.gethostname()
    return 'Hello World!' + hostname


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=18080)

2.2 编写Dockerfile

Dockerfile 的设计思想,是使用一些标准的原语,描述我们所要构建的 Docker 镜像。并且这些原语,都是按顺序处理的,这也算是一种应用的自描述,是一种很符合DevOps的要求。

关于编写Dockerfile的源码也已将放到GitHub上面了,内容如下:


# 拉取Python3
FROM rackspacedot/python37

# 将工作目录切换为/app
WORKDIR /app

# 将当前目录下的所有内容复制到/app下
ADD . /app

# 使用pip命令安装这个应用所需要的依赖
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# 允许外界访问容器的18080端口
EXPOSE 18080

# 设置容器进程为:python app.py,即:这个Python应用的启动命令
CMD ["python", "app.py"]

关于docker file里面的原语内容可以如下理解:

  • FROM:指docker从rackspacedot拉取一个python37的基础镜像
  • WORKDIR:切换容器的工作目录到/app目录下
  • ADD:理解为复制dockerfile所在目录的内容到/app工作目录
  • RUN:容器里执行 shell 命令
  • EXPOSE:声明容器暴露一个端口18080
  • CMD:指定 python app.py 为这个容器的进程,app.py 的实际路径是 /app/app.py。
  • ENTRYPOINT(默认):实际进程是:/bin/sh -c "python app.py",即 CMD 的内容就是 ENTRYPOINT 的参数,所以Docker 容器的启动进程为 ENTRYPOINT,而不是 CMD。

2.3 docker build

docker build 会自动加载当前目录下的 Dockerfile 文件,然后按照顺序,执行文件中的原语。
在编写Dockerfile所在的目录,执行如下的指令:

docker build -t flask_web .

关于指令细节:

  • -t:给这个镜像加一个 Tag
  • flask_web:这个镜像的名称
build success

Dockerfile 中的每个原语执行后,都会生成一个对应的镜像层。即使原语本身并没有明显地修改文件的操作(比如,ENV 原语),它对应的层也会存在。只不过在外界看来,这个层是空的。

当我们构建成功后,可以使用如下指令查看本地镜像内容:

docker image ls
docker image list

不过,上图中构建出的镜像非常大,这说明我选择的原始镜像非常有问题,这也是后续优化的点,这章不做讨论。

2.4 docker run

构建完的镜像都存在于本地,所以我们可以非常简单的使用docker run指令来运行。
指令如下:

docker run -p 18090:18080 flask_web

关于指令细节,作用如下:

  • p:指定映射端口,将宿主机18090端口映射到容器的18080端口
  • flask_web:为本地flask_web的镜像名称
runtime
  • 容器启动之后,我可以使用 docker ps命令看到:
docker ps
ps
  • 我们需要访问该web,可以浏览器访问:http://localhost:18090/
    我们将看到Hello World!2d278afce7a7的内容,代表我们容器的成功运行。

2.5 docker push

当我们完成镜像的编写,我们可以把这个容器的镜像上传到 DockerHub 上分享给更多的人。

  1. 首先需要注册一个 Docker Hub 账号,然后使用docker login命令登录
  2. docker tag给容器镜像取一个完整的名字
docker tag flask_web wy1140174371/flask_web:v1.0.0

具体指令作用如下:

  • flask_web:代表tag的镜像名称
  • wy1140174371:即为个人的dockerhub账户,也叫‘repository’
  • /flask_web:代表当前项目的名称
  • v1.0.0:代表tag的版本,小步增量
  1. 采用docker push推送到docker hub上
    执行如下指令:
docker push wy1140174371/flask_web:v1.0.0

上传成功后,可以在此处查看docker hub的镜像内容,flask_web

flask_web

2.6 docker commit(optional)

docker commit把一个正在运行的容器,直接提交为一个镜像。一般来说,需要这么操作原因是:当这个容器运行起来后,我又在里面做了一些操作,并且要把操作结果保存到镜像里。例如我在容器内新增了一个文件。
具体指令可以使用如下:

docker commit container-id wy1140174371/flask_web:v1.0.1

具体参数含义如下:

  • container-id:此处需要自己替换为正在运行的容器id,通过docker ps获取。
  • v1.0.1:版本注意增量

三. Volume

Volume 机制,允许我们将宿主机上指定的目录或者文件,挂载到容器里面进行读取和修改操作.

3.1 俩种方式

在 Docker 项目里,它支持两种 Volume 声明方式,可以把宿主机目录挂载进容器的 /test 目录当中:

docker run -v /test ...
docker run -v /home:/test ...

当然俩种方式有一定的区别:

  • 不声明式
    由于没有显示声明宿主机目录,那么 Docker 就会默认在宿主机上创建一个临时目录 /var/lib/docker/volumes/[VOLUME_ID]/_data,然后把它挂载到容器的 /test 目录上。
  • 指定宿主机目录
    这种情况下,Docker 就直接把宿主机的 /home 目录挂载到容器的 /test 目录上。

3.2 原理

这个功能利用了Linux 的绑定挂载(bind mount)机制。它的主要作用就是,允许我们将一个目录或者文件,而不是整个设备,挂载到一个指定的目录上。并且,这时我们在该挂载点上进行的任何操作,只是发生在被挂载的目录或者文件上,而原挂载点的内容则会被隐藏起来且不受影响。

3.3 图解

图解如下,mount --bind /home /test,会将 /home 挂载到 /test 上。其实相当于将 /testdentry,重定向到了 /homeinode。这样当我们修改 /test 目录时,实际修改的是 /home 目录的 inode。这也就是为何,一旦执行 umount 命令,/test 目录原先的内容就会恢复:因为修改真正发生在的,是 /home 目录里。

architecture

四. 拓展

4.1 docker exec

docker exec指令可以让我们进入容器内,并在容器内执行相关操作。
如下例子,就是一个进入容器后,并运行/bin/sh.

docker exec -it container-id /bin/sh

4.2 docker inspect

docker inspect指令可以看到当前正在运行的 Docker 容器的进程号(PID),即宿主机上进程号。
具体如下:

docker inspect --format '{{ .State.Pid }}' container-id

4.3 ENTRYPOINT

Docker 容器的启动进程为 ENTRYPOINT,而不是 CMD,即 CMD 的内容就是 ENTRYPOINT 的参数。

4.4 Docker Registry

DockerHub只是官方的镜像上传系统,但是我们也是可以自建其他的镜像系统的,例如Harbor。就比如我们的Java领域的Maven仓库,除了maven,github,sonatype等外,也可以自建nexus仓库等,按照实际需求来即可。

五. 总结

关于docker已经使用很多年了,在最近的时间内重新巩固了一下基础知识。这些东西其实光看光听帮助不大,主要的是我们需要通过实操来巩固记忆。
学习金字塔模型底层的主动式学习是最有效的方式,我一直是一个推崇方法论的实践者。
我经过了很久的工作秘密,确定了走DevOps的方向,在此路上我还是一个新手,大家共勉。

欢迎关注我的博客:https://blog.wyatt.plus

Reference

https://time.geekbang.org/column/article/18119?utm_campaign=guanwang&utm_source=baidu-ad&utm_medium=ppzq-pc&utm_content=title&utm_term=baidu-ad-ppzq-title
http://docker-saigon.github.io/post/Docker-Internals/#how:cb6baf67dddd3a71c07abfd705dc7d4b
https://medium.com/@kasunmaduraeng/docker-namespace-and-cgroups-dece27c209c7

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容