Docker 入门(2019-07-31)

大纲

  • docker是什么?
  • 谁在使用Docker?
  • docker与虚拟机
  • docker的使用
    • 安装
      • Docker Machine 与 Docker Desktop for Mac
    • 使用
    • docker如何制作镜像?
    • 运行一个docker容器
  • docker的架构

前言

准备环境是一件高成本、费时、手工且十分不优雅的事情。

1. docker是什么?

icon

Docker 是一个允许用户“在任何地方构建、分发及运行任何应用”的平台(引擎)。

一个架子,可以用来放很多抽屉。这样想象一下。

Docker提供了一种在容器中运行安全隔离的应用程序的方法,它与所有依赖项和库打包在一起。
Docker 是一个开源的应用容器引擎[1],让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制[2],相互之间不会有任何接口。

1 - 应用容器引擎
2 - 沙箱机制 - 网络编程虚拟执行环境

Sandboxie(又叫沙箱、沙盘)即是一个虚拟系统程序,允许你在沙盘环境中运行浏览器或其他程序,因此运行所产生的变化可以随后删除。它创造了一个类似沙盒的独立作业环境,在其内部运行的程序并不能对硬盘产生永久性的影响。其为一个独立的虚拟环境,可以用来测试不受信任的应用程序或上网行为。

简单来讲指的是虚拟环境、系统和真是环境相同的,主要的功能就是研究危险东西,比如一些随时可能导致系统崩溃的程序、病毒等,咱们常见的虚拟机就是一个沙箱。

一个完整的Docker有以下几个部分组成:

  1. DockerClient客户端
  2. Docker Daemon守护进程
  3. Docker Image镜像
  4. DockerContainer容器 [docker教程]

特点:

  • 上手快

用户只需要几分钟,就可以把自己的程序“Docker 化”。Docker 依赖于“写时复制” (copy-on-write)模型,使修改应用程序也非常迅速,可以说达到“随心所致,代码即改” 的境界。

随后,就可以创建容器来运行应用程序了。大多数 Docker 容器只需要不到 1 秒中即可 启动。由于去除了管理程序的开销,Docker 容器拥有很高的性能,同时同一台宿主机中也 可以运行更多的容器,使用户尽可能的充分利用系统资源。

  • 职责的逻辑分类

使用 Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如 何管理容器。Docker 设计的目的就是要加强开发人员写代码的开发环境与应用程序要部署 的生产环境一致性。从而降低那种“开发时一切正常,肯定是运维的问题(测试环境都是正 常的,上线后出了问题就归结为肯定是运维的问题)”

  • 快速高效的开发生命周期

Docker 的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用 程序具备可移植性,易于构建,并易于协作。(通俗一点说,Docker 就像一个盒子,里面 可以装很多物件,如果需要这些物件的可以直接将该大盒子拿走,而不需要从该盒子中一件 件的取。)

  • 鼓励使用面向服务的架构

Docker 还鼓励面向服务的体系结构和微服务架构。Docker 推荐单个容器只运行一个应 用程序或进程,这样就形成了一个分布式的应用程序模型,在这种模型下,应用程序或者服 务都可以表示为一系列内部互联的容器,从而使分布式部署应用程序,扩展或调试应用程序 都变得非常简单,同时也提高了程序的内省性。(当然,可以在一个容器中运行多个应用程序)

指明你需要的资源,调用外面的资源,也可以有内部分离。
也可以有个公共的,然后其他的指向过来。

2. 谁在使用Docker?

世界领先的公司和数百万开发人员使用Docker来部署和管理应用程序,包括:


美国大都会人寿保险公司

美国自动数据处理公司

3. docker与虚拟机

虚拟机

所谓虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能、并可以运行在一个完全隔离环境中的完整计算机系统。虚拟机就是相对于传统计算机而言的计算机概念,一个非实体的计算机,但具有所有传统计算机的功能。

下面我们来分析一下,docker与虚拟机。看看他们各自是怎么实现的?

image.png

虚拟机和Docker都能够给一台宿主机上的应用提供隔离的运行环境。区别是什么呢?

从上图右边虚拟机架构图能看出,虚拟机里在宿主操作系统和物理硬件之间多了一个中间层:Hypervisor。

Hypervisor是一种运行在物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享一套基础物理硬件,事实上成为虚拟环境中的“元”操作系统,Hypervisor可以协调访问服务器上的所有物理设备和虚拟机,也称为虚拟机监视器(Virtual Machine Monitor)。Hypervisor是所有虚拟化技术的核心。当服务器启动并执行Hypervisor时,它会给每一台虚拟机分配适量的内存、CPU、网络和磁盘,并加载所有虚拟机的客户操作系统,每台虚拟机有自己的虚拟操作系统和存储空间,因此需要消耗宿主机大量的物理资源,同时也需要花费一定时间来启动。

而上图左边,Docker直接运行在宿主机的操作系统上,没有Hypervisor这个中间层。Docker实际上就是运行于操作系统上的普通进程,通过Linux Primitives实现的彼此隔离,但是共享同一个操作系统内核。

正因为这种共享性,使得Docker的资源占用远小于虚拟机,而且启动速度也远远快于虚拟机。

接下来,我们可以用一张图形象的看下使用上的一些区别:

image.png

Size:
1.Mac上启动Windows虚拟机所占内存:

虚拟机

Docker

Startup:

  1. 虚拟机:Windows上启动ubuntu要2分钟左右,而Mac上启动Windows也要将近1分钟。
  2. docker只需要2s。

4. docker的使用

上面我们介绍了许多原理性的知识点,所有的原理都是为了实现,那么下面我们来上手实践一下,看是不是真的像原理以及和虚拟机的对比分析那样呢?

1. 安装

  1. 双击Docker.dmg打开安装程序,然后将Moby the whale拖到Applications文件夹。

    image.png

  2. 双击Docker.appApplications文件夹以启动Docker。(在下面的示例中,“应用程序”文件夹处于“网格”视图模式。)

老版本
新版

Docker.app启动后,系统会提示您使用系统密码进行授权。需要特权访问才能安装网络组件和Docker应用程序的链接。

image.png

顶部状态栏中的鲸鱼表示Docker正在运行,并且可以从终端访问。


image.png

如果您刚刚安装了该应用程序,您还会收到一条成功消息,其中包含建议的后续步骤和本文档的链接。单击
鲸鱼菜单

状态栏中的whale()以关闭此弹出窗口。

image.png
  1. 单击whale以获取首选项和其他选项。
  2. 选择关于Docker以验证您是否拥有最新版本。

这样我们就启动并运行了Docker Desktop for Mac。

  1. 可以在控制台使用docker -v进行版本查看。
    image.png

2. 使用

1. Check versions

$ $ docker --version
Docker version 19.03.1, build 74b1e89

$ docker-compose --version
docker-compose version 1.24.1, build 4667896b

$ docker-machine --version
docker-machine version 0.16.1, build cce350d7

2. Explore the application

我们运行docker run hello-world:

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
ca4f61b1923c: Pull complete
Digest: sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

3. 下载mongo镜像并启动一个容器(mongo的容器)

$ docker run --name mongo -d -p 27017:27017 mongo
Unable to find image 'mongo:latest' locally
latest: Pulling from library/mongo
...
306b575ddfff: Pull complete
ee1475733b36: Pull complete
Digest: sha256:ec1fbbb3f75fdee7c3433ce2d5b8200e7c9916c57902023777bec5754da5e525
Status: Downloaded newer image for mongo:latest
94678bd126546197658d6fb8a4a78e264c12a9227187b55c5d2a0de74ce34ac2

-d 后台执行
-p 端口映射出来,让宿主机可以访问到

4. Docker子命令

命令 目的
docker build 构建一个Docker镜像
docker run 以容器形式运行一个Docker镜像
docker commit 将一个Docker容器作为一个镜像提交
docker tag 给一个Docker镜像打标签
docker start [name|container id] 启动一个被暂停的容器
docker stop [name| container id] 停止一个已经启动的容器
docker rm name/id 可以删除已经停止的容器
docker rm -f name/id 可以删除正在运行的容器。
docker images 查看镜像
docker rmi id 删除镜像
docker push xxx 发布镜像
docker pull xxx 下载镜像

3. 制作镜像

我们先来说一下镜像和容器。


image.png

一个简单的理解就是将镜像看做类而将容器看做对象。对象是类的具体实例,同样,容器是镜像的实例。用户可以从单个镜像创建多个容器,就像对象一样,他们之间全都是相互隔离的。不论用户在对象内修改了什么,都不会影响类的定义 -- 它们从根本上就是不同的东西。

1. 创建镜像

创建镜像有4种标准的方式。

  • 手工
  • Dockerfile
  • Dockerfile以及配置管理工具(CM)
  • 从头创建镜像并导入一组文件

今天咱们主要介绍第二种:Dockerfile。

# 定义基础镜像
FROM node:12.8.1-stretch 
# 声明维护人员
MAINTAINER zhulinger520@163.com
# 克隆代码
RUN git clone https://github.com/springHyc/node-hello-world.git
# 移动到新的克隆目录
WORKDIR /node-hello-world/blog
# 运行node包管理器的安装命令(npm)
RUN npm install > /dev/null
# 指定从都构建的镜像启动的容器需要监听的端口
EXPOSE 4321
# 指定在启动时需要运行的命令
CMD ["node", "index.js"]

执行创建镜像的命令:
$ docker build -t blog-image:0.0.1 .

Sending build context to Docker daemon  2.048kB
Step 1/7 : FROM node:12.8.1-stretch
12.8.1-stretch: Pulling from library/node
9cc2ad81d40d: Pull complete 
e6cb98e32a52: Pull complete 
ae1b8d879bad: Pull complete 
42cfa3699b05: Pull complete 
053cac798c4e: Downloading [===========>                                       ]  49.24MB/215.1MB
e11ff976ff71: Download complete 
224731f6b161: Downloading [=============================>                     ]  13.04MB/21.88MB
56ed10abd115: Download complete 
053cac798c4e: Downloading [============>                                      ]  55.66MB/215.1MB

053cac798c4e: Pull complete 
e11ff976ff71: Pull complete 
224731f6b161: Pull complete 
56ed10abd115: Pull complete 
f93be52154ee: Pull complete 
Digest: sha256:2eb5b7ee06215cda1c697c178978c51367b78ee3992a058f37b73616521fc104
Status: Downloaded newer image for node:12.8.1-stretch
 ---> e3e4ac3015dd
Step 2/7 : MAINTAINER zhulinger520@163.com
 ---> Running in d92c67510758
Removing intermediate container d92c67510758
 ---> a45bb1abc41a
Step 3/7 : RUN git clone https://github.com/springHyc/node-hello-world.git
 ---> Running in c9d2ff81c844
Cloning into 'node-hello-world'...
Removing intermediate container c9d2ff81c844
 ---> 4fe592793e15
Step 4/7 : WORKDIR /node-hello-world/blog
 ---> Running in 6d316304889d
Removing intermediate container 6d316304889d
 ---> 0cbd2e8a3354
Step 5/7 : RUN npm install > /dev/null
 ---> Running in acd2a325eee2
npm WARN meadowlark@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

Removing intermediate container acd2a325eee2
 ---> 09c6454af527
Step 6/7 : EXPOSE 4321
 ---> Running in af6b52b86a06
Removing intermediate container af6b52b86a06
 ---> 84f3511639f6
Step 7/7 : CMD ["node", "index.js"]
 ---> Running in 02a93459f5a6
Removing intermediate container 02a93459f5a6
 ---> a5cab15f2dcc
Successfully built a5cab15f2dcc
Successfully tagged blog-image:0.0.1

$ docker ps -a // 查看镜像

image.png

2. 运行一个Docker容器

$ docker run -p 4321:4321 --name blog1 blog-image

Unable to find image 'blog-image:latest' locally
docker: Error response from daemon: pull access denied for blog-image, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
See 'docker run --help'.
BR-IT-A00354:docker-blog bairong$ docker run -p 4321:4321 --name blog1 blog-image:0.0.1
the server/replset/mongos/db options are deprecated, all their options are supported at the top level of the options object [poolSize,ssl,sslValidate,sslCA,sslCert,sslKey,sslPass,sslCRL,autoReconnect,noDelay,keepAlive,keepAliveInitialDelay,connectTimeoutMS,family,socketTimeoutMS,reconnectTries,reconnectInterval,ha,haInterval,replicaSet,secondaryAcceptableLatencyMS,acceptableLatencyMS,connectWithNoPrimary,authSource,w,wtimeout,j,forceServerObjectId,serializeFunctions,ignoreUndefined,raw,bufferMaxEntries,readPreference,pkFactory,promiseLibrary,readConcern,maxStalenessSeconds,loggerLevel,logger,promoteValues,promoteBuffers,promoteLongs,domainsEnabled,checkServerIdentity,validateOptions,appname,auth,user,password,authMechanism,compression,fsync,readPreferenceTags,numberOfRetries,auto_reconnect,minSize,monitorCommands,retryWrites,useNewUrlParser,useUnifiedTopology,serverSelectionTimeoutMS,useRecoveryToken]
Wed, 21 Aug 2019 07:01:09 GMT body-parser deprecated bodyParser: use individual json/urlencoded middlewares at index.js:31:31
Wed, 21 Aug 2019 07:01:09 GMT body-parser deprecated undefined extended: provide extended option at node_modules/body-parser/index.js:105:29
Express started on http://localhost:4321;press Ctrl - C to terminate.

可以打开[http://localhost:43210/api](172.30.5.101:43210/api)进行查看

3. 一个复杂的Dockerfile

上面我们介绍了一个简单项目的制作镜像以及运行一个docker 容器。
下面我们来看一个比较复杂的Dockerfile。它里面包含了,一个简单前端(react)项目,一个后端服务(node)以及后端连接所需要的DB(mongo)。

FROM ubuntu:18.04

MAINTAINER 515020386@qq.com

# apt 更新软件列表
RUN apt update

# 安装依赖
RUN apt install nginx git curl mongodb -y
RUN curl -sL https://deb.nodesource.com/setup_9.x | bash - && apt-get install nodejs -y

# 前端打包
RUN git clone -b master https://github.com/springHyc/hehe-blog.git

WORKDIR /hehe-blog
RUN npm install 
RUN npm run build
RUN mv build /web

# 后端安装依赖
WORKDIR /
RUN git clone -b localdb https://github.com/springHyc/node-hello-world.git
WORKDIR /node-hello-world/blog
RUN npm install

# 添加nginx配置文件
ADD ./blog.conf /etc/nginx/conf.d/

# 添加启动文件
WORKDIR /
ADD ./run.sh /

#
EXPOSE 9998
#
CMD ["bash", "run.sh"]

这是生成的镜像:


image.png

这是运行的容器:

image.png

我们可以打开172.30.5.101:30001进行查看。

5. docker的架构

image.png

DockerHub 是有Dokcer公司运营的一个公共注册中心。
咱们可以将自己的镜像推上去,也可以从上面选择我们需要的镜像。

docker push命令可以将某一个镜像发布到官方网站。
Docker注册中心早就的是与GitHub相似的社交编码文化。

参考

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

推荐阅读更多精彩内容