前端day3 - docker | 青训营笔记

117 阅读5分钟

容器化

时代演进

  • 物理机时代

    • 多个程序在一台机器上运行
  • 虚拟机时代

    • 一台物理机安装多个虚拟机(VM),一个虚拟机跑多个程序。
  • 容器化时代

    • 一台物理机安装多个容器实例(container),一个容器跑多个程序。

容器化解决了“环境”的问题。

它将软件程序和运行的基础环境分开。开发人员编码完成后将程序打包到一个容器镜像中,镜像中详细列出了所依赖的环境,在不同的容器中运行标准化的镜像,从根本上解决了环境不一致的问题。

容器化特点

  • 可移植性

    • 不依赖具体的操作系统或云平台,比如在阿里云或腾讯云直接随意迁移。
  • 占地小

    • 容器只需要其应用程序以及它需要运行的所有容器和库的依赖清单,不需要将所有的依赖库都打包在一起。
  • 共享bin和lib

    • 不同的容器可以共享binlib,进一步节省了空间。

Docker

2010年,dotCloud公司,开发了Docker的核心技术;

后来dotCloud公司将自己的容器技术进行了简化和标准化,取名为docker。

2013年dotCloud 公司宣布将 Docker 开源,随着越来越多的工程师发现了它的优点, Docker 的人气迅速攀升,成为当时最火爆的开源技术之一。

Docker怎么用

其实大多数人谈论 Docker 时说的是 Docker Engine,这只是一个构建和运行的容器。

在运行容器前需要编写Docker File,通过 dockerFile 生成镜像,然后才能运行 Docker 容器。

Docker File 定义了运行镜像(image)所需的所有内容,包括操作系统和软件安装位置。一般情况下都不需要从头开始编写 Docker File,在 Docker Hub 中有来自世界各地的工程师编写好的镜像,你可以基于此修改。

常用命令

镜像

  • 查看镜像

    • docker images
    • $ docker images
      REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
      php                 7-fpm               f214b5c48a25        9 days ago          368MB
      redis               3.2                 2fef532eadb3        11 days ago         76MB
      redis               4.0                 e1a73233e3be        11 days ago         83.4MB
      cogset/cron         latest              c01d5ac6fc8a        15 months ago       125MB
      
  • 镜像命名

    • username/repository:tag
    • 例如:cogest/lets-encrypt:0.14.2

  • 从镜像仓库获得image

    • docker pull
    • # 通过镜像名
      $ sudo docker pull ubuntu
      Using default tag: latest
      latest: Pulling from library/ubuntu
      124c757242f8: Downloading [==========================>  ]  30.19MB/31.76MB
      9d866f8bde2a: Download complete 
      fa3f2f277e67: Download complete 
      398d32b153e8: Download complete 
      afde35469481: Download complete 
      
      
      # 完整镜像名
      $ sudo docker pull openresty/openresty:1.13.6.2-alpine
      1.13.6.2-alpine: Pulling from openresty/openresty
      ff3a5c916c92: Pull complete 
      ede0a2a1012b: Pull complete 
      0e0a11843023: Pull complete 
      246b2c6f4992: Pull complete 
      Digest: sha256:23ff32a1e7d5a10824ab44b24a0daf86c2df1426defe8b162d8376079a548bf2
      Status: Downloaded newer image for openresty/openresty:1.13.6.2-alpine
      
  • 获取image的详细信息

    • docker inspect
    • $ sudo docker inspect redis:3.2
      [
          {
              "Id": "sha256:2fef532eadb328740479f93b4a1b7595d412b9105ca8face42d3245485c39ddc",
              "RepoTags": [
                  "redis:3.2"
              ],
              "RepoDigests": [
                  "redis@sha256:745bdd82bad441a666ee4c23adb7a4c8fac4b564a1c7ac4454aa81e91057d977"
              ],
      ## ......
          }
      ]
      
    • 查看指定image
    • $ sudo docker inspect redis:4.0
      $ sudo docker inspect 2fef532e
      
  • 删除镜像

    • docker rmi
    •  $ sudo docker rmi ubuntu:latest
      Untagged: ubuntu:latest
      Untagged: ubuntu@sha256:de774a3145f7ca4f0bd144c7d4ffb2931e06634f11529653b23eba85aef8e378
      Deleted: sha256:cd6d8154f1e16e38493c3c2798977c5e142be5e5d41403ca89883840c6d51762
      Deleted: sha256:2416e906f135eea2d08b4a8a8ae539328482eacb6cf39100f7c8f99e98a78d84
      Deleted: sha256:7f8291c73f3ecc4dc9317076ad01a567dd44510e789242368cd061c709e0e36d
      Deleted: sha256:4b3d88bd6e729deea28b2390d1ddfdbfa3db603160a1129f06f85f26e7bcf4a2
      Deleted: sha256:f51700a4e396a235cee37249ffc260cdbeb33268225eb8f7345970f5ae309312
      Deleted: sha256:a30b835850bfd4c7e9495edf7085cedfad918219227c7157ff71e8afe2661f63
      
    • 空格,删除多个镜像
    •  $ sudo docker rmi redis:3.2 redis:4.0
      Untagged: redis:3.2
      Untagged: redis@sha256:745bdd82bad441a666ee4c23adb7a4c8fac4b564a1c7ac4454aa81e91057d977
      Deleted: sha256:2fef532eadb328740479f93b4a1b7595d412b9105ca8face42d3245485c39ddc
       #  # ...... 
      Untagged: redis:4.0
      Untagged: redis@sha256:b77926b30ca2f126431e4c2055efcf2891ebd4b4c4a86a53cf85ec3d4c98a4c9
      Deleted: sha256:e1a73233e3beffea70442fc2cfae2c2bab0f657c3eebb3bdec1e84b6cc778b75
       #  # ...... 
      

容器

  • 创建容器

    • docker create
    •  $ sudo docker create nginx:1.12
      34f277e22be252b51d204acbb32ce21181df86520de0c337a835de6932ca06c3
      
    • docker create --name
    •  $ sudo docker create --name nginx nginx:1.12
      
  • 启动容器

    • docker start
    •  $ sudo docker start nginx
      
  • 创建+启动

    • docker run --name 容器名 -d/--detach(后台运行) 镜像名
    •  $ sudo docker run --name nginx -d nginx:1.12
      89f2b769498a50f5c35a314ab82300ce9945cbb69da9cda4b022646125db8ca7
      
  • 列出 Docker 中的容器

    • docker ps 列出运行中的容器
    •  $ sudo docker ps
      CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
      89f2b769498a        nginx:1.12          "nginx -g 'daemon of…"   About an hour ago   Up About an hour    80/tcp              nginx
      
    • docker ps -a 列出所有的容器
    • docker ps --all
    •  $ sudo docker ps -a
      CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
      425a0d3cd18b        redis:3.2           "docker-entrypoint.s…"   2 minutes ago       Created                                 redis
      89f2b769498a        nginx:1.12          "nginx -g 'daemon of…"   About an hour ago   Up About an hour    80/tcp              nginx
      
  • 停止容器

    • docker stop
    •  $ sudo docker stop nginx
      
  • 删除容器

    • docker rm
    •  $ sudo docker rm nginx
      
  • 控制容器让其运行给出的命令

    • docker exec
    • 让nginx容器运行more命令

    •  $ sudo docker exec nginx more /etc/hostname
      ::::::::::::::
      /etc/hostname
      ::::::::::::::
      83821ea220ed
      
    • -i/--interactive 保持输入流

      -t`` / ``--tty 启动一个伪终端

      二者可以合并为-it,以交互模式运行容器

    •  $ sudo docker exec -it nginx bash
      root@83821ea220ed:/#
      
  • 衔接到容器

    • docker attach 用于将当前的输入输出流连接到指定的容器上
    •  $ sudo docker attach nginx
      

网络

针对容器的网络配置

网络相关的命令,都是以docker network开头

  • 容器互联

    • docker create --link
    • docker run --link
    •  $ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql
       $ sudo docker run -d --name webapp --link mysql webapp:latest
      
    • 通过别名连接
    •  $ sudo docker run -d --name webapp --link mysql:database webapp:latest
      
  • 暴露端口

    • --expose
    • 在创建时使用

    •  $ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --expose 13306 --expose 23306 mysql:5.7
      
    • 暴露了13306和23306端口

  • 查看网络信息

    • 使用docker inspect
  • 创建网络

    • docker network create
    • -d :为新的网络指定驱动的类型
    • 默认是Bridge Driver

    •  $ sudo docker network create -d bridge individual
      
  • 在创建容器时,直接指定容器所加入的网络

    • 不同网络之间,不能进行link

    • --network
    •  $ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --network individual mysql:5.7
      
  • 查看已存在的网络

    • docker network ls
    • docker network list
    •  $ sudo docker network ls
      NETWORK ID          NAME                DRIVER              SCOPE
      bc14eb1da66b        bridge              bridge              local
      35c3ef1cc27d        individual          bridge              local
      
  • 端口映射

    • -p

    • --publish

    • -p <ip>:<host-port>:<container-port>

      • ip 是宿主操作系统的监听 ip,可以用来控制监听的网卡,默认为 0.0.0.0,也就是监听所有网卡。
      • host-port 和 container-port 分别表示映射到宿主操作系统的端口和容器的端口。
      • 这两者是可以不一样的。

        我们可以将容器的 80 端口映射到宿主操作系统的 8080 端口,传入 -p 8080:80 即可。

    •  $ sudo docker ps
      CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                      NAMES
      bc79fc5d42a6        nginx:1.12          "nginx -g 'daemon of…"   4 seconds ago       Up 2 seconds        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   nginx
      

文件

  • 三种文件挂载方式
  • Bind Mount 能够直接将宿主操作系统中的目录和文件挂载到容器内的文件系统中,通过指定容器外的路径和容器内的路径,就可以形成挂载映射关系,在容器内外对文件的读写,都是相互可见的。
  • Volume 也是从宿主操作系统中挂载目录到容器内,只不过这个挂载的目录由 Docker 进行管理,我们只需要指定容器内的目录,不需要关心具体挂载到了宿主操作系统中的哪里。
  • Tmpfs Mount 支持挂载系统内存中的一部分到容器的文件系统里,不过由于内存和容器的特征,它的存储并不是持久的,其中的内容会随着容器的停止而消失。
  • 挂载文件到容器

    • -v
    • --volume
    • --volume <host-path>:<container-path>
    • 把本机的/webapp/html:/usr/share/nginx/html文件夹挂载到nginx中

    •  $ sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html nginx:1.12
      
    • 在挂载选项 -v 后再接上 :ro 就可以只读挂载
    •  $ sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html:ro nginx:1.12
      
  • 挂载临时文件

    • --tmpfs
    •  $ sudo docker run -d --name webapp --tmpfs /webapp/cache webapp:latest
      
  • 使用数据卷

    • 数据卷的本质其实依然是宿主操作系统上的一个目录,只不过这个目录存放在 Docker 内部,接受 Docker 的管理。

    • 使用 -v--volume
    •  $ sudo docker run -d --name webapp -v /webapp/storage webapp:latest
      
  • 命名数据卷

    • -v <name>:<container-path>
    •  $ sudo docker run -d --name webapp -v appdata:/webapp/storage webapp:latest
      
    • -v 在定义绑定挂载时必须使用绝对路径,其目的主要是为了避免与数据卷挂载中命名这种形式的冲突。
  • 共用数据卷

    • 多个容器挂载同一个数据卷
    •  $ sudo docker run -d --name webapp -v html:/webapp/html webapp:latest
       $ sudo docker run -d --name nginx -v html:/usr/share/nginx/html:ro nginx:1.12
      
  • 使用docker volume操作数据卷

  • 创建数据卷

    • docker volume create
    •  $ sudo docker volume create appdata
      
  • 列出当前已经创建的数据卷

    • docker volume ls
    •  $ sudo docker volume ls
      DRIVER              VOLUME NAME
      local               html
      local               appdata
      
  • 删除数据卷

    • docker volume rm
    • $ sudo docker volume rm appdata
      
  • 删除容器关联的数据卷

    • docker rm -v
    • $ sudo docker rm -v webapp
      
  • 删除未被容器引用的数据卷

    • docker volume prune
    • $ sudo docker volume prune -f
      Deleted Volumes:
      af6459286b5ce42bb5f205d0d323ac11ce8b8d9df4c65909ddc2feea7c3d1d53
      0783665df434533f6b53afe3d9decfa791929570913c7aff10f302c17ed1a389
      65b822e27d0be93d149304afb1515f8111344da9ea18adc3b3a34bddd2b243c7
      ## ......
      
  • 数据卷容器

定义一个或多个数据卷并持有它们的引用

  • 创建数据卷容器

    • $ sudo docker create --name appdata -v /webapp/storage ubuntu
  • 引入数据卷容器

    • --volumes-from
    • $ sudo docker run -d --name webapp --volumes-from appdata webapp:latest
  • 备份迁移数据卷

    • 建立临时容器,将备份的目录和数据卷挂载到该容器上
    • 以/back目录为例

    •  $ sudo docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar cvf /backup/backup.tar /webapp/storage
      
    • tar cvf /backup/backup.tar /webapp/storage
    • 将数据打包
  • 恢复数据卷

    •  $ docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar xvf /backup/backup.tar -C /webapp/storage --strip
      
    • 解包