Docker五部曲之一:容器术语介绍

文章目录

  • 前言
  • 背景
  • 基本术语
    • 容器镜像
    • 容器镜像格式
    • 容器引擎
    • 容器
    • 容器主机
    • 注册中心
    • 容器编排
  • 进阶术语
    • 容器运行时
    • 镜像层
    • 标签
    • 存储库
    • 名称空间
  • 参考

前言

本文内容翻译自参考文献。

背景

要理解容器术语,重要的是要精确地理解容器是什么。容器实际上是两个不同的东西。像普通的Linux程序一样,容器实际上有两种状态——休眠和运行。在休眠状态下,容器是保存在磁盘上的一个文件(或一组文件)。这称为容器镜像或容器存储库。当您输入启动容器的命令时,容器引擎将解包所需的文件和元数据,然后将它们交给Linux内核。启动容器与启动普通Linux进程非常相似,需要通过API调用Liunx内核。这个API调用通常会启动额外的隔离并挂载容器镜像中文件的一个副本。一旦运行,容器就只是一个Linux进程。启动容器的过程,以及磁盘上的镜像格式,都由标准定义和管理。

有几种相互竞争的容器镜像格式(Docker, Appc, LXD),但业界正在推进开放容器倡议下的标准,有时简称为开放容器或OCI。OCI的范围包括一个容器镜像格式规范,它定义了容器镜像的磁盘格式以及元数据,元数据定义了硬件架构和操作系统(Linux、Windows等)。标准的容器镜像格式使软件生态系统蓬勃发展——不同的独立贡献者、项目和供应商能够构建可互操作的镜像和工具。用户需要签名、扫描、构建、运行、移动和管理容器镜像的工具之间的互操作性。

也有几个竞争的容器引擎,包括Docker, CRI-O, Railcar, RKT, LXC。这些容器引擎获取容器镜像并将其转换为容器(也就是正在运行的进程)。这是由OCI的范围控制的,其中包括容器运行时规范和称为RunC的参考运行时实现。此参考实现是开源的,由社区开发模型管理,并且通常被许多容器引擎用于在创建容器时与主机内核通信。

针对OCI容器镜像格式规范和容器运行时规范的工具确保了容器平台、容器引擎和云提供商和内部架构的支持工具的广泛生态系统之间的可移植性。了解容器的术语、容器标准和构建块的体系结构,将确保您能够与其他架构师进行沟通,以构建可扩展和可支持的容器化应用程序和环境,以便在未来几年高效地运行容器。

基本术语

容器镜像

从最简单的定义来看,容器镜像是一个从注册中心拉下的文件,在启动容器时用作本地挂载点。容器社区经常使用“容器镜像”,但是这种命名法可能会让人很困惑。Docker、RKT甚至LXD都是基于提取远程文件并将其作为容器运行的概念进行操作的。这些技术都以不同的方式处理容器镜像。LXD提取单个容器镜像(单层),而Docker和RKT使用基于OCI的镜像,这些镜像可以由多层组成。

从技术上讲,它比注册表服务器上的单个文件复杂得多。当人们使用术语“容器镜像”时,他们通常指的是Repository,指的是多个容器镜像层的一束,以及提供有关这些层的额外信息的元数据。

容器镜像的概念中隐含着容器镜像格式的概念。

容器镜像格式

历史上,每个容器引擎都有自己的容器镜像格式。LXD、RKT和Docker都有自己的镜像格式。有些是由一层组成的,而有些是由树结构中的一堆层组成的。今天,几乎所有的主要工具和引擎都转向了开放容器倡议(Open Container Initiative, OCI)定义的格式。这种镜像格式定义了容器镜像中的层和元数据。本质上,OCI镜像格式定义了由每个层的tar文件和清单组成的容器镜像。包含元数据的Json文件。

开放容器倡议(Open Container Initiative, OCI)最初基于Docker V2镜像格式,已经成功地统一了容器引擎、云提供商和工具提供商(安全扫描、签名、构建和移动)的广泛生态系统。这将有助于保护用户在他们的环境中投资知识和工具。

容器引擎

容器引擎是一个接受用户请求(包括命令行选项)、提取镜像并从最终用户的角度运行容器的软件。容器引擎有很多,包括docker、RKT、CRI-O和LXD。此外,许多云提供商、平台即服务(PaaS)和容器平台都有自己内置的容器引擎,它们使用Docker或OCI兼容的容器镜像。拥有行业标准的容器镜像格式允许所有这些不同平台之间的互操作性。

再深入一层,大多数容器引擎实际上并不运行容器,它们依赖于像runc这样兼容OCI的运行时。通常,容器引擎负责:

  • 处理用户输入
  • 通过API处理输入,通常来自容器编排器
  • 从注册中心服务器提取容器镜像
  • 使用图形驱动程序(取决于驱动程序的块或文件)在磁盘上解压和扩展容器镜像
  • 准备容器挂载点,通常在写时复制存储上(同样是块或文件,取决于驱动程序)
  • 准备将传递给容器的元数据,以便正确启动容器
    • 使用容器镜像中的一些默认值(例如archx86)
    • 使用用户输入来覆盖容器镜像中的默认值(例如CMD, ENTRYPOINT)
    • 使用容器镜像指定的默认值(例如SECCOM规则)
  • 调用容器运行时

容器

容器在操作系统中已经存在了相当长的时间。容器是容器镜像的运行时实例化。容器是一个标准的Linux进程,通常通过clone()系统调用而不是fork()或exec()创建。此外,容器通常通过使用cgroups、SELinux或AppArmor进一步隔离。

容器主机

容器主机是运行容器化进程的系统。例如,它可以是在VM中运行的RHEL Atomic Host,作为公共云中的实例,或者在数据中心的裸机上运行。一旦容器镜像(又名存储库)从Registry Server拉到本地容器主机,就说它在本地缓存中。

可以使用以下命令确定哪些存储库被同步到本地缓存:

[root@rhel7 ~]# docker images -aREPOSITORY                             TAG                     IMAGE ID                CREATED                 VIRTUAL SIZE
registry.access.redhat.com/rhel7   latest                  6883d5422f4e            3 weeks ago             201.7 MB

注册中心

注册服务器本质上是一个奇特的文件服务器,用于存储Docker存储库。通常,注册服务器被指定为普通DNS名称和可选的连接端口号。Docker生态系统的大部分价值来自于从注册服务器推送和拉取存储库的能力。

在这里插入图片描述

当Docker守护进程没有存储库的本地缓存副本时,它将自动从注册表服务器提取该副本。大多数Linux发行版都配置了从Docker中提取的Docker守护进程。但是它在一些Linux发行版上是可配置的。例如,Red Hat Enterprise Linux被配置为先从registry.access.redhat.com获取存储库,然后再尝试docker。io (Docker Hub)。

必须强调的是,注册中心服务器中存在隐式信任。您必须确定您对注册表提供的内容的信任程度,并且您可能希望允许或阻止某些注册表。除了安全性之外,还有其他问题,例如用户是否有权访问许可软件和遵从性问题。docker允许用户拉取软件的简单性使得信任上游内容变得至关重要。

在Red Hat Enterprise Linux中,默认的docker注册表是可配置的。通过修改配置文件,可以在RHEL7和RHEL7 Atomic中添加或阻止特定的注册表服务器:

vi /etc/sysconfig/docker

在RHEL7和RHEL7 Atomic中,Red Hat的注册表服务器是开箱即用的:

ADD_REGISTRY='--add-registry registry.access.redhat.com'

出于安全考虑,阻止公共docker存储库(如DockerHub)可能会很有用:

# BLOCK_REGISTRY='--block-registry'

容器编排

团队通常从安装容器主机开始,然后拉取一些容器镜像。然后,他们继续构建一些新的容器镜像,并将它们推送到注册表服务器上,以便与团队中的其他人共享。过了一段时间后,他们希望将几个容器连接在一起,并将它们作为一个单元部署。最后,在某种程度上,他们希望将该单元推进到通向生产的管道(Dev/QA/Prod)中。这是实现需要编制的途径。

容器编排器实际上做两件事:

  • 动态调度计算机集群中的容器工作负载。这通常被称为分布式计算。
  • 提供标准化的应用程序定义文件(kube yaml、docker compose等)

以上两个特性提供了许多功能:

  • 允许应用程序中的容器完全单独调度。这在以下情况下很有用:
    • 允许使用大型容器主机集群
    • 单个容器失败(进程挂起,内存不足)
    • 容器主机故障(磁盘、网络、重启)
    • 容器引擎失败(损坏、重新启动)
    • 单个容器需要按比例放大或缩小
  • 将相同应用程序的新实例部署到新环境中很容易。在云原生世界或传统世界中,您可能需要这样做的原因有很多,包括:
    • 在带有容器编排器的开发人员笔记本电脑上,
    • 在私有命名空间中的共享开发环境中运行,
    • 在内部公共命名空间中的共享开发环境中运行,以便在质量保证(QA)环境中进行可见性和测试,
    • 在云上动态配置和卸载的负载测试环境中,
    • 在新的生产环境中测试与生产环境的兼容性,在灾难恢复环境中测试与生产环境的兼容性
    • 在新的生产环境中升级了容器主机、容器引擎或容器编排器的环境,该环境具有新的地理位置(APAC、EMEA等)中的容器主机、容器引擎和容器编排器的相同版本。

社区和供应商正在开发许多容器调度器。从历史上看,Swarm、Mesos和Kubernetes是三巨头,但最近就连Docker和Mesosphere也宣布支持Kubernetes——几乎所有主要的云服务提供商都宣布支持Kubernetes。Kubernetes已经成为容器编排的事实上的标准,类似于之前的Linux。如果您正在考虑容器编排,红帽推荐我们的企业发行版OpenShift

进阶术语

容器运行时

容器运行时是通常在容器引擎中使用的较低层组件,但也可以手工用于测试。开放容器计划(OCI)运行时标准参考实现是runc。这是最广泛使用的容器运行时,但是还有其他兼容OCI的运行时,如crun、railcar和katcontainers。Docker、CRI-O和许多其他容器引擎都依赖于runc。容器运行时负责:

  • 使用容器引擎提供的容器挂载点(也可以是用于测试的普通目录)
  • 使用容器引擎提供的容器元数据(也可以是手工配置)
  • 与内核通信以启动容器化进程(克隆系统调用)
  • 设置群组
  • 设置SELinux策略
  • 设置App Armor规则

为了提供一些历史信息,当Docker引擎第一次创建时,它依赖于LXC作为容器运行时。后来,Docker团队开发了自己的库libcontainer来启动容器。这个库是用Golang编写的,并编译到原始的Docker引擎中。最后,创建OCI时,Docker提供了libcontainer代码,并将其转换为名为runc的独立实用程序。现在,runc是参考实现,并被其他容器引擎(如CRI-O)使用。在最低级别,这提供了一致启动容器的能力,无论容器引擎是什么。Runc是一个非常简洁的实用程序,需要提供挂载点(目录)和元数据(config.json)。有关runc的更多信息,请参阅本教程。

镜像层

存储库通常被称为镜像或容器镜像,但实际上它们由一个或多个层组成。存储库中的镜像层以父子关系连接在一起。每个镜像层表示自身和父层之间的变化。

下面,我们将检查本地容器主机上存储库的层。自Docker 1.7以来,没有本地工具来检查本地存储库中的镜像((有用于在线注册的工具)。在Dockviz工具的帮助下,您可以快速检查所有层。请注意,每一层都有标签和一个通用唯一标识符(UUID)。下面的命令将返回UUID的缩短版本,这些版本通常是唯一的,可以在一台机器上使用。如果你需要完整的UUID,使用——no-trunc选项。

docker run --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock nate/dockviz images -t├─2332d8973c93 Virtual Size: 187.7 MB│ └─ea358092da77 Virtual Size: 187.9 MB│   └─a467a7c6794f Virtual Size: 187.9 MB│         └─ca4d7b1b9a51 Virtual Size: 187.9 MB│           └─4084976dd96d Virtual Size: 384.2 MB│             └─943128b20e28 Virtual Size: 386.7 MB│               └─db20cc018f56 Virtual Size: 386.7 MB│                 └─45b3c59b9130 Virtual Size: 398.2 MB│                   └─91275de1a5d7 Virtual Size: 422.8 MB│                     └─e7a97058d51f Virtual Size: 422.8 MB│                       └─d5c963edfcb2 Virtual Size: 422.8 MB│                         └─5cfc0ce98e02 Virtual Size: 422.8 MB│                           └─7728f71a4bcd Virtual Size: 422.8 MB│                             └─0542f67da01b Virtual Size: 422.8 MB Tags: docker.io/registry:latest

注意,“docker”。Io /registry的存储库实际上是由许多镜像层组成的。更重要的是,请注意,用户可能基于这些层中的任何一层“运行”容器。下面的命令是完全有效的,尽管不能保证已经测试过,甚至不能保证正确地工作。通常,一个镜像生成器会标记(创建一个名称)你应该使用的特定图层:

docker run -it 45b3c59b9130 bash

储存库是以这种方式构造的,因为每当镜像构建器创建新镜像时,差异都会保存为一个层。在存储库中创建新层主要有两种方式。首先,如果手动构建惊险,每次“提交”都会创建一个新层。如果镜像构建器正在用Dockerfile构建一个镜像,那么文件中的每个指令都会创建一个新层。了解每个层之间容器存储库中发生了哪些变化是很有用的。

标签

即使用户可以指定容器装载并从存储库中的任何层开始,他们也不一定要这样做。当镜像构建器创建新的存储库时,他们通常会标记要使用的最佳镜像层。这些被称为标签(tag),是容器镜像构建器与容器镜像使用者沟通的工具,用于告知哪个层最好使用。通常,标记用于指定存储库中的软件版本。这只是约定——实际上,OCI或任何其他标准都强制要求可以使用哪些标签,并且它们可以被滥用于用户想要的任何东西。要小心这样做,因为它会给开发、运维和架构团队带来很多困惑,所以如果你将它用于软件版本以外的任何事情,请做好文档。

有一个特殊的标签——latest——它通常指向存储库中包含最新版本软件的层。这个特殊的标签仍然只是指向一个镜像层,像任何其他标签一样,所以它可以被滥用。

要远程查看存储库中可用的标记,请运行以下命令(jq实用程序使输出更具可读性):

curl -s registry.access.redhat.com/v1/repositories/rhel7/tags | jq{"7.0-21": "e1f5733f050b2488a17b7630cb038bfbea8b7bdfa9bdfb99e63a33117e28d02f","7.0-23": "bef54b8f8a2fdd221734f1da404d4c0a7d07ee9169b1443a338ab54236c8c91a","7.0-27": "8e6704f39a3d4a0c82ec7262ad683a9d1d9a281e3c1ebbb64c045b9af39b3940","7.1-11": "d0a516b529ab1adda28429cae5985cab9db93bfd8d301b3a94d22299af72914b","7.1-12": "275be1d3d0709a06ff1ae38d0d5402bc8f0eeac44812e5ec1df4a9e99214eb9a","7.1-16": "82ad5fa11820c2889c60f7f748d67aab04400700c581843db0d1e68735327443","7.1-24": "c4f590bbcbe329a77c00fea33a3a960063072041489012061ec3a134baba50d6","7.1-4": "10acc31def5d6f249b548e01e8ffbaccfd61af0240c17315a7ad393d022c5ca2","7.1-6": "65de4a13fc7cf28b4376e65efa31c5c3805e18da4eb01ad0c8b8801f4a10bc16","7.1-9": "e3c92c6cff3543d19d0c9a24c72cd3840f8ba3ee00357f997b786e8939efef2f","7.2": "6c3a84d798dc449313787502060b6d5b4694d7527d64a7c99ba199e3b2df834e","7.2-2": "58958c7fafb7e1a71650bc7bdbb9f5fd634f3545b00ec7d390b2075db511327d","7.2-35": "6883d5422f4ec2810e1312c0e3e5a902142e2a8185cd3a1124b459a7c38dc55b","7.2-38": "6c3a84d798dc449313787502060b6d5b4694d7527d64a7c99ba199e3b2df834e","latest": "6c3a84d798dc449313787502060b6d5b4694d7527d64a7c99ba199e3b2df834e"}

存储库

当使用docker命令时,存储库是在命令行上指定的,而不是镜像。在下面的命令中,“rhel7”是存储库。

docker pull rhel7

这实际上会自动扩展为:

docker pull registry.access.redhat.com/rhel7:latest

这可能令人困惑,许多人将其称为镜像或容器镜像。实际上,docker images子命令用于列出本地可用的存储库。从概念上讲,这些存储库可以被认为是容器镜像,但重要的是要意识到这些存储库实际上是由层组成的,并在一个称为manifest (manifest.json)的文件中包含元数据:

docker imagesREPOSITORY                                  TAG                     IMAGE ID                CREATED                 VIRTUAL SIZEregistry.access.redhat.com/rhel7            latest                  6883d5422f4e            4 weeks ago             201.7 MBregistry.access.redhat.com/rhel             latest                  6883d5422f4e            4 weeks ago             201.7 MBregistry.access.redhat.com/rhel6            latest                  05c3d56ba777            4 weeks ago             166.1 MBregistry.access.redhat.com/rhel6/rhel       latest                  05c3d56ba777            4 weeks ago             166.1 MB...

当我们在命令行上指定存储库时,容器引擎会为您做一些额外的工作。在这种情况下,docker守护进程(而不是客户端工具)配置了要搜索的服务器列表。在上面的示例中,守护进程将在每个已配置的服务器上搜索“rhel7”存储库。

在上面的命令中,只指定了存储库名称,但是也可以使用docker客户端指定完整的URL。为了强调这一点,让我们从剖析一个完整的URL开始。

在这里插入图片描述
你经常看到的另一种指定方式是:

REGISTRY/NAMESPACE/REPOSITORY[:TAG]

完整的URL由标准服务器名称、名称空间和可选的标记组成。实际上,指定URL的方式有很多种,当您探索docker生态系统时,您会发现许多部分是可选的。下面的命令都是有效的,并且都是同一存储库的一些排列:

 docker pull registry.access.redhat.com/rhel7/rhel:latestdocker pull registry.access.redhat.com/rhel7/rheldocker pull registry.access.redhat.com/rhel7docker pull rhel7/rhel:latest

名称空间

名称空间是用于分隔存储库组的工具。在公共DockerHub上,名称空间通常是共享镜像的人的用户名,但也可以是组名或逻辑名。

Red Hat使用名称空间来根据Red Hat Federated Registry服务器上列出的产品分离存储库组。以下是registry.access.redhat.com返回的一些示例结果。注意,最后一个结果实际上列在另一个注册表服务器上。这是因为Red Hat也会在我们合作伙伴的注册服务器上列出存储库:

registry.access.redhat.com/rhel7/rhel
registry.access.redhat.com/openshift3/mongodb-24-rhel7
registry.access.redhat.com/rhscl/mongodb-26-rhel7
registry.access.redhat.com/rhscl_beta/mongodb-26-rhel7
registry-mariadbcorp.rhcloud.com/rhel7/mariadb-enterprise-server:10.0

注意,有时不需要指定完整的URL。在这种情况下,给定的名称空间有一个默认存储库。如果用户只指定fedora名称空间,则默认存储库中的最新标记将被拉到本地服务器。因此,运行以下命令本质上是相同的,每一个都更具体:

docker pull fedora
docker pull docker.io/fedora
docker pull docker.io/library/fedora:latest

参考

  • https://developers.redhat.com/blog/2018/02/22/container-terminology-practical-introduction#container_host
  • https://opencontainers.org/about/overview/
  • https://github.com/opencontainers/image-spec/blob/main/manifest.md
  • https://github.com/opencontainers/image-spec/blob/main/layer.md
  • https://github.com/opencontainers/image-spec/blob/main/config.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/620303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux驱动学习—I2C总线

1、应用层实现I2C通信 1.1 I2C简介 I2C是很常见的一种总线协议,I2C是NXP公司设计的,I2C使用两条线在主控制器和从机之间进行数据通信。一条是SCL(串行时钟线),另外一条是SDA(串行数据线),因为I2C这两条数…

Windows Server 2019配置多用户远程桌面登录服务器

正文共:1234 字 21 图,预估阅读时间:2 分钟 很久之前,在介绍显卡直通的时候我们简单介绍过RDP(Remote Desktop Protocol,远程桌面协议)(前人栽树:失败的服务器显卡操作&a…

第 3 场 蓝桥杯小白入门赛 解题报告 | 珂学家 | 单调队列优化的DP + 三指针滑窗

前言 整体评价 T5, T6有点意思&#xff0c;这场小白入门场&#xff0c;好像没真正意义上的签到&#xff0c;整体感觉是这样。 A. 召唤神坤 思路: 前后缀拆解 #include <iostream> #include <algorithm> #include <vector> using namespace std;int main()…

Android平台RTMP推送|轻量级RTSP服务|GB28181设备接入模块之实时快照保存JPG还是PNG?

JPG还是PNG&#xff1f; JPG和PNG是两种常见的图片文件格式&#xff0c;在压缩方式、图像质量、透明效果和可编辑性等方面存在显著差异。 压缩方式&#xff1a;JPG是一种有损压缩格式&#xff0c;通过丢弃图像数据来减小文件大小&#xff0c;因此可能会损失一些图像细节和质量…

【AIGC】IP-Adapter:文本兼容图像提示适配器,用于文本到图像扩散模型

前言 IPAdapter能够通过图像给Stable Diffusion模型以内容提示&#xff0c;让其生成参考该图像画风&#xff0c;可以免去Lora的训练&#xff0c;达到参考画风人物的生成效果。 摘要 通过文本提示词生成的图像&#xff0c;往往需要设置复杂的提示词&#xff0c;通常设计提示词变…

系列十一、Spring Security登录接口兼容JSON格式登录

一、Spring Security登录接口兼容JSON格式登录 1.1、概述 前后端分离中&#xff0c;前端和后端的数据交互通常是JSON格式&#xff0c;而Spring Security的登录接口默认支持的是form-data或者x-www-form-urlencoded的&#xff0c;如下所示&#xff1a; 那么如何让Spring Securi…

Open3D 反算点云缩放系数(21)

Open3D 反算点云缩放系数(21) 一、算法介绍二、算法实现1.方法12.方法2(通用)一、算法介绍 上一章按照指定的系数,对点云进行了等比例缩放,这里输入缩放后的两块点云,反算二者之间的缩放系数。 二、算法实现 已知使用的俩点云是1/2的缩放关系,用于验证计算结果是否…

【数据结构】串,数组,广义表 | 笔记整理 | C/C++实现

文章目录 前言一、串1.1、串的定义1.2、案例引入1.3、串的类型定义和存储结构1.4、串的模式匹配算法1.4.1、BF算法1.4.2、KMP算法 二、数组2.1、数组的定义2.2、数组的抽象数据类型定义2.3、数组的顺序存储2.4、特殊矩阵的压缩存储 三、广义表四、病毒案例 前言 参考视频&…

【C++】wxWidgets库实现窗体程序

一、安装wxWidgets库 在Debian系统上使用wxWidgets库来创建一个基本的窗体程序&#xff0c;首先需要确保已经安装了wxWidgets相关的库和开发工具。下面是安装wxWidgets的步骤&#xff1a; 打开终端&#xff0c;使用下述命令安装wxWidgets库及其开发文件&#xff1a; sudo ap…

MySQL之导入、导出远程备份

一、Navicat工具导入、导出 1.1 导入 第一步&#xff1a; 右键&#xff0c;点击运行SQL文件 第二步&#xff1a; 选择要运行的SQL&#xff0c;点击开始 第三步&#xff1a; 关闭即可 1.2 导出 第一步&#xff1a; 右键选择&#xff0c;导出向导 第二步&#xff1a; 选择SQL脚…

1.3MATLAB变量及其操作

变量 变量是内存单元的一个抽象&#xff0c;在MATLAB中&#xff0c;变量以字母开头&#xff0c;后接数字下划线构成&#xff0c;MATLAB中变量名最多占据 63 个字符。变量区分大小写标准函数及命令一般使用小写字母 赋值语句 变量 表达式(;)表达式(;)总结&#xff1a;加分号&…

C++ 实现游戏(例如MC)键位显示

效果&#xff1a; 是不是有那味儿了&#xff1f; 显示AWSD&#xff0c;空格&#xff0c;Shift和左右键的按键情况以及左右键的CPS。 彩虹色轮廓&#xff0c;黑白填充。具有任务栏图标&#xff0c;可以随时关闭字体是Minecraft AE Pixel&#xff0c;如果你没有装&#xff08;大…

使用numpy处理图片——灰阶影像

大纲 载入图像灰阶处理lightnessaverageluminosity 灰阶&#xff08;Gray scale&#xff09;影像是每个像素只有一个采样颜色的图像。 载入图像 import numpy as np import PIL.Image as Imageimg Image.open(lena.png) data np.array(img)灰阶处理 我们有三种方法来生成这…

Linux中常使用的命令之ls、cd、pwd、mkdir、rmdir

ls: 列出目录 cd&#xff1a;切换目录 pwd&#xff1a;显示目前的目录 mkdir&#xff1a;创建一个新的目录 -m &#xff1a;配置文件的权限-p &#xff1a;帮助你直接将所需要的目录(包含上一级目录)递归创建起来&#xff01; rmdir&#xff1a;删除一个空的目录 注意这…

基于springboot时间管理系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括时间管理系统的网络应用&#xff0c;在外国时间管理系统已经是很普遍的方式&#xff0c;不过国内的管理系统可能还处于起步阶段。时间管理系统具有时间管理功能的选择。时间管…

Unity Shader 属性的定义

Unity Shader 属性的定义 什么是材质球 人的衣服 什么是shader 决定材质跟灯光的作用 Property 若是把shader看作class&#xff0c;那么Property就可以看成成员变量 属性定义的通用格式 Properites{ Property[Property…] } ep:定义一个int&#xff1a; name("dis…

ODBC 在指定的DSN中,驱动程序和应用程序之间的体系结构不匹配

常规办法就是64位或32位匹配&#xff0c;如果解决不了&#xff0c;往下看。 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓解决方案↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 解压AccessDatabaseEngine_X64.exe&#xf…

为什么选择Go语言编写网络应用程序

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等&#xff0c;您的关注将是我的更新动力&#xff01; 作为一名后端开发者&#xff0c;你一定对选择合适的编程语言来编写网络应用程序非常重视。在众多的编程语言中&#xff0c;Go语言…

我在代码随想录|写代码Day7之454.四数相加II ,​ 383. 赎金信​,​ 15. 三数之和​

454.四数相加II 题目 解题思路 四个数字相加的和为0,我们要选俩数组,让他们的笛卡尔积储存在哈希表中,然后我们要找的是这俩数和的相反数,然后就是将后面俩数组相加在后面的数组和中找相反数. 383. 赎金信 解题思路 题目意思是让在字符串1中找到字母组成字符串2所以找字符串1…

【无标题】关于异常处理容易犯的错

一般项目是方法打上 try…catch…捕获所有异常记录日志&#xff0c;有些会使用 AOP 来进行类似的“统一异常处理”。 其实&#xff0c;这种处理异常的方式非常不可取。那么今天&#xff0c;我就和你分享下不可取的原因、与异常处理相关的坑和最佳实践。 捕获和处理异常容易犯…