Docker官网浅学---最原汁原味的Docker循序渐进接触之旅

一、什么是容器(container)?

1.概念

​ 沙盒进程,与主机上的所有其他进程隔离,这种隔离利用了Linux的内核特性,Docker把这些变得易于使用。

2.总结

  • 是镜像的运行时实例。可以利用DOCKERAPI或CLI创建、启动、停止、移除或删除。
  • 可在本地、虚拟机上运行或发布到云上。
  • 具有可移植性(可以在任何操作系统上运行)。
  • 容器是彼此独立的,运行各自的软件、二进制和配置。

二、什么是容器镜像(container image)?

1.概念

​ 当运行一个容器,它会使用一个被隔离的文件系统。这个自定义的文件系统就是容器镜像提供的。因为镜像包含容器的文件系统,所以它必须包含运行一个应用的所有必须的东西 - 所有依赖、配置、脚本、二进制等等。镜像同样包含一些容器的其他配置,比如环境变量,默认的运行命令和其他的元数据。

三、Docker 架构

  • Docker使用client-server架构,即Docker client 与Docker daemon交互,Docker daemon做一些比较重的工作,比如建立、运行、分发Docker容器。
  • Docker client可以和Docker daemon可以运行在同一个系统,或也可以Docker client与远程Docker daemon交互。
  • Docker client与daemon交互使用基于UNIX sockets或网络接口的REST API。
  • 另一种Docker client是Docker Compose,它可以让你使用由大量容器组成的应用。
    在这里插入图片描述

四、Docker概览

  • Docker是一个提供应用开发、运输和运行的开放平台。Docker使应。用与基础设施能够分离开来,这样可以做到快速部署。
  • 使用Docker,能够像管理应用一样管理基础设施。
  • 利用Docker方法的优势,可以做到快速代码运输、测试和开发,这会极大的减少代码开发与生产部署的时间。

五、Dockerfile知识汇总

1. 概念

​ Dockerfile是一个简单的基于文本的指令脚本,被用来创建一个容器镜像。

2.代码示例与解读

# syntax=docker/dockerfile:1
FROM node:12-alpine
RUN apk add --no-cache python2 g++ make
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"] 
docker build -t getting-started .
  • 此命令使用上述的Dockerfile文件去创建一个新的容器镜像。
  • 你会注意到 ,当命令 运行时,有很多 layers 被下载,是因为我们指示这次构建我们想从node:12-alpine这个镜像开始,但是我们的机子上并没有此镜像,因此需要下载。
  • 当镜像被下载完毕后,我们copy到我们机子并使用yarn命令去安装我们应用的依赖。
  • CMD指令指示了当我们启动容器时的默认命令。
  • -t参数标识我们的镜像,这是镜像的最终名称,因为我们将镜像命名为getting-started,所以我们可以在运行容器的时候引用该镜像。
  • docker buidler命名的最后的.告诉Docker应该在当前文件下找Dockerfile文件。

六、容器命令积累

  1. Docker 启动命令* -> docker run -dp 3000:3000 getting-started //-d 后台启动; -p 端口映射。
  2. Docker 镜像构建命令 -> docker build -t getting-started . // -t 标识镜像tags; . 告诉Docker从当前文件下找Dockerfile文件。
  3. Docker 查看日志命令 -> docker logs-f <container’id> 。
  4. Docker 运行开发模式容器命令 -> docker run -dp 3000:3000 -w /app -v “$(pwd):/app” node:12-alpine sh -c “yarn install && yarn run dev” // 12节有详细解释。
  5. Docker 创建网络 -> docker network create todo-app 。
  6. Docker 连接mysql -> docker exec -it mysql -u root -p 。
  7. Docker 指定网络运行容器 -> docker run -it --network todo-app nicolaka/netshoot // nicolaka/netshoot 附带了许多工具,这些工具对于故障排除或调试网络问题非常有用。
  8. Docker docker-compose启动 -> docker-compose up -d // 使用docker-compose up命令启动应用程序堆栈。我们将添加-d标志来在后台运行一切。
  9. Docker 监听指定容器的日志在多容器应用环境下 -> docker-compose logs -f [service-name] 。
  10. Docker Compose 运行命令 -> docker-compose up -d 。
  11. Docker Compose 查看容器日志 -> docker-compose logs -f 。
  12. 进入dokcer redis -> docker exec -it [容器id] redis-cli
  13. redis容器挂在目录并使用lus脚本 ->docker run
    -d --privileged=true
    -p 6379:6379
    -v /docker/redis/conf/redis.conf:/etc/redis/redis.conf
    -v /docker/redis/data:/data
    –name redistest2 redis:4.0 redis-server /etc/redis/redis.conf --appendonly yes
    redis-cli --eval /data/gupao.sh

七、使用Docker CLI Remove容器

1.步骤

​ docker ps: 获得容器ID

​ docker stop

​ docker rm

2.Note

​ 以上命令可以合并为docker rm -f

八、分享应用

1.术语解读

  • ​ Docker registry: 默认的注册中心是 Docker Hub。
  • ​ Docker ID: Docker账号给予你访问世界上最大的容器镜像库与社区—Docker Hub。
  • ​ Docker Repository: 要想push镜像,需要现有一个仓库。

2. 推送镜像

  1. ​ docker tag 【image-name】 YOUR-USER-NAME/【image-name】
  2. ​ docker login -u YOUR-USER-NAME
  3. ​ docker push YOUR-USER-NAME/【image-name】:【tagName】

九、在全新的实例上运行镜像

1.测试网站

https://labs.play-with-docker.com/    

2.使用说明

​ 点击右侧 ADD NEW INSTANCE在终端中输入运行的命令:

docker run -dp 3000:3000 YOUR-USER-NAME/getting-started

十、容器的文件系统

1.概念

​ 当运行容器时,他会使用其镜像不同的层作为其文件系统,每一个容器都会获得其独立的“暂存空间”用来创建/修改/移除文件,任何的改变都不会影响其他的容器,即使他们使用同一个镜像。

十一、容器数据卷

1.卷的作用

​ 卷提供了将容器的特定文件系统路径连接回主机的能力。如果容器中的一个目录被挂载,那么在主机上也会看到该目录中的更改。如果我们在容器重启时挂载相同的目录,我们将看到相同的文件。

2.卷的类型

  • named volume: 类似一个存储数据的桶,Docker持有并维护它在磁盘上的物理位置,仅需要数据卷的名称,每次使用数据卷的时候,Docker将会提供正确的数据。
  • bind mounts: 可以控制主机上的准确挂载点。我们可以使用它来持久化数据,但它通常用于向容器中提供额外的数据。在处理应用程序时,我们可以使用绑定挂载将源代码挂载到容器中,让它看到代码更改、响应,并让我们立即看到更改。

3.卷类型的快速对比

	**绑定挂载**和**命名卷**是Docker引擎附带的两种主要卷类型。不过,还可以使用其他卷驱动程序来支持其他用例(SFTP、Ceph、NetApp、S3等)。
Named VolumesBind Mounts
Host LocationDocker选择你掌控
Mount Example(using -v)my-volume:/usr/local/data/path/to/data:/usr/local/data
用容器内容填充新卷
支持数据卷驱动程序

4.数据持久化

a.关于数据持久化的理论分析:

​ 假设数据库是一个文件而已,如果我们可以把那个文件持久化到宿主机上,并使之可以为下一个容器所使用,那么它将从上一个容器结束的地方开始。

​ 通过创建一个数据卷并把它挂载到数据存储的文件,我们就可以持久化数据。比如我们这个例子:当容器写入todo.db文件时,它将被持久化到卷中的主机上。

b.关于使用数据卷实现数据持久化的实践:

  • ​ 创建数据卷 -> docker volume create todo.db

  • ​ 删除之前未使用数据卷的Docker容器

  • ​ 重启容器,并使用一个-v参数指定一个具体的数据卷重启容器,我们将使用指定的卷并将其挂载到/etc/todos,这将捕获在该路径上创建的所有文件

    -> docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started

十二、启动开发模式容器

1.前提条件

为了运行我们的容器来支持一个开发环境的工作流程,我们需要保证:

  • 把我们的源码挂载进容器。
  • 安装所有依赖项,包括“dev”依赖项。
  • 启动nodemon来观察文件系统的变化。(对于基于node的应用程序,nodemon是一个很好的工具,可以监视文件更改,然后重新启动应用程序。在大多数其他语言和框架中都有等价的工具。)

2. 关于启动开发模式容器的实践

  1. ​ 确保没有任何该镜像之前的容器在运行。

  2. ​ 运行一下命令:

  3. ​ 查看日志 -> docker logs-f <container’id>

    docker run
         -dp 3000:3000
    	 -w /app            // 设置工作目录,或者说,当前命令从那个文件运行
         -v "$(pwd):/app"   // 绑定挂载主机上的一个文件路径到容器中的 /app文件 Note: $(pwd)命令会运行失败,需要给定一个主机上的绝对路径,且格式是						 这样的 G:demo/app -> /g/demo/app
    	 node:12-alpine
    	 sh -c "yarn install && yarn run dev" // 安装所有依赖并运行, alpine没有bash命令
    

3.使用绑定挂载的优势

在本地开发设置中,使用绑定安装非常常见。这样做的好处是,开发机器不需要安装所有的构建工具和环境。使用一个docker run命令,dev环境就可以pull到所有所需并完美运行。

十三、多容器应用

1.架构设计的原因

​ 一般来说容器只应做一件事情,并做好,且一个容器运行多个进程更复杂的操作,还有很多其他的原因,所以我们的应用应当这样设计:
在这里插入图片描述

2.容器网络

​ 默认情况下,容器是独立运行,并不会知道同机器上其他进程或其他容器的的 任何情况,那容器间该怎样通信?答案就是网络,但你也没必要成为一名网络工程师,记住一条原则就够了: 如果容器在一个网络他们就可以交互,如果不是就不能

3.将一个容器放在网络上的两种方式

有两种方法将一个容器放在网络上:

  1. 在开始时分配它。
  2. 连接一个现有的容器。

4.启动MySQL

  1. 创建网络 -> docker network create todo-app
  2. 启动一个MySQL容器并将其连接到网络 -> docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=todos mysql:5.7
  3. 连接mysql验证其是否启动 -> docker exec -it mysql -u root -p
  4. 连接上以后输入 SHOW DATABASES;

5.连接MySQL

mysql已经启动并正常运行,那么我们如何才能使用其工作,或者说我们的app如何能连接到该容器,首先我们要弄清楚如何找到mysql容器:

  1. 使用容器 nicolaka/netshoot,确保它连接的是相同的网络 -> docker run -it --network todo-app nicolaka/netshoot在 nicolaka/netshoot
  2. 容器内,使用dig命令,它是一个非常有用的DNS工具,我们将用它查找hostname为mysql的IP地址 -> dig mysql
    在这里插入图片描述
  3. 虽然mysql通常不是一个有效的主机名,但Docker能够将其解析为具有网络别名的容器的IP地址(还记得我们之前使用的——network-alias标志吗?)这意味着…我们的应用程序只需要简单地连接到一个名为mysql的主机,它将与数据库对话!

6.运行使用mysql的app

1.mysql设置

todo应用程序支持设置一些环境变量来指定MySQL连接设置 :

  • MYSQL_HOST - the hostname for the running
  • MySQL serverMYSQL_USER - the username to use for the connection
  • MYSQL_PASSWORD - the password to use for the connection
  • MYSQL_DB - the database to use once connected

注意 :***虽然使用env vars设置连接设置通常可以用于开发,但在生产环境中运行应用程序时非常不建议这样做。**你的应用程序需要知道如何查找变量并获取文件内容。[比较难先不做探究]*

2.关于运行使用mysql的app的实践:

​ a.运行命令:

docker run -dp 3000:3000
            -w /app -v "$(pwd):/app"
            --network todo-app
            -e MYSQL_HOST=mysql
            -e MYSQL_USER=root
            -e MYSQL_PASSWORD=secret
            -e MYSQL_DB=todos
            node:12-alpine
            sh -c "yarn install && yarn run dev"   

​ b.查看日志 -> docker logs -f

​ c.进入mysql查看数据 -> docker exec -it mysql -p todos

十四、使用Docker Compose

1.Docker Compose的作用

  1. Dcoker Compose 是用来帮助定义和分享多容器应用,在Docker Compose帮助下,我们可以用一个Yaml文件来定义我们的服务,仅用一个命令就可以代替十三节这些繁杂的命令。
  2. 使用Compose的最大优点是,您可以在文件中定义应用程序堆栈,将其保存在项目repo的根目录(现在它是版本控制的),并很容易让其他人对您的项目做出贡献。有人只需要复制你的repo并启动compose应用程序。事实上,你可能会看到GitHub/GitLab上有相当多的项目正在做这一点。

2.安装Docker Compose

Dock Desktop已经自动安装Docker Compose,如果你是用的Linux主机,那么你需要手动安装Docker Compose: https://docs.docker.com/compose/install

3.创建Compose文件

version: "3.7"


services:
  app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - /g/Demo/getting-started/app:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos
  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos


volumes:
  todo-mysql-data:

4.运行应用栈

  • 运行命令 -> docker-compose up -d
  • 查看容器日志 docker-compose logs -f

十五、关于镜像构建的最佳实践

1.关于层的一个定律

一旦一个layer发生了变化,那么它所有的下流的层都将被重新创建。

2.延展出关于镜像最佳构建的一个特别有趣的问题

​ 首先,还记得我们的Dockerfile文件嘛,用你刚学到的去看看它的镜像历史输出吧

# syntax=docker/dockerfile:1
FROM node:12-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]

在这里插入图片描述
您可能还记得,当我们更改映像时,必须重新安装yarn依赖项。有办法解决这个问题吗?每次构建时都围绕着相同的依赖关系交付没有多大意义,对吧?

3.使用Layer caching

1.首先我们来看一张图:
在这里插入图片描述
请运用【十五.1】的定律来尝试理解改图左侧和右侧的Dockerfile文件的不同

2.创建忽略文件: .dockerignore

3.重新构建镜像 -> docker build -t getting-started . // 注意你会看到很多层被重构了,这是因为我们的Dockerfile文件改变了很多

4.多阶段构建

1.顾名思义,多阶段构建,指使用多个阶段构建镜像,是一个非常有用的帮助。

  • 将构建时依赖项与运行时依赖项分开
  • 通过只发送应用程序需要运行的内容来减少整体图像大小
  • 多级构建还通过将构建时依赖关系与运行时依赖关系分离,帮助我们减少整体图像大小并提高最终容器的安全性。

2.两个例子与解析

​ a.Maven/Tomcat example:

​ 当构建一个基于java的应用,JKD仅在编译源码成字节码时被需要,可是,JDK在产品中并不需要,同样,你可能使用Maven或Gradle来构建APP,它们在我们的最终镜像中同样不需要,那么,多阶段构建就可以帮助你解决这个问题。

​ 在下面这个例子中,我们使用一个阶段“build”来使用Maven来执行真正的Java build。在第二个阶段(from FROM tomcat),我们把阶段“build”复制到文件中。这些也不是最终镜像所需要的。
在这里插入图片描述
b.React example:

​ 我们构建React Applications,我们需要Node环境来编译Js代码等等到H5页面,在某种情况下,我们不需要把Node环境放到我们的产品中,为什么不把静态资源放到Nginx中交付呢?

​ 下面的代码的意思是,我们使用node:12来执行build然后把输出复制到Nginx容器中。
在这里插入图片描述
c. getting-started’s Dockerfile:
在这里插入图片描述

  • 29
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赞一下鼓励

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值