1、运行一个容器:Hello World

运行一个简单的容器,输出“Hello World”

[root@lavm-5wutyiasaf ~]# docker run ubuntu /bin/echo "Hello World"
Hello World

命令参数说明

  • docker:Docker的二进制执行文件
  • run:与前边的docker组合运行一个容器
  • ubuntu:正常是“ubuntu:版本号”指定要运行的容器及版本,如果本地不存在的话会从Docker hub上下载
  • /bin/echo "Hello World":在容器中要执行的命令

命令执行流程

  1. Docker 客户端联系 Docker 守护进程
  2. Docker 守护进程检查本地是否有 ubuntu:15.10 镜像,如果没有则从 Docker Hub 下载
  3. Docker 守护进程基于该镜像创建新的容器
  4. Docker 守护进程分配一个文件系统给容器,并在镜像层外挂载一个读写层
  5. Docker 守护进程创建网络接口,连接容器到默认网络
  6. Docker 守护进程设置 IP 地址,从池中分配一个 IP 给容器
  7. Docker 守护进程在容器中执行 /bin/echo "Hello world" 命令
  8. Docker 守护进程将命令的输出流回应给 Docker 客户端,客户端将输出发送给用户终端

2、运行交互式容器

通过Docker的“-i”和“-t”参数,我们可以建立一个具有交互能力的容器,可以像使用传统虚拟机一样使用容器。

[root@lavm-5wutyiasaf ~]# docker run -i -t ubuntu:22.04 /bin/bash
root@07730f76c2e7:/# 
root@07730f76c2e7:/# 

参数说明

  • -i:在新容器内指定一个伪终端或者终端
  • -t:允许你对容器内的标准输入(STDIN)进项交互
  • /bin/bash:在容器内启动bash shell

运行后,将进入容器的bash终端,提示符类似于:

root@07730f76c2e7:/#

在容器内执行命令

现在可以在容器里执行各种命令,就像在linux系统中一样

##查看容器版本信息
root@07730f76c2e7:/# cat /etc/o
opt/        os-release  
root@07730f76c2e7:/# cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

##查看容器主机名
root@07730f76c2e7:/# hostname
07730f76c2e7

##查看容器进程
root@07730f76c2e7:/# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1   4612  2400 pts/0    Ss   09:08   0:00 /bin/bash
root        12  0.0  0.0   7048  1448 pts/0    R+   09:18   0:00 ps aux
root@a94ce49601e1:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@a94ce49601e1:/# echo "Hello World" > /tmp/test.txt
root@a94ce49601e1:/# cat /tmp/test.txt 
Hello World
##安装ip和ifconfig命令
root@a94ce49601e1:/# apt update
root@a94ce49601e1:/# apt install net-tools
root@a94ce49601e1:/# apt install iproute2

##ip a查询
root@a94ce49601e1:/# 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
13: eth0@if14: <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

##ifconfig查询
root@a94ce49601e1:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 22069  bytes 42495772 (42.4 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18376  bytes 1447657 (1.4 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

退出容器

可以使用“exit”命令退出,也可以使用快捷键“Ctrl + D”

root@07730f76c2e7:~# exit
exit
[root@lavm-5wutyiasaf ~]# 

容器退出后会停止运行,但不会删除,可以通过“docker ps -a”查到所有容器,包括已经停止的容器。

[root@lavm-5wutyiasaf ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED             STATUS                         PORTS     NAMES
a94ce49601e1   ubuntu:22.04   "/bin/bash"              12 minutes ago      Exited (0) 10 seconds ago                heuristic_carson
07730f76c2e7   ubuntu:22.04   "/bin/bash"              35 minutes ago      Exited (0) 16 minutes ago                bold_nightingale
1b4dbb14ddd0   ubuntu         "/bin/echo 'Hello Wo…"   59 minutes ago      Exited (0) 59 minutes ago                blissful_gates
5fd6f804e8f7   ubuntu         "/bin/echo 'Hello Wo…"   About an hour ago   Exited (0) About an hour ago             strange_williamson
66c9c7e39342   hello-world    "/hello"                 6 hours ago         Exited (0) 6 hours ago                   xenodochial_boyd

3、后台运行容器

实际运用中,我们需要让容器在后台运行。

使用“-d”参数可以让容器在后台运行。

[root@lavm-5wutyiasaf ~]# docker run -d ubuntu:22.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
2d8afc1c2b3d8a26e243a823c4cb5511c301d1dc5a2f07c4950d5d278cc44c11

参数说明

  • -d:让容器再后台运行
  • /bin/sh -c “COMMAND”:在容器中执行shell命令
  • while true ;do ... done:创建一个循环,示例中是每秒输出一次“hello world“

运行后容器会返回一个容器ID,像这样

2d8afc1c2b3d8a26e243a823c4cb5511c301d1dc5a2f07c4950d5d278cc44c11

容器管理

使用docker ps命令查看运行中的所有容器

[root@lavm-5wutyiasaf ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS        PORTS     NAMES
2d8afc1c2b3d   ubuntu:22.04   "/bin/sh -c 'while t…"   16 hours ago   Up 16 hours             inspiring_goodall

docker ps输出说明

  • CONTAINER ID:容器的唯一标识符
  • IMAGE:使用的镜像及版本
  • COMMAND:启动容器时运行的命令
  • CREATED:容器的创建时间
  • STATUS:容器的当前状态
  • PORTS:容器的端口映射信息
  • NAMES:容器的名称(如果没有指定,Docker会自动分配一个随机名称)

容器状态说明

  • created:已创建但未启动
  • restarting:重启中
  • running 或 up:运行中
  • removing:迁移中
  • paused:暂停中
  • exited:已停止
  • dead:已死亡(无法启动)

查看容器日志

通过容器ID查看日志

[root@lavm-5wutyiasaf ~]# docker logs 2d8afc1c2b3d
hello world
hello world
hello world
hello world
hello world
......(持续输出)

通过容器名称查看日志

[root@lavm-5wutyiasaf ~]# docker logs inspiring_goodall
hello world
hello world
hello world
hello world
hello world
......(持续输出)

实时查看日志(类似tail -f)

[root@lavm-5wutyiasaf ~]# docker logs -f inspiring_goodall
hello world
hello world
hello world
hello world
hello world
......(持续输出)

查看最近的5条日志

[root@lavm-5wutyiasaf ~]# docker logs --tail 5 inspiring_goodall
hello world
hello world
hello world
hello world
hello world

停止容器

使用 docker stop 命令停止容器

通过ID停止容器

[root@lavm-5wutyiasaf ~]# docker stop 2d8afc1c2b3d
2d8afc1c2b3d

通过容器名称停止容器

[root@lavm-5wutyiasaf ~]# docker stop exciting_rhodes
exciting_rhodes

4、命名容器

默认情况下,Docker会为每个容器分配一个随机名称。实际应用中为了方便管理,会为容器自定义一个名称。

使用 --name 参数可以为容器指定名称

[root@lavm-5wutyiasaf ~]# docker run -d --name hello-ubuntu ubuntu:latest /bin/sh -c "while true; do echo hello ubuntu; sleep 1; done"
889310d2441b54791567ee388a6b3004c31846a369a4afa89ab9592b16cddd78
[root@lavm-5wutyiasaf ~]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS          PORTS     NAMES
889310d2441b   ubuntu:latest   "/bin/sh -c 'while t…"   47 seconds ago   Up 46 seconds             hello-ubuntu

使用容器名称 hello-ubuntu 来引用容器

[root@lavm-5wutyiasaf ~]# docker logs --tail 5 hello-ubuntu
hello ubuntu
hello ubuntu
hello ubuntu
hello ubuntu
hello ubuntu

用容器名称对容器进行操作

[root@lavm-5wutyiasaf ~]# docker stop hello-ubuntu
hello-ubuntu
[root@lavm-5wutyiasaf ~]# docker start hello-ubuntu
hello-ubuntu
[root@lavm-5wutyiasaf ~]# docker restart hello-ubuntu
hello-ubuntu

注意事项

  • 容器名称必须时唯一的。如果尝试创建同名称的容器,Docker会返回错误。
  • 容器名称可以包含字母、数字、下划线、点和连字符。
  • 容器必须以字母或数字开头。

5、容器生命周期管理

了解容器的完整生命周期对于管理 Docker 环境至关重要。以下是容器生命周期的主要阶段和相关命令

创建容器

创建但不启动容器(create)

[root@lavm-5wutyiasaf ~]# docker create --name testubuntu ubuntu:22.04
d00fcb048bc627bf227196a2fef01220a5f4757e179fd9a38b41bbd6febe40ee
[root@lavm-5wutyiasaf ~]# docker ps -a
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS                      PORTS     NAMES
d00fcb048bc6   ubuntu:22.04         "/bin/bash"              6 seconds ago   Created                               testubuntu

该命令会创建一个容器但不会启动。创建后容器处于“Created”状态。

启动容器

启动已创建或停止的容器(start)

[root@lavm-5wutyiasaf ~]# docker start testubuntu
testubuntu

该命令会启动一个已创建或已停止的容器。启动后的容器处于一个“running”的状态。

暂停和恢复容器

暂时冻结容器中的所有进程(pause)

[root@lavm-5wutyiasaf ~]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED        STATUS        PORTS     NAMES
889310d2441b   ubuntu:latest   "/bin/sh -c 'while t…"   24 hours ago   Up 1 second             hello-ubuntu
[root@lavm-5wutyiasaf ~]# 
[root@lavm-5wutyiasaf ~]# docker pause hello-ubuntu
hello-ubuntu
[root@lavm-5wutyiasaf ~]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED        STATUS                   PORTS     NAMES
889310d2441b   ubuntu:latest   "/bin/sh -c 'while t…"   24 hours ago   Up 25 seconds (Paused)             hello-ubuntu

暂停容器会冻结容器中的所有进程,但不会释放资源。暂停的容器处于“Paused”状态。


恢复容器中的所有进程(unpause)

[root@lavm-5wutyiasaf ~]# docker unpause hello-ubuntu
hello-ubuntu
[root@lavm-5wutyiasaf ~]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED        STATUS         PORTS     NAMES
889310d2441b   ubuntu:latest   "/bin/sh -c 'while t…"   24 hours ago   Up 4 minutes             hello-ubuntu

停止容器

停止容器中所有的进程

[root@lavm-5wutyiasaf ~]# docker stop hello-ubuntu
hello-ubuntu
[root@lavm-5wutyiasaf ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

这个命令会发送 SIGTERM 信号给容器中的主进程,如果进程在一定时间内(默认 10 秒)没有退出, Docker 会发送 SIGKILL 信号强制终止进程。停止后的容器处于 "exited" 状态。

强制停止容器

立刻终止容器中的所有进程

[root@lavm-5wutyiasaf ~]# docker kill hello-ubuntu
hello-ubuntu
[root@lavm-5wutyiasaf ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

这个命令会立即发送 SIGKILL 信号给容器中的主进程,强制终止容器。 这可能会导致数据丢失,应该只在容器无法正常停止时使用。

删除容器

永久的删除容器

# 删除已停止的容器
[root@lavm-5wutyiasaf ~]# docker rm testubuntu
testubuntu

# 强制删除正在运行的容器
[root@lavm-5wutyiasaf ~]# docker rm -f exciting_rhodes
exciting_rhodes

# 删除所有已停止的容器
[root@lavm-5wutyiasaf ~]# docker rm $(docker ps -aq)
663a5afea5fb
b558ad89685f
f9363e187612
a94ce49601e1
07730f76c2e7
1b4dbb14ddd0
5fd6f804e8f7
66c9c7e39342
Error response from daemon: cannot remove container "/hello-ubuntu": container is running: stop the container before removing or force remove
Error response from daemon: cannot remove container "/angry_gagarin": container is running: stop the container before removing or force remove
Error response from daemon: cannot remove container "/inspiring_goodall": container is running: stop the container before removing or force remove

# 删除所有已停止的容器
[root@lavm-5wutyiasaf ~]# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
e11ae3a76f5aec04e00dab569a5fbe6dd0171aca6d547aa34c11531e8becb9c3
2d8afc1c2b3d8a26e243a823c4cb5511c301d1dc5a2f07c4950d5d278cc44c11

Total reclaimed space: 0B
[root@lavm-5wutyiasaf ~]# docker ps -a
CONTAINER ID   IMAGE           COMMAND                  CREATED        STATUS         PORTS     NAMES
889310d2441b   ubuntu:latest   "/bin/sh -c 'while t…"   25 hours ago   Up 3 minutes             hello-ubuntu

删除容器会永久的丢失器文件系统。如果容器中有未保存的数据,这些数据将丢失。

容器状态转换

容器状态可以按一下方式转换

  • created-->running:通过“docker start”
  • running-->paused:通过“docker pause”
  • paused-->running:通过“docker unpause”
  • running-->exited:通过“docker stop”或者“docker kill”
  • exited-->running:通过“docker start”
  • 任何状态-->删除:通过“docker rm”(运行中的容器需要使用“-f”参数)