别在说自己不知道docker了,全文通俗易懂的给你说明白docker的基础与底层原理

docker介绍

Docker 是一个开源的应用容器引擎,基于Go语言进行开发实现并遵从Apache2.0 协议开源,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的linux。

容器是完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。

Docker 从17.03版本之后分为CE(Community Edition:社区版)和EE(Enterprise Edition :企业版),

相对于社区版本,企业版本强调安全性,但需付费使用。所以咱们使用社区版就可以。

docker 发展历史

Docker 公司前身是 DotCloud,由 Solomon Hykes 在2010年成立,2013年更名 Docker。同年发布了 Docker-compose 组件提供容器的编排工具。

2014年 Docker 发布1.0版本,2015年Docker 提供 Docker-machine,支持 windows 平台。

在此期间,Docker 项目在开源社区大受追捧,同时也被业界诟病的是 Docker 公司对于 Docker 发展具有绝对的话语权,比如 Docker 公司推行了 libcontainer 难以被社区接受。

为了防止 Docker 这项开源技术被Docker 公司控制,在几个核心贡献的厂商,于是在一同贡献 Docker 代码的公司诸如 Redhat,谷歌的倡导下,成立了 OCI 开源社区。

OCI 开源社区旨在于将 Docker 的发展权利回归社区,当然反过来讲,Docker 公司也希望更多的厂商安心贡献代码到Docker 项目,促进 Docker 项目的发展。

于是通过OCI建立了 runc 项目,替代 libcontainer,这为开发者提供了除 Docker 之外的容器化实现的选择。

OCI 社区提供了 runc 的维护,而 runc 是基于 OCI 规范的运行容器的工具。换句话说,你可以通过 runc,提供自己的容器实现,而不需要依赖 Docker。当然,Docker 的发行版底层也是用的 runc。在 Docker 宿主机上执行 runc,你会发现它的大多数命令和 Docker 命令类似,感兴趣的读者可以自己实践如何用 runc 启动容器。

至2017年,Docker 项目转移到 Moby 项目,基于 Moby 项目,Docker 提供了两种发行版,Docker CE 和 Docker EE, Docker CE 就是目前大家普遍使用的版本,Docker EE 成为付费版本,提供了容器的编排,Service 等概念。Docker 公司承诺 Docker 的发行版会基于 Moby 项目。这样一来,通过 Moby 项目,你也可以自己打造一个定制化的容器引擎,而不会被 Docker 公司绑定。

docker 与虚拟机有何区别

Docker 不是虚拟化方法。它依赖于实际实现基于容器的虚拟化或操作系统级虚拟化的其他工具。

Docker 最初使用 LXC 驱动程序,然后移动到libcontainer ,现在重命名为 runc。

Docker 主要专注于在应用程序容器内自动部署应用程序。应用程序容器旨在打包和运行单个服务,而系统容器则设计为运行多个进程,如虚拟机。

因此,Docker 被视为容器化系统上的容器管理或应用程序部署工具。

  • 容器不需要引导操作系统内核,因此可以在不到一秒的时间内创建容器。此功能使基于容器的虚拟化比其他虚拟化方法更加独特和可取。
  • 由于基于容器的虚拟化为主机增加了很少或没有开销,因此基于容器的虚拟化具有接近本机的性能。
  • 对于基于容器的虚拟化,与其他虚拟化不同,不需要其他软件。
  • 主机上的所有容器共享主机的调度程序,从而节省了额外资源的需求。
  • 与虚拟机映像相比,容器状态(Docker 或 LXC 映像)的大小很小,因此容器映像很容易分发。
  • 容器中的资源管理是通过 cgroup 实现的。Cgroups 不允许容器消耗比分配给它们更多的资源。虽然主机的所有资源都在虚拟机中可见,但无法使用。这可以通过在容器和主机上同时运行 top 或 htop 来实现。所有环境的输出看起来都很相似。

docker 与传统虚拟机的对比结果如下:

特性Docker虚拟机
启动速度秒级分钟级
交付/部署开发、测试、生产环境一致无成熟体系
性能近似物理机性能损耗大
体量极小(MB)较大(GB)
迁移/扩展跨平台、可复制较为复杂

(1)传统虚拟机是需要安装整个操作系统的,然后再在上面安装业务应用,启动应用,通常需要几分钟去启动应用,而docker是直接使用镜像来运行业务容器的,其容器启动属于秒级别;

(2)Docker需要的资源更少,Docker在操作系统级别进行虚拟化,Docker容器和内核交互,几乎没有性能损耗,而虚拟机运行着整个操作系统,占用物理机的资源就比较多;

(3)Docker更轻量,Docker的架构可以共用一个内核与共享应用程序库,所占内存极小;同样的硬件环 境,Docker运行的镜像数远多于虚拟机数量,对系统的利用率非常高;

(4)与虚拟机相比,Docker隔离性更弱,Docker属于进程之间的隔离,虚拟机可实现系统级别隔离;

(5)Docker的安全性也更弱,Docker的租户root和宿主机root相同,一旦容器内的用户从普通用户权限 提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户root权限 和宿主机的root虚拟机权限是分离的,并且虚拟机利用如Intel的VT-d和VT-x的ring-1硬件隔离技术,这 种技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离;

(6)Docker的集中化管理工具还不算成熟,各种虚拟化技术都有成熟的管理工具,比如:VMware vCenter提供完备的虚拟机管理能力;

(7)Docker对业务的高可用支持是通过快速重新部署实现的,虚拟化具备负载均衡,高可用、容错、迁移和数据保护等经过生产实践检验的成熟保障机制,Vmware可承诺虚拟机99.999%高可用,保证业务连续性;

(8)虚拟化创建是分钟级别的,Docker容器创建是秒级别的,Docker的快速迭代性,决定了无论是开发、测试、部署都可以节省大量时间;

(9)虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化,Docker在Dockerfile中记录了容器构建过程,可在集群中实现快速分发和快速部署。

在这里插入图片描述

docker的应用场景

(1)web应用的自动化打包和发布;

(2)自动化测试和持续集成、发布;

(3)在服务型环境中部署和调整数据库或其他的后台应用;

(4)从头编译或者扩展现有的OpenShift 或者Cloud Foundry平台来搭建自己的PaaS环境。

基本概念

镜像(image)

操作系统分为内核和用户空间。对于linux来说,内核启动后,会挂载root文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系统的 root 文件系统。

Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。

由于镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。

容器(container)

容器是独立运行的一个或一组应用,是镜像运行时的实体。

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。

容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。

每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。

容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。

仓库(Repository)

Docker Registry 提供一个集中的存储、分发镜像的服务。

一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。

仓库名经常以 两段式路径 形式出现,比如 jwilder/nginx-proxy,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。

docker 基本架构

Docker 采用了 C/S 架构,包括客户端和服务端。Docker 守护进程 (Daemon)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)。

客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。
在这里插入图片描述
Docker 守护进程一般在宿主主机后台运行,等待接收来自客户端的消息。

Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker 守护进程交互。

docker底层实现

Linux 命名空间、控制组和 UnionFS 三大技术支撑了目前 Docker 的实现,也是 Docker 能够出现的最重要原因。

在这里插入图片描述

namespace,命名空间

Namespace是将内核的全局资源做封装,使得每个Namespace都有一份独立的资源,因此不同的进程在各自的Namespace内对同一种资源的使用不会互相干扰。

namespace是容器隔离的基础,保证A容器看不到B容器.

目前linux内核总共实现了6中Namespace:

  • IPC:隔离System V IPC和POSIX消息队列。
  • Network:隔离网络资源。
  • Mount:隔离文件系统挂载点。
  • PID:隔离进程ID。
  • UTS:隔离主机名和域名。
  • User:隔离用户ID和组ID。

Cgroups(Control Group),控制组

Cgroup 属于Linux内核提供的一个特性,用于限制和隔离一组进程对系统资源的使用,也就是做资源QoS,这些资源主要包括CPU、内存、block I/O和网络带宽。

Cgroup从2.6.24开始进入内核主线,目前各大发行版都默认打开了Cgroup特性。

从实现的角度来看,Cgroup实现了一个通用的进程分组的框架,而不同资源的具体管理则是由各个Cgroup子系统实现的。

对实际资源的分配和管理是由各个Cgroup子系统完成的,下面介绍几个主要的子系统。

  • cpuset子系统:为一组进程分配指定的CPU和内存节点。
  • cpu子系统:用于限制进程的CPU占用率。
  • cpuacct子系统:用来统计各个Cgroup的CPU使用情况。
  • memory子系统:用来限制Cgroup所能使用的内存上限。
  • blkio子系统:用来限制Cgroup的block I/O带宽。
  • devices子系统:用来控制Cgroup的进程对哪些设备有访问权限。

实际上 Docker 是使用了很多 Linux 的隔离功能,让容器看起来像一个轻量级虚拟机在独立运行,容器的本质是被限制了的 Namespaces,cgroup,具有逻辑上独立文件系统,网络的一个进程。

unionfs 联合文件系统

UnionFS(联合文件系统)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。

UnionFS 最常见的用途是在 Linux 系统中实现可写的只读文件系统,在不改变原始文件系统内容的前提下,给文件系统添加或修改文件。它也可以用来创建一个有多个层次结构的文件系统,其中最上层是可读写的,而底部的层次都是只读的。

UnionFS 主要具有以下特点:

  • 联合不会涉及原有的文件系统,所以不会破坏原有的数据。
  • 可以支持多个只读文件系统和一个可读写的文件系统联合在一起,实现可写的只读文件系统。
  • 可以通过加入新的层次来扩展文件系统,同时保留原有的数据和结构。
  • 可以使用类似于栈的方式来控制文件系统的层次结构。

UnionFS是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。

Docker 中使用的 AUFS(Advanced Multi-Layered Unification Filesystem)就是一种联合文件系统。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。

Docker 目前支持的联合文件系统包括 OverlayFS, AUFS, Btrfs, VFS, ZFS 和 Device Mapper。

容器格式

最初,Docker 采用了 LXC 中的容器格式。从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。

网络

Docker 的网络实现其实就是利用了 Linux 上的网络命名空间和虚拟网络设备(特别是 veth pair)。

Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。 Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以太网卡,只是它不需要真正同外部网络设备通信,速度要快很多。

Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做 veth pair)。

Docker 创建一个容器的时候,会执行如下操作:

  • 创建一对虚拟接口,分别放到本地主机和新容器中;
  • 本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 veth65f9;
  • 容器一端放到新容器中,并修改名字作为 eth0,这个接口只在容器的命名空间可见;
  • 从网桥可用地址段中获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 veth65f9。

完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。

可以在 docker run 的时候通过 --net 参数来指定容器的网络配置,有4个可选值:
(1)–net=bridge 这个是默认值,连接到默认的网桥。
(2) --net=host 告诉 Docker 不要将容器网络放到隔离的命名空间中,即不要容器化容器内的网络。此时容器使用本地主机的网络,它拥有完全的本地主机接口访问权限。容器进程可以跟主机其它 root 进程一样可以打开低范围的端口,可以访问本地网络服务比如 D-bus,还可以让容器做一些影响整个主机系统的事情,比如重启主机。因此使用这个选项的时候要非常小心。如果进一步的使用 --privileged=true,容器会被允许直接配置主机的网络堆栈。
(3)–net=container:NAME_or_ID 让 Docker 将新建容器的进程放到一个已存在容器的网络栈中,新容器进程有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享 IP 地址和端口等网络资源,两者进程可以直接通过 lo 环回接口通信。
(4)–net=none 让 Docker 将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自己进行配置。

使用 --net=none 后,可以自行配置网络,让容器达到跟平常一样具有访问网络的权限。通过这个过程,可以了解 Docker 配置网络的细节。

首先,启动一个 /bin/bash 容器,指定 --net=none 参数。

$ docker run -i -t --rm --net=none base /bin/bash

在本地主机查找容器的进程 id,并为它创建网络命名空间。

$ docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
2778
$ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid

检查桥接网卡的 IP 和子网掩码信息。

$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0

创建一对 “veth pair” 接口 A 和 B,绑定 A 到网桥 docker0,并启用它

$ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up

将B放到容器的网络命名空间,命名为 eth0,启动它并配置一个可用 IP(桥接网段)和默认网关。

$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1

以上,就是 Docker 配置网络的具体过程。

当容器结束后,Docker 会清空容器,容器内的 eth0 会随网络命名空间一起被清除,A 接口也被自动从 docker0 卸载。

此外,用户可以使用 ip netns exec 命令来在指定网络命名空间中进行配置,从而配置容器内的网络。

docker安装

自动化安装(推荐)

Docker 官方和国内daocloud 都提供了一键安装的脚本,使得Docker的安装更加便捷。

官方的一键安装方式:

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

在这里插入图片描述

耐心等待即可完成Docker的安装。

docker手动在线安装 (新手)

(1)内核版本检查

Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。

uname -r

在这里插入图片描述

(2)确保 yum 包更新到最新

使用 root 权限登录 Centos。确保 yum 包更新到最新。

sudo yum update

(3)卸载Docker(可选)

卸载历史版本。这一步是可选的,如果之前安装过旧版本的Docker,可以使用如下命令进行卸载:

yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce

(4) 安装必要的系统工具

在设置仓库之前,需先安裝所需的软件包。yum-utils提供了yum-config-manager,并且device mapper存储驱动程序需要device-mapper-persistent-data和lvm2。

 yum install -y yum-utils device-mapper-persistent-data lvm2

(5)设置源仓库

官方源地址:

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

注意: 官方的源地址比较慢。

阿里云源地址:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

(4) docker安装

执行命令安装最新版本的Docker Engine-Community 和 containerd。

执行缓存:

yum makecache fast

执行安装最新社区版docker

yum install docker-ce

docker-ce为社区免费版本。稍等片刻,docker即可安装成功。但安装完成之后的默认是未启动的,需要进行启动操作。

如需要docker-ce-cli或containerd.io或docker-buildx-plugin 或 docker-compose-plugin可执行如下命令:

yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

(5)启动并加入开机启动

# 启动docker
sudo systemctl start docker
# 开机启动
sudo systemctl enable docker

(6)验证docker是否安装成功

通过运行hello-world镜像来验证是否正确安装了Docker Engine-Community。

docker version

docker 离线安装

基础环境

  • 操作系统: Centos 7
  • Docker 下载地址:docker 24.0.5下载
  • 官方参考文档: 文档

docekr 安装

(1)下载

wget <https://download.docker.com/linux/static/stable/x86_64/docker-24.0.5.tgz

注意:如果事先下载好了可以忽略这一步

(2)解压

把压缩文件存在指定目录下(如root),并进行解压

tar -zxvf docker-24.0.5.tgz -C /root/

(3)将解压出来的docker文件内容移动到 /usr/bin/ 目录下

cp /root/docker/* /usr/bin/

(4)将docker注册为service

cat /etc/systemd/system/docker.servicevi /etc/systemd/system/docker.service

docker.service 内容如下:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID# Having non-zero Limit*s causes performance problems due to accounting overhead# in the kernel. We recommend using cgroups to do container-local accounting.LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0# set delegate yes so that systemd does not reset the cgroups of docker containersDelegate=yes# kill only the docker process, not all processes in the cgroupKillMode=process# restart the docker process if it exits prematurelyRestart=on-failure
StartLimitBurst=3
StartLimitInterval=60s[Install]
WantedBy=multi-user.target

(5)启动

chmod +x /etc/systemd/system/docker.service #添加文件权限并启动dockersystemctl daemon-reload #重载unit配置文件systemctl start docker #启动Dockersystemctl enable docker.service #设置开机自启

(6)验证

systemctl status docker #查看Docker状态docker -v #查看Docker版本docker info

调整镜像仓库

如果需要调整镜像仓库,可以按照以下方式进行调整,(建议使用默认的)

修改/etc/docker目录下的daemon.json文件,在文件中加入如下内容:

{"registry-mirrors": ["https://registry.docker-cn.com"]
}

保存退出,重启docker

#添加文件权限并启动docker
chmod +x /etc/systemd/system/docker.service#重载unit配置文件
systemctl daemon-reload#启动Docker 
systemctl restart docker#设置开机自启
systemctl enable docker.service 

docker 文件目录

Docker默认的文件目录位于/var/lib/docker

在这里插入图片描述

|-----containers:用于存储容器信息

|-----image:用来存储镜像中间件及本身信息,大小,依赖信息

|-----network

|-----swarm

|-----tmp:docker临时目录

|-----trust:docker信任目录

|-----volumes:docker卷目录

还可以通过docker指令确认文件的位置:

在这里插入图片描述

docker 常用命令

操作容器

查看docker版本信息

docker --version

在这里插入图片描述

查看docker 的系统相关信息

[root@localhost ~]# docker info
Client:Context:    defaultDebug Mode: falsePlugins:app: Docker App (Docker Inc., v0.9.1-beta3)buildx: Docker Buildx (Docker Inc., v0.9.1-docker)scan: Docker Scan (Docker Inc., v0.17.0)Server:Containers: 5Running: 5Paused: 0Stopped: 0Images: 21Server Version: 20.10.19Storage Driver: overlay2Backing Filesystem: xfsSupports d_type: trueNative Overlay Diff: trueuserxattr: falseLogging Driver: json-fileCgroup Driver: cgroupfsCgroup Version: 1Plugins:Volume: localNetwork: bridge host ipvlan macvlan null overlayLog: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslogSwarm: inactiveRuntimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runcDefault Runtime: runcInit Binary: docker-initcontainerd version: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6runc version: v1.1.4-0-g5fd4c4dinit version: de40ad0Security Options:seccompProfile: defaultKernel Version: 3.10.0-1160.76.1.el7.x86_64Operating System: CentOS Linux 7 (Core)OSType: linuxArchitecture: x86_64CPUs: 4Total Memory: 7.513GiBName: localhost.localdomainID: 4V4D:DEH4:4I6N:WBQA:GNUN:PROP:NT35:RK7N:43FA:BHHJ:EK2E:CWJEDocker Root Dir: /var/lib/dockerDebug Mode: falseRegistry: https://index.docker.io/v1/Labels:Experimental: falseInsecure Registries:127.0.0.0/8Registry Mirrors:https://yxzrazem.mirror.aliyuncs.com/Live Restore Enabled: false

查看守护进程

systemctl status docker

在这里插入图片描述

查看docker相关的进程

ps -ef |grep docker

在这里插入图片描述

linux 下 启动docker

systemctl start docker

linux下关闭docker

systemctl stop docker

linux下重启docker

systemctl restart docker

linux下设置随服务启动而启动

systemctl enable docker

启动容器

docker start 镜像名称例如:
docker start redis

停止容器

docker stop 镜像名称例如:
docker stop redis

重启容器

docker restart例如:
docker restart redis

创建一个新的容器并运行一个命令

docker run例如:docker run -d  \
--restart=always \
--name rmqbroker \
--link rmqnamesrv:namesrv \
-p 8083:10911 \
-p 8084:10909 \
-v  /usr/local/rocketmq/data/broker/logs:/root/logs \
-v  /usr/local/rocketmq/data/broker/store:/root/store \
-v /usr/local/rocketmq/conf/broker.conf:/opt/rocketmq-4.4.0/conf/broker.conf \
-e "NAMESRV_ADDR=namesrv:8082" \
-e "MAX_POSSIBLE_HEAP=200000000" \
rocketmqinc/rocketmq \
sh mqbroker -c /opt/rocketmq-4.4.0/conf/broker.conf 

详细参数:

-i, --interactive=false   打开STDIN,用于控制台交互
-t, --tty=false            分配tty设备,该可以支持终端登录,默认为false
-d, --detach=false         指定容器运行于前台还是后台,默认为false
-u, --user=""              指定容器的用户
-a, --attach=[]            登录容器(必须是以docker run -d启动的容器)
-w, --workdir=""           指定容器的工作目录
-c, --cpu-shares=0        设置容器CPU权重,在CPU共享场景使用
-e, --env=[]               指定环境变量,容器中可以使用该环境变量
-m, --memory=""            指定容器的内存上限
-P, --publish-all=false    指定容器暴露的端口
-p, --publish=[]           指定容器暴露的端口
-h, --hostname=""          指定容器的主机名
-v, --volume=[]            给容器挂载存储卷,挂载到容器的某个目录    顺序:主机:容器
--volumes-from=[]          给容器挂载其他容器上的卷,挂载到容器的某个目录
--cap-add=[]               添加权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cap-drop=[]              删除权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cidfile=""               运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法
--cpuset=""                设置容器可以使用哪些CPU,此参数可以用来容器独占CPU
--device=[]                添加主机设备给容器,相当于设备直通
--dns=[]                   指定容器的dns服务器
--dns-search=[]            指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件
--entrypoint=""            覆盖image的入口点
--env-file=[]              指定环境变量文件,文件格式为每行一个环境变量
--expose=[]                指定容器暴露的端口,即修改镜像的暴露端口
--link=[]                  指定容器间的关联,使用其他容器的IP、env等信息
--lxc-conf=[]              指定容器的配置文件,只有在指定--exec-driver=lxc时使用
--name=""                  指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字
--net="bridge"             容器网络设置:bridge 使用docker daemon指定的网桥host    //容器使用主机的网络container:NAME_or_ID  >//使用其他容器的网路,共享IP和PORT等网络资源none 容器使用自己的网络(类似--net=bridge),但是不进行配置
--privileged=false         指定容器是否为特权容器,特权容器拥有所有的capabilities
--restart="no"             指定容器停止后的重启策略:no:容器退出时不重启on-failure:容器故障退出(返回值非零)时重启always:容器退出时总是重启
--rm=false                 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
--sig-proxy=true           设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理

进入容器

docker exec例如:
docker exec -it mysql /bin/bash

详细参数

(1)-d :分离模式: 在后台运行

(2)-i :即使没有附加也保持STDIN 打开

(3)-t :分配一个伪终端

查看正在运行的容器

docker ps [OPTIONS]

详细参数说明:

1、-a : 显示所有的容器,包括未运行的

在这里插入图片描述

2、-f : 根据条件过滤显示的内容 ,目前支持过滤器:

(1)id (容器的id)
(2)label
(3)name(容器名称)
(4)xited (整数-容器退出状态码,只有在使用-all才有用)
(5)tatus 容器状态(created,restarting,running,paused,exited,dead)
(6)ncestor 过滤从指定镜像创建的容器
(7)efore (容器的名称或id),过滤在给定id或名称之后创建的容器
(8)solation (default process hyperv) (windows daemon only)
(9)olume (数据卷名称或挂载点),--过滤挂载有指定数据卷的容器
(10)etwork(网络id或名称),过滤连接到指定网络的容器

在这里插入图片描述

条件虽多,但万变不离其宗,只要再记住以下 3 条准则:

(1)选项后跟的都是键值对 key=value (可不带引号),如果有多个过滤条件,就多次使用 filter 选项。例如:

docker ps --filter id=a1b2c3 --filter name=bingohuang

(2)相同条件之间的关系是或,不同条件之间的关系是与。例如:

docker ps --filter name=bingo --filter name=huang --filter status=running

以上过滤条件会找出 name 包含 bingo 或 huang 并且 status 为 running 的容器。

(3)id 和 name,支持正则表达式,使用起来非常灵活。例如:

docker ps --filter name=^/bingohuang$

精确匹配 name 为 bingohuang 的容器。注意,容器实际名称,开头是有一个正斜线 / ,可用 docker inspect 一看便知。

docker ps --filter name=.bingohuang.

匹配 name 包含 bingohuang 的容器,和 --filter name=bingohuang 一个效果。

最后, 举一个复杂点的例子,用于清理名称包含 bingohuang,且状态为 exited 或 dead 的容器:

docker rm $(docker ps -q --filter name=.bingohuang. --filter status=exited --filter status=dead2>/dev/null)

3、–format :指定返回值的模板文件。

当使用了 --format 选项,那么 ps 命令只会输出 template 中指定的内容:

[root@localhost ~]# docker ps --format "{{.ID}}: {{.Command}}"
6cb60535636c: "sh -c 'java $JAVA_O…"
187721c7fcf2: "sh mqbroker -c /opt…"
4cc8f9661adf: "sh mqnamesrv"
35e0f7357c42: "docker-entrypoint.s…"
513edf42f9ff: "docker-entrypoint.s…"

4、 -l :显示最近创建的容器。

在这里插入图片描述

5、-n :列出最近创建的n个容器。

在这里插入图片描述

6、 --no-trunc :不截断输出。
在这里插入图片描述

7、-q :静默模式,只显示容器编号。

清理容器时非常好用,filter 过滤显示一节有具体实例。
在这里插入图片描述

8、-s :显示总的文件大小。

在这里插入图片描述

查看容器的进程信息

查看容器中运行的进程信息,支持 ps 命令参数。

docker top [OPTIONS] CONTAINER [ps OPTIONS]

在这里插入图片描述

查看容器信息

#
docker ps -a docker inspect  镜像id
例如:
docker inspect 35e0f7357c42

查询结果:

[root@localhost ~]# docker inspect 35e0f7357c42
[{"Id": "35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d","Created": "2023-08-18T13:29:42.313267686Z","Path": "docker-entrypoint.sh","Args": ["redis-server","/etc/redis/redis.conf","--appendonly","yes","--requirepass","123456"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 2520,"ExitCode": 0,"Error": "","StartedAt": "2023-08-18T13:29:43.064705738Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:7614ae9453d1d87e740a2056257a6de7135c84037c367e1fffa92ae922784631","ResolvConfPath": "/var/lib/docker/containers/35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d/resolv.conf","HostnamePath": "/var/lib/docker/containers/35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d/hostname","HostsPath": "/var/lib/docker/containers/35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d/hosts","LogPath": "/var/lib/docker/containers/35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d/35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d-json.log","Name": "/redis","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": ["/usr/local/redis/conf/redis.conf:/etc/redis/redis.conf","/usr/local/redis/data:/data"],"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {"max-file": "2","max-size": "100m"}},"NetworkMode": "default","PortBindings": {"6379/tcp": [{"HostIp": "","HostPort": "8081"}]},"RestartPolicy": {"Name": "always","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"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","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"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"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/ce422bd974b38b6d2e50cd3c6ae31cd097e7eca1309b1c726291f0d0e8c1fa0f-init/diff:/var/lib/docker/overlay2/551c90db13332f1053568b4fc7d8a44857732c7a3e50fd5f2babde4790648cbc/diff:/var/lib/docker/overlay2/2183aa3920c05a24269e1beb1b9ef02bc314799cdda483c56fc05b2a40e87c06/diff:/var/lib/docker/overlay2/0b71ca2907e4159780fd6f5aa79f6040366423b83d5d5d65308b622da7586d6e/diff:/var/lib/docker/overlay2/b81143c2a90a6d0a713b8d175c6ee14b779a6e3210585438674ebd7f515e0d98/diff:/var/lib/docker/overlay2/799533302effeb3a01127a342935b07ebdec17517202762be6d252ced54d0d98/diff:/var/lib/docker/overlay2/7f71f39debcdc970e1a6ca6a52aa8dfbcdffd71d9b1a9dcab4e43756aeb1cc19/diff","MergedDir": "/var/lib/docker/overlay2/ce422bd974b38b6d2e50cd3c6ae31cd097e7eca1309b1c726291f0d0e8c1fa0f/merged","UpperDir": "/var/lib/docker/overlay2/ce422bd974b38b6d2e50cd3c6ae31cd097e7eca1309b1c726291f0d0e8c1fa0f/diff","WorkDir": "/var/lib/docker/overlay2/ce422bd974b38b6d2e50cd3c6ae31cd097e7eca1309b1c726291f0d0e8c1fa0f/work"},"Name": "overlay2"},"Mounts": [{"Type": "bind","Source": "/usr/local/redis/conf/redis.conf","Destination": "/etc/redis/redis.conf","Mode": "","RW": true,"Propagation": "rprivate"},{"Type": "bind","Source": "/usr/local/redis/data","Destination": "/data","Mode": "","RW": true,"Propagation": "rprivate"}],"Config": {"Hostname": "35e0f7357c42","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"ExposedPorts": {"6379/tcp": {}},"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","GOSU_VERSION=1.12","REDIS_VERSION=6.2.6","REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.6.tar.gz","REDIS_DOWNLOAD_SHA=5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab"],"Cmd": ["redis-server","/etc/redis/redis.conf","--appendonly","yes","--requirepass","123456"],"Image": "redis","Volumes": {"/data": {}},"WorkingDir": "/data","Entrypoint": ["docker-entrypoint.sh"],"OnBuild": null,"Labels": {}},"NetworkSettings": {"Bridge": "","SandboxID": "d426e71fa5e3564e76fd6786010286fe07ab9e9d33b6b91f46a5b20d947452ea","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {"6379/tcp": [{"HostIp": "0.0.0.0","HostPort": "8081"},{"HostIp": "::","HostPort": "8081"}]},"SandboxKey": "/var/run/docker/netns/d426e71fa5e3","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "38efd7b6043e911a9b9c278c7d6aaa78f8da8808dc9e1dc24faa477d0661c329","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.3","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:03","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "8054906c5bc42e5260d9fc72aa07cb78508cf0ef9c2e19924a13975a0a2c0ddc","EndpointID": "38efd7b6043e911a9b9c278c7d6aaa78f8da8808dc9e1dc24faa477d0661c329","Gateway": "172.17.0.1","IPAddress": "172.17.0.3","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:03","DriverOpts": null}}}}
]

进入容器id对应的目录:

cd /sys/fs/cgroup/memory/docker/35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d/

进入结果:

[root@localhost ~]# cd /sys/fs/cgroup/memory/docker/35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d/[root@localhost 35e0f7357c420335c970e507a452e4f0678e68bfbcb9d5f36d9fc4e9f7e6198d]# ll
总用量 0
-rw-r--r--. 1 root root 0 8月  18 21:29 cgroup.clone_children
--w--w--w-. 1 root root 0 8月  18 21:29 cgroup.event_control
-rw-r--r--. 1 root root 0 8月  18 21:29 cgroup.procs
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.failcnt
--w-------. 1 root root 0 8月  18 21:29 memory.force_empty
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.kmem.failcnt
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.kmem.limit_in_bytes
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.kmem.max_usage_in_bytes
-r--r--r--. 1 root root 0 8月  18 21:29 memory.kmem.slabinfo
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.kmem.tcp.failcnt
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.kmem.tcp.limit_in_bytes
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.kmem.tcp.max_usage_in_bytes
-r--r--r--. 1 root root 0 8月  18 21:29 memory.kmem.tcp.usage_in_bytes
-r--r--r--. 1 root root 0 8月  18 21:29 memory.kmem.usage_in_bytes
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.limit_in_bytes
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.max_usage_in_bytes
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.memsw.failcnt
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.memsw.limit_in_bytes
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.memsw.max_usage_in_bytes
-r--r--r--. 1 root root 0 8月  18 21:29 memory.memsw.usage_in_bytes
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.move_charge_at_immigrate
-r--r--r--. 1 root root 0 8月  18 21:29 memory.numa_stat
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.oom_control
----------. 1 root root 0 8月  18 21:29 memory.pressure_level
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.soft_limit_in_bytes
-r--r--r--. 1 root root 0 8月  18 21:29 memory.stat
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.swappiness
-r--r--r--. 1 root root 0 8月  18 21:29 memory.usage_in_bytes
-rw-r--r--. 1 root root 0 8月  18 21:29 memory.use_hierarchy
-rw-r--r--. 1 root root 0 8月  18 21:29 notify_on_release
-rw-r--r--. 1 root root 0 8月  18 21:29 tasks

容器与主机之间的数据拷贝

docker cp例如:
docker cp  nginx:/www /tmp/    #将nginx容器的/www 拷贝到本地/tmp下

终止容器

终止一个运行中的容器

# 终止一个运行中的容器
docker container stop #查看终止状态的容器
docker container ls -a#重新启动终止容器
docker container start#将一个运行态的容器终止,然后再重新启动
docker container restart

保存镜像

(1) 方式1

用于将 Docker容器 里的文件系统作为一个 tar 归档文件导出到标准输出。

docker export [OPTIONS] CONTAINER例子:
# 将name = redis 的docker容器 的文件系统归档信息输出到文件
docker export -o redis.tar redis

OPTIONS说明:

-o :将输入内容写到文件。

(2)方式二

将指定镜像保存成 tar 归档文件。

docker save [OPTIONS] IMAGE [IMAGE...]例子:
docker save -o redis.tar redis

OPTIONS 说明:

-o :输出到的文件。

载入镜像

docker import 归档文件名称例子:
docker import redis.tar 

查看某个容器的文件目录

docker exec 容器名称 ls
例如:
docker exec mysql ls

在这里插入图片描述

删除容器

docker rm  

详细参数:

(1)-f : 强制删除一个运行中的容器

(2)-l :移除容器间的网络连接,而非容器本身

(3)-v : 删除与容器关联的卷

使用镜像

列出镜像列表

docker images ls

在这里插入图片描述

列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个 标签。

搜索镜像

docker search 镜像名称例如:
docker search redis

在这里插入图片描述

拉取镜像

docker pull 镜像名称:版本号例如:
docker pull redis

在这里插入图片描述

查看是否拉取成功

docker images -a

在这里插入图片描述

打tag

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]例子:
docker tag centos centos:v1

删除镜像

docker rmi 

详细参数:

(1) -f :强制删除;

(2)–no-prune :不移除该镜像的过程镜像,默认移除;

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

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

相关文章

Redis.conf详解

Redis.conf详解 配置文件unit单位对大小写不敏感 包含 网络 bind 127.0.0.1 # 绑定的ip protected-mode yes # 保护模式 port 6379 # 端口设置通用 GENERAL daemonize yes # 以守护进程的方式运行 默认为no pidfile /var/run/redis_6379.pid #如果以后台的方式运行&#xff…

python+django+mysql旅游景点推荐系统-前后端分离(源码+文档)

系统主要采用Python开发技术和MySQL数据库开发技术以及基于OpenCV的图像识别。系统主要包括系统首页、个人中心、用户管理、景点信息管理、景点类型管理、景点门票管理、在线反馈、系统管理等功能&#xff0c;从而实现智能化的旅游景点推荐方式&#xff0c;提高旅游景点推荐的效…

javaee idea创建maven项目,使用el和jstl

如果使用el表达式出现下图问题 解决办法 这是因为maven创建项目时&#xff0c;web.xml头部声明默认是2.3&#xff0c;这个默认jsp关闭el表达式 办法1 在每个需要用到el和jstl的页面的上面加一句: <% page isELIgnored"false" %> 方法2 修改web.xml文件开…

睿思BI旗舰版V5.3正式发布

发布时间&#xff1a;2023-7-20 主要更新内容: 1.增加3D地图功能 2.增加水球图 3.增加扇形图&#xff0c;在数据大屏 - 自定义组件中定义。 4.增加指标引导线功能&#xff0c;在数据大屏 - 自定义组件中定义。 5.详情页增加回调函数功能。 6.大屏/仪表盘模版下载&#xff0c;…

【C++】C++ 引用详解 ⑨ ( 常量引用初始化 | C / C++ 常量分配内存的四种情况 )

文章目录 一、常量引用初始化1、使用 " 普通变量 " 初始化 " 常量引用 "2、使用 " 常量 / 字面量 " 初始化 " 常量引用 "3、C / C 常量分配内存的四种情况4、代码示例 - 常量引用初始化 一、常量引用初始化 1、使用 " 普通变量 &…

<八> objectARX开发:动态拖动Jig创建自定义实体

1、介绍 接上一篇文章,在某些情况下,CAD中的实体对象初始参数并不是固定的,我们需要通过jig动态拖动方式来绘制自定义实体,下面就用一个简单的例子来介绍一下自定义实体动态绘制。   实体形状:包括实体夹点和文字夹点拖动实现。 2、效果 3、源码 static void RYMyGrou…

嵌入式linux之QT交叉编译环境搭建(最简单实测通用版)

这里总结下用于嵌入式linux下的QT交叉编译环境搭建&#xff0c;留作备忘&#xff0c;分享给有需要的小伙伴。不管你的是什么嵌入式linux环境&#xff0c;实测过的通用方法总结。 环境准备 需要准备的环境要求如下&#xff1a; 1.虚拟机(vmvare15.5) 2.ubuntu18.04-x64的linu…

【C语言】探讨蕴藏在表达式求解中的因素

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 &#x1f525;该篇将探讨 操作符 和 类型转换 对表达式求解的影响。 目录&#xff1a; 隐式类型转换算术转换操作符的属性❤️ 结语 隐…

CSDN每日一练 |『异或和』『生命进化书』『熊孩子拜访』2023-08-27

CSDN每日一练 |『异或和』『生命进化书』『熊孩子拜访』2023-08-27 一、题目名称&#xff1a;异或和二、题目名称&#xff1a;生命进化书三、题目名称&#xff1a;熊孩子拜访 一、题目名称&#xff1a;异或和 时间限制&#xff1a;1000ms内存限制&#xff1a;256M 题目描述&…

C++:list使用以及模拟实现

list使用以及模拟实现 list介绍list常用接口1.构造2.迭代器3.容量4.访问数据5.增删查改6.迭代器失效 list模拟实现1.迭代器的实现2.完整代码 list介绍 list是一个类模板&#xff0c;加<类型>实例化才是具体的类。list是可以在任意位置进行插入和删除的序列式容器。list的…

Python序列类型

序列&#xff08;Sequence&#xff09;是有顺序的数据列&#xff0c;Python 有三种基本序列类型&#xff1a;list, tuple 和 range 对象&#xff0c;序列&#xff08;Sequence&#xff09;是有顺序的数据列&#xff0c;二进制数据&#xff08;bytes&#xff09; 和 文本字符串&…

Android BatteryManager的使用及BatteryService源码分析

当需要监控系统电量时&#xff0c;用 BatteryManager 来实现。 参考官网 监控电池电量和充电状态 获取电池信息 通过监听 Intent.ACTION_BATTERY_CHANGED 广播实现&#xff0c;在广播接收器中获取电池信息。 这是个粘性广播&#xff0c;即使过了广播发出的时间点后再注册广…

从零起步:学习数据结构的完整路径

文章目录 1. 基础概念和前置知识2. 线性数据结构3. 栈和队列4. 树结构5. 图结构6. 散列表和哈希表7. 高级数据结构8. 复杂性分析和算法设计9. 实践和项目10. 继续学习和深入11. 学习资源12. 练习和实践 &#x1f389;欢迎来到数据结构学习专栏~从零起步&#xff1a;学习数据结构…

Java实现根据短连接获取1688商品详情数据,1688淘口令接口,1688API接口封装方法

要通过1688的API获取商品详情数据&#xff0c;您可以使用1688开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例&#xff0c;展示如何通过1688开放平台API获取商品详情属性数据接口&#xff1a; 首先&#xff0c;确保您已注册成为1688开放平台的开发者&#xf…

研华I/O板卡 Win10+Qt+Cmake 开发环境搭建

文章目录 一.研华I/O板卡 Win10QtCmake 开发环境搭建 一.研华I/O板卡 Win10QtCmake 开发环境搭建 参考这个链接安装研华I/O板卡驱动程序系统环境变量添加研华板卡dll Qt新建一个c项目 cmakeList.txt中添加研华库文件 cmake_minimum_required(VERSION 3.5)project(advantechDA…

【多线程】Thread类的用法

文章目录 1. Thread类的创建1.1 自己创建类继承Thread类1.2 实现Runnable接口1.3 使用匿名内部类创建Thread子类对象1.4 使用匿名内部类创建Runnable子类对象1.5 使用lambda创建 2. Thread常见的构造方法2.1 Thread()2.2 Thread(Runnable target)2.3 Thread(String name)2.4 Th…

Flink_state 的优化与 remote_state 的探索

摘要&#xff1a;本文整理自 bilibili 资深开发工程师张杨&#xff0c;在 Flink Forward Asia 2022 核心技术专场的分享。本篇内容主要分为四个部分&#xff1a; 相关背景state 压缩优化Remote state 探索未来规划 点击查看原文视频 & 演讲PPT 一、相关背景 1.1 业务概况 从…

【EI检索稳定】第六届电力电子与控制工程国际学术会议(ICPECE 2023)

第六届电力电子与控制工程国际学术会议 2023 6th International Conference on Power Electronics and Control Engineering (ICPECE 2023) 第六届电力电子与控制工程国际学术会议由广西大学主办&#xff0c;重庆大学、华东交通大学、长春理工大学、大连交通大学联合主办。电…

【AI模型】gym强化学习仿真平台配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍gym强化学习仿真平台配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&…

Linux内核学习(十)—— 块 I/O 层(基于Linux 2.6内核)

目录 一、剖析一个块设备 二、缓冲区和缓冲区头 三、bio 结构体 四、请求队列 五、I/O 调度程序 系统中能够随机&#xff08;不需要按顺序&#xff09;访问固定大小数据片&#xff08;chunks&#xff09;的硬件设备称作块设备&#xff0c;这些固定大小的数据片就称作块。最…