Docker

2018-11-09  本文已影响0人  MuMu童鞋

Docker

Docker简介 -- Docker Engine

Docker Engine 也就是我们常说的 "Docker",是一种 C/S 模型,Docker服务端是一个服务进程,管理着所有的容器,Docker 客户端则扮演着 Docker 服务端的远程控制器,可以用来控制 Docker 的服务端进程。

用户通过 Docker 客户端向 Docker Daemon 发送 REST 请求。
Docker 包括这么几个部分:

docker engine

一般用命令行在客户端使用 Docker,比如

docker run ... # 运行容器
docker ps # 查看正在运行的容器

Docker优势

Docker 三大组件

docker
镜像

Docker 镜像是一个特殊的文件系统,这个文件系统封装了运行时需要的库、资源、应用等。

docker pull ubuntu:18.04 # 获取镜像
docker images # 列出已经下载下来的镜像
docker image rm # 删除镜像
docker run -d -p xxxx:xxxx --name xxxx ubuntu:18.04 # 以ubuntu 18.04为基础镜像运行容器
容器

Docker 容器本质上是一个进程,运行于自己独立的命名空间中,所有的数据都存储在容器中。容器销毁后,这些数据也随之消失。多个容器互相之间是隔离的,一个容器所做的任何变更都只影响容器本身。

docker ls # 列出所有在运行的容器
docker ls -a # 列出所有容器
docker logs [container ID or NAMES] # 获取容器的输出信息
docker stop # 终止一个运行中的容器
docker rm [container ID or NAMES] # 删除一个运行中的容器
docker rm -f [container ID or NAMES] # 删除一个容器
docker run -d -p 8000:5000 --name demo ubuntu:18.04 # 在ubuntu 18.04 上运行名字是demo的容器,外部端口8000,容器端口5000
仓库

通常情况下我们可以使用 https://hub.docker.com/ 作为 Docker image 的仓库,但是有些场景下,我们希望能够有本地的仓库。使用 Docker 容器运行 registry 镜像的方式,来创建本地仓库。

使用 Docker

1. 数据卷

默认容器的数据是保存在容器的可读写层,当容器被删除时其上的数据将会丢失,所以为了实现数据的持久性则需要选择一种数据持久技术来保存数据。

数据卷是存在于一个或多个容器中的特定文件或文件夹,这个文件或文件夹以独立于 Docker 文件系统的形式存在于宿主机中,其生存周期独立于容器的生存周期。

对于容器的应用来说,数据卷是透明的,无法感知数据卷的存在,因此删除容器的时候,不会影响到数据卷。

数据卷优势:

# 创建一个名为test的数据卷
docker volume create test
# 列出所有的数据卷
docker volume ls
# 删除数据卷
docker volume rm test

我们使用 mount 选项来挂载数据卷。--mount 由多个键-值对组成,由逗号分隔,每一对由 key=value 组成。下面是 mount 参数的 key :

数据卷挂载方式
1.volumes

在多个容器间共享数据,希望将数据存储在远程主机或云提供商上,实现数据持久化,Docker 默认在主机上会有一个特定的区域(Linux系统上是 /var/lib/docker/volumes/),该区域用来存放 volume。
非 Docker 进程不可以去修改该区域。volume 是由Docker 创建的,可以通过 docker volume 进行管理,如创建、删除等操作。

生产环境---volume方式实现代码数据持久化
# 创建一个名为demovolume1数据卷
docker volume create demovolume1
# 在运行容器demo时,使用--mount参数
docker run -d --name demo --mount type=volume, source=demovolume2,targe=/volume ubuntu:18.04
# 其中--mount参数的含义是,把名为 demovolume2 的数据卷挂载到名为 demo 容器的 /volume 目录上
# 在启动容器时,自动创建数据卷 demovolume2
--mount source=demovolume,target=/volume

适用场景

2.bind mounts

可以被挂载在主机的任何地方,非Docker应用程序可以改变这些数据。在宿主机和容器间共享代码。
例如将宿主机某个项目的target目录挂载到容器中,这样在宿主机上修改代码,可以直接在容器中运行,而不用生成一个新的镜像。

适用场景

开发环境---共享目录实现代码实时更新

在开发环境里面,我们不可能每更新一次代码,就重新建立一个带有更新后的代码数据卷的镜像。我们可以把代码目录挂载到共享目录,开发时在本地主机修改代码时,Docker 实时生效。使用--mount参数type=bind表明要挂载在共享目录。

# 把本地主机当前目录 "${PWD}" 挂载到容器的/share目录下
docker run -d --name demo --mount type=bind,source="${PWD}",target=/share ubuntu:18.04
# 把本地主机当前目录下的/test.py文件挂载到容器的/share目录下
docker run -d --name demo --mount type=bind,source="${PWD}"/test.html,target=/share ubuntu:18.04

2. 利用Dockerfile构建自定义镜像

如果在一个基础镜像启动容器,我们采用命令行的方式,需要配置镜像,安装程序,运行容器,如果要重新启动一个容器,我们需要再重新配置一次。

Docker 可以让我们自己写配置镜像的文件(Dockerfile,注意大小写)来构建镜像。在实际应用中,我们可以把整个运行程序打包成一个新的 Docker 镜像,从镜像直接运行容器。

# 在 Dockerfile 文件中 # 是注释
# FROM 用于指定构建镜像使用的基础镜像
FROM ubuntu:18.04

# RUN 用于在构建镜像的时候在镜像中执行命令
# 安装 python3 和 相关的库
RUN apt update
RUN apt -y install python3 python3-pip
RUN pip3 install flask
RUN pip3 install gevent
RUN pip3 install flask_redis
RUN pip3 install requests

# 把本机当前目录下的 mpa-admin 文件拷贝到镜像的 /mpa-admin
# COPY 会自动创建镜像中不存在的目录
COPY mpa-admin /mpa-admin

# WORKDIR 用于指定从镜像启动的容器内的工作目录
WORKDIR /mpa-admin

# CMD 用于指定容器运行后要执行的命令和参数列表
# 这样从本镜像启动容器后会自动执行 python3 server.py 这个命令
# 在 /mpa-admin 下执行的
CMD ["python3", "server.py"]

在完成Dockerfile配置后,我们可以从镜像运行容器

docker build -t mpa_admin_image . # 在当前目录构建镜像
docker run -p 8000:7050 --name mpa_admin_1 mpa_admin_image # 运行容器

3.利用docker-compose管理多容器

Docker 的容器,是一个容器运行一个程序,但是在实际项目中,我们很多时候需要多个程序配合一起运行。
比如,web 程序里就需要包含server.py, redis, mysql等等。
Docker 官方推出 Compose 程序用于配置、管理多容器运行。Compose 通过单独的 docker-compose.yml 文件来管理一组容器。
Compose 把一组容器作为一个项目运行,并会设置好容器之间的互联的内部网络。

# 表示这是 compose 配置文件第三版
version: '3'

# 每个服务都是一个 Docker 容器
# 所以必须用 image 指定服务的镜像名或者从 Dockerfile 中 build 镜像
services:
  mpa_admin:

    # build 指定了 Dockerfile 所在的路径
    build: .

    # ports 指定暴露的端口,8000 是宿主机,7050 是容器使用端口
    # docker 容器的网络, 是相对于实体机的私有网络
    # 端口映射, 把容器的端口和实体机端口成对连通
    ports:
      - "8000:7050"

    # depends_on 设定了依赖,这里 redisdemo 会先于 mpa_web 启动
    # 但是如果 redisdemo 启动时间长于 mpa_admin
    # 那么 mpa_web 运行的时候 redisdemo 未必可用
    depends_on:
      - redisdemo

    # volumes 参数把当前目录挂载到容器的 /mpa_admin
    # docker-compose 的配置中支持相对路径的挂载
    volumes:
      - .:/mpa_admin

  # redis:alpine 是 redis 项目的官方 Docker 镜像
  redisdemo:
    image: "redis:alpine"

其中 mpa-admin 容器是通过当前目录的 Dockerfile 进行构建,同时将当前目录挂在到 /mpa_admin 目录,而 redis 则直接使用官方进行。

项目mpa-admin实践

  1. 安装 docker
  2. 安装 docker-compose
  3. 配置 Dockerfile 文件
# FROM 指定基础镜像
FROM ubuntu:18.0 安装 python3 和 flask web 框架 mpa-admin
RUN apt update
RUN apt -y install python3 python3-pip
RUN pip3 install flask
RUN pip3 install gevent
RUN pip3 install flask_redis
RUN pip3 install requests

#COPY mpa-admin /mpa-admin

# WORKDIR 用于指定从镜像启动的容器内的工作目录
WORKDIR /mpa-admin

# 在 /mpa-admin 下执行的
CMD ["sh", "devup.sh"]
  1. 配置 docker-compose.yml 文件
..:/mpa-admin:ro # 只读
version: '3'

services:
  pyweb:
    build: .
    ports:
      - "8075:7075"
    # volumes 关键字,将当前主机上的工程目录以 bind mounts 方式
    # 挂载到容器中的/mpa-admin 目录,这样就允许在不重复构建镜像实时修改代码
    volumes:
      - ..:/mpa-admin
  1. 启动项目:

Docker 会根据当前的目录下得Dockerfile构建基础镜像,并且运行 devup.sh 脚本。
同时由于使用了 volumes 挂载了本地目录到/mpa-admin,我们就可以直接在本地使用编辑器去编写代码,并且更新的代码能够实时被重新加载。

docker-compose up # 启动compose里的项目
docker-compose down # 关闭并删除compose项目的容器
上一篇下一篇

猜你喜欢

热点阅读