Docker学习笔记(2)

1 Docker容器初识

1.1 是什么?

基于Go的开源的轻量级、可移植的容器项目

1.2 能做什么?

为应用服务,提供开发、运行、测试、部署一系列的服务。简而言之,就是可以利用docker来编译运行我们的项目,每个容器就是一个服务,可以快速部署我们的服务。

  1. 借助镜像进行项目的快速部署(部署环境)
  2. 每个容器运行一个应用,不同容器相互隔离(隔离性)
  3. 每个运行的容器都是基本最小的虚拟机环境(运行资源)
  4. 在服务资源升级和回滚上,借助升级扩容,一键能完成成千上百的服务集群的快速部署。(伸缩扩容)

1.3 怎么做的?

Linux容器是对进程的隔离,好比给正常的进程套了一个保护层,容器里的进程接触的各种资源都是虚拟的,从而实现与底层系统的隔离。
它相比虚拟机来说,因为是进程级别的,所以有很多优势:启动快、资源占用少、体积小; 容器与宿主机是共享系统内核的。

Docker属于Linux容器一种封装,提供简单易用的容器使用接口。
Docker的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。

1.4 Docker与虚拟机的区别

传统方式是在硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层。

Docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,因此更加轻量级。

2 Docker的三大核心概念

在这里插入图片描述

2.1 镜像与容器的关系

镜像自身是只读的。容器从镜像启动的时候,会在镜像的最上层创建一个只读层。
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。(容器是独立运行的一个或一组应用,是镜像运行时的实体。

2.2 镜像与仓库的关系

仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
类似于git管理仓库的设计方法。

2.3 Docker镜像的分层结构

在这里插入图片描述

一个docker镜像由多个可读的镜像层组成,然后运行的容器会在这个docker的镜像上面多加一层可写的容器层,任何的对文件的更改都只存在此容器层。因此任何对容器的操作均不会影响到镜像。

3 使用Docker镜像

几个问题:

  1. 如何使用pull命令从Docker Hub仓库中下载镜像到本地?
  2. 如何查看本地已有的镜像信息和管理镜像标签?
  3. 如何在远端仓库使用search命令进行搜索和过滤?
  4. 如何删除镜像标签和镜像文件?
  5. 如何创建用户定制的镜像并且保存为外部文件?
  6. 如何往Docker Hub仓库中推送自己的镜像?

3.1 获取镜像

可以使用docker[image]pull命令直接从Docker Hub镜像源来下载镜像。该命令的格式为docker[image]pull NAME[: TAG]。
完整的命令为: docker pull 镜像所在仓库地址:镜像版本号,如

$docker pull hub.c.163.com/public/ubuntu:18.04

默认使用的是Docker Hub官方仓库的最新版本号

下载镜像到本地后,即可随时使用该镜像了,例如利用容器,在其中运行bash应用,执行打印“Hello World”命令:

$ docker run -it ubuntu:18.04 bash
root@65663247040f:/# echo "Hello World"
Hello World
root@65663247040f:/# exit

3.2 查看镜像信息

  1. 使用images列出镜像
    docker images 或者 docker image ls

  2. 使用tag命令添加镜像标签
    docker tag ubuntu:latest myubuntu:latest
    类似链接,快捷方式的作用, 我们可以直接使用myubuntu:latest来使用ubuntu:latest

  3. 使用inspect命令查看镜像详细信息
    docker [image] inspect ubuntu:18.04

  4. 使用history命令查看镜像历史
    既然镜像文件由多个层组成,那么怎么知道各个层的内容具体是什么呢?这时候可以使用history子命令,该命令将列出各层的创建信息。
    docker history ubuntu:18.04

3.3 查找镜像

使用 docker search 命令可以搜索Docker Hub官方仓库中的镜像。语法为docker search [option] keyword。支持的命令选项主要包括:
-f, --filter: 过滤输出内容
例子:
搜索官方带nginx的镜像:
docker search --filter=is-official=true nginx

3.4 删除和清理镜像

Docker镜像的rm和prune子命令

  1. 使用标签删除镜像
    docker rmi myubuntu:18.04
  2. 使用镜像id删除镜像
    docker rm a21c0840213e
  3. 清理镜像
    docker image prune

3.5 创建镜像

有三种创建方式:

  1. 基于已有容器创建
    举个例子:
    已有容器
$ docker run -it ubuntu:18.04 /bin/bash
root@a925cb40b3f0:/# touch test
root@a925cb40b3f0:/# exit

使用docker [container] commit来提交为一个新的镜像。提交时可以使用ID 或名称来指定容器

$ docker [container] commit -m "Added a new file" -a "Docker Newbee" a925cb40b3f0test:0.1
9e9c814023bcffc3e67e892a235afe61b02f66a947d2747f724bd317dda02f27

-m message
-a author

  1. 基于本地模板导入
    cat ubuntu-18.04-minial.tar.gz | docker import ubuntu:18.04

  2. 基于Dockerfile创建
    利用给定的指令基于某个父镜像创建新镜像的过程
    举个例子:

runoob@runoob:~$ cat Dockerfile 
FROM    centos:6.7
MAINTAINER      Fisher "fisher@sudops.com"

RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd runoob
RUN     /bin/echo 'runoob:123456' |chpasswd
RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE  22
EXPOSE  80
CMD     /usr/sbin/sshd -D

每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。

runoob@runoob:~$ docker build -t runoob/centos:6.7 .
Sending build context to Docker daemon 17.92 kB
Step 1 : FROM centos:6.7
 ---> d95b5ca17cc3
Step 2 : MAINTAINER Fisher "fisher@sudops.com"
 ---> Using cache
 ---> 0c92299c6f03
Step 3 : RUN /bin/echo 'root:123456' |chpasswd
 ---> Using cache
 ---> 0397ce2fbd0a
Step 4 : RUN useradd runoob
......

3.6 存出和载入镜像

  1. 存出
    例如,导出本地的 ubuntu:18.04 镜像为文件ubuntu18.04.tar,
    如下所示:
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 18.04 0458a4468cbc 2 weeks ago 188 MB
$ docker save -o ubuntu_18.04.tar ubuntu:18.04

之后,用户就可以过复制 ubuntu_18.04.tar文件将该镜像分享给他人。

  1. 载入
    可以使用docker [image] load将导出的tar文件再导人到本地镜像库。支持 -i、-input string 选项,从指定文件中读人镜像内容。
    例如,从文件ubuntu_18.04.tar导人镜像到本地镜像列表,如下所示:
    $ docker load -i ubuntu_18.04.tar
    或者:
    $ docker load < ubuntu_18.04.tar

3.7 上传镜像

用户给本地的镜像如test:latest添加标签user/test:latest,然后push上传

$ docker tag test:latest user/test:latest
$ docker push user/test:latest
The push refers to a repository [
[docker.io/user/test]
Sending image list
Please
login prior to push:
Username:
Password:
Email:

4 操作Docker容器

Docker容器的create、start、run、wait 和 logs子命令。

4.1 新建容器和运行容器

  1. 新建容器

    $ docker create -it ubuntu:latest
    af8f4f922dafee22c8fe6cd2ae11d16e25087d61flblfa55b36e94db7ef45178
    $ docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    af8f4f922daf ubuntu:latest "/bin/bash" 17 seconds ago Created silly_euler
    
  2. 新建并启动一个容器

    $ docker run -it ubuntu /bin/bash
    

    参数说明:
    -i: 交互式操作。
    -t: 终端。
    ubuntu: ubuntu 镜像。
    /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
    要退出终端,直接输入 exit:
    当利用docker [container] run来创建并启动容器时,Docker在
    后台运行的标准包括:

    • 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
    • 利用镜像创建一个容器,并启动该容器;
    • 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
    • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去;
    • 从网桥的地址池配置一个IP 地址给容器;
    • 执行用户指定的应用程序;
    • 执行完毕后容器被自动终止。
  3. 启动一个已经停止的容器

    首先查看所有容器,包括停止和未停止的
    $ docker ps -a
    启动一个已经停止的容器
    $ docker start b750bbbcfd88

  4. 守护态运行
    在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式。

    $ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
    ce554267d7a4c34eefc92c5517051dc37b918b588736d0823e4c846596b04d83
    

    注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec

4.2 停止容器

  1. 暂停容器,然后恢复运行
    $ docker run --name test --rm -it ubuntu bash
    $ docker pause test
    $ docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    893c811cf845 ubuntu "bash" 2 seconds ago Up 12 seconds (Paused) test
    
    可通过unpause恢复运行
  2. 终止容器并重新运行
    $ docker stop <容器 ID>
    $ docker start <容器 ID>
    
    一下是将运行态的容器先终止再重新启动
    $ docker restart <容器 ID>
    

4.3 进入容器

attach或exec命令
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
docker attach
或者
docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。

下面演示了使用 docker attach 命令。

$ docker attach 1e560fca3906

注意点:
当我们使用完容器之后进行exit操作,不仅会从容器中退出,还会停止容器的运行。
当多个窗口同时attach 到同一个容器的时候,所有窗口都会同步显示;当某个窗口因命令阻塞时,其他窗口也无法执行操作了。
所以推荐使用exec。

下面演示了使用 exec 命令。

docker exec -it 243c32535da7 /bin/bash

当我们使用完容器之后进行exit操作,使用docker ps可查看到刚才的容器。会从容器退出,但不会停止容器。

4.4 删除容器

默认情况下,docker rm命令只能删除处于终止或退出状态的容器,并不能删除还处于运行状态的容器。
添加-f可以强制删除

$ docker rm -f 1e560fca3906

4.5 导入和导出容器

导出容器 1e560fca3906 快照到本地文件 ubuntu.tar。
$ docker export 1e560fca3906 > ubuntu.tar
导入容器快照
$ cat docker/ubuntu.tar | docker import ubuntu.tar - test/ubuntu:v1

4.6 查看容器

ps、inspect、top、stats子命令

  1. 查看正在运行的容器
    docker ps
  2. 查看某容器的详情
    docker container inspect test
  3. 查看某容器的进程
    docker top test
  4. 查看某容器的统计信息
    查看容器所有信息
    haicoder(www.haicoder.net)# docker stats --all
    只查看静态信息
    haicoder(www.haicoder.net)# docker stats --no-stream

5 访问Docker仓库

仓库是存放镜像的地方,一个仓库可以存放多个镜像。一个registry服务器是具体的服务器用来存放仓库的地方。

5.1 Docker Hub公共镜像仓库

5.2 第三方镜像市场

5.3 搭建本地私有仓库

  1. 使用registry镜像创建私有仓库
$ docker run -d -p 5000:5000 registry:2

这将自动下载并启动一个registry容器,创建本地的私有仓库服务。
2. 管理私有仓库

6 Docker数据管理

引言:
docker的镜像是由多个只读的文件系统叠加在一起形成的。当我们在我启动一个容器的时候,docker会加载这些只读层并在这些只读层的上面(栈顶)增加一个读写层。这时如果修改正在运行的容器中已有的文件,那么这个文件将会从只读层复制到读写层。该文件的只读版本还在,只是被上面读写层的该文件的副本隐藏。当删除docker,或者重新启动时,之前的更改将会消失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。
为了很好的实现数据保存和数据共享,Docker提出了Volume这个概念,简单的说就是绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。又被称作数据卷。

容器中的管理数据主要有两种方式:

  • 数据卷(Volumes)
  • 数据容器

6.1 数据卷

为什么使用数据卷?

  • 数据持久化
  • 数据共享。宿主机和docker的数据是一致的

它完全独立于容器的生存周期,docker不会在容器删除时,删除其挂载的数据卷。

  1. 创建数据卷
    docker volume create mydata
  2. 查看所有数据卷
    docker volume ls
  3. 查看数据卷信息
    docker volume inspect mydata
    注:Mountpoint为数据在本机存储的位置,如果磁盘存储空间不足可修改此位置

挂载:
在用 docker run命令的时候,使用-v标记来创建一个数据卷并挂载到容器里。在一次run中多次使用可以挂载多个数据卷。
docker run -t -i --name datac -v /tmp/webdata1:/webdata1 -v /tmp/webdata2:/webdata2 ubuntu:14.04 /bin/bash
/tmp/webdata1和/tmp/webdata2为创建的宿主机的两个目录,挂载到容器里,一次run可以挂载多个数据卷

6.2 数据卷容器

有一些持续更新的数据需要在容器之间共享,那最好创建数据卷容器。数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。

  1. 创建一个命名的数据卷容器dbdata
    docker create -v /tmp/webdata1 --name dbdata ubuntu:14.04 /bin/true
  2. 创建其他容器来挂载数据卷容器dbdata
    在其他容器中使用–volumes-from来挂载dbdata容器中的数据卷。
    创建db1容器和db2容器,挂载数据卷容器dbdata:
    docker run --volumes-from dbdata --name db1 -i -t ubuntu:14.04 /bin/bash
    docker run --volumes-from dbdata --name db2 -i -t ubuntu:14.04 /bin/bash
    分别在db1和db2的容器中创建数据,可以看到数据卷容器dbdata中都有这两个容器的数据

6.3 利用数据卷容器备份、恢复、迁移数据

首先使用 --volumes-from 标记来创建一个加载 dbdata 容器卷的容器,并从本地主机挂载当前到容器的 /backup 目录。命令如下:
docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
容器启动后,使用了 tar 命令来将 dbdata 卷备份为本地的 /backup/backup.tar 。

恢复
如果要恢复数据到一个容器,首先创建一个带有数据卷的容器 dbdata2。
docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
然后创建另一个容器,挂载 dbdata2 的容器,并使用 untar 解压备份文件到挂载的容器卷中。
docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar

7 端口映射与容器互联

如何实现多个容器之间能够互相访问对方的服务

7.1 端口映射实现容器访问

当容器中运行一些网络应用,要让外部访问这些应用时,可以通过-P或-p 参数来指定端口映射。
当使用-P(大写的)标记时,Docker会随机映射一个49000~49900的端口到内部容器开放的网络端口:
-p(小写),可以指定映射端口

7.2 Docker容器互联

端口映射并不是唯一把 docker 连接到另一个容器的方法。
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。

创建一个新的 web 容器,并将它连接到 db 容器:
docker run -d -P --name web --link db:db training/webapp python app.py
此时,db 容器和 web 容器建立互联关系。
–link参数的格式为–link name:alias,其中name是要链接的容器的名称,alias是别名。

8 DockerFile创建容器

8.1 Dockerfile主体分为四个部分

基础镜像信息、维护者信息、镜像操作指令、容器启动时执行指令

8.2 Dockerfile指令说明

指令主要分为两大类:配置指令和操作指令

8.3 指令介绍

  1. FROM和RUN指令
    FROM:定制的镜像都是基于的镜像名称,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
    RUN:用于执行后面跟着的命令行命令。有以下两种格式:
    方式一:shell 格式:

    RUN <命令行命令>
    # <命令行命令> 等同于,在终端操作的 shell 命令。
    

    方式二:exec 格式:

    RUN ["可执行文件", "参数1", "参数2"]
    # 例如:b
    成功,会返回最终镜像的ID
    例如:
    # RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offlinbe
    成功,会返回最终镜像的ID
    例如:
    

    注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

    FROM centos
    RUN yum -y install wget \
        && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
        && tar -xvf redis.tar.gz
    

    如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

  2. LABEL
    LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式
    如,可以添加作者的信息
    LABEL org.opencontainers.image.authors=“runoob”

  3. ARG与ENV
    ENV设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
    ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

  4. ADD和COPY指令
    ADD和COPY指令类似,当使用本地目录为源目录时,推荐使用COPY指令
    ADD
    COPY
    ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

  5. CMD和RUN指令
    类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
    CMD 在docker run 时运行。
    RUN 是在 docker build。

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

  1. ENTRYPOINT和CMD指令
    类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

  2. EXPOSE
    仅仅只是声明端口。
    作用:
    帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
    在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
    格式:
    EXPOSE <端口1> [<端口2>…]

8.4 创建镜像

使用docker build来创建镜像
Docker服务端在校验Dockerfile格式通过后,逐条执行其中定义的指令,碰到ADD、COPY和RUN指令会生成一层新的镜像。最终如果创建镜像成功,会返回最终镜像的ID
例如:
[root@localhost soft]# docker build -t centos:base -f /soft/docker/Dockerfile /soft
注意:通过-f来指定Dockerfile文件的位置,后面的/soft及其目录下必须能够找到Dockerfile文件否则就会报上下文环境的错误,MV,COPY,ADD的文件位置都是相对/soft来说的。
–tag, -t,镜像的名字及tag,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个tag

9 为镜像添加ssh服务

如何远程访问容器?
创建带有ssh服务的镜像:
两种方式,1:基于docker commit命令, 2:基于Dockerfile创建

9.1 基于docker commit命令

  1. 正常拉取镜像创建容器
  2. 运行容器的时候进入到容器中安装和配置ssh服务
  3. 生成公钥到authorized_keys文件中
  4. 编写ssh服务自动启动的run.sh中
  5. commit保存为一个新的sshd:ubuntu镜像
  6. 下次使用镜像的时候添加端口映射就可以使用ssh登陆到容器了

9.2 基于Dockerfile创建

  1. 创建Dockerfile文件和run.sh
  2. 编写run.sh,在宿主机生成密钥对到authorized_keys中
  3. 编写Dockerfile文件配置ssh服务
  4. 创建镜像、执行并测试镜像

总结:Docker理念是一个容器只运行一个服务,每个容器启动都增加一个额外的ssh服务,应用容器应该保持原有的生命周期,系统容器应该支持ssh,便于管理员的登陆。

10 Docker Compose:Docker管理工具

Docker Compose是一个用来定义和运行复杂应用的Docker工具。一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose不再需要使用shell脚本来启动容器,而使用服务编排的方式来管理容器。

Docker Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。Docker Compose 的前身是 Fig。Fig 是一个由 Orchard 公司开发的强有力的工具,在当时是进行多容器管理的最佳方案。

Fig 是一个基于 Docker 的 Python 工具,允许用户基于一个 YAML 文件定义多容器应用,从而可以使用 fig 命令行工具进行应用的部署。Fig 还可以对应用的全生命周期进行管理。

11 研发人员看待docker

  1. Docker可以快速部署安装开发测试环境
  2. 方便部署各类服务

12 Docker Machine

在本地或云环境搭建一套Docker主机集群

13 Docker Compose

Compose 是用于定义和运行多容器 Docker 应用程序的工具。
通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

13.1 使用Compose的三个步骤

  1. 使用 dockerfile 定义应用程序的环境。
  2. 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  3. 执行 docker-compose up 命令来启动并运行整个应用程序。

13.2 Compose的yaml文件编写

version: "3"

services:
  webapp:
    image: examples/web
    ports:
      - "80:80"
    volumes:
      - "/data"

所有的服务都在services根目录下面,里面是服务器容器的配置信息

一些感想:

  1. dockerfile和run.sh是一般是成对出现的,dockerfile用来构建镜像,run.sh用来启动服务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值