Docker完整版(一)

Docker完整版(一)

一、Docker概述

官网 http://www.docker.com

中文官网 https://docker.p2hp.com || https://dockerdocs.cn

仓库(镜像网站) https://hub.docker.com

1.1、Docker简介

Docker 是一个开源的应用容器引擎,基于Go 语言并遵从Apache2.0协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux、windows机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口。

1.2、Docker的用途

  • 1、提供统一的运行环境

    • 在生产环境中,很多时候的开发、测试及上线环境都是不一样的,从而导致项目在不同阶段出现很多其他阶段所不存在的奇怪的问题。
    • Docker容器除了可以提供相同的应用外,还提供了该应用的统一运行环境,确保在任何宿主机上都可以跑出相同的结果。
  • 2、便捷的应用迁移

    • Docker 容器确保了统一的运行环境,几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
  • 3、超快的启动时间

    • 传统的虚拟机技术启动应用一般需要数分钟:首先需要启动虚拟机,再加载虚拟机操作系统,最后还需要手工启动应用。
    • Docker容器应用,由于直接运行在宿主机系统中,无需启动操作系统,因此可以做到秒级、甚至毫秒级的启动。
    • Docker容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。
    • Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个Docker 容器。
  • 4、更轻松的维护和扩展

    • Docker公司及各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础镜像进一步定制,大大降低了应用服务的镜像制作成本。
    • Docker使用的分层存储以及镜像的技术,使得应用重复的部分复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。
  • 5、持续交付和部署

    • 对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的在生产环境中部署该镜像。

1.3、容器与虚拟机的区别

Docker容器的本质就是通过容器虚拟技术虚拟出的一台主机,就像虚拟机一样。可以将应用及其运行环境部署在这台虚拟机上运行,但容器与虚拟机又有本质的不同。

名词解释:

  • infrastructure (基础服务)硬件
  • Host OS 主机操作系统
  • VM 虚拟机
  • Hypervisor (虚拟机监视器)虚拟层程序
  1. 实现原理技术不同 虚拟机是用来进行硬件资源划分的完美解决⽅案,利用的是硬件虚拟化技术,如此VT-x 、AMD-V会通过⼀个 hypervisor 层来实现对资源的彻底隔离。 而容器则是操作系统级别的虚拟化,利用的是内核的 Cgroup 和 Namespace 特性,此功能通过软件来实现,仅仅是进程本身就可以实现互相隔离,不需要任何辅助。
  2. 使用资源方面不同 Docker 容器与主机共享操作系统内核,不同的容器之间可以共享部分系统资源,因此更加轻量级, 消耗的资源更少。 虚拟机会独占分配给自己的资源,不存在资源共享,各个虚拟机之间近乎完全隔离,更加重量级,也会消耗更多的资源。
  3. 应用场景不同 若需要资源的完全隔离并且不考虑资源的消耗,可以使用虚拟机。若是想隔离进程并且需要运行大量进程实例,应该选择 Docker 容器。
特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为MB 一般为GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个

1.4、Docker系统架构

Docker使用客户端-服务器架构。Docker客户端与Docker守护进程进行对话,该守护进程完成了构建,运行和分发Docker容器的繁重工作。Docker客户端和守护程序可以 在同一系统上运行,或者您可以将Docker客户端连接到远程Docker守护程序。Docker客户端和守护程序在UNIX套接字或网络接口上使用REST API进行通信。另一个Docker客户端是Docker Compose,它使您可以处理由一组容器组成的应用程序。

Docker的基本组成:

Docker client 客户端

Docker server( docker daemon 守护进程)

Docker Image 镜像

Docker Container 容器

Docker Registry 仓库

  • Docker守护程序

    Docker守护程序(dockerd)侦听Docker API请求并管理Docker对象,例如图像,容器,网络和卷。守护程序还可以与其他守护程序通信以管理Docker服务。

  • Docker客户端

    Docker客户端(docker)是许多Docker用户与Docker交互的主要方式。当您使用诸如之类的命令时docker run,客户端会将这些命令发送到dockerd,以执行这些命令。该docker命令使用Docker API。Docker客户端可以与多个守护程序通信。

  • Docker注册表

    Docker注册表存储Docker映像。Docker Hub是任何人都可以使用的公共注册表,并且默认情况下,Docker已配置为在Docker Hub上查找映像。您甚至可以运行自己的私人注册表。

    使用docker pulldocker run命令时,将从配置的注册表中提取所需的图像。使用该docker push命令时,会将映像推送到已配置的注册表。

  • Docker对象

    使用Docker时,您正在创建和使用映像,容器,网络,卷,插件和其他对象。本节是其中一些对象的简要概述。

  • Image称为Docker镜像,就是一组文件。将这组文件运行起来就是容器Container。Image和Container可以看做是类和对象的关系。 从一个Image可以运行多个不同的Container

  • Docker镜像是一个存入镜像的仓库。通常被部署在互联网服务器或者云端。

    Docker Hub( https://hub.docker.com ) 提供了庞大的镜像集合供使用。

    Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

Docker 面向对象
容器 对象
镜像

1.5、Docker仓库

Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。

Docker Hub( https://hub.docker.com ) 提供了庞大的镜像集合供使用。

  • 公有 Docker Registry

Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。

最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像。除此以外,还有 CoreOSQuay.io,CoreOS 相关的镜像存储在这里;Google 的 Google Container RegistryKubernetes 的镜像使用的就是这个服务。

由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务( Registry Mirror ),这些镜像服务被称为加速器 。常见的有 阿里云加速器、DaoCloud 加速器 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。

国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 时速云镜像仓库网易云镜像服务DaoCloud 镜像市场、阿里云镜像库 等。

  • 私有 Docker Registry

除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。

开源的 Docker Registry 镜像只提供了 Docker Registry API 的服务端实现,足以支持 docker 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本 Docker Trusted Registry

中,提供了这些高级功能。

除了官方的 Docker Registry 外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,VMWare HarborSonatype Nexus

二、Docker引擎

2.1、Docker引擎架构

Docker引擎是用来运行和管理容器的核心软件,其现代架构由四部分主要组件构成:Docker Client,Dockerd、Containerd、Runc。

  • Docker Client:
    Dcoker客户端,Docker引擎提供的CLI工具,用于用户向 Docker 提交命令请求。
  • Dockerd:
    即Docker Daemon,在现代Dockerd中的主要包含的功能有镜像构建、镜像管理、REST API、核心网络及编排等。其通过 gRPC 与 Containerd 进行通信。
  • Containerd:
    即 Container Daemon,该项目的主要功能是管理容器的生命周期。不过,其本身并不会去创建容器,而是调用 Runc 来完成容器的创建。
    Docker 公司后来将 Containerd 项目捐献给了 CNCF(云原生基金会)。
  • Runc:
    即 Run Container,是 OCI(开放容器倡议基金会) 容器运行时规范的实现,Runc项目的目标之一就是与 OCI 规范保持一致。所以,Runc 所在层也称为 OCI 层。这使得 Docker Daemon 中不用再包含任何容器运行时的代码了,简化了 Docker Daemon。
    Runc 只有一个作用------创建容器,其本质是一个独立的容器运行时 CLI 工具。其在 fork 出一个容器子进程后会启动该容器进程。在容器进程启动完毕后,Runc 会自动退出。
  • Shim
    Shim是实现"Daemonless Container"不可或缺的工具,是容器与Docker Daemon 解耦,使得 Docker Daemon 的维护与升级不会影响到运行中的容器。
    每次创建容器时,Containerd 会先 fork 出 Shim 进程,再由 Shim 进程 fork 出 Runc 进程。当 Runc 自动退出之前,会先将新容器进程的父进程指定为相应的 Shim 进程。
    除了作为容器的父进程之外,Shim 进程还具有两个重要功能:
    1、保持所有 STDIN 和 STDOUT 流的开启状态,从而使得当 Docker Daemon 重启时,容器不会因为 Pipe 的关闭而终止。
    2、将容器的退出状态反馈给 Docker Daemon。

2.2、Docker引擎分类

在安装Docker之前需要先了解 Docker 官方对其版本的分类,分为大版本和小版本。

  • 大版本分为三类:Moby、社区版 Docker-CE 和 企业版 Docker-EE。
  • 小版本:从v1.13.1之后,Docker 的发布计划发生了变化,每个大版本下都出现了两个小版本 Edge 月版 与 Stable 季版。不过现在的官网中一般只能看到 Stable 版本。

2.3、Docker引擎的安装

Docker 可以安装在Windows、Linux、Mac 等系统中,但生产环境下,服务器使用 Linux 中的 CentOS 居多,下面就以 Docker 在 CentOS 中安装为例来安装并运用Docker。

1、操作系统要求

要安装Docker Engine,您需要一个CentOS 7或8及以上的维护版本。不支持或未测试存档版本。推荐使用CentOS7

centos-extras库必须启用。默认情况下,此存储库是启用的,但是如果已禁用它,则需要重新启用它。

2、安装方式

  • 大多数用户会 设置Docker的存储库并从中进行安装,以简化安装和升级任务。这是推荐的方法

  • 一些用户下载并手动安装RPM软件包, 并完全手动管理升级。这在诸如在无法访问互联网的空白系统上安装Docker的情况下很有用。

  • 在测试和开发环境中,一些用户选择使用自动 便利脚本来安装Docker。

3、查看系统版本

bash 复制代码
cat /etc/redhat-release
或者
cat /etc/system-release
或者使用uname命令

4、卸载旧版本

较旧的Docker版本称为dockerdocker-engine。如果已安装这些程序,请卸载它们以及相关的依赖项。

bash 复制代码
 sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

如果 yum 报告未安装这些软件包,则可以。

5、使用存储库安装

在新主机上首次安装Docker Engine之前,需要设置Docker存储库。之后,您可以从存储库安装和更新Docker。

①、安装yum-utils软件包(提供yum-config-manager 实用程序)并设置稳定的存储库。

bash 复制代码
 sudo yum install -y yum-utils
 
 # 官方地址但一般我们不推荐使用
 sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
 # 推荐使用国内镜像地址:阿里云源
 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

CentOS8执行yum命令报错如下:

bash 复制代码
cd /etc/yum.repos.d/

sed -i -e "s/mirrorlist=/#mirrorlist=/g" /etc/yum.repos.d/CentOS-Linux-*.repo

sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-Linux-*.repo

解决办法:参考链接

②、安装Docker引擎

安装最新版本的Docker Engine和容器

bash 复制代码
$ sudo yum install -y docker-ce docker-ce-cli containerd.io

③、查看Docker版本

bash 复制代码
$ docker version

④、启动Docker

bash 复制代码
# 非开机自启动
$ sudo systemctl start docker 

# 开机自启动
$ sudo systemctl enable docker

⑤、通过运行hello-world 映像来验证是否正确安装了Docker Engine

bash 复制代码
$ sudo docker run hello-world

6、卸载Docker Engine

①、卸载Docker Engine,CLI和Containerd软件包:

bash 复制代码
$ sudo yum remove docker-ce docker-ce-cli containerd.io

②、主机上的映像,容器,卷或自定义配置文件不会自动删除。要删除所有图像,容器和卷:

bash 复制代码
$ sudo rm -rf /var/lib/docker
$ sudo rm -rf /var/lib/containerd

必须手动删除所有自己的已编辑的配置文件。

2.4、Docker镜像加速器

鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,我们可以需要配置加速器来解决

Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:

1、Docker官方加速器

我们以 Docker 官方加速器进行介绍

https://docs.docker.com/registry/recipes/mirror/#use-case-the-china-registry-mirror

通过命令查看:在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

json 复制代码
{
  "registry-mirrors": ["https://<my-docker-mirror-host>"]
}

注意,一定要保证该文件符合 json 规范,否则 Docker 将不能启动

重启Docker:

bash 复制代码
sudo systemctl daemon-reload

sudo systemctl restart docker

2、阿里云加速器

阿里云的镜像源有个加速器,可以加速你获取容器的速度。这个加速器地址是每个人专属的。 网址: https://dev.aliyun.com/,登录阿里云个人帐号。

https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

可以通过修改 daemon 配置文件/etc/docker/daemon.json来使用加速器

bash 复制代码
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://自己的镜像地址"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

3、网易云加速器

无需注册网易云用户,地址:https://dyblogs.cn/gitbook/docker/_book/install/mirror.html

json 复制代码
{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com"
  ]
}

修改完重启Docker引擎即可。

最后检查加速器是否生效

配置加速器之后,如果拉取镜像仍然十分缓慢,请手动检查加速器配置是否生效,在命令行执行 docker info ,查看镜像地址是否匹配,如匹配,说明配置成功。

bash 复制代码
$ docker info

三、Docker镜像

3.1、镜像基础

1、镜像简介

镜像是一种轻量级、可执行的独立软件包,也可以说是一个精简的操作系统。镜像中包含应用软件及应用软件的运行环境,具体来说镜像包含运行某个软件所需的所有内容,包括代码、库、环境变量和配置文件等,几乎所有应用,直接打包为 Docker 镜像后就可以运行。

由于镜像的运行时是容器,容器设计的初衷就是快速和小巧,所以镜像通常都比较小,镜像中不包含内核,其共享宿主机的内核;镜像中只包含简单的 Shell,或没有 Shell。

2、镜像仓库分类

镜像中心中存储着大量的镜像仓库 Image Repository,每个镜像仓库中包含着大量相关镜像,根据这些镜像发布者的不同,形成了四类不同的镜像仓库。

(1)、Docker Official Image

Docker 官方镜像仓库。该仓库中的镜像由 Docker 官方构建发布,代码质量较高且安全,有较完善的文档。该类仓库中的镜像会及时更新,一般常用的系统,工具软件、中间件都有相应的官方镜像仓库。例如:Zookeeper、Redis、Nginx 等。

官方镜像仓库的名称 <repository> 一般直接为该类软件的名称 <software-name> 。

(2)、Verified Publisher

已验证发布者仓库。该仓库中的镜像由非 Docker 官方的第三方发布。但该第三方是由 Docker 公司审核认证过的,一般为大型企业,团体或组织。审核通过后,Docker 公司会向其颁发"VERIFIED PUBLISHER" 标识。这种仓库中镜像的质量还是有保证的。

除了官方镜像仓库,其他都是非官方镜像仓库。非官方镜像仓库名称 <repository> 一般由发布者用户名与软件名称两部分构成,形式为:<username> / <software-name> 。

(3)、Sponsored OSS

由 Docker 公司赞助开发的镜像仓库。该类仓库中的镜像也由非 Docker 官方的第三方发布,但该镜像的开发是由 Docker 公司赞助的。该类型的第三方一般为个人、团体或组织。这种仓库中镜像的质量也是有保证的。

(4)、无认证仓库

没有以上任何标识的仓库。这种仓库中镜像的质量参差不齐,质量上无法保证,在使用时需谨慎。

3、第三方镜像中心

镜像中心默认使用的都是 Docker 官方的 Docker Hub。不过镜像中心是可配置的,可以使用指定的第三方镜像中心。对于第三方镜像中心的仓库名称 <repository>由三部分构成: <domain-name>/ <username>/ <software-name>。其中的<domain-name> 指的是第三方镜像中心的域名或 IP 。

4、镜像定位 <repository>: <tag> 进行唯一定位。其中 <tag> 一般称为镜像的版本号。<tag> 中有一个比较特殊的版本------ latest 。如果不指定,默认 <tag> 即为 latest 版本。不过,虽然其字面意思是最新版,一般其也的确存放的是最新版,但并不能保证其真的就是最新版。

3.2、镜像相关命令

地址: https://dockerdocs.cn/engine/reference/commandline/docker/index.html

  1. docker pull
bash 复制代码
 docker pull [OPTIONS] NAME[:TAG|@DIGEST]


Docker 镜像可以由多个层组成。在上面的示例中,图像由单层组成;e756f3fdd6a3

图层可以被图像重复使用。例如,debian:bookworm图像与debian:latest。因此,拉取debian:bookworm图像只会拉取其元数据,而不是其图层,因为该图层已经存在于本地:

  1. docker images
bash 复制代码
 docker images [OPTIONS] [REPOSITORY[:TAG]]

默认值docker images将显示所有顶级图像,它们的存储库和标签以及它们的大小。

Docker映像具有中间层,可docker build通过允许缓存每个步骤来提高可重用性,减少磁盘使用并加快速度。这些中间层默认情况下不显示。

SIZE是由图像和所有其父图像所占用的空间累积。这也是docker save映像时创建的Tar文件的内容所使用的磁盘空间。

如果图像具有多个存储库名称或标签,则将多次列出该图像。该单个图像(通过其匹配可识别IMAGE IDSIZE仅用完列出的一次。

列出最近创建的图像:

bash 复制代码
$ docker images

REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
<none>                    <none>              77af4d6b9913        19 hours ago        1.089 GB
committ                   latest              b6fa739cedf5        19 hours ago        1.089 GB
<none>                    <none>              78a85c484f71        19 hours ago        1.089 GB
docker                    latest              30557a29d5ab        20 hours ago        1.089 GB
<none>                    <none>              5ed6274db6ce        24 hours ago        1.089 GB
postgres                  9                   746b819f315e        4 days ago          213.4 MB
postgres                  9.3                 746b819f315e        4 days ago          213.4 MB
postgres                  9.3.5               746b819f315e        4 days ago          213.4 MB
postgres                  latest              746b819f315e        4 days ago          213.4 MB

REPOSITORY:表示镜像的仓库源

TAG:镜像的标签

IMAGE ID:镜像ID

CREATED:镜像创建时间

SIZE:镜像大小

按名称和标签列出图像:

docker images命令采用一个可选[REPOSITORY[:TAG]]参数,该参数将列表限制为与该参数匹配的图像。如果您指定,REPOSITORY但不指定 TAG,则该docker images命令将列出给定存储库中的所有图像。

例如,要列出" java"存储库中的所有图像,请运行以下命令:

bash 复制代码
$ docker images java

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
java                8                   308e519aac60        6 days ago          824.5 MB
java                7                   493d82594c15        3 months ago        656.3 MB
java                latest              2711b1d6f3aa        5 months ago        603.9 MB

[REPOSITORY[:TAG]]值必须是"完全匹配"。例如,这意味着 docker images jav与图像不匹配java

如果同时提供REPOSITORYTAG,则仅列出与该存储库和标签匹配的图像。要在带有标签" 8"的" java"存储库中查找所有本地图像,可以使用:

bash 复制代码
$ docker images java:8

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
java                8                   308e519aac60        6 days ago          824.5 MB

如果没有匹配项REPOSITORY[:TAG],则列表为空。

bash 复制代码
$ docker images java:0

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

虚悬镜像

镜像列表中,还可以看到一个特殊的镜像,这个镜像既没有仓库名,也没有标签,均为<none>

这个镜像原本是有镜像名和标签的,比如原来为 tomcat:8.0,随着官方镜像维护,发布了新版本后,重新 docker pull tomcat:8.0 时,tomcat:8.0 这个镜像名被转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消,从而成为了 。除了 docker pull 可能导致这种情况,docker build 也同样可以导致这种现象。由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image) 。 一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用命令:docker image prune 删除。

  1. docker search
bash 复制代码
 docker search [OPTIONS] TERM

按名称搜索镜像:

bash 复制代码
$ docker search busybox

NAME                             DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
busybox                          Busybox base image.                             316       [OK]
progrium/busybox                                                                 50                   [OK]
radial/busyboxplus               Full-chain, Internet enabled, busybox made...   8                    [OK]
odise/busybox-python                                                             2                    [OK]
azukiapp/busybox                 This image is meant to be used as the base...   2                    [OK]
ofayau/busybox-jvm               Prepare busybox to install a 32 bits JVM.       1                    [OK]
shingonoide/archlinux-busybox    Arch Linux, a lightweight and flexible Lin...   1                    [OK]
odise/busybox-curl                                                               1                    [OK]
ofayau/busybox-libc32            Busybox with 32 bits (and 64 bits) libs         1                    [OK]
peelsky/zulu-openjdk-busybox                                                     1                    [OK]
skomma/busybox-data              Docker image suitable for data volume cont...   1                    [OK]
elektritter/busybox-teamspeak    Lightweight teamspeak3 container based on...    1                    [OK]
socketplane/busybox                                                              1                    [OK]
oveits/docker-nginx-busybox      This is a tiny NginX docker image based on...   0                    [OK]
ggtools/busybox-ubuntu           Busybox ubuntu version with extra goodies       0                    [OK]
nikfoundas/busybox-confd         Minimal busybox based distribution of confd     0                    [OK]
openshift/busybox-http-app                                                       0                    [OK]
jllopis/busybox                                                                  0                    [OK]
swyckoff/busybox                                                                 0                    [OK]
powellquiring/busybox                                                            0                    [OK]
williamyeh/busybox-sh            Docker image for BusyBox's sh                   0                    [OK]
simplexsys/busybox-cli-powered   Docker busybox images, with a few often us...   0                    [OK]
fhisamoto/busybox-java           Busybox java                                    0                    [OK]
scottabernethy/busybox                                                           0                    [OK]
marclop/busybox-solr

其中 AUTOMATED 表示当前镜像是否是"自动化镜像"。什么是自动化镜像?就是使用 Docker Hub 连接一个包含 Dockerfile 文件(专门构建镜像用的文件)的 GitHub 仓库或者 Bitbucket 仓库的源码托管平台,然后 Docker Hub 就会自动根据 Dockerfile 内容构建镜像。这种构建出的镜像会被标记为 AUTOMATED,这种构建镜像的方式称为 Trusted Build(受信构建)。只要 Dockerfile 文件内容发生变化,那么 Docker Hub 就会构建出新的镜像。

  1. docker rmi
bash 复制代码
 docker rmi [OPTIONS] IMAGE [IMAGE...]

从主机节点删除(并取消标记)一幅或多幅图像。如果图像具有多个标签,则将此命令与标签一起使用时,只会删除该标签。如果标签是图像的唯一标签,则图像和标签都将被删除。

这不会从注册表中删除图像。除非使用该-f选项,否则无法删除正在运行的容器的映像。要查看主机上的所有图像,请使用docker imagesdocker image ls命令。

删除单个 docker rmi -f 镜像ID

删除多个 docker rmi -f 镜像ID1 镜像ID2docker rmi -f 镜像名:[tag] 镜像名:[tag]

删除全部 docker rmi -f $(docker images -q)

  1. docker save
bash 复制代码
 docker save [OPTIONS] IMAGE [IMAGE...]

将一个或多个图像保存到tar存档(默认情况下流式传输到STDOUT)

名称,简写 默认 描述
--output , -o 写入文件,而不是STDOUT

例子:

bash 复制代码
$ docker save busybox > busybox.tar

$ ls -sh busybox.tar

2.7M busybox.tar

$ docker save --output busybox.tar busybox

$ ls -sh busybox.tar

2.7M busybox.tar

$ docker save -o fedora-all.tar fedora

$ docker save -o fedora-latest.tar fedora:latest
  1. docker load
bash 复制代码
 docker load [OPTIONS]

从tar存档或STDIN加载图像

名称,简写 默认 描述
--input , -i 从tar存档文件中读取,而不是从STDIN中读取
--quiet , -q 抑制负载输出

例子:

bash 复制代码
$ docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

$ docker load < busybox.tar.gz

Loaded image: busybox:latest
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              769b9341d937        7 weeks ago         2.489 MB

$ docker load --input fedora.tar

Loaded image: fedora:rawhide

Loaded image: fedora:20

$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              769b9341d937        7 weeks ago         2.489 MB
fedora              rawhide             0d20aec6529d        7 weeks ago         387 MB
fedora              20                  58394af37342        7 weeks ago         385.5 MB
fedora              heisenbug           58394af37342        7 weeks ago         385.5 MB
fedora              latest              58394af37342        7 weeks ago         385.5 MB

3.3、镜像分层

  1. 什么是分层

Docker 镜像由一些松耦合(关系不怎么紧密)的只读镜像层组成,Docker Daemon 负责堆叠这些镜像层,并将它们关联为一个统一的整体,即对外表现出的是一个独立的对象。

通过 docker pull 命令拉取指定的镜像时,每个 Pull complete 结尾的行就代表下载完毕了一个镜像层。

  1. 为什么分层

采用这种分层结构的优势很多,例如,每个分层都是只读的,所有分层的修改都是以新分层的形式出现,并不会破坏原分层内容;再如,每个分层只记录变更内容,所以有利于节省存储空间等。

不过,分层结构的最大好处是,在不同镜像间实现资源共享 ,即不同镜像对相同下层镜像的复用。对于 docker pull 命令,其在拉取之前会先获取到其要拉取镜像的所有ImageID,然后在本地查找是否存在这些分层。如果存在,则不再进行拉取,而是共享本地的该分层。大大节省了存储空间与网络带宽,提升了拉取效率。

  1. 镜像层构成

每个镜像层由两部分构成:镜像文件系统与镜像 json 文件。这两部分具有相同的 ImageID。

镜像文件系统就是对镜像占有的磁盘空间进行管理的文件系统,拥有该镜像所有镜像层的数据内容。而镜像 json 文件则是用于描述镜像的相关属性的集合,通过 docker inspect [镜像]就可以直观看到。

  1. 镜像 FS 构成

Docker 镜像的 FS(文件系统)构成是指镜像是由多层只读镜像层组成的,每层都完成了特定的功能。而这些只读镜像层根据其位置与功能的不同可以分为两类:基础镜像层和扩展镜像层。

(1)基础镜像层

所有镜像的最下层都具有一个可以看得到的基础镜像层 Base Image ,基础镜像层的文件系统称为根文件系统 rootfs。而 rootfs 则是建立在 Linux 系统中 "看不到的"引导文件系统 bootfs 之上

(2)扩展镜像层

在基础镜像层之上的镜像层称为扩展镜像层。顾名思义,其是对基础镜像层功能的扩展。在 Dockerfile 中,每条指令都是用于完成某项特定功能的,而每条指令都会生成一个扩展镜像层。

(3)容器层

一旦镜像运行了起来就形成了容器,而容器就是一个运行中的 Linux 系统,其也是具有文件系统的。容器的这个文件系统是在 docker 镜像最外层之上增加了一个可读写的容器层,对文件的任何更改都只存在于容器层。因此任何对容器的操作都不会影响到镜像本身。

容器层如果需要修改某个文件,系统会从容器层开始向下一层层的查找该文件,直到找到为止。任何对于文件的操作都会记录在容器层。例如,要修改某文件,容器层会首先把在镜像层找到的文件 copy 到容器层,然后再进行修改。删除文件也只会将存在于容器层中的文件副本删除。

可以看出,Docker 容器就是一个叠加后的文件系统,而这个容器层称为 Union File System,联合文件系统。

  1. LinuxOS启动过程(扩展)

现在操作系统都是C/S模式的微内核架构,由两大部分构成:内核(Server)与服务模块(Client)。

Linux 的 bootfs 文件系统由两部分构成:bootloader 与 kernel。

各个容器中的 rootfs 就是由宿主机的 kernel 驱动的。

3.4、镜像摘要

每个镜像都有一个长度为 64 位的 16 进制字符串作为其摘要 digest。

  1. 查看摘要
    docker pull 镜像结束之后会给出该拉取的镜像的摘要 digest.

    通过 docker inspect 命令可以查看指定镜像的详细信息。其中包含该镜像的摘要信息。
  2. 摘要是什么
    摘要,即 digest,是镜像内容的一个 Hash 值,即所谓的 Content Hash(内容散列) 。只要镜像内容发生了变更,其内容散列值就一定会发生改变。也就是说,一个镜像一旦创建完毕,其 digest 就不会发生改变了,因为镜像是只读的。
    Docker 默认采用的 Hash 算法是 SHA256,即Hash值是一个长度为256位的二进制值。Docker 使用 16 进制表示,即变为了长度为 64 为的字符串。
  3. 摘要有何用
    摘要的主要作用是区分相同 <repository>:<tag> 的不同镜像。
    例如镜像 xxx:2.8 在生产运行过程中发现存在一个 BUG 。现对其进行了修复,并使用原来标签将其 push 回了仓库,那么原镜像被覆盖。但生产环境中遗留了大量运行中的修复前的镜像的容器。此时,通过镜像标签已经无法区分镜像是修改前的还是修复后的了,因为它们的标签是相同的。此时通过查看镜像的 digest 就可以区分出修改前后的版本,因为内容发生了变化,digest 一定会变。
    为了确保再次拉取到的是修复后的镜像,可通过 digest 进行镜像的拉取。其用法是:docker pull <repository>@<digest>
  4. 分发散列值
    在 push 和 pull 镜像时,都会对镜像进行压缩以减少网络带宽和传输时长。但亚索会改变镜像内容,会导致经过网络传输后,出现镜像内容与其 digest 不相符的问题。
    为了避免该问题,Docker 又为镜像配置了 Distribution Hash(分发散列值)。在镜像被压缩后立即计算分发散列值,然后使该值随压缩过的镜像一同进行发送。在接收方接收后,立即计算压缩镜像的分发散列值,再与携带的分发散列值对比。如果相同,则说明传输没有问题。

3.5、多架构镜像

  1. 什么叫多架构镜像
    Multi-architecture Image(多架构镜像),是某 <repository> 中的某 <tag> 镜像针对不同操作系统/系统架构的不同镜像实现。即多架构镜像中包含的镜像的 <repository>:<tag> 都是相同的,但它们针对的操作系统/系统架构是不同的。

  2. 多架构镜像原理

    无论用户使用的是什么操作系统/系统架构,其通过 docker pull命令拉取到的一定是针对该操作系统/系统架构的镜像,无需用户自己考虑操作系统/系统架构的问题。Docker Hub 能够根据提交的 pull 请求的 Docker 系统的架构自动选择其对应的镜像。

    在 Docker Hub 中,镜像的多架构信息保存在 Manifest 文件中。在拉取镜像时,Docker 会随着 pull 命令将当前 Docker 系统的 OS 与架构信息一并提交给 Docker Hub。Docker Hub 首先回根据镜像的 <repository>:<tag> 查找是否存在 Manifest。如果不存在,则直接查找并返回 <repository>:<tag> 镜像即可;如果存在,则会在 Manifest 中查找是否存在指定系统/架构的镜像。如果存在该系统/架构,则根据 Manifest 中记录的地址找到该镜像的位置。

四、Docker容器

4.1、容器基础

  1. 容器启动流程

    通过docker run命令可以启动运行一个容器。该命令在执行时首先会在本地查找指定的镜像,如果找到了,则直接启动,否则会到镜像中心查找。如果镜像中心存在该镜像,则会下载到本地并启动,否则直接报错。
    如果再与多架构镜像原理相整合,则就形成了完整的容器启动流程。
  2. 容器运行本质
    Docker 容器存在的意义就是为了运行容器中的应用,对外提供服务,所以启动容器的目的就是启动运行该容器中的应用。容器中的应用运行完毕后,容器就会自动终止。所以,如果不想让容器启动后立即终止运行,通常采用的方式有两种,是应用处于与用户交互的状态 或者等待状态

4.2、容器创建并启动命令

对于容器的运行,有两种运行模式:交互模式守护进程模式。下面通过运行Ubuntu 与 Tomcat 来演示这两种运行模式的不用。

  1. 以交互模式运行Ubuntu

    bash 复制代码
    docker run --name myubuntu -it ubuntu /bin/bash
  2. 以交互模式运行Tomcat

    通过ls -l命令查看Tomcat根目录下的文件,注意不支持ll命令。

    -p 8081:8080表示将8080端口映射到8081,通过访问8081端口访问运行的Tomcat容器。

    也可以使用 -P 大写字母,表示让系统自动分配映射端口号,可通过命令docker ps -a查看详细信息。

    使用快捷键Ctrl + p + q以不结束应用的方式退出当前应用。

  3. 以守护进程方式运行容器

4.3、容器创建命令

bash 复制代码
docker create --name tom -p 8081:8080 tomcat:8.5.49

docker create命令仅创建容器但不启动,其用法与docker run非常相似。注意,其没有-d选项。

4.4、容器退出命令

退出容器指的是退出以交互模式运行的容器。分为两种退出方式:

  1. 退出并停止容器exit
    在容器运行命令中再运行 exit 命令后,通过 docker ps -a 可以查看到该容器已经退出了。
  2. 退出不停止容器Ctrl + P + Q
    使用快捷键 Ctrl + P + Q 能够返回到宿主机命令行。在通过 docker ps -a 可以查看到该容器是 UP 状态,说明容器退出了但没有停止。

4.5、容器状态查看命令

  1. 查看所有正在运行的容器:

    bash 复制代码
    docker ps
  2. 查看所有容器:

    bash 复制代码
    docker ps --a
  3. 查看所有容器的ID:

    bash 复制代码
    # 查看所有处于运行状态的容器的ID
    docker ps --q
    
    # 查看所有容器的ID
    docker ps --qa
  4. 查看最后创建的容器:

    bash 复制代码
    docker ps --l
  5. 查看最后创建的n个容器:

    bash 复制代码
    docker ps --n 2

4.6、容器再运行命令

当我们以分离模式运行了一个容器,或以交互模式运行了一个容器,但容器内部执行的命令占用了交互命令行,而此时我们又想进入到容器中对容器内部进行一些操作,此时就需要用到exec/attach命令了。

注意,它们只能对正在运行的容器进行操作。

  1. 新建进程进入容器exec

    bash 复制代码
    docker exec -it mytom2 /bin/bash

    该命令也用于进入到了运行状态的容器中。
    此时查看正在运行的容器,发现mytom2容器并未退出。说明exec命令会创建一个新的独立于容器的进程,而exit命令仅用于结束该新建进程。

  2. 外部操作容器exec

    bash 复制代码
    docker exec -it mytom2 ls -l

    前面是在进入到容器后才对容器进行操作的,也可以不进入容器直接对容器内部进行操作。例如仅想查看tomcat容器中工作目录中所包含的文件,直接在exec命令后紧跟要执行的命令即可直接看到其结果。

  3. 容器附加标准输入attach

    bash 复制代码
    docker run --name myubuntu -it ubuntu
    
    docker attach myubuntu

    对于该命令的测试,首先以交互方式运行一个ubuntu容器docker run --name myubuntu -it ubuntu,然后使用Ctrl + P + Q命令退出但不停止容器。

    然后使用attach命令进入容器命令行。此时,再使用exit命令退出容器。然后会发现容器也停止了。由于exit命令的作用是,结束当前进程,所以说明attach命令并没有另外再创建新的进程,而是使用了容器进程,exit命令退出了当前进程,也就退出了容器。

  4. 容器附加标准输出attach

    bash 复制代码
    docker run --name mytom -d tomcat:8.5.49
    
    docker attach mytom

    启动一个tomcat容器docker run --name mytom -d tomcat:8.5.49,指定容器名称为mytom。然后通过docker attach命令则可看到如下场景:占用了命令行,且没有任何输出,即使通过浏览器访问该tomcat也没有任何输出。此时的mytom容器已经附加了标准输出,只不过,其输出的是tomcat的启停日志信息。

    通过Ctrl + C可结束tomcat,此时可看到停止日志显示了出来。但由于此时的tomcat已经停止,tomcat容器已经退出,所以该docker attach命令也就随之结束了。

4.7、容器内进程查看命令

bash 复制代码
docker top [容器]

docker top [容器] | grep 711

命令用于查看指定的运行的容器中正在运行的进程详情,这个详情包括当前这个进程正在运行的命令。

当然,如果容器中运行的进程较多,也可以通过grep对结果进行过滤。

4.8、容器日志查看命令

docker logs [容器]可以查看指定容器中应用的运行日志,无论该容器是运行还是停止状态。

  1. 查看所有日志:查看的是所有容器中应用的运行日志。这个日志对于不同的容器来说,其日志内容是不同的。由docker run 命令的[command]决定(如果没有则由Dockerfile中的CMD指令决定)。

    bash 复制代码
    docker logs [容器]
  2. 查看最后的日志:通过添加选项-n--tail可以指定要显示的最后几条日志。

    bash 复制代码
    docker logs -n 3 [容器]
  3. 查看指定时间内的日志:通过添加选项--since可以指定要显示自从指定时间以来的日志。这个时间可以是一个绝对时间,也可以是一个相对时长。

    • 使用绝对时间:显示自从2023年1月1日后产生日志的最后3条。

      bash 复制代码
      docker logs --since 2023-01-01 --tail 3 [容器]
      或者
      docker logs --since='2023-01-01' --tail=3 [容器]
    • 使用相对时间:显示自从30分钟之前产生日志中的最后3条。其中m表示分,可以使用s表示秒,h表示小时。

      bash 复制代码
      docker logs --since 30m --tail 3 [容器]
      或者
      docker logs --since=30m --tail=3 [容器]
  4. 查看指定时间外的日志:通过添加选项--until可以指定要显示截止到指定时间之前的日志。这个时间可以是一个绝对时间,也可以是一个相对时长。

    • 使用绝对时间:显示截止到2023年3月10日前产生日志的最后3条。

      bash 复制代码
      docker logs --until 2023-03-10 --tail 3 tom
      或则
      docker logs --until="2023-03-10" --tail=3 tom
    • 使用的是相对时长:显示截止到5分钟之前产生日志中的最后3条。

      bash 复制代码
      docker logs --until 5m --tail 3 tom
      或则
      docker logs --until=5m --tail=3 tom
  5. 查看日志时间戳:

    bash 复制代码
    docker logs -t --tail 5 tom

    如果要查看某日志的详细时间戳,可以使用-t选项。命令docker logs -t --tail 5 tom查看的是最后5条日志的时间戳,并与不添加-t的输出进行了对比。

  6. 查看动态日志:

    bash 复制代码
    docker logs -f --tail 3 tom

    通过添加选项-f可以查看运行中 容器的动态日志。其会占用命令行,一直等待日志的输出。

4.9、容器启停命令

param:可以是容器名称或者容器ID

  1. 启动start:

    bash 复制代码
    docker start param

    通过docker start param命令可以启动已经停止的指定容器,这个容器可以通过容器名称指定,也可以通过容器ID指定。

  2. 重启restart:

    bash 复制代码
    docker restart param

    通过docker restart param命令可以重启处于运行状态的指定容器。

  3. 优雅停止stop:

    bash 复制代码
    docker stop param

    通过docker stop param命令可以优雅停止指定容器。所谓优雅停止是指,若当前容器正在被其它进程访问,则在访问结束后再停止。

  4. 强制停止kill:

    bash 复制代码
    docker kill param

    通过docker kill param命令可以强制停止指定容器。所谓强制停止是指,无论容器当前是否被其它进程访问都直接停止。

  5. 停止所有容器:

    bash 复制代码
    docker kill $(docker ps -qa)
    或则
    docker stop $(docker ps -qa)

    无论是docker kill $(docker ps -qa)还是docker stop $(docker ps -qa),都可以停止所有容器。因为这两个命令的参数都可以是容器ID。

  6. 暂停pause:

    bash 复制代码
    docker pause param

    通过命令可以暂停容器对外提供服务

  7. 解除暂停unpause:

    bash 复制代码
    docker unpause param

    通过命令可解除容器的暂停服务状态

4.10、容器删除命令

  1. 正常删除:

    bash 复制代码
    docker rm [容器]

    命令在默认情况下,要删除的容器必须是已经停止的容器。当然,这个容器可以使用容器名或容器ID指定。

  2. 强制删除:

    bash 复制代码
    docker rm -f [容器]

    在docker rm命令中添加-f可实现强制删除容器。即无论容器是否停止都会删除。

  3. 删除所有容器:

    bash 复制代码
    docker rm -f $(docker ps -aq)

4.11、容器与宿主机文件传递cp

docker cp命令可以完成容器与宿主机中文件/目录的相互复制,无论该容器是否处于运行状态。

  1. 将容器中文件复制到宿主机:

    bash 复制代码
    docker cp tom:/usr/local/tomcat/webapps ./

    将tom容器的tomcat中的webapps目录复制到宿主机的当前目录。

  2. 将宿主机文件复制到容器:

    bash 复制代码
    docker cp hello.txt tom:/usr/local/tomcat/webapps

    将宿主机中当前目录下的hello.txt文件复制到mytomcat容器的/usr/local/tomcat/webapps目录中,并查看容器中是否已经存在了hello.txt文件。

  3. 不支持容器间的cp。

4.12、提交容器为镜像

通过docker commit命令可以将一个容器文件系统的当前快照生成为一个新的镜像。

需求:这里要在一个Ubuntu容器或Centos容器中安装net-tools工具包。为了方便演示,这里选择CentOS容器,直接使用yum安装。当然,如果使用Ubuntu容器也可以,要么直接使用apt-get安装net-tools,要么先安装yum后再安装net-tools。

  1. 修改容器层

    首先创建并启动一个容器,例如centos:7镜像的容器。然后发现该容器中是没有安装ifconfig命令的。

    bash 复制代码
    docker run --name mycentos -it centos:7

    安装net-tools网络工具命令包。

    bash 复制代码
    yum install -y net-tools

    此时再使用ifconfig,已经可以使用了。

  2. 生成镜像

    下面要将已经安装了ifconfig命令的容器生成为一个镜像,以方便后期自己或他人使用。

    bash 复制代码
    # docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
    docker commit -a "Corgi <Corgi@163.com>" -m "Added net-tools" mycentos centos7:net-tools

    这里指定生成的镜像<repository>的为centos7,<tag>为net-tools。

  3. 使用新镜像

    bash 复制代码
    docker run --name mycuscentos7 -it centos7:net-tools

    下面是使用新生成的镜像创建并启动一个容器,发现其中的ifconfig命令是可以使用的。

  4. 生成悬虚镜像

    悬虚镜像,即没有<repository>与<tag>的镜像。悬虚镜像一般都是由于某些失误操作或其它一些操作而生成的副产物,一般是要被清除掉的。如果非要使用悬虚镜像,那只能通过其ImageID来使用了。

    下面要将已经安装了ifconfig命令的容器生成为一个悬虚镜像,即没有指定<repository>与<tag>。

    bash 复制代码
    commit -a "Corgi <Corgi@163.com>" -m "Added net-tools" mycentos

4.13、导入/导出镜像

docker savedocker load命令,分别用于导出/导入镜像
docker exportdocker import命令,分别用于导出/导入容器

  1. 导出容器export

    bash 复制代码
    docker export -o tomcat8.tar mytom

    将一个容器的文件系统导出为tar文件。将tomcat:8.5.49镜像的容器tom导出到当前/root目录的tomcat8.tar文件中。

  2. 导入容器import

    bash 复制代码
    docker import tomcat8.tar tom8:1.0

    命令用于根据指定的tar文件构建新的镜像。将当前目录下的tomcat8.tar导出为镜像tom8:1.0。

  3. 与save/load命令的对比

    • export与save
      • export作用于容器;save作用于镜像,但它们导出的结果都为tar文件
      • export一次只能对一个容器进行导出;save一次可以对多个镜像进行导出
      • export只是对当前容器的文件系统快照进行导出,其会丢弃原镜像的所有历史记录与元数据信息;save则是保存了原镜像的完整记录
    • import与load
      • import导入的是容器包;load加载的是镜像包,但最终都会恢复为镜像
      • import恢复的镜像只包含当前镜像一层;load恢复的镜像与原镜像的分层是完全相同的
      • import恢复的镜像就是新构建的镜像,与原镜像的ImageID不同;load恢复的镜像与原镜像是同一个镜像,即ImageID相同
      • import可以为导入的镜像指定<repository>与<tag>;load加载的镜像不能指定<repository>与<tag>,<repository>与<tag>原镜像的相同
  4. 与docker commit的对比

    • 相同点:docker export + docker import会将一个容器变为一个镜像,docker commit也可以将一个容器变一个镜像。
    • 不同点:docker export + docker import恢复的镜像仅包含原容器生成的一层分层,docker commit生成的镜像中包含容器的原镜像的所有分层信息。

4.14、docker system 命令集

docker system 是一个命令集,其有四个子命令。

  1. 查看docker磁盘占用数据

    bash 复制代码
    # 用于查看docker各部分占用情况
    docker system df
    
    # 添加-v选项,获取更为详细的占用情况
    docker system df -v
  2. 查看docker发生过的事件

    docker system events命令等价于docker events命令,可查看指定日间之内(--since)或之外(--until)在docker上所发生的所有事件。这些事件包含运行过的命令有docker内部执行的一些操作。

  3. 查看docker详情

    docker system info命令等价于docker info,用于查看当前docker的详情。包括docker Client与docker Server详情。其中docker server包含镜像、容器情况,docker所在系统的软硬件情况等。

  4. 删除docker中的无用数据

    bash 复制代码
    # 删除docker中的无用数据,这些无用数据包含已经停止的容器、没有任何连接容器的网络、悬空镜像,及悬空镜像的构建缓存
    docker system prune
相关推荐
Lary_Rock26 分钟前
RK3576 LINUX RKNN SDK 测试
linux·运维·服务器
云飞云共享云桌面2 小时前
8位机械工程师如何共享一台图形工作站算力?
linux·服务器·网络
昌sit!3 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
追风林4 小时前
mac 本地docker-mysql主从复制部署
mysql·macos·docker
一坨阿亮4 小时前
Linux 使用中的问题
linux·运维
dsywws5 小时前
Linux学习笔记之vim入门
linux·笔记·学习
A ?Charis6 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
幺零九零零6 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
城南vision6 小时前
Docker学习—Docker核心概念总结
java·学习·docker