邯郸做外卖网站的公司,小程序怎么删除,做餐饮要看的网站,自己做的网站怎么被百度收录如何利用容器技术提升你的工作效率#xff1f;掌握基础理论和常用命令是必不可少的#xff0c;本文将为你全面介绍容器技术#xff0c;并教你必知必会的技能#xff0c;让你工作、学习效率翻倍#xff0c;对于网络安全工作者也是必不可少的技能#xff01; 0. 引言
学习… 如何利用容器技术提升你的工作效率掌握基础理论和常用命令是必不可少的本文将为你全面介绍容器技术并教你必知必会的技能让你工作、学习效率翻倍对于网络安全工作者也是必不可少的技能 0. 引言
学习容器技术对大家的日常工作和学习都有很多好处主要如下 提高开发效率使用容器技术可以快速搭建开发环境和部署环境大大提高了开发效率。 更好的可移植性容器技术使得应用程序更易于在不同的操作系统和云平台之间移植从而实现更好的可移植性。 更好的资源利用率容器可以在相同的硬件资源上运行更多的应用程序从而更好地利用硬件资源。 更好的安全性容器技术通过隔离应用程序和操作系统提供了更好的安全性防止应用程序之间的相互干扰和攻击。 更好的可扩展性容器技术可以轻松地进行水平和垂直扩展从而更好地应对高并发和大流量的需求。
另学习容器技术对于网络安全领域的工作者更是有以下好处 更好地理解应用程序容器技术可以帮助网络安全工作者更好地理解应用程序的运行机制因为容器技术可以将应用程序及其依赖项打包成一个可移植的整体 更好地管理应用程序容器技术可以提供更好的应用程序管理和部署机制可以帮助网络安全工作者更好地控制应用程序的运行环境减少潜在的安全漏洞 博主搭建的漏洞环境、漏洞靶场也几乎都是容器化部署的。 更好地隔离应用程序容器技术可以提供更好的应用程序隔离机制可以将不同的应用程序隔离开来从而减少由于应用程序之间相互干扰导致的安全问题 更好地应对攻击容器技术可以提供更好的应对攻击的机制例如通过容器镜像签名来确保容器镜像来源的可靠性以及通过容器网络隔离来限制容器之间的通信等。
1. 基础理论
1.1. 什么是容器Container
容器是一种统一的软件交付的标准所构建的软件包容器镜像可以跨平台Linux或Windows随处运行可以对以下场景进行隔离
应用配置如数据源配置应用端口配置等;业务应用如购物网站SaaS服务等系统软件如openssl、gcc、curl、python、jdk等;系统配置如防火墙策略配置iptables;操作系统RedHat、Ubuntu、CentOS等。
1.1.1. 容器与虚拟机的区别
容器技术起源于Linux是一种内核虚拟化技术提供轻量级的虚拟化以便隔离进程和资源。尽管容器技术已经出现很久却是随着Docker的出现而变得广为人知。Docker是第一个使容器能在不同机器之间移植的系统。 Docker 简化了打包应用的流程、打包应用的库和依赖甚至整个操作系统的文件系统能被打包成一个简单的可移植的包这个包可以被用来在任何其他运行Docker的机器上使用。
容器和虚拟机具有相似的资源隔离和分配方式容器虚拟化了操作系统而不是硬件更加便携和高效。 对比指标容器虚拟机备注磁盘占用小大镜像层最小可至KB级别虚拟机大小一般为GB级别启动速度快慢传统的虚拟机技术启动应用服务往往需要数分钟而Docker容器应用由于直接运行于宿主内核无需启动完整的操作系统因此可以做到秒级、甚至毫秒级的启动时间大大节约了开发、测试、部署的时间。并发高低宿主机可启动成百上千个容器但虚拟机至多同时启动几十个性能较高较差容器性能接近宿主机本地进程虚拟机进程逊于宿主机本地进程资源利用率高低由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销容器对系统资源的利用率更高。维护扩展性高低Docker使用的分层存储以及镜像的技术使得应用重复部分的复用更为容易也使得应用的维护更新更加简单基于基础镜像进一步扩展镜像也变得非常简单。此外Docker团队同各个开源项目团队一起维护了大批高质量的官方镜像既可以直接在生产环境使用又可以作为基础进一步定制大大的降低了应用服务的镜像制作成本。
1.2. 镜像Image是什么
将应用软件及所有相关的交付件统一打成一个包这个包称为镜像镜像可通过容器引擎快速运行。Docker Hub 中 95% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。比如我们现在构建一个新的镜像Dockerfile 如下
FROM debian
RUN apt-get install emacs
RUN apt-get install apache2
CMD [/bin/bash]注解
Dockerfile是一个文本文档其中包含用户可以在命令行上调用以组装镜像的所有命令。Docker可以通过读取Dockerfile中的指令自动构建镜像如果多个镜像都从相同的base镜像构建而来那么Docker主机上只需在磁盘上保存一份base镜像。同时内存中也只需加载一份base镜像即镜像的每一层都可以被共享就可以为所有容器服务了。
1.3. 什么是镜像仓库Image Registry
镜像仓库用于存放镜像以及促进不同人和不同电脑之间共享这些镜像。当编译镜像时要么可以在编译它的电脑上运行要么可以先上传镜像到一个镜像仓库然后下载到另外一台电脑上并运行它。Docker Hub便是一个用于存放Docker镜像的在线仓库它可以存放私人和公开的镜像。 1.4. 什么是卷Volume
容器中的文件在磁盘上是临时存放的当容器重建时容器中的文件将会丢失另外当在一个 Pod 中同时运行多个容器时常常需要在这些容器之间共享文件这也是容器不好解决的问题。K8s 抽象出了 Volume 来解决这两个问题也就是存储卷K8s的Volume是Pod的一部分Volume不是单独的对象不能独立创建只能在Pod中定义。
Pod中的所有容器都可以访问Volume但必须要挂载且可以挂载到容器中任何目录。 注意数据卷类似于Linux下对目录或文件进行mount镜像中的被指定为挂载点的目录中的文件会复制到数据卷中仅数据卷为空时会复制。 1.5. 什么是K8S
Kubernetes是一个开源的容器编排部署管理平台用于管理云平台中多个主机上的容器化应用。Kubernetes的目标是让部署容器化的应用简单并且高效Kubernetes提供了应用部署、规划、更新、维护的一种机制。K8S架构图如下 对应用开发者而言可以把Kubernetes看成一个集群操作系统。Kubernetes提供服务发现、伸缩、负载均衡、自愈甚至选举等功能让开发者从基础设施相关配置等解脱出来。 Kubernetes可以把大量的服务器看做一台巨大的服务器在一台大服务器上面运行应用程序。无论Kubernetes的集群有多少台服务器在Kubernetes上部署应用程序的方法永远一样。 1.5.1. Kubernetes中的基本对象
下图中介绍了Kubernetes中基本对象及它们之间的一些关系。 容器组PodPod是Kubernetes创建或部署的最小单位。一个Pod封装一个或多个容器container、存储资源volume、一个独立的网络IP以及管理控制容器运行方式的策略选项。 无状态工作负载DeploymentDeployment是对Pod的服务化封装。一个Deployment可以包含一个或多个Pod每个Pod的角色相同所以系统会自动为Deployment的多个Pod分发请求。 有状态工作负载StatefulSetStatefulSet是用来管理有状态应用的对象。和Deployment相同的是StatefulSet管理了基于相同容器定义的一组Pod。但和Deployment不同的是StatefulSet为它们的每个Pod维护了一个固定的ID。这些Pod是基于相同的声明来创建的但是不能相互替换无论怎么调度每个Pod都有一个永久不变的ID。 任务JobJob是用来控制批处理型任务的对象。批处理业务与长期伺服业务Deployment的主要区别是批处理业务的运行有头有尾而长期伺服业务在用户不停止的情况下永远运行。Job管理的Pod根据用户的设置把任务成功完成就自动退出Pod自动删除。 定时任务CronJobCronJob是基于时间控制的Job类似于Linux系统的crontab在指定的时间周期运行指定的任务。 守护进程集DaemonSetDaemonSet是这样一种对象守护进程它在集群的每个节点上运行一个Pod且保证只有一个Pod这非常适合一些系统层面的应用例如日志收集、资源监控等这类应用需要每个节点都运行且不需要太多实例一个比较好的例子就是Kubernetes的kube-proxy。 服务ServiceService是用来解决Pod访问问题的。Service有一个固定IP地址Service将访问流量转发给Pod而且Service可以给这些Pod做负载均衡。 路由IngressService是基于四层TCP和UDP协议转发的Ingress可以基于七层的HTTP和HTTPS协议转发可以通过域名和路径做到更细粒度的划分。 配置项ConfigMapConfigMap是一种用于存储应用所需配置信息的资源类型用于保存配置数据的键值对可在容器工作负载中作为文件或者环境变量使用。通过ConfigMap可以方便的做到配置解耦使得不同环境有不同的配置。 保密字典SecretSecret是一种加密存储的资源对象您可以将认证信息、证书、私钥等保存在Secret中在容器工作负载中作为文件或者环境变量使用而不需要把这些敏感数据暴露到镜像或者Pod定义中从而更加安全和灵活。 Secret与ConfigMap非常像都是key-value键值对形式使用方式也相同不同的是Secret会加密存储Secret的Value必须使用Base64编码所以适用于存储敏感信息。
对字符串进行Base64编码可以直接使用“echo -n 要编码的内容 | base64”命令即 可示例如下 # echo -n 3306 | base64MzMwNg存储卷Persistent VolumePVPV指持久化数据存储卷主要定义的是一个持久化存储在宿主机上的目录比如一个NFS的挂载目录。 存储卷声明Persistent Volume ClaimPVCKubernetes提供PVC专门用于持久化存储的申请PVC可以让您无需关心底层存储资源如何创建、释放等动作而只需要申明您需要何种类型的存储资源、多大的存储空间。 空目录EmptyDirEmptyDir是最简单的一种Volume类型根据名字就能看出这个Volume挂载后就是一个空目录应用程序可以在里面读写文件emptyDir Volume的生命周期与Pod相同Pod删除后Volume的数据也同时删除掉。emptyDir的一些用途 缓存空间例如基于磁盘的归并排序。为耗时较长的计算任务提供检查点以便任务能从崩溃前状态恢复执行。 emptyDir实际是将Volume的内容写在Pod所在节点的磁盘上另外emptyDir也可以设置存储介质为内存 主机路径HostPathHostPath是一种持久化存储emptyDir里面的内容会随着Pod的删除而消失但HostPath不会如果对应的Pod删除HostPath Volume里面的内容依然存在于节点的目录中如果后续重新创建Pod并调度到同一个节点挂载后依然可以读取到之前Pod写的内容。
HostPath存储的内容与节点相关所以它不适合像数据库这类的应用如果数据库的Pod被调度到别的节点了那读取的内容就完全不一样了。
1.5.2. 网络访问场景
工作负载网络访问可以分为如下几种场景: 从集群内部访问工作负载创建ClusterIP类型的Service通过Service访问工作负载。 从集群外部访问工作负载从集群外部访问工作负载推荐使用ServiceNodePort类型或LoadBalancer类型或Ingress访问。 通过公网访问工作负载需要节点或LoadBalancer绑定公网IP。通过内网访问工作负载通过节点或LoadBalancer的内网IP即可访问工作负载。如果跨VPC需要通过对等连接等手段打通不同VPC网络。 工作负载访问外部网络 工作负载访问内网负载访问内网地址在不同容器网络模型下有不同的表现需要注意在对端安全组放通容器网段具体请参见容器如何访问VPC内部网络。 工作负载访问公网访问公网有几种方法可以实现一是让容器所在节点绑定公网IP容器网络模型为VPC网络或容器隧道网络或给Pod IP绑定公网IP云原生2.0网络另一个是通过NAT网关配置SNAT规则具体请参见从容器访问公网。
1.6. Docker容器典型使用流程 制作镜像首先开发者在开发环境机器上开发应用并制作镜像。Docker执行命令构建镜像并存储在机器上。 上传镜像开发者发送上传镜像命令。Docker收到命令后将本地镜像上传到镜像仓库。 运行镜像开发者向生产环境机器发送运行镜像命令。生产环境机器收到命令后Docker会从镜像仓库拉取镜像到机器上然后基于镜像运行容器。
1.7. 常用操作 接下来本文主要介绍一些常用操作。若想了解更多Docker常用操作命令可以参阅
Download Docker Commands Cheat SheetDocker技术入门与实战.pdf (访问密码: 6277)命令参数细节可参阅官方文档Use the Docker command line
1.7.1. 制作DockerFile
常见 Dockerfile 由FROM、RUN、EXPOSE组成如下
# 使用官方提供的Nginx镜像作为基础镜像
FROM nginx:alpine# 执行一条命令修改Nginx镜像index.html的内容
RUN echo hello world /usr/share/nginx/html/index.html# 允许外界访问容器的80端口
EXPOSE 801.7.1.1. Dockerfile命令介绍
1.7.1.1.1. FROM
所谓定制镜像那一定是以一个镜像为基础在其上进行定制。Dockerfile中FROM是必备的指令并且必须是第一条指令。
1.7.1.1.2. RUN
RUN 指令是用来执行命令行命令的。由于命令行的强大能力RUN 指令在定制镜像时是最常用的指令之一。如下为一个正确的写法的Dockerfile。
FROM debian:stretchRUN set -x; buildDepsgcc libc6-dev make wget \ apt-get update \ apt-get install -y $buildDeps \ wget -O redis.tar.gz http://download.redis.io/releases/redis-5.0.3.tar.gz \ mkdir -p /usr/src/redis \ tar -xzf redis.tar.gz -C /usr/src/redis --strip-components1 \ make -C /usr/src/redis \ make -C /usr/src/redis install \ rm -rf /var/lib/apt/lists/* \ rm redis.tar.gz \ rm -r /usr/src/redis \ apt-get purge -y --auto-remove $buildDeps解读
这里没有使用很多个RUN一一对应不同的命令而是仅仅使用一个RUN指令并使用将各个所需命令串联起来此操作可将7层镜像简化为1层减少了镜像体积。Dockerfile 支持 Shell 类的行尾添加\的命令换行方式以及行首#进行注释的格式。良好的格式比如换行、缩进、注释等会让维护、排障更为容易这是一个好的习惯。命令的最后添加了清理工作的命令删除了为了编译构建所需要的软件清理了所有下载、展开的文件并且还清理了apt缓存文件。这是很重要的一步我们之前说过镜像是多层存储每一层的东西并不会在下一层被删除会一直跟随着镜像。因此镜像构建时一定要确保每一层只添加真正需要添加的东西任何无关的东西都应该清理掉。
1.7.1.1.3. LABEL
LABEL 指令用来给镜像以键值对的形式添加一些元数据metadata LABEL keyvalue keyvalue keyvalue ...
比如声明镜像的作者 LABEL author筑梦之月
1.7.1.1.4. COPY
COPY [--chownuser:group] 源路径... 目标路径
源路径 可以是多个甚至可以是通配符其通配符规则要满足 Go 的 filepath.Match (opens new window)规则如
COPY hom* /mydir/
COPY hom?.txt /mydir/目标路径可以是容器内的绝对路径也可以是相对于工作目录的相对路径工作目录可以用WORKDIR指令来指定。目标路径不需要事先创建如果目录不存在会在复制文件前先行创建缺失目录。
此外还需要注意一点使用COPY指令源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。可在使用该指令的时候还可以加上--chownuser:group选项来改变文件的所属用户及所属组。
注意 如果源路径为文件夹复制的时候不是直接复制该文件夹而是将文件夹中的内容复制到目标路径。
1.7.1.1.5. ADD
ADD 指令和 COPY 的格式和性质基本一致。但是在COPY基础上增加了一些功能。比如源路径可以是一个URL这种情况下Docker引擎会试图去下载这个链接的文件放到目标路径 去。
如果 源路径 为一个tar压缩文件压缩格式为gzip, bzip2以及xz的情况下ADD指令将会自动解压缩这个压缩文件到目标路径 去。
在Docker官方的Dockerfile最佳实践文档中要求尽可能的使用COPY因为COPY的语义很明确就是复制文件而已而ADD则包含了更复杂的功能其行为也不一定很清晰。最适合使用ADD的场合就是所提及的需要自动解压缩的场合。
1.7.1.1.6. CMD
CMD指令用于执行目标镜像中包含的软件可以包含参数。指令有以下两种格式
CMD 命令CMD [可执行文件, 参数1, 参数2...]
比如
CMD echo $HOMECMD [ sh, -c, echo $HOME ]
1.7.1.1.7. ENTRYPOINT
ENTRYPOINT主要用于设置镜像的主命令允许将镜像当成命令本身来运行用 CMD 提供默认选项例如下面的示例镜像提供了命令行工具ls
ENTRYPOINT [ls]CMD [--help]现在直接运行该镜像创建的容器会显示命令帮助或者提供正确的参数来执行某个命令比如查看当前容器根目录文件
$ docker run 镜像ID /
$ docker run 2c5cdd305083 /
bin
dev
etc
home
lib
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var1.7.1.1.8. WORKDIR
WORKDIR 工作目录路径
使用WORKDIR指令可以来指定工作目录或者称为当前目录以后各层的当前目录就被改为指定的目录如该目录不存在WORKDIR会帮你建立目录。
1.7.1.1.9. ENV
这个指令很简单就是设置环境变量而已格式有两种
ENV key valueENV key1value1 key2value2...
1.7.1.1.10. EXPOSE
EXPOSE 端口1 [端口2...]
EXPOSE指令是声明容器运行时提供服务的端口这只是一个声明在容器运行时并不会因为这个声明应用就会开启这个端口的服务。在Dockerfile 中写入这样的声明有两个好处:
帮助镜像使用者理解这个镜像服务的守护端口以方便配置映射在运行时使用随机端口映射时也就是docker run -P时会自动随机映射 EXPOSE 的端口。
1.7.1.1.11. USER
USER 用户名[:用户组]
USER 指令和 WORKDIR 相似都是改变环境状态并影响以后的层。WORKDIR 是改变工作目录USER 则是改变之后层的执行 RUN, CMD 以及 ENTRYPOINT 这类命令的身份。 注意: USER只是帮助你切换到指定用户而已这个用户必须是事先建立好的否则无法切换。 关于Dockerfile的更多命令介绍请参阅 Docker技术入门与实战.pdf (访问密码: 6277) https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
1.7.2. 构建镜像
执行docker build命令打包镜像命令格式如下
docker build -f dockerfile -t name:version .
比如 docker build -t hello . 其中-t表示给镜像加一个标签也就是给镜像取名这里镜像名为hello。. 表示在当前目录下执行该打包命令。
1.7.3. 查看镜像
执行docker images命令查看镜像。
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ghcr.io/scanoss/scanoss-py latest 2c5cdd305083 2 weeks ago 471MB
owasp/benchmark latest 7bbf7f60d339 3 weeks ago 2.28GB1.7.4. 运行镜像
有了镜像后您可以在本地执行docker run命令运行镜像。命令举例如下
docker run -it -p 宿主机端口容器端口 --name 新名字 镜像名新建并启动容器
参数说明
-d后台运行容器(启动便退出再次进入exit退出后会后台运行) -i是以交互模式启动 -t是为它分配一个伪终端it经常一起使用 -p 端口容器默认端口指定一个本机端口映射到容器内端口使得可以从宿主机访问容器内 -P随机分配映射端口。 -v宿主机目录文件:容器目录文件文件映射保持容器文件与外部同步
比如
# docker run -p 8080:80 hello此命令会启动一个容器命令中-p是将本地机器的8080端口映射到容器的80端口即本地机器的8080端口的流量会映射到容器的80端口。
1.7.5. 上传镜像
上传镜像前需要给镜像取一个完整的名称如下所示
docker tag 7bbf7f60d339 owasp/benchmark:1.0这里
7bbf7f60d339 是镜像ID1.0 则是owasp benchmark镜像分配的版本号。
然后执行docker push命令就可以将镜像上传到镜像仓库。
# docker push owasp/benchmark:1.01.7.6. 拉取镜像
当需要使用镜像时使用docker pull命令拉取下载该命令即可。
# docker pull owasp/benchmark:1.01.7.7. 导入、导出镜像
将镜像保存为镜像库存储文件
docker save -o 镜像库存储文件名 镜像ID
将镜像库存储文件导入到镜像库
docker load -i 镜像库存储文件名
1.7.8. 删除镜像
删除当前镜像
docker rmi 镜像ID
删除所有不使用的镜像
docker image prune --force --all 或者 docker image prune -f -a
1.7.9. 导出和导入容器
如果要导出本地某个容器生成容器快照可以使用docker export命令格式如下
docker export 容器ID
比如导出如下容器
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d9624b874754 owasp/benchmark /bin/bash 10 days ago Exited (255) 6 minutes ago 0.0.0.0:8443-8443/tcp priceless_blackwell$ docker export d9624b874754 benchmark.tar可以使用docker import从容器快照文件中再导入为镜像例如
$ cat ubuntu.tar | docker import - owasp/benchmark:1.0
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
owasp/benchmark 1.0 7bbf7f60d339 About a minute ago 171.3 MB保存容器快照时容器挂载的文件不会保存进镜像需要分析挂载的路径并拷贝相关数据目录 注意 既可以使用docker load来导入镜像存储文件到本地镜像库也可以使用docker import来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息即仅保存容器当时的快照状态而镜像存储文件将保存完整记录体积也要大。
1.7.10. 查看容器
列出运行中的容器
docker ps
列出本机所有的容器包括停止和运行
docker ps -a
列出所有的容器 ID
docker ps -aq
1.7.10.1. 查看容器详情
docker inspect
1.7.11. 进入、退出容器
进入容器有两种方式 方式一 docker attach 容器ID 方式二docker exec 容器ID
进入容器通常使用第二种方式docker exec后面跟的常见参数如下
d, --detach 在容器中后台执行命令
i, --interactivetrue
如果采用方式一如果从stdin中exit会导致容器的停止。
1.7.12. 停止容器
停止运行的容器
docker stop 容器ID
杀死容器进程
docker kill 容器ID
停止所有的容器
docker stop $(docker ps -aq)
1.7.13. 重启容器
docker restart 容器ID
1.7.14. 文件复制
从主机复制到容器
docker cp 宿主机路径 容器ID:容器路径
从容器复制到主机
docker cp 容器ID:容器路径 宿主机路径
1.7.15. 删除容器
删除单个容器
docker rm 容器ID
删除所有停止的容器
docker container prune -f
# docker container prune -f
Deleted Containers:
0884f6e6557c2b04e5951f55470dd7975a4975d14c045bf9514ec08eb43877f0
0f78c5a75d5f8f9e2d5b1d003417e47feae8a10cec5e8fe72317d28bdad49db9
665f41f59280753545879e081a1505878008b1056ca988be5f9dfc3b57f8b719
93700e7699dfa48134adec8d36643efab1fb5b15687f432ca8803ad4c21d8077
d9624b87475454cff7753981d6ae9deac47379e41dcab1b720155e2bd92373c3Total reclaimed space: 9.482GB删除所有停止的容器可以清理磁盘空间但删除前请确认好防止重要环境丢失。 1.7.16. 创建一个数据卷
docker volume create 卷名
1.7.17. 查看数据卷
docker volume ls
$ docker volume ls
DRIVER VOLUME NAME
local d9624b87475454cff7753981d6ae9deac47379e41dcab1b720155e2bd92373c3
local 665f41f59280753545879e081a1505878008b1056ca988be5f9dfc3b57f8b719在主机里使用以下命令可以查看指定数据卷的信息
$ docker volume inspect python
[{CreatedAt: 2023-04-11T16:18:4708:00,Driver: local,Labels: {dev.container.volume: true},Mountpoint: /var/lib/containers/storage/volumes/python/_data,Name: python,Options: {},Scope: local}
]1.7.18. 删除数据卷
docker volume rm 卷名
数据卷是被设计用来持久化数据的它的生命周期独立于容器Docker不会在容器被删除后自动删除数据卷并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用docker rm -v这个命令。 无主的数据卷可能会占据很多空间要清理请使用以下命令
docker volume prune
$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
d9624b87475454cff7753981d6ae9deac47379e41dcab1b720155e2bd92373c3
665f41f59280753545879e081a1505878008b1056ca988be5f9dfc3b57f8b719Total reclaimed space: 171kB1.7.19. 挂载数据卷
1.7.19.1. 默认目录挂载
命令
docker run [options] -v 任意别名:容器内的路径[:ro | rw] 镜像名|镜像ID
解读
任意别名是一个数据卷名字名字可以随便写Docker会在/var/lib/docker/volumes 目录下生成该数据卷Docker默认的数据卷目录Podman会在/var/lib/containers/storage/volumes/目录下生成该数据卷Podman默认的数据卷目录并且在数据卷里生成_data目录用于与容器目录同步数据容器的挂载目录内容覆盖到宿主机的挂载目录内容。
举例
docker run -d -p 8023:8080 --name tomcat -v tomcat_volume:/usr/local/tomcat/webapps tomcat:latest
tomcat_volume代表一个数据卷名字可以是任意这相当于相对路径它会在/var/lib/docker/volumes/下创建tomcat_volume目录作为数据卷。
1.7.19.2. 具体目录挂载
命令
docker run [options] -v 宿主机绝对路径 | 任意别名:容器内的路径[:ro | rw] 镜像名|镜像ID
解读
宿主机路径必须是绝对路径如果目录不存在Docker会自动为你创建它宿主机的的挂载目录内容覆盖到容器的挂载目录内容。
1.7.19.3. 匿名目录挂载
命令 docker run [options] -v 容器内的路径[:ro | rw] 镜像名|镜像ID 解读 没指定名字的挂载都是匿名挂载-v只写了容器内路径并没写宿主机路径这样会在Docker宿主机下/var/lib/docker/volumes/目录中生成匿名数据卷目录。
如执行以下命令
docker run -d -p 3306:3306 --name mysql -v /var/lib/mysql mysql:5.7
可以发现在/var/lib/containers/storage/volumes/目录下自动生成了一串随机字符串组成的匿名数据卷目录d9624b87475454cff7753981d6ae9deac47379e41dcab1b720155e2bd92373c3。
$ ls -lh /var/lib/containers/storage/volumes/
total 4.0K
brw------- 1 root root 8, 32 Apr 11 16:18 backingFsBlockDev
drwx------ 3 root root 4.0K Mar 16 16:45 d9624b87475454cff7753981d6ae9deac47379e41dcab1b720155e2bd92373c31.7.20. 挂载主机目录
1.7.20.1. 挂载一个主机目录作为数据卷
使用--mount标记可以指定挂载一个本地主机的目录到容器中去。
$ docker run -d -P \--name web \# -v /src/webapp:/usr/share/nginx/html \--mount typebind,source/src/webapp,target/usr/share/nginx/html \nginx:alpinero代表 read-only容器的路径只允许读不允许写。不影响宿主机的路径可读可写 rw默认值代表可读可写
1.7.20.2. 挂载一个本地主机文件作为数据卷
--mount 标记也可以从主机挂载单个文件到容器中
$ docker run --rm -it -v $HOME/.bash_history:/root/.bash_history \--mount typebind,source$HOME/.bash_history,target/root/.bash_history \ubuntu:20.04 \2. 最佳实践
2.1. Dockerfile最佳实践
2.1.1. 避免安装不必要的包
为了降低复杂性、减少依赖、减小文件大小、节约构建时间我们该避免安装任何不必要的包。例如不要在数据库镜像中包含一个文本编辑器。
2.1.2. 将多行参数排序
将多行参数按字母顺序排序比如要安装多个包时。这可以帮助我们避免重复包含同一个包更新包列表时也更容易。也便于阅读和审查。建议在反斜杠符号\之前添加一个空格以增加可读性。
下面是buildpack-deps镜像的例子
RUN apt-get update apt-get install -y \bzr \cvs \git \mercurial \subversion2.1.3. 使用多阶段构建
多阶段构建可大幅减小最终镜像的大小而无须尽力地去想办法减少中间层和文件的数量。镜像是在构建过程的最后阶段构建的因此可以通过利用构建缓存来最小化镜像层。例如如果构建包含多个层并且希望确保构建缓存可重用我们可以将它们从更改频率较低的顺序排列到更改频率较高的顺序。以下列表是指令顺序的示例
安装构建应用程序所需的工具安装或更新库依赖项生成应用程序
Go 应用程序的 Dockerfile 样例如下所示
FROM golang:1.16-alpine AS buildRUN apk add --no-cache git
RUN go get github.com/golang/dep/cmd/dep# List project dependencies with Gopkg.toml and Gopkg.lock
# These layers are only re-built when Gopkg files are updated
COPY Gopkg.lock Gopkg.toml /go/src/project/
WORKDIR /go/src/project/RUN dep ensure -vendor-only# Copy the entire project and build it
# This layer is rebuilt when a file changes in the project directory
COPY . /go/src/project/
RUN go build -o /bin/project# This results in a single layer image
FROM scratch
COPY --frombuild /bin/project /bin/project
ENTRYPOINT [/bin/project]
CMD [--help]2.2. 镜像加速
执行命令vi /etc/containers/registries.conf在文件最后添加如下registry
unqualified-search-registries [docker.io][[registry]]
location docker.io[[registry.mirror]]
location mirror.baidubce.com在cmd窗口执行命令docker info看到如下信息则表明镜像加速配置成功。
registries:docker.io:Blocked: falseLocation: docker.ioMirrorByDigestOnly: false- Insecure: falseLocation: mirror.baidubce.comPullFromMirror: Prefix: docker.ioPullFromMirror: search:- docker.io2.3. root方式进入容器
场景用于执行需要root用户才能执行的操作比如临时加装软件。
比如普通用户安装vim软件时会提示无权限
$ apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?在Docker容器中可以使用--privileged参数让容器拥有宿主机的root权限。 命令如下
docker run -it --privileged container id /bin/bash Note如果你没有在启动容器时使用--privileged参数那么容器中的root用户将不会拥有宿主机的root权限。因此如果你需要在Docker容器中使用宿主机的root权限请确保在启动容器时使用了--privileged参数。 3. 参考链接 https://support.huaweicloud.com/cce/index.html https://phoenixnap.com/kb/docker-commands-cheat-sheet https://kubernetes.io/zh-cn/docs/home/ https://frxcat.fun/pages/90cc29/ 镜像的分层结构 - 每天5分钟玩转容器技术11 Docker技术入门与实战.pdf (访问密码: 6277) https://docs.docker.com/develop/develop-images/dockerfile_best-practices/