安装完Docker的服务,我们就可以开始使用Docker了。

Docker镜像

  之前我们提到,docker是一个运行容器的工具,可以单独隔离每个服务的运行环境,达到互不干扰和节约资源的目的。而docker运行的容器,是基于一层一层的镜像联合挂载构建而成。所以我们需要先有镜像。
  所谓镜像,其实可以理解为,一个个的最简化的安装包,里面只集成了一些必备的程序和文件,且每一层和每一层镜像是可以相互一样的,大大的节约了空间,提高了资源利用率。举个最简单的例子,我们从官方下载一个centos系统的镜像包centos:apline,大小才5.55兆,而centos差不多至少200兆了,而centos安装的ISO镜像文件也都差不多1G左右。这是因为容器使用的镜像系统,需要依赖宿主机内核来运行,容器本身是没有内核的,只包含一些基础功能命令而已。可用docker images查看本地镜像,从大小来看,就知道容器确实很精简。

1
2
3
4
5
root@DockerUbuntu:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 965ea09ff2eb 6 weeks ago 5.55MB
centos latest 0f3e07c0138f 2 months ago 220MB
centos 7.6.1810 f1cb7c7d58b7 8 months ago 202MB

  我们可以在docker官方镜像仓库https://hub.docker.com查看官方镜像,也可以通过命令直接搜索centos的可用容器

1
docker search centos

  注意:官方仓库也有很多是个人的镜像,为避免未知风险,一定要采用官方镜像,千万别使用安全性未知或来源不明的的镜像。一般排在第一个是官方镜像。
  使用命令docker pull centos就可以自动从docker官方镜像仓库docker.io,下载centos镜像了,因为我们没有指定版本标签,所以这条命令会默认下载centos:latest版本,也就是最新版。生产中我们出于稳定性和便于管理,都会推荐使用指定的稳定版本,而不会采用latest版本(,随着版本发型,之前的latest版本和几个月之后的latest版很有可能就不是一个版本,不利于规范化统一)。我们本次以CentOS7.6中的最新版centos:7.6.1810最为本次演示的版本。下载镜像命令如下:

1
docker pull centos:7.6.1810

  使用docker image rm [ OPTION ] 容器ID可以删除不要的镜像,如果已有容器基于此镜像启动,则会提示错误,无法删除,需先停止容器,或直接加-f选项强制删除镜像,此时容器也会被停止。注意,当容器被停止时,上面的数据也都会丢失,所以需要谨慎关闭容器和删除镜像。
  此外,docker官方镜像站,因为在国外(美国,不过应该是有CDN或者国内镜像加速站点的,不过还是有点点慢),肯定不如阿里的容器镜像仓库速度快。所以我们可以配置阿里的镜像加速器,需要注册阿里账号。
  进入阿里网站http://cr.console.aliyun.com,登陆之后,可以看到阿里的镜像仓库(之后再细说)还有镜像加速器,点击镜像加速器,可看到如图所示界面:
Docker镜像加速  执行将下面代码,便可实现镜像加速了。

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

  之后使用docker info命令就可以看到已经添加镜像仓库成功
docker info

Docker容器

  有了镜像之后我们就可以从中运行容器了。基础的命令有docker pulldocker pushdocker createdocker rundocker psdocker rmdocker startdocker stopdocker imagesdocker execdocker inspect等等

pull push

1
2
3
4
5
6
7
8
9
10
root@DockerUbuntu:~# docker pull --help

Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Pull an image or a repository from a registry

Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
-q, --quiet Suppress verbose output

  docker pull命令我们之前也使用过,可以用来拉镜像,相当于命令docker image pull。根据官方帮助信息,我们可以知道,docker pull 如果要拉去指定版本,需要加:tag版本标签,加-a选项可以拉取所有镜像,不过生产中一般都是用的时候公司内部的本地镜像仓库Harbor,所以拉取镜像时,格式要跟公司Harbor服务器的IP或者域名,指定拉取镜像的源仓库,如果不加,则默认从docker官网拉取。镜像名称格式为:Harbor IP/项目名/image 名字:版本号

1
docker pull 172.18.32.101/centos/centos-base:v1

  docker push是用来推送本地镜像至仓库的,相当于命令docker image push,用法格式与pull相似。
使用pull推送至公司Harbor时,需要先在docker启动文件/lib/systemd/system/docker.serviceExecStart选项结尾加入参数--insecure-registry,表示加入不安全的镜像仓库,可加多个,示例如下。

1
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.32.19 --insecure-registry 192.168.32.20

tag

1
2
3
4
5
6
root@DockerUbuntu:~# docker tag --help

Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
root@DockerUbuntu:~#

  docker tag命令可以用来打标记,格式如上。一般为了区分不同版本,我们会在每次制作完镜像后打上不同的标记,而且要分发到不同的镜像仓库时也要重新打一个对应仓库IP/项目名的镜像,才可以pushpull

run

  docker run可以算是最常用的docker基础命令了,意思是创建并运行容器,相当于docker createdocker start的组合。用法格式如下。

1
docker run [ OPTION ] 镜像ID [ CMD ]

OPTION

  常用选项有-i-t-d-p-v-e--name--net

  • -i,–interactive, Keep STDIN open even if not attached
      以交互式方式运行。不过只加-t是没法实现交互式的,通常需要-t参数配合,来给容器加一个伪终端实现交互式。
  • -t,–tty, Allocate a pseudo-TTY
      给容器分配一个伪终端,与-i配合使用,通常写作-it
  • -d,–detach, Run container in background and print container ID
      使容器启动时后台运行,如果不加这个选项,则会占据宿主机当前终端,服务类容器等交互式容器一般都会加上这个选项。
  • -p,–publish, list Publish a container’s port(s) to the host
      映射本地端口到容器的指定端口,同时映射多个端口,则写多个-p 宿主机端口:容器端口选项。
  • -v,–volume, list Bind mount a volume
      使用-v 参数, 将宿主机目录映射到容器内部, 默认是可读写的。-v SOUCE:DEST:ro后面加ro则可实现只读。
  • -e,–env, list Set environment variables
      可用-e选项为容器添加启动时的环境变量。虽然大多环境变量都是在制作容器时就写进容器里,不过此选项应用在环境变量经常变化的场景,方面修改。
  • --name,Assign a name to the container
      给创建的容器命名。同一个宿主机上的容器之间可以通过自定义的容器名称相互访问,由于容器在启动的时候其内部 IP 地址是 DHCP 随机分配的,所以如果通过内部访问的话,自定义名称是相对比较固定的,因此设置容器别名比较适用于此场景。
  • –link,Add link to another container
      为容器设置一个别名,相当于一个路径名。自定义的容器名称可能后期会发生变化, 那么一旦名称发生变化,程序之间也要随之发生变化,比如程序通过容器名称进行服务调用, 但是容器名称发生变化之后再使用之前的名称肯定是无法成功调用, 每次都进行更改的话又比较麻烦, 因此可以使用自定义别名的方式解决,即容器名称可以随意更,只要不更改别名即可。
  • --net
      为容器指定网络。容器网络类型,常见的为bridge、host、null,也可以自己创建自定义网络。可用docker network list查看当前已有的网络。
    1
    2
    3
    4
    5
    root@DockerUbuntu:~# docker network list
    NETWORK ID NAME DRIVER SCOPE
    1eb441f702d2 bridge bridge local
    241d3e94a6b3 host host local
    7cc9cf9eb69e none null local
      docker服务安装完成后,默认在每个宿主机会生成一个名称为 docker0 的网卡其 IP 地址都是 172.17.0.1/16,并且会生成三种不同类型的网络,也就是bridge、host和null,分别代表网桥(桥接)、宿主机网络和无网络访问。
      如果不加--net选项则默认使用bridge,相当于桥接在宿主机的docker0网卡上。
      host网络就是指容器使用宿主机网络,所以端口就不能重复使用,多个使用host网络的容器间端口也不能重复。
      null网络指容器只有回环网卡,没有外部网卡,无法与外部交流交流,不常使用,适用于某些不需要与外界通信的数据计算或图形、数据处理服务。
      还有一种比较特的类型就是container模式,就是指定与一个已有容器共享网络,格式为--net=container:指定名称或 ID 。使用此模式创建的容器需指定和一个已经存在的容器共享一个网络,而不是和宿主机共享网,新创建的容器不会创建自己的网卡也不会配置自己的 IP,而是和一个已经存在的被指定的容器东西 IP 和端口范围,因此这个容器的端口不能和被指定的端口冲突, 除了网络之外的文件系统、进程信息等仍然保持相互隔离,两个容器的进程可以通过 lo 网卡及容器 IP 进行通信。

    CMD

      docker run后面跟的CMD表示指定启动容器的命令,如果不指定,则为容器默认命令。可用 命令docker inspect 容器ID查看容器详细参数查看容器创建时的的CMD。
      因为容器中没有守护进程systemd,所以进程编号PID=1的根进程,就是我们启动容器时指定的CMD命令或创建容器设定的默认CMD。如果这个PID=1的守护进程结束,则整个容器就将被关闭。所以我们一般会指定一个可以占据前台终端的服务来作为守护进程,例如bash或者tail -f /etc/hosts命令,对于后台nginx等服务来说,想让他们作为守护进程启动容器,需要将在后台执行的这个选项关闭,如nginx可以通过docker run -it -d nginx:alpine nginx -g "daemon off;"命令,加上-g "daemon off"选项传递参数或者在配置文件中设置daemon off来关闭后台执行选项,否则容器启动就会因为没有前台进程而终止。为了方便我们修改配置或者重启服务,企业生产中我们都采用tail -f /etc/hosts来作为前台进程,这样我们重启服务容器就不受影响了。

    ps

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    root@DockerUbuntu:~# docker ps --help

    Usage: docker ps [OPTIONS]

    List containers

    Options:
    -a, --all Show all containers (default shows just running)
    -f, --filter filter Filter output based on conditions provided
    --format string Pretty-print containers using a Go template
    -n, --last int Show n last created containers (includes all states) (default -1)
    -l, --latest Show the latest created container (includes all states)
    --no-trunc Don't truncate output
    -q, --quiet Only display numeric IDs
    -s, --size Display total file sizes
      docker ps命令比较简单,较长使用的参数是-a-q,分别是显示所有容器(包括为未运行容器,ps默认只显示正在运行的容器)和只显示容器ID。也可以使用docker ps -aq来显示所有容器的ID,可配合其他命令如docker rm命令使用。docker rm -f `docker ps -aq`删除本地所有容器(很危险,小心操作!)。

    rm

      docker rm命令是用来删除容器的,如果容器正在运行,使用docker rm命令删除时会报错提示Error response from daemon: You cannot remove a running container XXX. Stop the container before attempting removal or force remove,告诉我们无法删除运行中的容器,需要先将容器停止或者强制删除,使用docker rm -f命令强制删除,或者使用下面的停止命令

start stop

  docker start 容器ID启动容器,可以加选项-i,表示启动容器并输出容器内的标准输出至宿主机终端。需要注意的是,如果当时用docker run或者docker create命令创建容器时,没有加-it-d等一些其它选项或者参数的话,在start容器这一步也没法作出更改了的。容器怎么创建的,启动时就会按照创建时设定好的模式运行,这些是没办法再次修改了的,包括启动CMD。
  docker stop 容器ID终止容器。需要注意:终止容器时,容器内的数据都将丢失,在备份重要数据之前不要终止容器。

images

  docker images命令其实相当于docker image ls,显示本地所有镜像。docker image CMD还有很多,之后介绍镜像管理的时候 在详细介绍。

exec

  docker exec命令可以向一个已运行容器发送命令。用法如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@DockerCentOS ~]# docker exec --help

Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Run a command in a running container

Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container

  最常使用的格式是docker exec -it 容器ID bash/sh,可以进入正在运行的容器。


一个低调的男人