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

Docker基础入门

第 1 章:核心概念与安装配置

本章首先介绍Docker 的三大核心概念:

  • 镜像 (Image)
  • 容器(Container)
  • 仓库(Repository)

只有理解了这三个核心概念,才能顺利地理解Docker容器的整个生命周期。

随后,将介绍如何在CentOS操作系统上安装Docker。

1.1 核心概念

Docker 大部分的操作都围绕着它的三大核心概念: 镜像、容器和仓库。因此,准确把握这三大核心概念对于掌握Docker技术尤为重要。

1. Docker 镜像

Docker 镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。

例如,一个镜像可以包含一个基本的操作系统环境,里面仅安装了Apache应用程序(或用户需要的其他软件)。 可以把它称为一个Apache镜像。

镜像是创建Docker容器的基础。

通过版本管理和增量的文件系统, Docker 提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并直接使用。

2. Docker 容器

Docker 容器类似于一个轻量级的沙箱, Docker利用容器来运行和隔离应用。

容器是从镜像创建的应用运行实例。 它可以启动、开始、停止、 删除,而这些容器都是彼此相互隔离、互不可见的。

可以把容器看作一个简易版的 Linux 系统环境(包括root用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子。

注:镜像自身是只读的。 容器从镜像启动的时候,会在镜像的最上层创建一个可写层。

3. Docker 仓库

Docker 仓库类似于代码仓库,是Docker集中存放镜像文件的场所。

有时候我们会将Docker仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。 实际上,仓库注册服务器是存放仓库的地方,其上往往存放着多个仓库。 每个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。 例如存放Ubuntu 操作系统镜像的仓库,被称为 Ubuntu 仓库,其中可能包括 16.04、 18.04 等不同版本的镜像。仓库注册服务器的示例如图2-1所示。

根据所存储的镜像公开分享与否, Docker仓库可以分为公开仓库(Public)和私有仓库(Private)两种形式。

目前,最大的公开仓库是官方提供的Docker Hub,其中存放着数量庞大的镜像供用户下载。 国内不少云服务提供商(如腾讯云、 阿里云等)也提供了仓库的本地源,可以提供稳定的国内访问。

当然,用户如果不希望公开分享自己的镜像文件, Docker 也支持用户在本地网络内创建 一个只能自己访问的私有仓库。

当用户创建了自己的镜像之后就可以使用push命令将它上传到指定的公有或者私有仓 库。 这样用户下次在另外一台机器上使用该镜像时,只需要将其从仓库上pull下来就可以了。

注意:可以看出, Docker利用仓库管理镜像的设计理念与 Git代码仓库的概念非常相似,实际上Docker 设计上借鉴了 Git 的很多优秀思想。

1.2 安装Docker 引擎

Docker引擎是使用 Docker容器的核心组件,可以在主流的操作系统和云平台上使用,包括Linux操作系统(如 Ubuntu、Debian, CentOS、 Red.hat 等), macOS 和 Windows 操作系统, 以及IBM、亚马逊、微软等知名云平台。

用户可以访问Docker官网的 Get Docker ( https://www.docker.com/get-docker)页面,查看获取Docker 的方式,以及Docker支持的平台类型,如图 2-2所示。

目前Docker 支持 Docker 引擎、 Docker Hub、 Docker Cloud 等多种服务。

  • Docker 引擎:包括支持在桌面系统或云平台安装 Docker,以及为企业提供简单安全 弹性的容器集群编排和管理;
  • DockerHub:官方提供的云托管服务,可以提供公有或私有的镜像仓库;
  • DockerCloud :官方提供的容器云服务,可以完成容器的部署与管理,可以完整地支 持容器化项目,还有CI、 CD功能。

1.CentOS 环境下安装 Docker

Docker 目前支持 CentOS 7 及以后的版本。 系统的要求跟 Ubuntu 情况类似, 64 位操作 系统,内核版本至少为3.10。

首先,为了方便添加软件源,以及支持devicemapper存储类型,安装如下软件包:

$ sudo yum update 
$ sudo yum instal l -y yum-utils \ 
device-mapper-persistent-data \ 
lvm2 

添加Docker 稳定版本的 yum软件源:

sudo yum-config-manager \ 
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo 

之后更新yum软件源缓存,并安装Docker:

sudo yum update sudo yum install -y docker-ce

最后,确认Docker服务启动正常:

 sudo systernctl start docker 

2.通过脚本安装

用户还可以使用官方提供的 shell 脚本来在 Linux 系统上安装 Docker 的最新正式版本,该脚本会自动检测系统信息并进行相应配置:

curl -fsSL https://get.docker.com/ | sh 

或者:

 wget -qO- https://get.docker.com/ | sh 

如果想尝鲜最新功能,可以使用下面的脚本来安装最新的“尝鲜”版本。 但要注意,非稳定版本往往意味着功能还不够稳定,不要在生产环境中使用:

curl -fsSL https://test.docker.com/ | sh 

另外, 也可以从store.docker.com/search?offering=community&q=&type=edition找到各个平台上的Docker安装包,自行下载使用。

1.3 配置Docker服务

为了避免每次使用 Docker 命令时都需要切换到特权身份,可以将当前用户加入安装中自动创建的docker用户组,代码如下:

sudo usermod -aG docker USER_NAME

用户更新组信息,退出并重新登录后即可生效。

Docker 服务启动时实际上是调用了dockerd命令,支持多种启动参数。 因此,用户可以直接通过执行dockerd命令来启动Docker服务,如下面的命令启动Docker服务,开启 Debug 模式,并监听在本地的 2376端口:

 dockerd -D -H tcp://127.0.0.1:2376

这些选项可以写入/etc/docker/路径下的 daemon.json 文件中,由 dockerd服务启动时读取:

对于CentOS、 RedHat等系统,服务通过 systemd来管理,配置文件路径为/etc/systemd/ system/docker.service.d/docker.conf。更新配置后需要通过 systemctl 命令来管理 Docker 服务:

sudo systemctl daemon-reload 
sudo systemctl start docker.service 

此外,如果服务工作不正常,可以通过查看Docker 服务的日志信息来确定问题,例如在RedHat 系统上日志文件可能为/var/log/messages,在CentOS 系统上可以执行命令:

journalctl -u docker.service

每次重启 Docker服务后,可以通过查看Docker信息(docker info命令),确保服务已经正常运行。

第 2 章:使用Docker镜像

镜像是Docker三大核心概念中最重要的, 自 Docker诞生之日起镜像就是相关社区最为热门的关键词。

Docker 运行容器前需要本地存在对应的镜像, 如果镜像不存在,Docker 会尝试先从默认镜像仓库下载(默认使用 DockerHub 公共注册服务器中的仓库,用户也可以通过配置, 使用自定义的镜像仓库。

本章将围绕镜像这一核心概念介绍具体操作, 包括如何使用pull命令从国内仓库中下载镜像到本地;如何查看本地已有的镜像信息和管理镜像标签;如何在远端仓库使用 search 命令进行搜索和过滤;如何删除镜像标签和镜像文件;如何创建用户定制的镜像并且保存为外部文件。 最后,还将介绍如何往国内仓库中推送自己的镜像。

2.1 配置国内镜像源并获取镜像

镜像是运行容器的前提, 官方的DockerHub网站已经提供了数十万个镜像供大家开放下载。但由于DockerHub仓库在国内访问需要加速器,所以需要配置国内镜像源。本节主要介绍Docker镜像的pull子命令。

首先进入/etc/docker/daemon.json文件中添加一下镜像:

[root@open-Euler1 docker]# cat /etc/docker/daemon.json 
{"registry-mirrors": ["https://docker.m.daocloud.io","https://hub-mirror.c.163.com","https://mirror.baidubce.com","https://docker.nju.edu.cn"]
}

可以使用docker [image] pull 命令直接从配置的镜像源来下载镜像。 该命令的格式为

docker [image] pull NAME[:TAG] 

其中, NAME是镜像仓库名称(用来区分镜像), TAG是镜像的标签(往往用来表示版本信息)。 通常情况下,描述一个镜像需要包括 “名称+标签“ 信息。

例如, 获取一个Ubuntu 18.04系统的基础镜像可以使用如下的命令:

docker pull ubuntu:18.04
18. 04: Pulling from library/ubuntu
......
Digest: sha256:e27e9d7f7f28d67aa9e2d7540bdc2b33254b452ee8e60f388875e5b7d9b2b696 
S七atus: Downloaded newer image for ubuntu:18.04

对于Docker镜像来说, 如果不显式指定TAG, 则默认会选择latest标签,这会下载仓库中最新版本的镜像。

下面的例子将从Ubuntu仓库下载一个最新版本的Ubuntu操作系统的镜像:

docker pull ubuntu 
Using default tag: latest
latest: Pulling from library/ubuntu
......
Digest: sha256:e27e9d7f7f28d67aa9e2d7540bdc2b33254b452ee8e60f388875e5b7d9b2b696 
Status: Downloaded newer image for ubuntu:latest

该命令实际上下载的就是 ubuntu:latest镜像。

注意:一般来说, 镜像的latest 标签意味着该镜像的内容会跟踪最新版本的变更而变化, 内 容是不稳定的。因此,从稳定性上考虑,不要在生产环境中忽略镜像的标签信息或使用默认的latest 标记的镜像。

下载过程中可以看出 ,镜像文件一般由若干层(layer)组成 ,6c953ac5d795这样的串是层的唯一id(实际上完整的id包括256比特,64个十六进制字符组成)。使用docker pull命令下载中会获取并输出镜像的各层信息。当不同的镜像包括相同的层时,本地仅存储了层的一份内容,减小了存储空间。

大家可能会想到,在不同的镜像仓库服务器的情况下,可能会出现镜像重名的情况。

严格地讲,镜像的仓库名称中还应该添加仓库地址(即registry, 注册服务器)作为前缀,只是默认使用的是官方DockerHub服务,该前缀可以忽略。

不过Docker 会通过你在 daemon.json 中配置的 registry-mirrors 列表来尝试下载 ubuntu 镜像,而不是直接从 Docker Hub 下载。如果第一个镜像站点不可用,Docker 会自动尝试列表中的下一个,直到镜像被成功下载或列表中的所有镜像站点都尝试过。

总之,通过这种方式,你可以简化 docker pull 命令,不需要为每个镜像手动添加前缀,同时还能享受到加速下载的好处。

pull子命令支持的选项主要包括:

-a, --all-tags=true|false:是否获取仓库中的所有镜像,默认为否;

--disable-content-trust:取消镜像的内容校验,默认为真。

另外,有时需要使用镜像代理服务来加速Docker镜像获取过程 ,可以在Docker服务启动配置中增加--registry-mirror=proxy_URL来指定镜像代理服务地址

下载镜像到本地后,即可随时使用该镜像了,例如利用该镜像创建一个容器,在其中运 行bash应用,执行打印 "Hello World"命令:

docker run -it ubuntu:18.04 bash 
root@65663247040f:/# echo "Hello World" 
Hello World 
roo七@65663247040f:/# exit

2.2 查看镜像信息

本节主要介绍Docker镜像的ls、tag和inspect子命令。

1. 使用images命令列出镜像

使用docker images或docker image ls 命令可以列出本地主机上已有镜像的基本信息。

例如,下面的命令列出了上一小节中下载的镜像信息:

[root@open-Euler1 ~]# docker images
REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
wordpress                     latest    458dad822ff7   3 weeks ago     701MB
nginx                         latest    b52e0b094bc0   4 weeks ago     192MB
busybox                       latest    31311c5853a2   5 months ago    4.27MB
reg.yym.com/library/busybox   latest    31311c5853a2   5 months ago    4.27MB
myubuntu                      18.04     f9a80a55f492   21 months ago   63.2MB
ubuntu                        18.04     f9a80a55f492   21 months ago   63.2MB
reg.yym.com/openlab/ubuntu    18.04     f9a80a55f492   21 months ago   63.2MB
mysql                         5.6       dd3b2a5dcb48   3 years ago     303MB

在列出信息中,可以看到几个字段信息:

  • 来自于哪个仓库,比如ubuntu表示ubuntu系列的基础镜像;
  • 镜像的标答信息,比如 18.04、latest表示不同的版本信息。 标签只是标记,并不能标 识镜像内容;
  • 镜像的ID(唯一标识镜像),如果两个镜像的ID相同,说明它们实际上指向了同一 个镜像,只是具有不同标签名称而已;
  • 创建时间,说明镜像最后的更新时间;
  • 镜像大小,优秀的镜像往往体积都较小。

其中镜像的ID信息十分重要,它唯一标识了镜像。在使用镜像ID的时候,一般可以使用该ID的前若干个字符组成的可区分串来替代完整的ID。

TAG 信息用于标记来自同一个仓库的不同镜像。例如ubuntu 仓库中有多个镜像,通过 TAG 信息来区分发行版本,如18.04、18.10 等。

镜像大小信息只是表示了该镜像的逻辑体积大小,实际上由于相同的镜像层本地只会存储一份,物理上占用的存储空间会小于各镜像逻辑体积之和。

images子命令主要支持如下选项,用户可以自行进行尝试:

  • -a, --all=true | false: 列出所有(包括临时文件)镜像文件,默认为否;
  • --digests=true | false: 列出镜像的数字摘要值,默认为否;
  • -f, --filter=[] : 过滤列出的镜像,如dangling=true只显示没有被使用的镜像;也可指定带有特定标注的镜像等;
  • --format="TEMPLATE" : 控制输出格式,如. ID代表ID信息,.Repository 代表仓库信息等;
  • --no-trunc=true | false: 对输出结果中太长的部分是否进行截断,如镜像的ID 信息,默认为是;
  • -q, --quiet=true | false: 仅输出ID信息, 默认为否。

更多子命令选项还可以通过man docker-images来查看。

2. 使用tag命令添加镜像标签

为了方便在后续工作中使用特定镜像,还可以使用docker tag命令来为本地镜像任意添加新的标签。 例如,添加一个新的myubuntu:latest镜像标签:

docker tag ubuntu:18.04 myubuntu:18.04

再次使用docker images列出本地主机上镜像信息,可以看到多了一个myubuntu:18.04标签的镜像:

[root@open-Euler1 ~]# docker images
REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
wordpress                     latest    458dad822ff7   3 weeks ago     701MB
nginx                         latest    b52e0b094bc0   4 weeks ago     192MB
reg.yym.com/library/busybox   latest    31311c5853a2   5 months ago    4.27MB
busybox                       latest    31311c5853a2   5 months ago    4.27MB
myubuntu                      18.04     f9a80a55f492   21 months ago   63.2MB
ubuntu                        18.04     f9a80a55f492   21 months ago   63.2MB
reg.yym.com/openlab/ubuntu    18.04     f9a80a55f492   21 months ago   63.2MB
mysql                         5.6       dd3b2a5dcb48   3 years ago     303MB

之后,用户就可以直接使用myubuntu:18.04来表示这个镜像了。

注意:这些myubuntu:18.04镜像的ID跟ubuntu:18.04是完全一致的,它们实际上指向了同一个镜像文件,只是别名不同而巳。docker tag命令添加的标签实际上起到了类似链接的作用。

3.使用inspect命令查看详细信息

[root@open-Euler1 ~]# docker inspect ubuntu:18.04 
[{"Id": "sha256:f9a80a55f492e823bf5d51f1bd5f87ea3eed1cb31788686aa99a2fb61a27af6a","RepoTags": ["myubuntu:18.04","ubuntu:18.04","reg.yym.com/openlab/ubuntu:18.04"],"RepoDigests": ["reg.yym.com/openlab/ubuntu@sha256:0891d22f55fab66664581bbfca80601dfc9d6e8fff8f65a493e9f96644e29417"],"Parent": "","Comment": "","Created": "2023-05-30T09:32:09.432301537Z","DockerVersion": "20.10.21","Author": "","Config": {"Hostname": "","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash"],"Image": "sha256:e24e6fe4d70b767b0621c909f548dab783f946ef6d9346ecc2272730b821a402","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.opencontainers.image.ref.name": "ubuntu","org.opencontainers.image.version": "18.04"}},"Architecture": "amd64","Os": "linux","Size": 63156473,"GraphDriver": {"Data": {"MergedDir": "/var/lib/docker/overlay2/926b8629b6c6a80e8f5763650a82542ebc1a730897eac9969eb9941f8058ce9b/merged","UpperDir": "/var/lib/docker/overlay2/926b8629b6c6a80e8f5763650a82542ebc1a730897eac9969eb9941f8058ce9b/diff","WorkDir": "/var/lib/docker/overlay2/926b8629b6c6a80e8f5763650a82542ebc1a730897eac9969eb9941f8058ce9b/work"},"Name": "overlay2"},"RootFS": {"Type": "layers","Layers": ["sha256:548a79621a426b4eb077c926eabac5a8620c454fb230640253e1b44dc7dd7562"]},"Metadata": {"LastTagTime": "2025-03-09T16:15:06.918305625+08:00"}}
]

4.使用history命令查看镜像历史

既然镜像文件由多个层组成, 那么怎么知道各个层的内容具体是什么呢?这时候可以使用history子命令, 该命令将列出各层的创建信息。

例如,查看ubuntu:18.04 镜像的创建过程,可以使用如下命令:

[root@open-Euler1 ~]# docker history ubuntu:18.04 
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
f9a80a55f492   21 months ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      21 months ago   /bin/sh -c #(nop) ADD file:3c74e7e08cbf9a876…   63.2MB    
<missing>      21 months ago   /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B        
<missing>      21 months ago   /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B        
<missing>      21 months ago   /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH     0B        
<missing>      21 months ago   /bin/sh -c #(nop)  ARG RELEASE                  0B   

注意, 过长的命令被自动截断了,可以使用前面提到的--no-trunc选项来输出完整的命令。

2.3 搜寻镜像

本节主要介绍Docker 镜像的search子命令。 使用docker search命令可以搜索Docker Hub官方仓库中的镜像。语法为docker search [option] keyword。支持的命令选项主要包括:

例如, 搜索官方提供的带nginx关键字的镜像,如下所示:

2.4 删除和清理镜像

本节主要介绍Docker镜像的rm和prune子命令。

1.使用标签删除镜像

使用docker rmi或docker image rm命令可以删除镜像,命令格式为docker rmi IMAGE [IMAGE ... ], 其中IMAGE可以为标签或 ID

支持选项包括:

例如, 要删除掉myubuntu:latest镜像, 可以使用如下命令:

docker rmi myubuntu:18.04

大家可能会想到,本地的ubuntu:18.04镜像是否会受到此命令的影响。 无须担心, 当同一个镜像拥有多个标签的时候, docker rmi 命令只是删除了该镜像多个标签中的指定标签而已,并不影响镜像文件。 因此上述操作相当于只是删除了镜像f9a80a55f492的一 个标签副本而已。

但当镜像只剩下一个标签的时候就要小心了, 此时再使用docker rmi命令会彻底删除镜像。

例如通过执行docker rmi命令来删除只有一个标签的镜像,可以看出会删除这个镜像文件的所有文件层:

[root@open-Euler1 ~]# docker rmi busybox:latest 
Untagged: busybox:latest
Untagged: busybox@sha256:498a000f370d8c37927118ed80afe8adc38d1edcbfc071627d17b25c88efcab0

2. 使用镜像ID来删除镜像

当使用docker rmi 命令,并且后面跟上镜像的ID(也可以是能进行区分的部分ID串前缀)时,会先尝试删除所有指向该镜像的标签,然后删除该镜像文件本身。

注意,当有该镜像创建的容器存在时,镜像文件默认是无法被删除的,例如:先利用ubuntu:18.04镜像创建一个简单的容器来输出一段话:

使用docker ps -a命令可以看到本机上存在的所有容器:

可以看到, 后台存在一个退出状态的容器,是刚基于ubuntu:18.04镜像创建的。试图删除该镜像,Docker会提示有容器正在运行, 无法删除:

如果要想强行删除镜像,可以使用-f参数:

注意,通常并不推荐使用-f参数来强制删除一个存在容器依赖的镜像。正确的做法是,先删除依赖该镜像的所有容器,再来删除镜像。

首先删除容器a21c0840213e:

然后使用ID来删除镜像, 此时会正常打印出删除的各层信息:

3. 清理镜像

使用Docker一段时间后, 系统中可能会遗留一些临时的镜像文件, 以及一些没有被使用的镜像, 可以通过docker image prune命令来进行清理。

支待选项包括:

例如,如下命令会自动清理临时的遗留镜像文件层,最后会提示释放的存储空间:

2.5 存出和载入镜像

本节主要介绍 Docker 镜像的 save 和 load子命令。 用户可以使用 docker [image] save 和 docker [image] load命令来存出和载人镜像。

1. 存出镜像

如果要导出镜像到本地文件,可以使用docker [image] save命令。 该命令支持-o、-output string 参数, 导出镜像到指定的文件中。

例如,导出本地的ubuntu:18.04 镜像为文件ubuntu_18.04.tar,如下所示:

[root@open-Euler1 ~]# docker save -o ubuntu_18.04.tar ubuntu:18.04 
[root@open-Euler1 ~]# ll
total 645544
-rw-------. 1 root root       884 Jan 10 11:11 anaconda-ks.cfg
-rw-r--r--  1 root root   9150593 Mar  1 11:03 apache-tomcat-8.0.30.tar.gz
-rw-r--r--  1 root root     30720 Mar  8 12:09 backup.tar
-rw-r--r--  1 root root 586290688 Mar  8 12:56 discuz.tar
-rw-r--r--  1 root root        27 Mar  2 17:11 index.html
-rw-------  1 root root  65541632 Mar  9 16:26 ubuntu_18.04.tar

之后,用户就可以通过复制ubuntu_18.04.tar文件将该镜像分享给他人。

2. 载入镜像

可以使用docker [image] load将导出的 tar 文件再导人到本地镜像库。支持-i、-input string 选项,从指定文件中读入镜像内容。

例如,从文件ubuntu_18.04.tar 导人镜像到本地镜像列表,如下所示:

docker load -i ubuntu_18.04.tar
或者
docker load < ubuntu_18.04.tar

这将导入镜像及其相关的元数据信息(包括标签等)。导入成功后,可以使用docker images命令进行查看, 与原镜像一致。

第 3 章:操作Docker容器

容器是Docker 的另一个核心概念。 简单来说,容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层,同时,容器中的应用进程处于运行状态。

如果认为虚拟机是模拟运行的一整套操作系统(包括内核、 应用运行态环境和其他系统环境)和跑在上面的应用。 那么 Docker 容器就是独立运行的一个(或一组)应用,以及它们必需的运行环境。

本章将具体介绍围绕容器的重要操作,包括创建一个容器、 启动容器、终止一个容器、进入容器内执行操作、删除容器和通过导入导出容器来实现容器迁移等。

3.1 创建容器

从现在开始,忘掉“臃肿”的虚拟机吧,对容器的操作就像直接操作应用一样简单和快速。

本节主要介绍Docker容器的 create、 start、 run,、wait 和 logs 子命令。

1. 新建容器

可以使用docker [container] create 命令创建一个容器,例如:

[root@open-Euler2 ~]# docker create -it busybox:latest
22c599d83bcb4393f2a7c4749a809c86d1735ddeb3b720356db57213e2e9f2e9
[root@open-Euler2 ~]# docker ps -a
CONTAINER ID   IMAGE            COMMAND   CREATED         STATUS    PORTS     NAMES
22c599d83bcb   busybox:latest   "sh"      4 seconds ago   Created             musing_sutherland
[root@open-Euler2 ~]# 

使用docker [container] create 命令新建的容器处于停止状态,可以使用 docker [container] start 命令来启动它。

由于容器是整个Docker技术栈的核心, create命令和后续的run命令支持的选项都 十分复杂,需要在实践中不断体会。

选项主要包括如下几大类: 与容器运行模式相关、与容器环境配置相关、与容器资源限制和安全保护相关,参见表4-1~表4-3。

2. 启动容器

使用docker [container] start 命令来启动一个已经创建的容器。例如,启动刚创建的busybox容器,然后通过docker ps命令,可以查看到一个运行中的容器:

[root@open-Euler2 ~]# docker start 22c599d83bcb #通过容器id启动
22c599d83bcb
[root@open-Euler2 ~]# docker ps
CONTAINER ID   IMAGE            COMMAND   CREATED         STATUS          PORTS     NAMES
22c599d83bcb   busybox:latest   "sh"      6 minutes ago   Up 14 seconds             musing_sutherland

3. 新建并启动容器

除了创建容器后通过start命令来启动也可以直接新建并启动容器。

所需要的命令主要为docker [container]run,等价于先执行docker [container] create 命令,再执行docker [container] start 命令。

例如,下面的命令输出一个“Hello World!"之后容器自动终止:

[root@open-Euler2 ~]# docker run ubuntu /bin/echo 'Hello World!'
Hello World!
[root@open-Euler2 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
7f620e289a32   ubuntu    "/bin/echo 'Hello Wo…"   46 seconds ago   Exited (0) 45 seconds ago             zen_chaum

这跟在本地直接执行/bin/echo 'Hello World!" 相比几乎感觉不出任何区别。

当利用 docker [container] run来创建并启动容器时, Docker在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
  • 利用镜像创建一个容器,并启动该容器;
  • 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去;
  • 从网桥的地址池配置一个IP地址给容器;
  • 执行用户指定的应用程序;
  • 执行完毕后容器被自动终止。

下面的命令启动一个bash终端,允许用户进行交互:

[root@open-Euler2 ~]# docker run -it ubuntu /bin/bash
root@28d877face35:/# 

其中,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,-i 则让容器的标准输入保持打开。 更多的命令选项可以通过man docker-run命令来查看。

在交互模式下,用户可以通过所创建的终端来输人命令,例如:

root@28d877face35:/# pwd
/
root@28d877face35:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@28d877face35:/# psPID TTY          TIME CMD1 pts/0    00:00:00 bash10 pts/0    00:00:00 ps

在容器内用ps命令查看进程,可以看到,只运行了bash应用,并没有运行其他无关的进程。 用户可以按Ctrl+d或输入exit 命令来退出容器。

对于所创建的 bash 容器,当用户使用exit命令退出 bash 进程之后,容器也会自动退出。 这是因为对于容器来说,当其中的应用退出后,容器的使命完成,也就没有继续运行的必要了。

4. 守护态运行

更多的时候,需要让Docker容器在后台以守护态(Daemonized)形式运行。 此时,可以通过添加-d参数来实现。

例如,下面的命令会在后台运行容器:

[root@open-Euler2 ~]# docker run -itd ubuntu:latest
552e48e07720bf063b6f4c4208c04188d98afee57c9a0f3cf6d4fec5ca1d5d9b
[root@open-Euler2 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND       CREATED         STATUS         PORTS     NAMES
552e48e07720   ubuntu:latest   "/bin/bash"   4 seconds ago   Up 3 seconds             frosty_dirac

5. 查看容器输出

要获取容器的输出信息,可以通过docker [container] logs命令。

例如,查看某容器的输出可以使用如下命令:

[root@open-Euler2 ~]# docker logs 552e48e07720 
root@552e48e07720:/# pwd
/
root@552e48e07720:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@552e48e07720:/# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 09:23 pts/0    00:00:00 /bin/bash
root          10       1  0 09:25 pts/0    00:00:00 ps -ef
root@552e48e07720:/# 
exit

3.2 停止容器

本节主要介绍Docker容器的 pause/unpause、 stop 和 prune 子命令。

1. 暂停容器

可以使用docker [container] pause CONTAINER [CONTAINER ... ]命令来暂停一个运行中的容器。

例如,启动一个容器,并将其暂停:

[root@open-Euler2 ~]# docker run --name test1 --rm -it ubuntu bash
root@3d0b00932ba4:/# (这里可以用ctrl+p然后ctrl+q后台运行该容器)
[root@open-Euler2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
3d0b00932ba4   ubuntu    "bash"    19 seconds ago   Up 19 seconds             test1
[root@open-Euler2 ~]# docker pause test1
test1
[root@open-Euler2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS                   PORTS     NAMES
3d0b00932ba4   ubuntu    "bash"    43 seconds ago   Up 43 seconds (Paused)             test1

处于 paused 状态的容器,可以使用 docker [container] unpause CONTAINER [CONTAINER ... ] 命令来恢复到运行状态。

2. 终止容器

可以使用docker [container] stop 来终止一个运行中的容器。 该命令的格式为 docker [container] stop [-t | --time [=10]]  [CONTA工NER... ] 。

该命令会首先向容器发送SIGTERM信号,等待一段超时时间后(默认为 10 秒),再发送SIGKILL 信号来终止容器:

[root@open-Euler2 ~]# docker stop 3d0b00932ba4 
3d0b00932ba4

此时,执行docker container prune 命令,会自动清除掉所有处于停止状态的容器。

此外,还可以通过docker [container] kill 直接发送SIGKILL信号来强行终止容器。

当 Docker 容器中指定的应用终结时,容器也会自动终止。 例如,对于上一章节中只启动了一个终端的容器,用户通过exit命令或Ctrl+d来退出终端时,所创建的容器立刻终止,处于stopped状态。

可以用docker ps -qa命令看到所有容器的 ID。 例如:

[root@open-Euler1 ~]# docker ps -aq
2b7d17d89536
62a2df1db920

处于终止状态的容器,可以通过docker [container] start命令来重新启动:

[root@open-Euler2 ~]# docker run -itd ubuntu
5301c6e2b355b1459af95e73214b9f2abd1eb86c044e6a771214150335f78dd7
[root@open-Euler2 ~]# docker stop 5301c6e2b355
5301c6e2b355
[root@open-Euler2 ~]# docker start 5301c6e2b355
5301c6e2b355
[root@open-Euler2 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
5301c6e2b355   ubuntu    "/bin/bash"   5 minutes ago   Up 4 seconds             loving_hamilton

注意:Docker 容器在后台运行时,通常依赖于一个前台进程。如果这个进程退出,容器就会自动停止。这通常是容器自动关闭的最常见原因。如果你在创建容器时没有指定一个前台运行的命令,容器启动后没有前台进程在运行,它就会立即退出。例如,如果你只运行了 docker run -d ubuntu 而没有指定要运行的命令,容器会启动然后立即停止。

docker [container] restart 命令会将一个运行态的容器先终止,然后再重新启动:

[root@open-Euler2 ~]# docker restart 5301c6e2b355  
5301c6e2b355
[root@open-Euler2 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS         PORTS     NAMES
5301c6e2b355   ubuntu    "/bin/bash"   17 minutes ago   Up 5 seconds             loving_hamilton

3.3 进入容器

在使用-d参数时,容器启动后会进入后台,用户无法看到容器中的信息,也无法进 操作。

这个时候如果需要进入容器进行操作,推荐使用官方的attach或exec命令。

1. attach 命令

attach 是 Docker自带的命令,命令格式为:

docker [container] attach [--detach-keys[=[]]] [--no-stdin] [--sig-proxy[=true]] CONTAINER

这个命令支持三个主要选项:

下面示例如何使用该命令:

[root@open-Euler2 ~]# docker run -itd ubuntu
724bce51d10962c460c0fea34233b70c7df48cf4177a7bb3eaae5e8b2b58b330
[root@open-Euler2 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
724bce51d109   ubuntu    "/bin/bash"   6 seconds ago   Up 5 seconds             laughing_haslett
[root@open-Euler2 ~]# docker attach 724bce51d109
root@724bce51d109:/# 

docker attach 的限制

  1. 同步显示:当多个终端窗口使用 docker attach 命令连接到同一个容器时,所有窗口都会同步显示相同的输出。这意味着,如果一个窗口执行了一个命令,其输出会出现在所有连接的窗口中。

  2. 阻塞问题:如果容器中的某个前台进程阻塞了(例如,等待用户输入),所有通过 docker attach 连接的会话都会被阻塞。这导致其他窗口无法执行操作,直到阻塞的命令被解除。

  3. 退出行为:当你通过 docker attach 进入容器并运行 bash 时,如果你退出 bash(例如,通过输入 exit),容器会因为没有前台进程在运行而停止。这是因为 Docker 容器在没有前台进程运行时会自动停止。

2.exec 命令

从Docker 的 1.3.0 版本起, Docker提供了一个更加方便的工具exec命令,可以在运行中容器内直接执行任意命令。

该命令的基本格式为:

比较重要的参数有:

例如,进入到刚创建的容器中,并启动一个bash:

[root@open-Euler2 ~]# docker exec -it 163622efdbfb bash
root@163622efdbfb:/# exit
[root@open-Euler2 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
163622efdbfb   ubuntu    "/bin/bash"   9 minutes ago   Up 9 minutes             sad_mclaren

可以看到会打开一个新的bash终端,在不影响容器内其他应用的前提下,用户可以与容器进行交互。在退出这个终端后docker容器依旧在运行。

注意:通过指定-it参数来保持标准输入打开,并且分配一个伪终端。 通过exec命令对容器执行操作是最为推荐的方式。

3.4 删除容器

可以使用docker [container) rm命令来删除处于终止或退出状态的容器,命令格式为

主要支持的选项包括:

例如,查看容器信息,并删除:

[root@open-Euler2 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
163622efdbfb   ubuntu    "/bin/bash"   15 minutes ago   Up 15 minutes             sad_mclaren
[root@open-Euler2 ~]# docker rm -f 163622efdbfb

3.5 导入和导出容器

某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用 Docker 的导入和导出功能,这也是Docker自身提供的一个重要特性。

1. 导出容器

导出容器是指,导出一个已经创建的容器到一个文件,不管此时这个容器是否处于运行状态。 可以使用docker [container] export 命令,该命令格式为:

其中,可以通过-O选项来指定导出的tar文件名,也可以直接通过重定向来实现。

首先,查看所有的容器,如下所示:

[root@open-Euler2 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS                     PORTS     NAMES
6f90ba016d87   ubuntu    "/bin/bash"   3 seconds ago    Exited (0) 2 seconds ago             tender_galileo
163622efdbfb   ubuntu    "/bin/bash"   30 minutes ago   Up 30 minutes                        sad_mclaren

分别导出容器163622efdbfb和6f90ba016d87 容器到文件test_for_run.tar文件和test_for_stop.tar文件:

[root@open-Euler2 ~]# docker export -o test_for_stop.tar 6f90ba016d87 
[root@open-Euler2 ~]# ls
anaconda-ks.cfg  docker  docker-28.0.1.tgz  test_for_stop.tar
[root@open-Euler2 ~]# docker export 163622efdbfb > test_for_run.tar
[root@open-Euler2 ~]# ls
anaconda-ks.cfg  docker  docker-28.0.1.tgz  test_for_run.tar  test_for_stop.tar

之后,可将导出的tar文件传输到其他机器上,然后再通过导人命令导入到系统中,实现容器的迁移。

2. 导入容器

导出的文件又可以使用docker [container] import 命令导入变成镜像,该命令格式为:

下面将导出的test_for_run.tar和test_for_stop.tar文件导入到系统中:

从本地文件导入
[root@open-Euler2 ~]# docker import test_for_run.tar test/ubuntu:latest
sha256:2870932093027479e25dd3ba0ce271e2f5165ab6888211f5da5cfde67871714e
从本地文件导入
[root@open-Euler2 ~]# cat test_for_stop.tar | docker import - test1/ubuntu:latest
sha256:e2a387d82e57fc391ec26eff072da08afe93b82c48c321e6f8b61040636c8c44
[root@open-Euler2 ~]# docker images
REPOSITORY                    TAG       IMAGE ID       CREATED              SIZE
test1/ubuntu                  latest    e2a387d82e57   About a minute ago   78.1MB
test/ubuntu                   latest    287093209302   2 minutes ago        78.1MB
ubuntu                        latest    a04dc4851cbc   5 weeks ago          78.1MB
busybox                       latest    31311c5853a2   5 months ago         4.27MB
reg.yym.com/library/busybox   latest    31311c5853a2   5 months ago         4.27MB

实际上,既可以使用docker load命令来导入镜像存储文件到本地镜像库,也可以使用docker [container] import 命令来导入一个容器快照到本地镜像库。这两者的区别在于:容器快照文件将丢弃所有的历史记录和元数据信息(仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积更大。 此外,从容器快照文件导入时可以重新指定标签等元数据信息。

3.6 查看容器

本节主要介绍Docker容器的inspect、 top 和 stats子命令。

1 . 查看容器详情

查看容器详情可以使用docker container inspect [OPTIONS] CONTAINER [CONTAINER . .. ]子命令。

例如,查看某容器的具体信息,会以json格式返回包括容器Id、 创建时间、路径、状态、镜像、配置等在内的各项信息:

[root@open-Euler2 ~]# docker inspect 163622efdbfb 
[{"Id": "163622efdbfb20af07e9e6683329b10040cec7908da3aba32816198f74992cc9","Created": "2025-03-09T10:10:41.968207238Z","Path": "/bin/bash","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 5297,"ExitCode": 0,"Error": "","StartedAt": "2025-03-09T10:10:42.088967496Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:a04dc4851cbcbb42b54d1f52a41f5f9eca6a5fd03748c3f6eb2cbeb238ca99bd","ResolvConfPath": "/var/lib/docker/containers/163622efdbfb20af07e9e6683329b10040cec7908da3aba32816198f74992cc9/resolv.conf","HostnamePath": "/var/lib/docker/containers/163622efdbfb20af07e9e6683329b10040cec7908da3aba32816198f74992cc9/hostname","HostsPath": "/var/lib/docker/containers/163622efdbfb20af07e9e6683329b10040cec7908da3aba32816198f74992cc9/hosts","LogPath": "/var/lib/docker/containers/163622efdbfb20af07e9e6683329b10040cec7908da3aba32816198f74992cc9/163622efdbfb20af07e9e6683329b10040cec7908da3aba32816198f74992cc9-json.log","Name": "/sad_mclaren","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "bridge","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"ConsoleSize": [53,131],"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": [],"BlkioDeviceWriteBps": [],"BlkioDeviceReadIOps": [],"BlkioDeviceWriteIOps": [],"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": [],"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware","/sys/devices/virtual/powercap"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/3706374a37c42283828eddcc48dae753e2163b75bccd434ab95646f25f832fd8-init/diff:/var/lib/docker/overlay2/b84437fb662c47b2bd81a8cbd37c8fd5942cc53bda52ad4c04ca5ad9ee5734c5/diff","MergedDir": "/var/lib/docker/overlay2/3706374a37c42283828eddcc48dae753e2163b75bccd434ab95646f25f832fd8/merged","UpperDir": "/var/lib/docker/overlay2/3706374a37c42283828eddcc48dae753e2163b75bccd434ab95646f25f832fd8/diff","WorkDir": "/var/lib/docker/overlay2/3706374a37c42283828eddcc48dae753e2163b75bccd434ab95646f25f832fd8/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "163622efdbfb","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": true,"OpenStdin": true,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash"],"Image": "ubuntu","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.opencontainers.image.ref.name": "ubuntu","org.opencontainers.image.version": "24.04"}},"NetworkSettings": {"Bridge": "","SandboxID": "54ef1aa90e578ab95a9312a67535bcc54301fe61fecb0d359d2d7108156d4f1a","SandboxKey": "/var/run/docker/netns/54ef1aa90e57","Ports": {},"HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "411700c6f651957227448d3ed62631fa6b4225767abde9188c0aaa7e8a3fbe63","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"MacAddress": "02:42:ac:11:00:02","NetworkID": "510077d34566ca7d2e3594e34653a4b07424e460fd9fe8b4d0769fe7e6e8d758","EndpointID": "411700c6f651957227448d3ed62631fa6b4225767abde9188c0aaa7e8a3fbe63","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"DriverOpts": null,"DNSNames": null}}}}
]

2. 查看容器内进程

查看容器内进程可以使用docker [container] top [OPTIONS] CONTAINER [CONTAINER . .. ] 子命令。

这个子命令类似于Linux 系统中的 top命令,会打印出容器内的进程信息,包括PID、 用户、时间、命令等。 例如,查看某容器内的进程信息,命令如下:

[root@open-Euler2 ~]# docker top 163622efdbfb 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                5297                5276                0                   18:10               pts/0               00:00:00            /bin/bash

3. 查看统计信息

查看统计信息可以使用docker [container] stats [OPTIONS] [CONTAINER ... ] 子命令,会动态显示CPU、内存、存储、网络等使用情况的统计信息。

支持选项包括:

例如,查看当前运行中容器的系统资源使用统计:

[root@open-Euler2 ~]# docker stats 163622efdbfb CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O   PIDS
163622efdbfb   sad_mclaren   0.00%     592KiB / 1.394GiB   0.04%     1.44kB / 0B   0B / 0B     1

3.7 其他容器命令

本节主要介绍Docker容器的 cp、 diff、 port和update子命令。

1. 复制文件

container cp 命令支持在容器和主机之间复制文件。命令格式为docker [container] cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH |-。 支持的选项包括:

例如,将本地的路径data复制到test容器的/tmp路径下:

[root@open-Euler2 ~]# docker container cp test.txt 163622efdbfb:/tmp/
Successfully copied 2.05kB to 163622efdbfb:/tmp/

2. 查看变更

container diff 查看容器内文件系统的变更。 命令格式为 docker [container] diff CONTAINER。

例如,查看指定容器内的数据修改:

[root@open-Euler2 ~]# docker container diff 163622efdbfb
C /root
A /root/.bash_history
C /tmp
A /tmp/test.txt

3. 查看端口映射

container port 命令可以查看容器的端口映射情况。 命令格式为docker container port CONTAINER [PRIVATE_PORT[/PROTO]] 。例如,查看指定容器的端口映射情况:

[root@open-Euler2 ~]# docker container port 163622efdbfb
9000/tcp -> 0.0.0.0:9000

4. 更新配置

container update 命令可以更新容器的一些运行时配置,主要是一些资源限制份额。 命令格式为docker [container] update [OPTIONS] CONTAINER [CONTAINER .. . ] 。

支持的选项包括:

相关文章:

Docker基础入门

第 1 章&#xff1a;核心概念与安装配置 本章首先介绍Docker 的三大核心概念&#xff1a; 镜像 (Image)容器&#xff08;Container)仓库&#xff08;Repository&#xff09; 只有理解了这三个核心概念&#xff0c;才能顺利地理解Docker容器的整个生命周期。 随后&#xff0…...

【Linux】详谈 基础I/O

目录 一、理解文件 狭义的理解&#xff1a; 广义理解&#xff1a; 文件操作的归类认知 系统角度 二、系统文件I/O 2.1 标志位的传递 系统级接口open ​编辑 open返回值 写入文件 读文件 三、文件描述符 3.1&#xff08;0 & 1 & 2&#xff09; 3.2 文件描…...

爬虫案例七Python协程爬取视频

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Python协程爬取视频 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 爬虫案例七协程爬取视频 提示&#xff1a;以下是本篇文章正文…...

[20250304] 关于 RISC-V芯片 的介绍

[20250304] 关于 RISC-V芯片 的介绍 1. 调研报告 一、RISC-V 芯片结构分析 RISC-V 芯片基于开源指令集架构&#xff08;ISA&#xff09;&#xff0c;其核心优势在于模块化设计与高度灵活性。 指令集架构 基础指令集&#xff1a;包含 RV32I&#xff08;32 位&#xff09;、R…...

一学就会:A*算法详细介绍(Python)

&#x1f4e2;本篇文章是博主人工智能学习以及算法研究时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在&am…...

Hadoop、Hive、Spark的关系

Part1&#xff1a;Hadoop、Hive、Spark关系概览 1、MapReduce on Hadoop 和spark都是数据计算框架&#xff0c;一般认为spark的速度比MR快2-3倍。 2、mapreduce是数据计算的过程&#xff0c;map将一个任务分成多个小任务&#xff0c;reduce的部分将结果汇总之后返回。 3、HIv…...

Excel·VBA江西省预算一体化工资表一键处理

每月制作工资表导出为Excel后都需要调整格式&#xff0c;删除0数据的列、对工资表项目进行排序、打印设置等等&#xff0c;有些单位还分有“行政”、“事业”2个工资表就需要操作2次。显然&#xff0c;这种重复操作的问题&#xff0c;可以使用VBA代码解决 目录 代码使用说明1&a…...

23种设计模式简介

一、创建型&#xff08;5种&#xff09; 1.工厂方法 总店定义制作流程&#xff0c;分店各自实现特色披萨&#xff08;北京店-烤鸭披萨&#xff0c;上海店-蟹粉披萨&#xff09; 2.抽象工厂 套餐工厂&#xff08;家庭装含大披萨薯条&#xff0c;情侣装含双拼披萨红酒&#…...

python fire 库与 sys.argv 处理命令行参数

fire库 Python Fire 由Google开发&#xff0c;它使得命令行接口&#xff08;CLI&#xff09;的创建变得容易。使用Python Fire&#xff0c;可以将Python对象&#xff08;如类、函数或字典&#xff09;转换为可以从终端运行的命令行工具。这能够以一种简单而直观的方式与你的Py…...

PDF处理控件Aspose.PDF,如何实现企业级PDF处理

PDF处理为何成为开发者的“隐形雷区”&#xff1f; “手动调整200页PDF目录耗时3天&#xff0c;扫描件文字识别错误导致数据混乱&#xff0c;跨平台渲染格式崩坏引发客户投诉……” 作为开发者&#xff0c;你是否也在为PDF处理的复杂细节消耗大量精力&#xff1f;Aspose.PDF凭…...

Spring(1)——mvc概念,部分常用注解

1、什么是Spring Web MVC&#xff1f; Spring MVC 是一种基于 Java 的实现了 MVC&#xff08;Model-View-Controller&#xff0c;模型 - 视图 - 控制器&#xff09;设计模式的 Web 应用框架&#xff0c;它是 Spring 框架的一个重要组成部分&#xff0c;用于构建 Web 应用程序。…...

C语言(23)

字符串函数 11.strstr函数 1.1函数介绍&#xff1a; 头文件&#xff1a;string.h char *strstr ( const char * str1,const char *str2); 作用&#xff1a;在一个字符串&#xff08;str1&#xff09;中寻找另外一个字符串&#xff08;str2&#xff09;是否出现过 如果找到…...

Immich自托管服务的本地化部署与随时随地安全便捷在线访问数据

文章目录 前言1.关于Immich2.安装Docker3.本地部署Immich4.Immich体验5.安装cpolar内网穿透6.创建远程链接公网地址7.使用固定公网地址远程访问 前言 小伙伴们&#xff0c;你们好呀&#xff01;今天要给大家揭秘一个超炫的技能——如何把自家电脑变成私人云相册&#xff0c;并…...

基于SpringBoot的在线付费问答系统设计与实现(源码+SQL脚本+LW+部署讲解等)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

【Linux】信号处理以及补充知识

目录 一、信号被处理的时机&#xff1a; 1、理解&#xff1a; 2、内核态与用户态&#xff1a; 1、概念&#xff1a; 2、重谈地址空间&#xff1a; 3、处理时机&#xff1a; 补充知识&#xff1a; 1、sigaction&#xff1a; 2、函数重入&#xff1a; 3、volatile&…...

pandas——to_datatime用法

Pandas中pd.to_datetime的用法及示例 pd.to_datetime 是 Pandas 库中用于将字符串、整数或列表转换为日期时间&#xff08;datetime&#xff09;对象的核心函数。它在处理时间序列数据时至关重要&#xff0c;能够灵活解析多种日期格式并统一为标准时间类型。以下是其核心用法及…...

《DataWorks 深度洞察:量子机器学习重塑深度学习架构,决胜复杂数据战场》

在数字化浪潮汹涌澎湃的当下&#xff0c;大数据已然成为推动各行业发展的核心动力。身处这一时代洪流&#xff0c;企业对数据的处理与分析能力&#xff0c;直接关乎其竞争力的高低。阿里巴巴的DataWorks作为大数据领域的扛鼎之作&#xff0c;凭借强大的数据处理与分析能力&…...

Java 大视界 -- 基于 Java 的大数据实时数据处理框架性能评测与选型建议(121)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

多线程-JUC

简介 juc&#xff0c;java.util.concurrent包的简称&#xff0c;java1.5时引入。juc中提供了一系列的工具&#xff0c;可以更好地支持高并发任务 juc中提供的工具 可重入锁 ReentrantLock 可重入锁&#xff1a;ReentrantLock&#xff0c;可重入是指当一个线程获取到锁之后&…...

DeepSeek:中国AGI先锋,用技术重塑通用人工智能的未来

在ChatGPT掀起全球大模型热潮的背景下&#xff0c;中国AI领域涌现出一批极具创新力的技术公司&#xff0c;深度求索&#xff08;DeepSeek&#xff09;​便是其中的典型代表。这家以“探索未知、拓展智能边界”为使命的AI企业&#xff0c;凭借长文本理解、逻辑推理与多模态技术的…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...