【Docker】Docker Container(容器)

文章目录

  • 一、什么是容器?
  • 二、为什么需要容器?
  • 三、容器的生命周期
  • 四、容器命令详解
    • [docker create](#docker create)
    • [docker logs](#docker logs)
    • [docker attach](#docker attach)
    • [docker exec](#docker exec)
    • [docker start](#docker start)
    • [docker stop](#docker stop)
    • [docker restart](#docker restart)
    • [docker kill](#docker kill)
    • [docker top](#docker top)
    • [docker stats](#docker stats)
    • [docker container inspect](#docker container inspect)
    • [docker port](#docker port)
    • [docker cp](#docker cp)
    • [docker diff](#docker diff)
    • [docker commit](#docker commit)
    • [docker pause](#docker pause)
    • [docker unpause](#docker unpause)
    • [docker rm](#docker rm)
    • [docker export](#docker export)
    • [docker import](#docker import)
    • [docker wait](#docker wait)
    • [docker rename](#docker rename)
    • [docker container prune](#docker container prune)
    • [docker update](#docker update)

一、什么是容器?

通俗地讲,容器 是镜像的运行实体。镜像是静态的只读文件,而容器带有运行时需要的可写文件层,并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容器有 初建、运行、停止、暂停 和 删除 五种状态。

虽然容器的本质是主机上运行的一个进程,但是容器有自己独立的命名空间隔离和资源限制。也就是说,在容器内部,无法看到主机上的进程、环境变量、网络等信息,这是容器与直接运行在主机上进程的本质区别。

容器是基于镜像创建的可运行实例,并且单独存在,一个镜像可以创建出多个容器。运行容器化环境时,实际上是在容器内部创建该文件系统的读写副本。 这将添加一个容器层,该层允许修改镜像的整个副本。

容器的生活案例

镜像与容器就相当于同样是开发商提供的毛坯房,但是两家人装修出来的完全不一样。

或者我们都学习了 Java 或者 C++之类的面向对象的语言,可以理解为镜像为基础类,容器是实例化出来的一个个对象,没有用户需要的不一样,里面的内容也就不一样了。


二、为什么需要容器?

镜像是静态的文件,并不能提供服务,就像我拿了个 Linux 或者 Windows 的光盘一样,只有安装到主机里面运行起来才能对外提供服务,我们才能使用。

虚拟化和容器化的最主要目的就是资源隔离,随着资源隔离的实现逐渐也带来了更大的收益。

  • 资源利用率高
    将利用率较低的服务器资源进行整合,用更少硬件资源运行更多业务,降低 IT 支出和运维管理成本。
  • 环境标准化
    一次构建,随处执行。实现执行环境的标准化发布,部署和运维。开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。
  • 资源弹性伸缩
    根据业务情况,动态调整计算、存储、网络等硬件及软件资源。比如遇到双 11 了,把服务扩容 100 个,双 11 过去了, 把扩容的 100 个收回去。
  • 差异化环境提供
    同时提供多套差异化的执行环境,限制环境使用资源。
    比如我的服务一个以来 Ubuntu 操作系统,一个服务依赖 CentOS 操作系统,但是没有预算购买两个物理机,这个时候容器化就能很好的提供多种不同的环境。
  • 沙箱安全
    为避免不安全或不稳定软件对系统安全性、稳定性造成影响,可使用虚拟化技术构建虚拟执行环境。
    比如我在容器里面执行 rm -rf /* 不会把整个服务器搞死,也不影响其他人部署的程序使用。
  • 容器对比虚拟机更轻量,启动更快
    传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
    docker 不需要虚拟内核,所以启动可以更快,相当于 windows 的开机时间省去了。
  • 维护和扩展容易
    Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。比如 docker hub 提供了很多镜像,各个系统的一个命令就可以拿到了,研发也可以自己定制镜像分享给各个产品。

三、容器的生命周期

容器的生命周期是容器可能处于的状态。

  1. created:初建状态
  2. running:运行状态
  3. stopped:停止状态
  4. paused:暂停状态
  5. deleted:删除状态

各生命周期之间的转换关系如图所示:

  • docker create : 创建容器后,不立即启动运行,容器进入初建状态;
  • docker run : 创建容器,并立即启动运行,进入运行状态;
  • docker start : 容器转为运行状态;
  • docker stop : 容器将转入停止状态;
  • docker kill : 容器在故障(死机)时,执行 kill(断电),容器转入停止状态,这种操作容易丢失数据,除非必要,否则不建议使用;
  • docker restart : 重启容器,容器转入运行状态;
  • docker pause : 容器进入暂停状态;
  • docker unpause : 取消暂停状态,容器进入运行状态;
  • docker rm : 删除容器,容器转入删除状态。
  • killed by out-of-memory(因内存不足被终止) :宿主机内存被耗尽,也被称为 OOM:非计划终止 这时需要杀死最吃内存的容器
  • container process exitde(异常终止):出现容器被终止后,将进入 Should restart?选择操作:
    • yes 需要重启,容器执行 start 命令,转为运行状态。
    • no 不需要重启,容器转为停止状态。

容器OOM

Docker 在处理 OOM 事件时分为三种情况

  • 如果容器中的应用耗尽了主机系统分配给容器的内存限额,就会触发 OOM 事件。例如,在容器当中,部署了一个 web 服务。假设主机分配给此容器的内存上限为 1G,当脚本申请的内存大于 1G 时,此容器就会触发 OOM 事件。而在这种情况下,此容器将会被强制关闭。
    但需要注意的是,此时关闭容器的并非是 Docker Daemon,而是宿主机操作系统。因为一个容器其实就是一组运行在宿主机操作系统当中的进程,宿主机操作系统通过 cgroups 对这组进程设定资源上限,当这些进程申请的资源到达上限时,触发的是宿主机操作系统的内核 OOM 事件,因此最终是由宿主机内核来关闭这些进程。
  • 如果用户不想关闭这个容器,那么可以选择 --oom-kill-disable 来禁用 OOM-Killer。使用此参数时,仍需要注意,如果使用-m 设置了此容器内存上限,那么当容器到达内存资源上限时,主机不会关闭容器,但也不会继续向此容器继续分配资源,此时容器将处于 hung 状态。只需要将最坏的情况封闭在一定范围之内,而不至于蔓延出去。
  • 如果用户使用了--oom-kill-disable,但也没有使用-m 来设定上限,因而此时此容器将会尽可能多地使用主机内存资源。换言之,主机内存有多大,它就将用多大。

容器异常退出

每个容器内部都存在一个 Init 进程,容器中其他所有进程都是此进程的子进程。运行的容器是因为 Init 进程在运行,如果一个子进程因为某种原因造成了退出,那么其父进程也会同步退出,直至 Init 进程也退出。当 Init 进程退出时,也就代表着此容器被关闭。 ocker 目前没有办法知道此时的进程退出属于正常退出还是异常退出。当出现容器关闭情况时, Docker Daemon 会尝试再次重新将此容器由 Stopped 状态转为 Running状态。只有设置了--restart 参数的容器, Docker Daemon 才会去尝试启动,否则容器会保持停止状态。


容器暂停

Docker"剥夺"了此容器的 CPU 资源。而其他资源,如 Memory 资源、Network 资源等还保留未动。如此一来,失去了 CPU 资源的进程,是不会被主机内核系统所调度的,所以此容器就处于"冰封"状态。


四、容器命令详解

容器命令清单

docker create

  • 功能
    创建一个容器但不启动它
  • 语法
bash 复制代码
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
  • 别名
bash 复制代码
docker container create
  • 关键参数

    • -i: 以交互模式运行容器,通常与 -t 同时使用;
    • -P: 随机端口映射,容器内部端口随机映射到主机的端口
    • -p: 指定端口映射,格式为: 主机(宿主)端口:容器端口
    • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
    • --name="nginx-lb": 为容器指定一个名称;
    • -h "mars": 指定容器的 hostname;
    • -e username="ritchie": 设置环境变量;
    • --cpuset-cpus="0-2" or --cpuset-cpus="0,1,2": 绑定容器到指定 CPU 运行;
    • -m :设置容器使用内存最大值;
    • --network="bridge": 指定容器的网络连接类型;
    • --link=[]: 添加链接到另一个容器;
    • --volume , -v: 绑定一个卷
    • --rm :shell 退出的时候自动删除容器
    • --restart:自动重启
  • 样例

bash 复制代码
docker create --name mywebsite1 -p 80:80 nginx:1.24.0
bash 复制代码
docker create --name mywebsite2 -p 8050:80 nginx:1.24.0



docker logs

  • 功能
    查看容器日志
  • 语法
bash 复制代码
docker logs [OPTIONS] CONTAINER
  • 别名
bash 复制代码
docker container logs
  • 关键参数

    • -f ,--follow: 跟踪日志输出
    • --since :显示某个开始时间的所有日志
    • -t,--timestamps : 显示时间戳
    • -n, --tail :仅列出最新 N 条容器日志
  • 样例

bash 复制代码
docker logs mywebsite3
bash 复制代码
docker logs -f mywebsite3
bash 复制代码
docker logs -f --since="2024-02-05" mywebsite3
bash 复制代码
docker logs -f -n 5 mywebsite3

docker attach

  • 功能
    连接到正在运行中的容器
  • 语法
bash 复制代码
docker attach [OPTIONS] CONTAINER
  • 别名
bash 复制代码
docker container attach
  • 关键参数

    • --sig-proxy:是否将所有信号代理,默认是 true,如果设置为 false,退出的话不会影响容器, 否则退出会导致容器退出。
  • 样例

bash 复制代码
docker attach mywebsite3

这里我们可以看到如果此时使用ctrl+c会把容器杀死。

bash 复制代码
docker attach --sig-proxy=false mywebsite3



docker exec

  • 功能
    在容器中执行命令
  • 语法
bash 复制代码
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
  • 别名
bash 复制代码
docker container exec
  • 关键参数

    • -d :分离模式: 在后台运行
    • -i :即使没有附加也保持 STDIN 打开
    • -t :分配一个伪终端
    • -e :设置环境变量
    • -u,--user :指定用户 "<name|uid>[:<group|gid>]"
    • -w,--workdir:指定工作目录
  • 样例

bash 复制代码
docker exec -it mywebsite3 bash
bash 复制代码
docker exec -it mywebsite3 nginx -v
bash 复制代码
docker exec -it -e mynginx=cjl mywebsite3 bash
bash 复制代码
docker exec -it -u nginx mywebsite3 nginx -v

docker start

  • 功能
    启动停止的容器
  • 语法
bash 复制代码
docker start [OPTIONS] CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container start
  • 样例
bash 复制代码
docker start mywebsite3

docker stop

  • 功能
    停止运行的容器
  • 语法
bash 复制代码
docker stop [OPTIONS] CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container stop
  • 关键参数
    • -s :发送的信号
  • 样例
bash 复制代码
docker stop mywebsite3

docker restart

  • 功能
    重启命令
  • 语法
bash 复制代码
docker restart [OPTIONS] CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container restart
  • 关键参数
    • -s :发送信号
  • 样例
bash 复制代码
docker restart mywebsite3
bash 复制代码
docker restart -s 9 mywebsite3

docker kill

  • 功能
    强制退出容器
  • 语法
bash 复制代码
docker kill [OPTIONS] CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container kill
  • 关键参数

    • -s :发送的信号
  • 注意事项

    • Docker stop 发送的是 SIGTERM 信号, docker kill 发送的是 SIGKILL 信号
  • 样例

bash 复制代码
docker kill mywebsite3

docker top

  • 功能
    查看容器中运行的进程信息,支持 ps 命令参数。
  • 语法
bash 复制代码
docker top CONTAINER [ps OPTIONS]
  • 别名
bash 复制代码
docker container top
  • 注意事项
    • 容器运行时不一定有/bin/bash 终端来交互执行 top 命令,而且容器还不一定有top 命令,可以使用 docker top 来实现查看 container 中正在运行的进程。
  • 样例
bash 复制代码
docker top 642fd46da1b7

docker stats

  • 功能
    显示容器资源的使用情况,包括: CPU、内存、网络 I/O 等。
  • 语法
bash 复制代码
docker stats [OPTIONS] [CONTAINER...]
  • 别名
c 复制代码
docker container stats
  • 关键参数

    • --all , -a :显示所有的容器,包括未运行的。
    • --format :指定返回值的模板文件。如 table,json
    • --no-stream :展示当前状态就直接退出了,不再实时更新。
    • --no-trunc :不截断输出。
  • 返回报文

    • CONTAINER ID 与 NAME: 容器 ID 与名称。
    • CPU % 与 MEM %: 容器使用的 CPU 和内存的百分比。
    • MEM USAGE / LIMIT: 容器正在使用的总内存,以及允许使用的内存总量。
    • NET I/O: 容器通过其网络接口发送和接收的数据量。
    • BLOCK I/O: 容器从主机上的块设备读取和写入的数据量。
    • PIDs: 容器创建的进程或线程数。
  • 样例

bash 复制代码
docker stats
bash 复制代码
#监控某一个容器
docker stats mywebsite3
bash 复制代码
#查看所有容器(包括已经停止的)
docker stats -a 
bash 复制代码
docker stats --format json
bash 复制代码
docker stats --no-stream

docker container inspect

  • 功能
    查看容器详细信息
  • 语法
bash 复制代码
docker container inspect [OPTIONS] CONTAINER [CONTAINER...]
  • 关键参数
    • -f :指定返回值的模板文件。如 table、 json
    • -s :显示总的文件大小。
  • 注意事项
    • docker inspect 会自动检查是镜像还是容器然后显示相信信息
  • 样例
bash 复制代码
docker container inspect 642fd46da1b7
bash 复制代码
docker container inspect -f json mywebsite3
bash 复制代码
docker container inspect -s mywebsite3

docker port

  • 功能
    用于列出指定的容器的端口映射,或者查找将 PRIVATE_PORT NAT 到面向公众的端口。
  • 语法
bash 复制代码
docker port CONTAINER [PRIVATE_PORT[/PROTO]]
  • 别名
bash 复制代码
docker container port
  • 样例
bash 复制代码
docker port mywebsite3

docker cp

  • 功能
    在容器和宿主机之间拷贝文件
  • 语法
bash 复制代码
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
  • 别名
bash 复制代码
docker container cp
  • 样例
bash 复制代码
docker cp mywebsite3:/usr/share/nginx/html/index.html .

修改文件并重新拷贝到容器中

bash 复制代码
docker cp ./index.html mywebsite3:/usr/share/nginx/html/

docker diff

  • 功能
    检查容器里文件结构的更改
  • 语法
bash 复制代码
docker diff CONTAINER
  • 样例
bash 复制代码
docker diff mywebsite3

docker commit

  • 功能
    从容器创建一个新的镜像
  • 语法
bash 复制代码
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
  • 参数
    • -a :提交的镜像作者。
    • -c :使用 Dockerfile 指令来创建镜像;可以修改启动指令。
    • -m :提交时的说明文字。
    • -p :在 commit 时,将容器暂停。
  • 样例
bash 复制代码
docker commit mywebsite3forcommit mywebsite3:v1.0

当我们修改容器中的文件然后再次制作一个镜像时,发现新增加的文件是存在的。

bash 复制代码
docker commit -a 'cjl' -m 'create by cjl' -p mywebsite3forcommit mywebsite3:v3.0

下面演示最后一个选项:-c选项

bash 复制代码
docker commit -a 'cjl' -m 'create by cjl' -c 'CMD ["tail","-f","/etc/hosts"]' -p mywebsite3forcommit mywebsite3:v4.0




docker pause

  • 功能
    暂停容器中所有的进程
  • 语法
bash 复制代码
docker pause CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container pause
  • 样例
bash 复制代码
docker pause mywebsite4

docker unpause

  • 功能
    恢复容器中所有的进程。
  • 语法
bash 复制代码
docker unpause CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container unpause
  • 样例
bash 复制代码
docker unpause mywebsite5 mywebsite6

docker rm

  • 功能
    删除停止的容器
  • 语法
bash 复制代码
docker rm [OPTIONS] CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container rm
  • 关键参数
    • -f :通过 SIGKILL 信号强制删除一个运行中的容器。
  • 样例
bash 复制代码
docker rm mywebsite7
bash 复制代码
docker rm -f mywebsite7

docker export

  • 功能
    导出容器内容为 tar 文件
  • 语法
bash 复制代码
docker export [OPTIONS] CONTAINER
  • 别名
bash 复制代码
docker container export
  • 关键参数

    • -o:写入到文件。
  • 样例

bash 复制代码
docker export -o mywebsite4.tar mywebsite4

docker import

  • 功能
    从归档文件中创建镜像
  • 语法
bash 复制代码
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
  • 别名
bash 复制代码
docker image import
  • 关键参数
    • -c :应用 docker 指令创建镜像;
    • -m :提交时的说明文字;
  • 样例
bash 复制代码
docker import mywebsite4.tar mywebsite4:v1.0

这里我们需要注意的是,使用docker import命令导出的镜像会丢失原始镜像中的数据

bash 复制代码
docker import -c 'CMD ["nginx","-g","daemon off;"]' -m "create by cjl" mywebsite4.tar mywebsite4:v2.0

docker wait

  • 功能
    阻塞运行直到容器停止,然后打印出它的退出代码。
  • 语法
bash 复制代码
docker wait CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container wait
  • 样例
bash 复制代码
docker wait mywebsite5

docker rename

  • 功能
    重命名容器
  • 语法
bash 复制代码
docker rename CONTAINER NEW_NAME
  • 别名
bash 复制代码
docker container rename
  • 样例
bash 复制代码
docker rename mywebsite6 mywebsite6.1

docker container prune

  • 功能
    删除所有停止的容器
  • 语法
bash 复制代码
docker container prune [OPTIONS]
  • 关键参数
    • -f, --force:不提示是否进行确认
  • 样例
bash 复制代码
docker container prune

docker update

  • 功能
    更新容器配置(CPU使用数量、内存使用大小等)
  • 语法
bash 复制代码
docker update [OPTIONS] CONTAINER [CONTAINER...]
  • 别名
bash 复制代码
docker container update
  • 关键参数
    • --cpus: cpu 数量
    • --cpuset-cpus :使用哪些 cpu
    • --memory :内存限制
    • --memory-swap:交换内存
    • --cpu-period :是用来指定容器对 CPU 的使用要在多长时间内做一次重新分配
    • --cpu-quota: 是用来指定在这个周期内,最多可以有多少时间用来跑这个容器
  • 样例
bash 复制代码
docker update -m 500m mywebsite4

上面发生报错是因为docker 默认没有启用memory-swap交换内存,直接设置了内存问题会出问题,也就是说宿主 swap 支持使用多少则容器即可使用多少。因此设置内存的同时必须设置--memory-swap。


相关推荐
昌sit!3 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
追风林4 小时前
mac 本地docker-mysql主从复制部署
mysql·macos·docker
A ?Charis6 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
城南vision6 小时前
Docker学习—Docker核心概念总结
java·学习·docker
wclass-zhengge6 小时前
Docker篇(Docker Compose)
运维·docker·容器
茶馆大橘6 小时前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel
北漂IT民工_程序员_ZG7 小时前
k8s集群安装(minikube)
云原生·容器·kubernetes
coding侠客7 小时前
揭秘!微服务架构下,Apollo 配置中心凭啥扮演关键角色?
微服务·云原生·架构
梦魇梦狸º10 小时前
腾讯轻量云服务器docker拉取不到镜像的问题:拉取超时
docker·容器·github
鬼才血脉10 小时前
docker+mysql配置
mysql·adb·docker