docker容器

docker 容器

什么是容器?

通俗地讲,容器是镜像的运行实体。镜像是静态的只读文件,而容器带有运行时需要

的可写文件层,并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容器有初建、运行、停止、暂停和删除五种状态。虽然容器的本质是主机上运行的一个进程,但是容器有自己独立的命名空间隔离和资源限制。也就是说,在容器内部,无法看到主机上的进程、环境变量、网络等信息,这是容器与直接运行在主机上进程的本质区别。容器是基于镜像创建的可运行实例,并且单独存在,一个镜像可以创建出多个容器。运行容器化环境时,实际上是在容器内部创建该文件系统的读写副本。 这将添加一个容器层,该层允许修改镜像的整个副本。

容器的生命周期

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

created:初建状态

running: 运行状态

stopped:停止状态

paused:暂停状态

deleted:删除状态

各个生命周期转换图如下:

下面我们将结合小汽车启动的例子来讲解这几个状态;

  1. docker create :创建容器,此时容器处于created状态,不会进入running状态;在小汽车例子中类似于我们插入钥匙,点火,但是小汽车并没有跑起来;
  2. docker run: 创建容器,并立即启动容器,此时容器处于running状态;在小汽车例子中,类似于我们插入钥匙,点火,然后发动发动机,让小汽车跑起来;
  3. docker start: 让容器运行起来(前提是容器已经存在);
  4. docker stop: 将容器停止起来;在小汽车例子中类似于熄火;
  5. docker kill: 容器在故障(死机)时,执行 kill(断电),容器转入停止状态,这种操作容易丢失数据,除非必要,否则不建议使用;
  6. docker restart: 重启容器,容器转入运行状态;
  7. docker pause: 容器进入暂停状态,类似于小汽车在运行中,突然踩了一脚刹车,并没有熄火;
  8. docker unpause: 取消暂停状态,容器进入运行状态;
  9. docker rm : 删除容器
  10. killed by out-of-memory(因内存不足被终止) :宿主机内存被耗尽,也被称为 OOM:非计划终止 这时需要杀死最吃内存的容器
  11. container process exitde(异常终止):出现容器被终止后,将进入 Should restart?选
    择操作:

yes 需要重启,容器执行 start 命令,转为运行状态。

no 不需要重启,容器转为停止状态。
容器OOM:

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

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

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

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

容器命令

docker create

语法 :docker container create [options] image [command] [arg...]
别名 :docker create
功能 :基于某个镜像,创建出一个容器,但是并不会启动容器,此时容器处于created状态;
参数

command: 容器启动要执行的命令

-- restart: 在容器退出时,自动重启;

其余参数,大多与docker run一致,可以参考docker run的参数;
注意docker create 没有-d选项!!!
实战

docker start

语法 :docker container start [options] container [container...]
别名 :docker start
功能 :启动一个或多个停止的容器;
参数

-i: 以交互的方式启动容器;

-a: 前台方式启动容器,将容器的日志信息,打印到标准输出,标准错误;
实战

docker run

详细请看这篇博客:
docker run

docker ps

详细请看这篇博客:
docker ps

docker stats

docker stats

docker logs

语法 :docker container logs [options] container
别名 :docker logs
功能 :获取容器的日志信息;
参数

--details: 显示详细的日志信息

-f: 实时追踪日志消息

--tail N: 从末尾开始显示N条日志消息;

--since: 显示自xxx时间以来的日志信息

-t: 显示时间戳
实战 :

docker attach

语法 :docker container attach
别名 :docker attach
功能:将本地标准输出、标准输入、标准错误附加到容器上;这里附加的意思,可以理解为绑定,例如:标准输出附加的意思就是:"容器内部产生的输出(例如,应用程序的打印语句)将会被发送到宿主机的终端或指定的文件/设备。这样,用户就可以在宿主机上查看容器的输出信息。"其它也是同理;

参数

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

docker stop

语法 :docker container stop [OPTIONS] CONTAINER [CONTAINER...]
别名 :docker stop
功能 :容器内的主进程将接收SIGTERM,并在宽限期后接收SIGKILL。第一个信号可以用容器的Dockerfile中的STOPSIGNAL指令来改变,或者用--stop-signal选项来改变docker运行。
参数

-t: 在杀死容器之前需要停止几秒

-s: 停止容器用的信号

实战

docker exec

语法 :docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]
别名 :docker exec
功能 :在一个运行的容器中执行命令
参数

-d: 以后台的方式来运行命令;

-i:以交互的方式运行命令,保持stdin打开

-t: 分配一个伪终端

-w: 指定命令执行的工作目录

-e: 设置环境变量

-u: 以指定用户来运行
实战

docker restart

语法 :docker container restart [options] CONTAINER [CONTAINER...]
别名 :docker restart
功能 :重新启动一个或多个容器;
实战

docker kill

语法 :docker container kill [options] CONTAINER [CONTAINER...]
别名 :docker kill
功能 :杀死一个或多个正在运行的容器;
实战

注意: dokcer kill 与docker stop都是停止容器,但是docker kill更加暴力,有可能会造成数据丢失,而docker stop比较温和,在真正终止容器之前,会先停留一段时间,让容器完成一些"停止前的工作";

docker top

语法 :docker container top CONTAINER [ps options]
别名 :docker top
功能 :查看一个运行的容器中的进程信息;[ps options]这里表示参数支持ps命令的参数,在写的时候不需要带上ps,直接写它的参数即可;
实战

docker container inspect

语法 :docker container inspect [options] CONTAINER [CONTAINER...]
功能 :查看一个或多个容器的详细信息
参数

-f: 返回指定值的模板文件

-s:显示总的大小
注意:

docker inspect 会自动检查是容器还是镜像来显示信息;
实战

docker port

语法 :docker container port CONTAINER [PRIVATE_PORT[/PROTO]]
别名 :docker port
功能 :查看容器的端口映射情况或者使用 [PRIVATE_PORT[/PROTO]] 查看指定端口在宿主机上的映射情况
实战

docker cp

语法 :docker container cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
别名 :docker cp
功能 :在宿主机和容器之间拷贝文件
实战

docker diff

语法 :docker container diff CONTAINER
别名 :docker diff
功能 :检查对容器文件系统上的文件或目录的更改
解释 :

A: 一个新文件或目录被添加;

D: 一个新文件或目录被删除;

C: 一个新文件或目录被改变;
实战

docker commit

语法 :docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
别名 :docker commit
功能 :根据容器的改变创建一个新的镜像;
参数

-a: 指定镜像作者

-m: 镜像介绍信息;

-c:将dockerfile指令应用于创建的镜像;

-p: 提交期间暂停容器,默认为true,如果不想暂停可以设置为false;
实战

docker pause

语法 :docker container pause CONTAINER [CONTAINER...]
别名 :docker pause
功能 :暂停一个或多个容器里面的所有进程
实战

docker unpause

语法 :docker container unpause CONTAINER [CONTAINER...]
别名 :docker unpause
功能 :取消暂停一个或多个容器内的所有进程
实战

docker rm

docker rm

docker export

语法 :docker container export [OPTIONS] CONTAINER
别名 :docker export
功能 :将容器的文件系统导出为tar包
参数

-o:输出文件,默认stdout
实战

解包的命令是:docker image import / docker import
docker import exportTest.tar exporttest:v1

docker save 和docker export都可以压缩成镜像包,那么一般选择那个比较好?

答:一般选择docker save比较多一点,因为docker export导出来的镜像会有部分元数据丢失:

但是docker save导出来的镜像包是基于镜像的,而docker export是基于容器导出来的,因此容器中做出的修改操作,也会被导出来;

docker wait

语法 :docker container wait CONTAINER [CONTAINER...]
别名 :docker wait
功能 :阻塞等待直到一个或多个容器停止,然后打印它们的退出代码
实战

docker rename

语法 :docker container rename CONTAINER NEW_NAME
别名 :docker rename
功能 :给容器重命名
实战

docker container prune

语法 :docker container prune [OPTIONS]
功能 :删除所有停止的容器
参数

-f: 不提示确认信息
实战

docker update

语法 :docker container update [OPTIONS] CONTAINER [CONTAINER...]
别名 :docker update
功能 :更新一个或多个容器的配置信息
参数

--cpus:cpu 数量

--cpuset-cpus :使用哪些 cpu

--memory :内存限制 ○ --memory-swap:交换内存

--cpu-period :是用来指定容器对 CPU 的使用要在多长时间内做一次重新分配

--cpu-quota:是用来指定在这个周期内,最多可以有多少时间用来跑这个容器
实战

容器操作案例

容器基本操作

  1. 通过nginx镜像文件创建容器:
  2. 查看容器信息
  3. 停止当前容器
  4. 删除容器

容器的状态转移

  1. 创建容器:
  2. 通过docker ps -a我们查看到容器的状态为created:
  3. 通过docker start启动容器;
  4. 通过docker ps -a查看容器状态:
  5. 通过docker stop停止容器:
  6. 重新启动容器,然后使用docker kill杀掉容器:
  7. docker rm -f 强制删除正在运行的容器:

容器交互模式

attached模式
docker container run -p 80:80 nginx

  1. 通过上述方式创建容器,就是 attached 模式,这样容器会在前台运行
  2. 访问服务器网址的时候,每访问一次,命令窗口就会打印一次日志,Docker 容器的日志会实时的展现到窗口并且占用此端口
  3. 如果是在 Linux 服务器上,按 Ctrl+C 就会停止掉 Docker 服务,很容易误操作,所以我们需要一个更好的,更稳定的模式,对应的是 detached 模式
  4. attached 模式仅适用于容器和程序的调试阶段
    detached 模式

在 docker container run -p 80:80 nginx 命令基础上加一个-d 或者--detach选项表示 detached 模式, 即在后台执行

  1. 在后台运行,启动后只显示容器 ID,并且可以输入任何命令
  2. 就算关掉窗口依然继续运行,停止和删除容器都需要使用 shell 命令,减少了很多
    的误操作
  3. 比起 attached 模式更建议使用
    interactive 模式

当我们创建好一个容器之后, 可能需要去容器内部获取一些信息或执行一些命令,就需要进入到交互式模式。例如创建一个 Ubuntu 容器之后,需要到系统里输入各种Shell 命令和系统进行交互就需要进入交互式模式才可以完成.

  1. 创建运行容器并进入到交互模式
    docker container run -it nginx:1-perl bash
  2. 退出交互式模式: 在交互式 shell 中输入 exit

宿主机与容器内容拷贝

  1. 将容器内的index.html文件拷贝到宿主机:
  2. 修改index.html目录中的内容,并拷贝会容器中
  3. 我们来请求一下nginx服务:

    发现nginx的默认界面发生变化,说明本次实验成功!

容器自动删除

  1. 在docker run启动容器的时候,带上--rm 选项:
  2. docker stop停止容器,并查看容器信息:

容器自动重启

容器重启选项如下:

docker run --restart=no [容器名] :默认值不自动重启

docker run --restart=on-failure:3 [容器名] : on-failure 若容器的退出状态非 0,则

docker 自动重启容器,还可以指定重启次数,若超过指定次数未能启动容器则放弃

docker run --restart=always [容器名] :always 容器退出时总是重启

docker run --restart=unless-stopped [容器名] unless-stopped 容器退出时总是重启,

但不考虑 Docker 守护进程启动时就已经停止的容器

如果容器启动时没有设置--restart 参数,则通过下面命令进行更新:

docker update --restart=always [容器名]

  1. 使用docker run启动容器,并且开启自动重启:
  2. 进入容器内部,杀掉1号进程,模拟程序崩溃:

容器日志查看

  1. 运行一个容器
  1. 使用docker logs命令查看日志:

  2. 也可以直接去docker root目录下查看:

  3. 进入containers目录:

  4. 根据要查看的容器的容器id进入对应目录:

  5. 查看"容器id-json.log" 文件

通过这样的办法,我们也可以查看容器日志信息;

综合实战

MySQL容器化安装

  1. 进入dockerHub选取MySQL镜像:
  2. 我们选取最新镜像吧:
  3. 查看一下镜像的详细信息:
  4. 启动mysql镜像:
  5. 进入容器:
  6. 进入mysql服务,并建一张表,在表中写入数据:

  7. Windows客户端远程连接mysql服务:

redis容器化安装

  1. 查看redis镜像:
  2. 拉取所有rediis镜像
  3. 查看redis镜像详细信息:
  4. 启动redis镜像服务:
  5. 进入容器内的redis服务:
  6. 通过其它redis客户端链接到redis容器:

C++ 容器制作

  1. 下载centos镜像:
  2. 启动容器
  3. 将yum源换为国内源(参看中科大源网站)
    参考这篇博客CentOS 8 安装国内、本地YUM源
  4. 下载g++ 和vim
    yum groupinstall "Development Tools"
    yum -y install vim

  5. 编写C++代码:
  6. 编译代码:
  7. 在容器中运行:
  8. 退出容器:
  9. docker start 启动容器:

常见问题:

docker import 和 docker load 有什么区别?

  1. docker save images_name:将一个镜像导出为文件,再使用 docker load 命令将文件导入为一个镜像,会保存该镜像的的所有历史记录。比 docker export 命令导出的文件大,很好理解,因为会保存镜像的所有历史记录。
  2. docker export container_id:将一个容器导出为文件,再使用 dockerimport 命令将容器导入成为一个新的镜像,但是相比 docker save 命令,容器文件会丢失所有元数据和历史记录,仅保存容器当时的状态,相当于虚拟机快照。既可以使用 docker load 命令来导入镜像库存储文件到本地镜像库,也可以使用docker import 命令来导入一个容器快照到本地镜像库
  3. 两者的区别在于容器快照将会丢弃所有的历史记录和元数据信息,而镜像存储文件将保存完整记录,体积也会更大
相关推荐
二十雨辰3 小时前
[linux]docker基础
linux·运维·docker
time never ceases4 小时前
使用docker方式进行Oracle数据库的物理迁移(helowin/oracle_11g)
数据库·docker·oracle
YCyjs4 小时前
K8S群集调度二
云原生·容器·kubernetes
Hoxy.R4 小时前
K8s小白入门
云原生·容器·kubernetes
MonkeyKing_sunyuhua6 小时前
ubuntu22.04 docker-compose安装postgresql数据库
数据库·docker·postgresql
追风林6 小时前
mac m1 docker本地部署canal 监听mysql的binglog日志
java·docker·mac
€☞扫地僧☜€7 小时前
docker 拉取MySQL8.0镜像以及安装
运维·数据库·docker·容器
茶馆大橘7 小时前
微服务系列六:分布式事务与seata
分布式·docker·微服务·nacos·seata·springcloud
全能全知者8 小时前
docker快速安装与配置mongoDB
mongodb·docker·容器