当前位置: 首页 > news >正文

【Docker学习】深入研究命令docker exec

使用docker的过程中,我们会有多重情况需要访问容器。比如希望直接进入MySql容器执行命令,或是希望查看容器环境,进行某些操作或访问。这时就会用到这个命令:docker exec。

命令:

docker container exec

描述:

在运行的容器中执行命令。

您使用 docker exec 指定的命令只会在容器的首要进程(PID 1)运行时执行,如果容器重启,该命令不会被重新启动。

该命令在容器的默认工作目录中运行。

该命令必须是一个可执行程序。链式命令或引号内的命令不起作用

这样是有效的:docker exec -it my_container sh -c “echo a && echo b” 

这样是无效的:docker exec -it my_container “echo a && echo b”

用法:

docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]

别名:

docker exec(docker的一些命令可以简写,docker exec和docker container exec是等价的)

选项:

选项描述
-d, –detach分离模式:在后台运行命令
–detach-keys覆盖用于分离容器的键序列
-e, –envAPI 1.25+ 设置环境变量
–env-file读取的环境变量文件
-i, –interactive即使未附着也保持 STDIN 打开
–privileged为命令提供扩展权限
-t, –tty分配一个伪TTY
-u, –user用户名或用户ID(格式:<name|uid>[:<group|gid>])
-w, –workdir容器内的工作目录

示例1:选项-d, –detach、-i, –interactive、-t, –tty

-d相当于后台运行,使用这个选项,不影响终端的进一步操作。-i和-t两个选项通常一起使用,在【Docker学习】docker run之黄金搭档-it选项 – 筑天兄的清净小站 (skycreator.top)有详细介绍。

关于这三个选项,官方给出的例子挺好。我就直接使用官方例子,在我的阿里云上操作,借花献佛了。

使用exec,首先要确保有一个运行着的容器。使用以下命令创建并启动一个名为mycontainer的基于alpine的容器,该容器以sh shell作为其主进程。其中,-d选项(–detach的简写形式)会让容器以后台运行的方式启动,即分离模式,并附加一个伪TTY(-t)。-i选项设置为保持STDIN附加(-i),这可以防止sh进程立即退出。

docker run --name mycontainer -d -i -t alpine /bin/sh

执行之后,使用ps来查看一下:

在这之后,我们使用-d选项,在运行的mycontainer容器中运行一个命令touch /tmp/execWorks。该命令在容器的根目录tmp下创建execWorks文件。

docker exec -d mycontainer touch /tmp/execWorks

这条命令执行之后没效果,需要进入容器的sh下查看。使用-it选项(-i加-t选项),直接与容器交互。

docker exec -it mycontainer sh

在容器的终端进入tmp文件夹查看,发现execWorks被创建。

示例2:选项–detach-keys

这个选项说起来比较复杂,在【Docker学习】docker start深入研究 – 筑天兄的清净小站 (skycreator.top)中有详细讲解,大家可以对照着来学习。

示例3:选项-e, –env和选项–env-file

这两个选项都是设置环境变量的,前者是直接设置,后者是通过一个文件设置。在【Docker学习】docker run的环境变量相关选项(-e, –env, –env-file) – 筑天兄的清净小站 (skycreator.top)中有详细讲解,这个不再赘述了。

示例4:–privileged

这个选项用于提升容器权限,它为容器提供了以下功能:

  • 启用所有Linux内核功能
  • 禁用默认的seccomp配置文件
  • 禁用默认的AppArmor配置文件 
  • 禁用SELinux进程标签 
  • 授予访问所有主机设备的权限 
  • 使/sys变为可读写 
  • 使cgroups挂载变为可读写 

换句话说,容器几乎可以做主机能做的任何事情。这个标志的存在是为了允许特殊用途,比如在Docker中运行Docker。

这个选项很强大,未来详细讲解,这里只简要介绍。

我们使用刚才的容器作测试,进入容器的终端,执行命令

docker exec -it mycontainer sh

在终端输入以下命令,将一个tmpfs文件系统挂载到/mnt目录,允许在这个目录下存储临时数据,这些数据在系统重启后不会保留。

/ # mount -t tmpfs none /mnt

这个命令具体作用如下:

  • mount:这是用来挂载文件系统的命令。
  • -t tmpfs:这指定了要挂载的文件系统类型为tmpfs,这是一种基于内存的文件系统,也称为临时文件系统。数据存储在内存中,而不是写入磁盘,这意味着它的读写速度非常快,但数据在系统重启后会丢失。
  • none:这里指定了设备的源,none表示没有实际的设备或文件名与tmpfs关联。因为tmpfs不依赖于具体的设备,所以使用none作为占位符。
  • /mnt:这是挂载点,即文件系统在目录树中的位置。在这个例子中,tmpfs将被挂载到/mnt目录下。

看看运行结果。显示permission denied,说明没有权限。默认情况下,Docker会丢弃大多数可能危险的核心功能,包括CAP_SYS_ADMIN(挂载文件系统所必需的)。

那么我们执行–privileged选项看看。

居然没有效果!!!好吧,看来只能放大招了。

官网讲解–privileged选项时,也讲解了docker run 的–cap-add选项,该选项可以为容器添加linux功能。而SYS-ADMIN是linux系统管理必备的功能。因此我使用该选项,先给mycontainer加入这个功能。

docker run --cap-add SYS_ADMIN --name mycontainer -dit  alpine /bin/sh

执行之后,我尝试进行挂载,这次成功了。通过df -h命令查看文件系统磁盘空间使用情况。可以看到最下面一行,文件系统是none的就是我进行的挂载。不过这么做也用不着–privileged选项了。

官网的例子使用的并不是alpine,而是ubuntu。通过对比–privileged使用与否的情况,可以看到ubuntu的/dev目录发生了明显的变化:

上面是不使用–privileged选项的/dev目录。

上面是使用–privileged选项的/dev目录。

可以明显看出两者的不同,说明使用–privileged选项,为/dev目录增加了不少特性。

回过头再来看alpine,使用不使用/dev的目录是相同的。如下图所示:

也就是说,alpine这个镜像并没有为–privileged选项预留功能。毕竟alpine是阉割版的linux系统,它的大小只有4m多。下面是几个linux官方镜像的大小对比。

另外,docker run的–cap-add选项,没有加入到docker exec中,可能是因为这只能是创建时加入,运行中的容器是不能直接设置的。

示例5:-u, –user选项

这个选项用于以某个用户身份进入容器。

还是使用alpine这个镜像的mycontainer容器,进入容器的shell下,添加一个普通用户zl

adduser zl

然后exit退出,重新使用docker exec进入,这次加入-u选项

docker exec -it -u zl  mycontainer sh

在shell中输入id,查看当前用户的信息

可以看出,当前用户是zl,uid,gid和groups均显示出来了。

示例6:-w, –workdir选项

该选项用于设置容器的工作目录。不指定的情况下,工作目录就是/,如下图所示:

下面指定了工作目录为/etc,使用pwd查看当前工作目录,即是/etc。

关于alpine

Alpine是一个轻量级的Linux发行版,它基于musl libc和 BusyBox,旨在提供一个小巧、安全、简单且高效的操作系统。Alpine特别适合用于容器和云环境,因为它的大小很小,启动速度快,同时提供了一个包管理器工具apk,可以用来安装、更新和管理软件包。

在Docker等容器平台中,Alpine经常被用作基础镜像,因为它可以创建出非常小的容器镜像,这对于开发和部署都非常有利。由于它的体积小,Alpine在资源有限的场景下也非常受欢迎,比如在嵌入式设备或者需要快速部署的应用中。

Alpine 官网:https://www.alpinelinux.org/

Alpine 官方仓库:https://github.com/alpinelinux

Alpine 官方镜像:https://hub.docker.com/_/alpine/

Alpine 官方镜像仓库:https://github.com/gliderlabs/docker-alpine

关于–privileged

请谨慎使用–privileged标志。带有–privileged的容器并不是一个安全沙箱化的进程。在此模式下的容器可以在主机上获取root权限的shell并控制系统。

对于大多数用例来说,这个标志不应该是首选解决方案。如果您的容器需要提升的权限,您应该更愿意明确授予必要的权限,例如通过使用–cap-add添加单个内核功能。

关于df -h命令

在Linux和类Unix操作系统中,df -h是一个常用的命令,用于显示文件系统的磁盘空间使用情况。df代表disk free,即磁盘空闲空间。-h选项表示human-readable,它会以更易于阅读的格式显示大小,例如将字节转换为千字节、兆字节或吉字节,并附加适当的单位(K、M、G)。

df -h命令的输出通常包括以下信息:

  • 文件系统的挂载点(Mounted on)
  • 文件系统的总大小(Size)
  • 已使用的空间大小(Used)
  • 可用的空闲空间(Avail)
  • 使用百分比(Use%)
  • 文件系统的标识(Filesystem)

相关文章:

  • SVM兵王问题
  • 摄像头应用测试
  • 牛逼!50.3K Star!一个自动将屏幕截图转换为代码的开源工具
  • 【fastapi+mongodb】使用motor操作mongodb
  • 给页面元素添加水印
  • Tomcat调优参数
  • Linux系统如何通过编译方式安装python3.11.3
  • Java——接口
  • Vue 2与Vue 3的区别
  • java图书电子商务网站的设计与实现源码(springboot+vue+mysql)
  • vue3父组件使用ref获取子组件的属性和方法
  • java 拦截器-用户无操作超时退出利用Redis
  • 【智能算法应用】模拟退火算法求解多车型车辆路径问题HFVRP
  • 在CSDN上成长的感悟,你的粉丝长啥样?
  • DEM、DSM和DTM之间的区别及5米高程数据获取
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • 5、React组件事件详解
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Android Volley源码解析
  • Docker: 容器互访的三种方式
  • ES6语法详解(一)
  • Java精华积累:初学者都应该搞懂的问题
  • Java新版本的开发已正式进入轨道,版本号18.3
  • Kibana配置logstash,报表一体化
  • MySQL主从复制读写分离及奇怪的问题
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Python_网络编程
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • Vue2 SSR 的优化之旅
  • 程序员最讨厌的9句话,你可有补充?
  • 老板让我十分钟上手nx-admin
  • 聊聊flink的BlobWriter
  • 配置 PM2 实现代码自动发布
  • puppet连载22:define用法
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 正则表达式-基础知识Review
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • $NOIp2018$劝退记
  • (0)Nginx 功能特性
  • (1)无线电失控保护(二)
  • (undone) MIT6.824 Lecture1 笔记
  • (vue)页面文件上传获取:action地址
  • (二十六)Java 数据结构
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (六)Flink 窗口计算
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (算法二)滑动窗口
  • (一) storm的集群安装与配置