Docker学习记录

1、Docker概念

1.1 什么是Docker

  • Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

  • Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

  • 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

1.2 Docker的应用场景

  • Web 应用的自动化打包和发布。
  • 自动化测试和持续集成、发布。
  • 在服务型环境中部署和调整数据库或其他的后台应用。
  • 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。

2、Docker架构

2.1 三个基本概念

Docker 包括三个基本概念:

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。

Docker 容器通过 Docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。

Docker面向对象
容器对象
镜像

2.2 具体的概念解释

以下是关于docker里面几种概念的解释:

概念说明
Docker 镜像(Images)Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。
Docker 容器(Container)容器是独立运行的一个或一组应用,是镜像运行时的实体。
Docker 客户端(Client)Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。
Docker 主机(Host)一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
Docker RegistryDocker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
Docker MachineDocker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

3、Docker Hello World

Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。

输出Hello world

root@VM-20-7-ubuntu:~# docker run ubuntu:15.10 /bin/echo "Hello World!"
Hello World!do

各个参数解析:

  • docker: Docker 的二进制执行文件。
  • run: 与前面的 docker 组合来运行一个容器。
  • ubuntu:15.10 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
  • /bin/echo “Hello world”: 在启动的容器里执行的命令

以上命令完整的意思可以解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo “Hello world”,然后输出结果。

3.1 运行交互式的容器

我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现**“对话”**的能力:

root@VM-20-7-ubuntu:~# docker run -i -t ubuntu:15.10 /bin/bash
root@b27fe05907da:/#

各个参数解析:

  • -t: 在新容器内指定一个伪终端或终端。
  • -i: 允许你对容器内的标准输入 (STDIN) 进行交互。

注意第二行 root@0123ce188bd8:/#,此时我们已进入一个 ubuntu15.10 系统的容器

我们尝试在容器中运行命令 cat /proc/versionls分别查看当前系统的版本信息和当前目录下的文件列表

root@b27fe05907da:/# cat /proc/version
Linux version 5.4.0-77-generic (buildd@lgw01-amd64-028) (gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)) #86-Ubuntu SMP Thu Jun 17 02:35:03 UTC 2021
root@b27fe05907da:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

我们可以通过运行 exit 命令或者使用 CTRL+D 来退出容器。

root@b27fe05907da:/# exit
exit
root@VM-20-7-ubuntu:~# 

注意第三行中 root@runoob:~# 表明我们已经退出了当前的容器,返回到当前的主机中。

3.2 启动容器(后台模式)

使用以下命令创建一个以进程方式运行的容器

root@VM-20-7-ubuntu:~# docker run -d ubuntu:15.10 /bin/bash "while true;do echo hello world;sleep 1;done"
53e43d05c3adb8e04de6b64c6d038ce32cd88acdff56fd2931aa30b4d7a94421

在输出中,我们没有看到期望的 “hello world”,而是一串长字符

53e43d05c3adb8e04de6b64c6d038ce32cd88acdff56fd2931aa30b4d7a94421

这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。

首先,我们需要确认容器有在运行,可以通过 docker ps 来查看:

runoob@runoob:~$ docker ps
CONTAINER ID        IMAGE                  COMMAND              ...  
5917eac21c36        ubuntu:15.10           "/bin/sh -c 'while t…"    ...

输出详情介绍:

CONTAINER ID: 容器 ID。

IMAGE: 使用的镜像。

COMMAND: 启动容器时运行的命令。

CREATED: 容器的创建时间。

STATUS: 容器状态。

状态有7种:

  • created(已创建)
  • restarting(重启中)
  • running 或 Up(运行中)
  • removing(迁移中)
  • paused(暂停)
  • exited(停止)
  • dead(死亡)

PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。

NAMES: 自动分配的容器名称。

在宿主主机内使用 docker logs 命令,查看容器内的标准输出:

runoob@runoob:~$ docker logs 2b1b7a428627

3.3 停止容器

我们使用 docker stop 命令来停止容器:

runoob@runoob:~$ docker stop 5917eac21c36 

4、Docker容器使用

4.1 Docker客户端

docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。

root@VM-20-7-ubuntu:/# docker

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default
                           "/root/.docker")
  -c, --context string     Name of the context to use to connect to
                           the daemon (overrides DOCKER_HOST env
                           var and default context set with "docker
                           context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level
                           ("debug"|"info"|"warn"|"error"|"fatal")
                           (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA
                           (default "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default
                           "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default
                           "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  builder     Manage builds
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

To get more help with docker, check out our guides at https://docs.docker.com/go/guides/

可以通过命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。

例如我们要查看 docker stats 指令的具体使用方法:

root@VM-20-7-ubuntu:/# docker stats --help

Usage:  docker stats [OPTIONS] [CONTAINER...]

Display a live stream of container(s) resource usage statistics

Options:
  -a, --all             Show all containers (default shows just running)
      --format string   Pretty-print images using a Go template
      --no-stream       Disable streaming stats and only pull the
                        first result
      --no-trunc        Do not truncate output

4.2 容器使用

获取镜像

如果我们本地没有 ubuntu 镜像,我们可以使用 docker pull 命令来载入 ubuntu 镜像:

$ docker pull ubuntu

启动容器

以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器:

root@VM-20-7-ubuntu:/# docker run -it ubuntu /bin/bash
root@1c720e2bc0c1:/# 

参数说明:

  • -i: 交互式操作。
  • -t: 终端。
  • ubuntu: ubuntu 镜像。
  • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

要退出终端,直接输入 exit:

root@1c720e2bc0c1:/# exit
exit

启动已停止运行的容器

查看所有的容器命令如下:

root@VM-20-7-ubuntu:/# docker ps -a
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS                        PORTS                                                                      NAMES
1c720e2bc0c1   ubuntu             "/bin/bash"              2 minutes ago    Exited (130) 44 seconds ago  

使用 docker start 启动一个已停止的容器:

root@VM-20-7-ubuntu:/# docker start 1c720e2bc0c1
1c720e2bc0c1
root@VM-20-7-ubuntu:/# docker ps -a
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS                        PORTS                                                                      NAMES
1c720e2bc0c1   ubuntu             "/bin/bash"              3 minutes ago    Up 5 seconds  

后台运行

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

root@VM-20-7-ubuntu:/# docker run -itd --name ubuntu-test ubuntu /bin/bash
root@VM-20-7-ubuntu:/# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED             STATUS             PORTS                                                                      NAMES
0ac68b31c4ea   ubuntu             "/bin/bash"              7 seconds ago       Up 6 seconds                                                                                  ubuntu-test

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

停止一个容器

停止容器的命令如下:

root@VM-20-7-ubuntu:/# docker stop 0ac68b31c4ea
0ac68b31c4ea

停止的容器可以通过 docker restart 重启:

root@VM-20-7-ubuntu:/# docker restart 0ac68b31c4ea
0ac68b31c4ea

进入容器

在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:

  • docker attach
$ docker attach 0ac68b31c4ea
root@0ac68b31c4ea:/# exit
exit

注意: 如果从这个容器退出,会导致容器的停止。

  • docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
$ docker exec -it 0ac68b31c4ea /bin/bash
root@0ac68b31c4ea:/# exit
exit

注意: 如果从这个容器退出,容器不会停止,这就是为什么推荐大家使用 docker exec 的原因。

更多参数说明请使用 docker exec --help 命令查看。

导出和导入容器

  • 导出容器

如果要导出本地某个容器,可以使用 docker export 命令。

$ docker export 1e560fca3906 > ubuntu.tar

导出容器 1e560fca3906 快照到本地文件 ubuntu.tar。

$ docker export 0ac68b31c4e > ubuntu.tar
$ ls -ll
total 73404
-rw-r--r--   1 root root 75157504 Nov 28 00:19 ubuntu.tar

这样将导出容器快照到本地文件。

  • 导入容器快照

可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1

root@VM-20-7-ubuntu:/# cat ubuntu.tar | docker import - test/ubuntu:v1
sha256:901a515302ae1510f51be1c0c03b626a90d4f777d74256f8fecabd915f6b25b6
root@VM-20-7-ubuntu:/# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
test/ubuntu   v1        901a515302ae   8 seconds ago   72.8MB

此外,也可以通过指定 URL 或者某个目录来导入,例如:

$ docker import http://example.com/exampleimage.tgz example/imagerepo

删除容器

删除容器使用 docker rm 命令:

$ docker rm -f 0ac68b31c4e
0ac68b31c4e

下面的命令可以清理掉所有处于终止状态的容器。

~$ docker container prune

运行一个 web 应用

前面我们运行的容器并没有一些什么特别的用处。

接下来让我们尝试使用 docker 构建一个 web 应用程序。

我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。

$	docker pull training/webapp  # 载入镜像
$ docker run -d -P training/webapp python app.py
322facb2de01ef2cab0d43573a670478b95b6fa59334687a338be9c859963619

参数说明:

  • **-d😗*让容器在后台运行。
  • **-P😗*将容器内部使用的网络端口随机映射到我们使用的主机上。

查看 WEB 应用容器

使用 docker ps 来查看我们正在运行的容器:

root@VM-20-7-ubuntu:/# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                                                                      NAMES
bda11450fed6   training/webapp    "python app.py"          18 seconds ago   Up 17 seconds   0.0.0.0:49153->5000/tcp, :::49153->5000/tcp                                romantic_nobel

这里多了端口信息,Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 49153上。

这时我们可以通过浏览器访问WEB应用,我们也可以通过 -p 参数来设置不一样的端口:

root@VM-20-7-ubuntu:/# docker run -d -p 5000:5000 training/webapp python app.py

容器内部的 5000 端口映射到我们本地主机的 5000 端口上。

网络端口的快捷方式

通过 docker ps 命令可以查看到容器的端口映射,docker 还提供了另一个快捷方式 docker port,使用 docker port 可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。

上面我们创建的 web 应用容器 ID 为 b5d420d7d518 名字为 modest_wozniak

我可以使用 docker port b5d420d7d518docker port modest_wozniak 来查看容器端口的映射情况。

$ docker port b5d420d7d518
5000/tcp -> 0.0.0.0:5000
5000/tcp -> :::5000
$ docker port modest_wozniak
5000/tcp -> 0.0.0.0:5000
5000/tcp -> :::5000

。查看 WEB 应用程序日志

docker logs [ID或者名字] 可以查看容器内部的标准输出。

$ docker logs -f b5d420d7d518
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

-f:docker logs 像使用 tail -f 一样来输出容器内部的标准输出。

从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志

查看WEB应用程序容器的进程

我们还可以使用 docker top 来查看容器内部运行的进程

$ docker top b5d420d7d518
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                632178              632155              0                   00:38               ?                   00:00:00            python app.py

检查 WEB 应用程序

使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

$ docker inspect b5d420d7d518
[
    {
        "Id": "b5d420d7d518793d2ceb1b3902fcdec7c3ef2c727e2c33a5a8911736b0bb0d43",
        "Created": "2021-11-27T16:38:11.977852278Z",
        "Path": "python",
        "Args": [
            "app.py"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 632178,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-11-27T16:38:12.289540167Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        ....

4.3 Docker镜像的使用

当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。

列出镜像列表

我们可以使用 docker images 来列出本地主机上的镜像。

$ docker images
REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
test/ubuntu       v1        901a515302ae   31 minutes ago   72.8MB
wordpress         latest    e3a452c0a154   8 days ago       616MB
mysql             5.7       8b43c6af2ad0   10 days ago      448MB
ubuntu            latest    ba6acccedd29   6 weeks ago      72.8MB
ubuntu            15.10     9b9cb95443b5   5 years ago      137MB
training/webapp   latest    6fae60ef3446   6 years ago      349MB

各个选项说明:

  • **REPOSITORY:**表示镜像的仓库源
  • **TAG:**镜像的标签
  • **IMAGE ID:**镜像ID
  • **CREATED:**镜像创建时间
  • **SIZE:**镜像大小

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。

所以,我们如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:

$ docker run -t -i ubuntu:15.10 /bin/bash 

如果要使用版本为 14.04 的 ubuntu 系统镜像来运行容器时,命令如下:

$ docker run -t -i ubuntu:14.04 /bin/bash

如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。

获取一个新的镜像

当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。

$ docker pull ubuntu:15.10
15.10: Pulling from lib
7dcf5a444392: Pull complete
759aa75f3cee: Pull complete
3fa871dc8a2b: Pull complete
224c42ae46e7: Pull complete
Digest: sha256:02521a2d079595241c6793b2044f02eecf294034f31d6e235ac4b2b54ffc41f3
Status: Downloaded newer image for ubuntu:15.10
docker.io/library/ubuntu:15.10

下载完成后,我们可以直接使用这个镜像来运行容器。

查找镜像

我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为:Docker Hub

我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。

$ docker search httpd
NAME                                    DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
httpd                                   The Apache HTTP Server Project                  3746      [OK]
centos/httpd-24-centos7                 Platform for running Apache httpd 2.4 or bui…   40
centos/httpd                                                                            34                   [OK]
arm32v7/httpd                           The Apache HTTP Server Project                  10
polinux/httpd-php                       Apache with PHP in Docker (Supervisor, CentO…   5                    [OK]

NAME: 镜像仓库源的名称

DESCRIPTION: 镜像的描述

OFFICIAL: 是否 docker 官方发布

stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。

AUTOMATED: 自动构建。

删除镜像

镜像删除使用 docker rmi 命令,比如我们删除 hello-world 镜像:

$ docker rmi ubuntu:15.10
Untagged: ubuntu:15.10
Untagged: ubuntu@sha256:02521a2d079595241c6793b2044f02eecf294034f31d6e235ac4b2b54ffc41f3
Deleted: sha256:9b9cb95443b5f846cd3c8cfa3f64e63b6ba68de2618a08875a119c81a8f96698
Deleted: sha256:b616585738eaf78ff7d86c7526caf7c91a35bc4028ef63204e5bfee82f7494b5
Deleted: sha256:dee1316f97acc7e1a5088b02fbc2b3078e0bfa038dd904b8072e2de5656e7bb8
Deleted: sha256:e7d9ae1a69c53c9fefa1aef34348be5a5dbf2fe79e7dd647b3d4f4e927587ebc
Deleted: sha256:f121afdbbd5dd49d4a88c402b1a1a4dca39c9ae75ed7f80a29ffd9739fc680a7

创建镜像

当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。

  • 从已经创建的容器中更新镜像,并且提交这个镜像
  • 使用 Dockerfile 指令来创建一个新的镜像

更新镜像

更新镜像之前,我们需要使用镜像来创建一个容器。

docker run -t -i ubuntu /bin/bash

在运行的容器内使用 apt-get update 命令进行更新。

在完成操作之后,输入 exit 命令来退出这个容器。

此时 ID 为 d7539653fa1a 的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本。

root@VM-20-7-ubuntu:/# docker commit -m="has updated" -a="syy" 59546b4fd307 syy/ubuntu:v2
sha256:972efb81ae7800412932682d8b1cbd23c4d60dc0a7a441e4e950135dd2e3ac54

各个参数说明:

  • -m: 提交的描述信息
  • -a: 指定镜像作者
  • **e218edb10161:**容器 ID
  • runoob/ubuntu:v2: 指定要创建的目标镜像名

我们可以使用 docker images 命令来查看我们的新镜像 runoob/ubuntu:v2

root@VM-20-7-ubuntu:/# docker images
REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
syy/ubuntu        v2        972efb81ae78   7 seconds ago    104MB

构建镜像

我们使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。

$ vim Dockerfile
#输入以下内容
FROM    ubuntu
MAINTAINER      Fisher "fisher@sudops.com"
 
RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd syy
RUN     /bin/echo 'syy:123456' |chpasswd
RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE  22
EXPOSE  80
CMD     /usr/sbin/sshd -D
$ cat Dockerfile 
FROM    ubuntu
MAINTAINER      Fisher "fisher@sudops.com"
 
RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd syy
RUN     /bin/echo 'syy: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 命令来构建一个镜像。

$ docker build -t syy/centos:6.7 .

参数说明:

  • -t :指定要创建的目标镜像名
  • . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径

使用 docker images 查看创建的镜像已经在列表中存在

设置镜像标签

我们可以使用 docker tag 命令,为镜像添加一个新的标签。

root@VM-20-7-ubuntu:/# docker tag 972efb81ae78 syy/ubuntu:test
root@VM-20-7-ubuntu:/# docker images
REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
syy/ubuntu        test      972efb81ae78   13 minutes ago   104MB
syy/ubuntu        v2        972efb81ae78   13 minutes ago   104MB     73.1MB

docker tag [镜像ID],这里是 972efb81ae78,用户名称、镜像源名(repository name)和新的标签名(tag)。

使用 docker images 命令可以看到,ID为972efb81ae78的镜像多一个标签。

4.4 Docker 容器连接

前面我们实现了通过网络端口来访问运行在 docker 容器内的服务。

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P-p 参数来指定端口映射。

网络端口映射

我们创建了一个 python 应用的容器。

$ docker run -d -P training/webapp python app.py

另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。

我们使用 -P 绑定端口号,使用 docker ps 可以看到容器端口 5000 绑定主机端口 49154。

$ docker ps
CONTAINER ID   IMAGE             COMMAND           CREATED          STATUS          PORTS                                         NAMES
e3ea25d48072   training/webapp   "python app.py"   25 seconds ago   Up 24 seconds   0.0.0.0:49154->5000/tcp, :::49154->5000/tcp   adoring_wescoff

我们也可以使用 -p 标识来指定容器端口绑定到主机端口。

两种方式的区别是:

  • -P :是容器内部端口随机映射到主机的高端口。
  • -p : 是容器内部端口绑定到指定的主机端口。

另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。

$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
3e5bb9cdc1067ab91aa9baddd3ad9a827a4e117b9d6fa38561ad980e853271af
root@VM-20-7-ubuntu:/# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED             STATUS             PORTS                                                                      NAMES
3e5bb9cdc106   training/webapp    "python app.py"          2 minutes ago       Up 2 minutes       127.0.0.1:5001->5000/tcp                                                   trusting_albattani
b5d420d7d518   training/webapp    "python app.py"          46 minutes ago      Up 46 minutes      0.0.0.0:5000->5000/tcp, :::5000->5000/tcp                                  modest_wozniak
bda11450fed6   training/webapp    "python app.py"          48 minutes ago      Up 48 minutes      0.0.0.0:49153->5000/tcp, :::49153->5000/tcp                                romantic_nobel

如果要绑定 UDP 端口,可以在端口后面加上 /udp

root@VM-20-7-ubuntu:/# docker run -d -p 127.0.0.1:5001:5000/udp training/webapp python app.py
a04fe667ff315590b755238ecb5c490c83aaa7bdf767f8ca8e69a9c8ac62ae19
root@VM-20-7-ubuntu:/# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED             STATUS             PORTS                                                                      NAMES
a04fe667ff31   training/webapp    "python app.py"          3 seconds ago       Up 2 seconds       5000/tcp, 127.0.0.1:5001->5000/udp                                         inspiring_babbage
3e5bb9cdc106   training/webapp    "python app.py"          3 minutes ago       Up 3 minutes       127.0.0.1:5001->5000/tcp                                                   trusting_albattani
b5d420d7d518   training/webapp    "python app.py"          47 minutes ago      Up 47 minutes      0.0.0.0:5000->5000/tcp, :::5000->5000/tcp                                  modest_wozniak
bda11450fed6   training/webapp    "python app.py"          49 minutes ago      Up 49 minutes      0.0.0.0:49153->5000/tcp, :::49153->5000/tcp                                romantic_nobel

docker port 命令可以让我们快捷地查看端口的绑定情况。

root@VM-20-7-ubuntu:/# docker port a04fe667ff31 
5000/udp -> 127.0.0.1:5001

Docker 容器互联

端口映射并不是唯一把 docker 连接到另一个容器的方法。

docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。

docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。

容器命名

当我们创建一个容器的时候,docker 会自动对它进行命名。另外,我们也可以使用 --name 标识来命名容器,例如:

root@VM-20-7-ubuntu:/home/ubuntu# docker run -d -P --name webapp training/webapp python app.py
e30ef2c877c9ac9192243b17b3c09c9d2b4dd383e0c1a9b387152dd07d3f880e
root@VM-20-7-ubuntu:/home/ubuntu# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                                                                      NAMES
e30ef2c877c9   training/webapp    "python app.py"          4 seconds ago   Up 3 seconds   0.0.0.0:49154->5000/tcp, :::49154->5000/tcp                                webapp
新建网络

下面先创建一个新的 Docker 网络。

$ docker network create -d bridge test-net
4e046933732baf4d4f47ab79fd2f3ffde705545c21bb90f2094ca26680ac9854

参数说明:

-d:参数指定 Docker 网络类型,有 bridge、overlay。其中 overlay 网络类型用于 Swarm mode。

连接容器

运行一个容器并连接到新建的 test-net 网络:

$ docker run -itd --name test1 --network test-net ubuntu /bin/bash
5a97318b617032c7a2056c8a19088dc7b7da6d2f126bbdd9adbf05a18a537a26

打开新的终端,再运行一个容器并加入到 test-net 网络:

$ docker run -itd --name test2 --network test-net ubuntu /bin/bash
f708bdb6b7856766537a41e1c93772e766aed624ddd23c8002dfd6e85554eef7

下面通过 ping 来证明 test1 容器和 test2 容器建立了互联关系。

如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping

$ apt-get update
$ apt install iputils-ping

在 test1 容器输入以下命令:

root@5a97318b6170:/# ping test2
PING test2 (172.19.0.3) 56(84) bytes of data.
64 bytes from test2.test-net (172.19.0.3): icmp_seq=1 ttl=64 time=0.537 ms
64 bytes from test2.test-net (172.19.0.3): icmp_seq=2 ttl=64 time=0.102 ms
64 bytes from test2.test-net (172.19.0.3): icmp_seq=3 ttl=64 time=0.114 ms
64 bytes from test2.test-net (172.19.0.3): icmp_seq=4 ttl=64 time=0.102 ms
^C
--- test2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3045ms
rtt min/avg/max/mdev = 0.102/0.213/0.537/0.186 ms

在 test2 容器上也同理,这样,test1 容器和 test2 容器建立了互联关系。

如果你有多个容器之间需要互相连接,推荐使用 Docker Compose。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值