【Docker】Docker学习之基本管理


Docker的管理包括多个方面,例如镜像管理、容器管理、网络管理以及存储管理等。
镜像管理:介绍Docker镜像的查找、下载、列出、删除以及创建等
容器管理:介绍Docker容器的创建、启动、停止、运行、重新启动等管理操作
网络管理:介绍Docker容器的创建、连接、删除以及端口映射等操作

镜像管理

在Docker中,镜像是容器的模板。容器中的虚拟机都是以镜像为模板创建的。

查找镜像

Docker提供了docker search命令来查找远程镜像仓库中的镜像。例如:

xinzhe@node01:~$ sudo docker search mysql

下载镜像

找到合适的镜像之后,用户可以将其下载到本地电脑中,以便创建容器。Docker提供了docker pull命令下载镜像。例如

xinzhe@node01:~$ sudo docker pull ubuntu

通常情况下,镜像都是分层存储的。其中每一层都可以由不同的镜像共用。
在Docker的镜像管理中,标签发挥了重要的作用,用来区分同一个镜像的不同版本。

列出本地镜像

查看已经下载本地的镜像,命令为docker images,例如:

sudo docker images

删除镜像

删除镜像使用docker rmi命令,其中rmi中的字母i表示镜像。例如:

sudo docker rmi ubuntu

查看镜像

对于下载到本地的镜像文件,可以使用docker inspect命令来查看其详细信息,例如

sudo docker inspect mysql

构建镜像

构建Docker镜像有两种方法,其一是使用docker commit命令,其二是使用docker build命令和Dockerfile文件。
使用docker commit命令构建镜像的过程可以想象为是往版本控制系统里提交变更。先创建一个容器,并在容器里做出修改,最后再将修改结果提交为一个新的镜像。
以Ubuntu为例:
(1)以交互方式启动一个Ubuntu容器,执行如下命令:

xie@node01:~$ sudo docker run -i -t ubuntu /bin/bash
root@a36e407b3042:/#

其中的docker run表示启动一个容器,参数-i表示采用交互方式,-t表示为当前用户分配一个虚拟终端,后面为Ubuntu镜像名称,/bin/bash为要执行的命令。执行成功后,root为当前Ubuntu容器的用户,@符号后面的为容器的ID。
(2)在容器中安装Apache2

root@a36e407b3042:/# apt-get install -y apache2

(3)安装完成之后,接下来就是构建镜像
使用exit命令退出当前镜像,返回到Docker的管理界面。找到刚才使用的容器,执行如下命令:

 sudo docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED             STATUS                         PORTS     NAMES
a36e407b3042   ubuntu        "/bin/bash"              35 minutes ago      Exited (0) 11 seconds ago                pensive_beaver

第一列为容器的ID。使用容器ID作为参数创建新的镜像,命令如下:

xie@node01:~$ sudo docker commit a36e407b3042 demo/webserver
sha256:bbf69edf5ab5a6c9deeebc6ef0fb5e1112aeb8c09f3cdf6229a5688a5066864e

其中的demo/webserver为新的镜像的名称。当docker commit命令执行完成之后,可以使用docker images命令查看镜像是否创建成功。

xie@node01:~$ sudo docker images
REPOSITORY       TAG       IMAGE ID       CREATED              SIZE
demo/webserver   latest    bbf69edf5ab5   About a minute ago   213MB

镜像标签管理

镜像的标签可以区分不同的版本,在语法上,标签和镜像名称之间通过冒号":"隔开。Docker提供了docker tag命令来设置镜像的标签,语法为:docker tar source_image[:tag] target_image[:tag]
例如:

root@node01:~# docker images
REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
demo/webserver   latest    bbf69edf5ab5   15 hours ago    213MB
ubuntu           latest    f643c72bc252   7 weeks ago     72.9MB
mysql            5.7       42cdba9f1b08   3 months ago    448MB
hello-world      latest    bf756fb1ae65   12 months ago   13.3kB
root@node01:~# docker tag hello-world demo:hello-world
root@node01:~# docker images
REPOSITORY       TAG           IMAGE ID       CREATED         SIZE
demo/webserver   latest        bbf69edf5ab5   15 hours ago    213MB
ubuntu           latest        f643c72bc252   7 weeks ago     72.9MB
mysql            5.7           42cdba9f1b08   3 months ago    448MB
demo             hello-world   bf756fb1ae65   12 months ago   13.3kB
hello-world      latest        bf756fb1ae65   12 months ago   13.3kB
root@node01:~#

当然,还可以通过镜像ID来引用镜像。

容器管理

在Docker中,容器是提供服务的主体。

创建容器

容器是Docker提供网络服务的主体。在Docker中,用户可以通过两种方式来创建容器。首先,用户可以通过docker create命令来创建一个容器,创建的新容器处于停止状态。其次,docker run命令也可以创建一个新的容器,并且会启动该容器。语法如下:

docker create [options] images

用户可以通过options为容器指定相应的选项,用来设置新的容器。常用的选项有:

  • –add-host=[]:指定主机到IP地址的映射关系,其格式为host:ip
  • –dns=[]:为容器指定域名服务器
  • –h:为容器指定主机名
  • –i:打开容器的标准输入
  • –u,–user=:创建用户

通常情况下,用户在创建容器时只要指定镜像名称及其版本即可。其他的都可以采用默认的选项。例如

root@node01:~# docker create centos
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
9295b7f1dd54256d84217836679b6d515006843bb80f3b0856d8b61d8e8fb544

执行成功后,返回新容器的ID。
另外,还可以在docker create命令中,镜像可以指定标签或者版本号。如下:

docker create centos:latest

当本地电脑中不存在用户指定的镜像时,docker会自动搜索远程仓库。找到之后,会自动将其下载到本地,然后再创建容器。
docker run命令不仅可以创建容器,而且在创建容器之后,会立即启动该容器。语法和docker create类似。有两个选项需要注意:

  • -t:为当前的容器分配一个命令行虚拟终端,以便于用户和容器交互,以该选项创建的容器可以称为交互式容器。
  • -d:以该选项创建的容器称为后台型容器,新的容器保持在后台运行。
    例如,创建一个名称为demo_centos的容器,创建之后立即启动该容器,并且进入交互模式:
docker run -i -t --name demo_centos centos /bin/bash

如果想要退出当前容器,直接执行exit即可。

创建一个后台型容器:

root@node01:~# docker run -d centos
f000edaf0cfb3787d78ab9c148cd1789068c57222a2c0f2dcda21b70e54b2fd3
root@node01:~#

查看容器

Docker提供了docker ps命令来查看当前系统中的容器:如下:

root@node01:~# docker ps ## 列出正在运行的容器
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

注意,同一台宿主机上不允许存在有同名的容器,否则会冲突。
另外,带上参数 -a 可以列出当前系统中所有的容器,包括运行中的容器以及处于停止状态的容器。-f可以筛选符合条件的容器,示例如下:

root@node01:~# docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS                     PORTS     NAMES
f000edaf0cfb   centos        "/bin/bash"              6 minutes ago   Exited (0) 6 minutes ago             awesome_wilbur
f9f8f2139ebd   centos        "/bin/bash"              9 minutes ago   Exited (0) 9 minutes ago             demo_centos
9295b7f1dd54   centos        "/bin/bash"              3 hours ago     Created                              ecstatic_neumann
a36e407b3042   ubuntu        "/bin/bash"              18 hours ago    Exited (0) 18 hours ago              pensive_beaver
235d02631723   hello-world   "/hello"                 19 hours ago    Exited (0) 19 hours ago              romantic_sinoussi
b90910f1cbc5   hello-world   "/hello"                 19 hours ago    Exited (0) 19 hours ago              heuristic_mirzakhani
360b0e70f946   mysql:5.7     "docker-entrypoint.s…"   2 months ago    Exited (0) 2 months ago              mysql
root@node01:~# docker ps -a -f name=mysql
CONTAINER ID   IMAGE       COMMAND                  CREATED        STATUS                    PORTS     NAMES
360b0e70f946   mysql:5.7   "docker-entrypoint.s…"   2 months ago   Exited (0) 2 months ago             mysql

启动容器

对于处于停止状态的容器,可以通过docker start命令来启动,示例如下:

docker start mysql

除此之外,docker还支持restart。

停止容器

Docker提供了两个命令来停止处于运行态中的容器:docker stop和docker kill

  • docker stop命令通过发送停止信号给容器,让其停止运行。某些情况下,会出现无法停止的现象,此时可以指定在强制停止容器前等待的时间,等待时间可以通过-t选项来指定,时间单位为秒。如果超过等待时间,系统会强制停止该容器。
root@node01:~# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED        STATUS         PORTS                               NAMES
360b0e70f946   mysql:5.7   "docker-entrypoint.s…"   2 months ago   Up 3 minutes   0.0.0.0:3306->3306/tcp, 33060/tcp   mysql
root@node01:~# docker stop -t 10 mysql
mysql
root@node01:~# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
  • docker kill命令用来强制终止某个容器,命令发送出KILL信号后,容器会立即终止运行。
root@node01:~# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED        STATUS        PORTS                               NAMES
360b0e70f946   mysql:5.7   "docker-entrypoint.s…"   2 months ago   Up 1 second   0.0.0.0:3306->3306/tcp, 33060/tcp   mysql
root@node01:~# docker kill mysql
mysql
root@node01:~# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

删除容器

删除容器使用docker rm命令,参数为容器名称或者标识。例如:

docker rm f643c72bc252

注意:如果是正在运行的容器,需要首先将其停止,然后再删除。

网络管理

首先介绍Docker自身的4种网络工作方式,然后介绍一些自定义的网络模式

Docker网络原理

在Windows或者Linux系统中,当Docker安装完成之后,Docker都会在宿主机中创建一个虚拟网桥,通过该网桥实现容器之间以及容器与外部网络的连接。通常情况下,虚拟网桥的名称为docker0。例如

root@node01:~# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 00:50:56:3b:fb:25 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
    link/ether 02:42:ac:bb:c5:21 brd ff:ff:ff:ff:ff:ff

网桥工作在OSI七层模型中的数据链路层。网桥是早期的两端口二层网络设备,用来连接不同网段。网桥就像一个中继器,从一端接收信号,送入另一端。网桥将网络中的多个网段在数据链路层连接起来。

在Docker中,各个容器是通过一个名称为docker0的虚拟网桥实现连接的。该虚拟网桥可以设置IP地址,相当于一个隐藏的虚拟网卡。
docker守护进程在一个容器中启动时,实际上它要创建网络连接的两端。一端是在容器中的网络设备,而另一端是在运行docker守护进程的主机上打开一个名为veth*的一个接口,用来实现docker0这个网桥与容器的网络通信。可以通过brctl命令来查看虚拟网桥docker0的信息,例如

root@node01:~# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242acbbc521       no

网络模式

Docker支持四种网络模式,网络模式可以在创建容器时就使用–network选项来指定。这四种模式分别是host、container、none以及bridge。

1.host模式

Docker使用了Linux的命名空间来进行资源隔离,如PID命名空间隔离进程,Mount命名空间隔离文件系统,Network命名空间隔离网络等。一个Network命名空间提供了一份独立的网络环境,包括网卡、路由、iptable规则等都与其他的Network命名空间隔离。一个Docker容器一般会分配一个独立的Network命名空间。但是,如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network命名空间,而是和宿主机共用一个Network命名空间,容器将不会虚拟出自己的网卡,配置自己的IP地址等,而是使用宿主机的IP和端口。

root@node01:~# docker run -d -t -i --network=host centos
5797e64e193d2d0610f027509bad36e9decc38014013ef87c0522dc21ac6e883

创建完成后,查看网络参数:

root@node01:~# docker exec 5797e64e193d2d0610f027509bad36e9decc38014013ef87c0522dc21ac6e883 ip a show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:50:56:3b:fb:25 brd ff:ff:ff:ff:ff:ff
    inet 192.168.23.121/24 brd 192.168.23.255 scope global noprefixroute ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe3b:fb25/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:ac:bb:c5:21 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:febb:c521/64 scope link
       valid_lft forever preferred_lft forever
root@node01:~#

实际上,这些网络信息正是主机的网络信息。

root@node01:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:50:56:3b:fb:25 brd ff:ff:ff:ff:ff:ff
    inet 192.168.23.121/24 brd 192.168.23.255 scope global noprefixroute ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe3b:fb25/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:ac:bb:c5:21 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:febb:c521/64 scope link
       valid_lft forever preferred_lft forever
root@node01:~#

2. container模式(容器模式)

容器模式指定新创建的容器和已经存在的一个容器共享一个Network命名空间,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP地址,而是和一个指定的容器共享IP地址、端口范围等。两个容器的进程可以通过共享网卡设备通信

3. none模式(无模式)

这种模式下,Docker容器拥有自己的Network命名空间,但是,并不为Docker容器进行任何网络配置。也就是说,该Docker容器没有网卡、IP地址、路由等信息,需要自己添加。

4. bridge模式(桥接模式)

bridge模式是Docker默认的网络设置,该模式下会为每一个容器分配Network命名空间、设置IP地址等,并将一个主机上的Docker容器连接到一个虚拟网桥上。

Docker容器的互连

由于同一个主机中所有的容器都连接在同一个虚拟网桥docker0上,因此在默认情况下,同一主机中的容器之间是可以互相连接的

root@node01:~# docker run -d -t -i --network=bridge centos
9283956b5d0ac3cb4602704aec4e75622b0cb8caa703b51b9b0e8088550d0dbf
root@node01:~# docker run -d -t -i --network=bridge centos
680eadfd68e698a8ccb4cbe47d8da4843d24a60a858089292eb18ab2b6e96267
root@node01:~# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
680eadfd68e6   centos    "/bin/bash"   2 seconds ago   Up 1 second              nice_ellis
9283956b5d0a   centos    "/bin/bash"   4 seconds ago   Up 3 seconds             laughing_einstein
root@node01:~# docker exec 680eadfd68e6 ip a show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
root@node01:~# docker exec 9283956b5d0a ip a show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
root@node01:~#

这里两个容器的IP分别是172.17.0.3和172.17.0.2,可以使用ping命令测试是否与对方通信:

root@node01:~# docker exec 9283956b5d0a ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.128 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.063 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.081 ms
64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.110 ms
64 bytes from 172.17.0.3: icmp_seq=5 ttl=64 time=0.146 ms
64 bytes from 172.17.0.3: icmp_seq=6 ttl=64 time=0.072 ms
64 bytes from 172.17.0.3: icmp_seq=7 ttl=64 time=0.079 ms
^Z
[1]+  Stopped                 docker exec 9283956b5d0a ping 172.17.0.3
root@node01:~# docker exec 680eadfd68e6 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.051 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.071 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.055 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.059 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.079 ms
^Z
[2]+  Stopped                 docker exec 680eadfd68e6 ping 172.17.0.2
root@node01:~#

默认情况下,容器的IP地址是随机分配的,并且每次启动容器都可能发生变化。如果使用–ip选项为容器指定固定IP,则需要创建自定义网络。

容器与外部网络的互连

容器与外部网络的互连涉及两个方面:一是容器内部访问外部网络,二是外部网络访问容器内部。
由于容器通过自己的网络接口桥接到虚拟网桥docker0上,因此默认情况下,容器内部可以访问外部网络。

root@node01:~# docker exec 680eadfd68e6 ping -c 4 www.baidu.com
PING www.a.shifen.com (36.152.44.96) 56(84) bytes of data.
64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=1 ttl=127 time=26.1 ms
64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=2 ttl=127 time=24.8 ms
64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=3 ttl=127 time=30.8 ms
64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=4 ttl=127 time=52.4 ms

--- www.a.shifen.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 9ms
rtt min/avg/max/mdev = 24.785/33.498/52.359/11.115 ms
root@node01:~#

通常情况下,外部网络是不可以直接访问容器内部的。如果要访问容器提供的网络服务,就需要通过端口映射,也就是将主机的某个端口映射到容器的网络服务端口。通过端口映射,用户只要访问主机的指定端口就可以了。示例如下:

root@node01:~# docker run -itd -p 80:80 httpd
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
a076a628af6f: Pull complete
e444656f7792: Pull complete
0ec35e191b09: Pull complete
4aad5d8db1a6: Pull complete
eb1da3ea630f: Pull complete
Digest: sha256:2fab99fb3b1c7ddfa99d7dc55de8dad0a62dbe3e7c605d78ecbdf2c6c49fd636
Status: Downloaded newer image for httpd:latest
610f58f62bcb548abdbb45943a8da73ee19465ddb3f0a33654ed9a447531645f
root@node01:~#

通过浏览器访问主机的80端口。出现Apache HTTP Server默认页面:
HTTPD

至此,我们已经基本掌握了Docker的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

镰刀韭菜

看在我不断努力的份上,支持我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值