如何把Docker容器变成物理机系统

news2024/12/27 11:22:45

如何把容器变成物理机

本文的主题是把容器变成物理机,根据所学的知识。以及通过各种搜索引擎。他们都告诉我们,这是不可能的。这真的是不可能的吗?我不信,那我就要创造奇迹。请继续往下看。本文将教你如何把容器变成物理机。作品来自2678885646@qq.com

这里只讲硬货,不废话!!!

什么是容器

在这里插入图片描述

​ 简单来说,容器是一个隔离的操作系统沙盒,目的是隔离所有操作系统的进程,那么我们也可以称容器的名称为被隔离的进程,在不同维度隔离级别有6个。隔离进程的名称空间是内核提供的功能,必须内核支持才可以。也就是说容器的内核跟宿主机的是同一个内核。Docker官方把它称作集装箱,我觉得这非常的形象,他们都工作在Linux 内核这条船上。

既然现在知道容器是个什么了,接下来要了解的是容器的运行逻辑。在用法上,一般把软件包直接放到容器内,然后在容器启动的时候,执行一个命令或者某个脚本文件,熟悉docker的人如果自己动手构建过自己的容器,就会知道CMD命令和ENTRYPOINT这个指令是定义docker的启动之后的执行逻辑。然后docker会安装启动之后的逻辑执行,若这个进程exit了,那么这个容器的运行状态也是exit状态。但是这些对我们本文的主题来讲并不重要。

docker的资源限制是通过cgroup来实现的,但是这也是针对运行状态的容器才会有资源消耗,我们是要转化这个容器,对我们的操作而言并不重要,另外顺便提一嘴,cgroup也是Linux内核的功能。

在空间占用方向上,(作品来自2678885646@qq.com)通常一个容器只需要几MB到数10MB不等,而咱们操作系统都需要G这个单位去计算,这是为什么呢?后面将会说容器与操作系统共享的几个文件和目录,这个是它变小的关键。

Docker的六个维度的隔离

内容备注内核版本
PID进程编号2.6.24
NET网络设备、网络协议栈、端口2.6.29
IPC信号量、消息队列、共享内存2.6.19
MOUNT文件系统2.4.19
UTS用户名和主机域2.6.19
USER操作系统的用户和用户组3.8.x

为什么容器比物理机占用空间小呢?这个问题涉及到了Linux设计架构,linus大佬在设计Linux的时候将Linux分成了rootfs,内核,vfs(虚拟文件系统)几部分,当然这又是一个巨大的话题,毕竟内核源码超过2760万行,想了解具体逻辑,这并不简单。我们需要知道,虚拟文件系统包括/proc /dev /sys /dev/pts,且不仅仅包括这些,因为过于复杂,对于容器来讲,只需要了解这几个即可。

  • /sys 他是内核的接口,是一个虚拟文件系统,由内核生成。
  • /proc 这个是内存和进程保存的地方,也就是物理硬件的RAM。
  • /dev 这个目录里存储了物理硬件的抽象为文件。
  • /dev/pts 这里面存储了一些虚拟终端

总之这些目录必须存在且由内核生成。刚刚聊到容器占用磁盘空间会比物理机小很多,根本原因是因为物理机是已经启动起来了,大部分文件在物理机种都已经包含,包括内核模块都不需要安装,这些东西对于一个已经启动了的容器来讲是完全不必要的。另外一个方面就是容器内部极度精简,所以到你们看到的时候就只有几十MB。我们今天要做的步骤就有这一步,将所有缺少了的东西全部补全。

什么是物理机

相对而言,物理机抽象概念上来讲是一个完整的操作系统。包括容器内的全部内容,并且包括各种物理硬件的驱动,EFI或者bios引导,内核模块,内核源码。

总而言之,它是一个标准,它是用来定义“完整的系统”。

容器和虚拟机机区别和联系

从用户眼里来看,它们相同的部分是都具有文件系统,都能运行应用程序。在我看来,这只是浅尝辄止罢了。

我不想用传统的眼光看待它们,又是通过运行模式啦,又是通过运行速度,又是性能损耗啦。我觉得这些都是没有太大意义的。这些比较讲了操作系统和容器出现之后的事情,而不是在创造创造这个东西之前。

我要做鲁迅笔下的勇士,不管是蜘蛛还是螃蟹,在尝之前都不知道什么味道,而不是要把尝了之后的味道从侧面告诉大家 “吃螃蟹的人比较多“,”几乎没有吃蜘蛛的人”。而我们就到这个阶段,来比较吃螃蟹和吃蜘蛛的口感,这往往是世俗之人忘记了的根本。

让我们来重新认识操作系统吧

从时间发生的顺序来讲,首先你按了开机键。bios开始从主板芯片CMOS里加载。然后开始读取硬盘里的esp分区,根据grub引导,找到系统内核,开始加载内核,生成vfs文件系统,加载init进程,开机解锁。这时,完整的操作系统就可以运行了。

那么容器的启动过程呢? docker run -it --rm alpine bash?么,不不不。首先他会将rootfs以及overlay进行叠加,放到宿主机系统的某个目录。然后调用内核api生成六个名称空间,将部分系统文件映射到容器内部(fs名称空间内),调用内核生成vfs,然后执行bash进程,这个是这条命令要干的事。

现在我将这俩进行对比,我们补全容器在启动过程中跟物理机不同的地方,这样是不是容器就能像是物理机一样运行了呢?答案是肯定的。让我们实际操作一下试试。

我们需要做什么

  • 制作一个容纳这个容器的磁盘

    • 分区表
    • 分区类型
    • 更新fstab
  • 生成rootfs,并补全缺少的目录和vfs

    • bindmount
    • /sys
    • /proc
    • /dev
    • /dev/pts
    • /etc/reslove.conf
    • hostname
    • /etc/fstab
  • 补全内核

    • linux-image
    • linux-header
  • 补全进程管理器

    • systemd
  • 补全init进程

    • init
  • 补全网络管理

    • NetworkManager
  • 补全grub引导

    • grub-install
  • 重启测试

    • 独立测试

开始干

制作一个容纳这个容器的磁盘

这一步我们通过VMware生成vmdk硬盘并使用DiskGenius进行分区。

VMware步骤:

创建一个空的虚拟机然后增加磁盘,这里我们用50G,实测1G都用不了。

在这里插入图片描述

开启EFI引导

在这里插入图片描述

最终我的虚拟机配置是这样的。

在这里插入图片描述

DiskGenius步骤

在diskgenius里面选择打开刚刚创建的vmdk文件

在这里插入图片描述

转换为GPT分区表

在这里插入图片描述

分区结果展示,我这里使用了1G的esp分区,49G的根分区

在这里插入图片描述

这样我们的磁盘准备工作就完成了。

生成rootfs

回到VMware,开机使用iso镜像进行引导,进入体验模式。如下图所示。

在这里插入图片描述

安装docker

apt update
# 安装docker
apt install curl -y && curl -sSL get.docker.com | bash

分区挂载

# 查看我们刚刚创建的硬盘分区名称
root@ubuntu:~# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0    7:0    0   2.2G  1 loop /rofs
loop1    7:1    0     4K  1 loop /snap/bare/5
loop2    7:2    0    62M  1 loop /snap/core20/1611
loop3    7:3    0  54.2M  1 loop /snap/snap-store/558
loop4    7:4    0 346.3M  1 loop /snap/gnome-3-38-2004/115
loop5    7:5    0  91.7M  1 loop /snap/gtk-common-themes/1535
loop6    7:6    0    47M  1 loop /snap/snapd/16292
sda      8:0    0    50G  0 disk
├─sda1   8:1    0     1G  0 part
└─sda2   8:2    0    49G  0 part 
sr0     11:0    1   3.6G  0 rom  /cdrom
root@ubuntu:~# mount /dev/sda2 /mnt/
root@ubuntu:~# mkdir -pv /mnt/boot/efi
mkdir: 已创建目录 '/mnt/boot'
mkdir: 已创建目录 '/mnt/boot/efi'
root@ubuntu:~# mount /dev/sda1 /mnt/boot/efi/
root@ubuntu:~# df -h
文件系统        容量  已用  可用 已用% 挂载点
udev            1.9G     0  1.9G    0% /dev
tmpfs           389M  1.9M  388M    1% /run
/dev/sr0        3.6G  3.6G     0  100% /cdrom
/dev/loop0      2.2G  2.2G     0  100% /rofs
/cow            1.9G  776M  1.2G   40% /
tmpfs           1.9G     0  1.9G    0% /dev/shm
tmpfs           5.0M  4.0K  5.0M    1% /run/lock
tmpfs           1.9G     0  1.9G    0% /sys/fs/cgroup
tmpfs           1.9G     0  1.9G    0% /tmp
/dev/loop1      128K  128K     0  100% /snap/bare/5
/dev/loop2       62M   62M     0  100% /snap/core20/1611
/dev/loop3       55M   55M     0  100% /snap/snap-store/558
/dev/loop6       47M   47M     0  100% /snap/snapd/16292
/dev/loop5       92M   92M     0  100% /snap/gtk-common-themes/1535
/dev/loop4      347M  347M     0  100% /snap/gnome-3-38-2004/115
tmpfs           389M   60K  389M    1% /run/user/999
tmpfs           389M     0  389M    0% /run/user/0
/dev/sda2        49G   16K   46G    1% /mnt
/dev/sda1      1022M  4.0K 1022M    1% /mnt/boot/efi

创建rootfs

使用当前最新镜像23.10

在这里插入图片描述

root@ubuntu:~# cd /mnt/
root@ubuntu:/mnt# docker export $(docker create ubuntu:23.10) | tar -C . -xvf -


在这里插入图片描述

临时代替内核补全vfs

for i in run sys proc dev dev/shm dev/pts; do echo "mount /$i"; mount --bind /$i /mnt/$i; done
root@ubuntu:/mnt# findmnt | grep mnt
│ │ └─/run/snapd/ns/snap-store.mnt         nsfs[mnt:[4026532702]] nsfs            rw
├─/mnt                                     /dev/sda2              ext4            rw,relatime
│ ├─/mnt/boot/efi                          /dev/sda1              vfat            rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro
│ ├─/mnt/run                               tmpfs                  tmpfs           rw,nosuid,nodev,noexec,relatime,size=398272k,mode=755,inode64
│ ├─/mnt/sys                               sysfs                  sysfs           rw,nosuid,nodev,noexec,relatime
│ ├─/mnt/proc                              proc                   proc            rw,nosuid,nodev,noexec,relatime
│ └─/mnt/dev                               udev                   devtmpfs        rw,nosuid,noexec,relatime,size=1952868k,nr_inodes=488217,mode=755,inode64
│   ├─/mnt/dev/shm                         tmpfs                  tmpfs           rw,nosuid,nodev,inode64
│   └─/mnt/dev/pts                         devpts                 devpts          rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000

root@ubuntu:/mnt#

进入rootfs补全系统文件

使用下面的命令进入新的根分区

# chroot /mnt/

补全DNS配置

root@ubuntu:/# echo "nameserver 8.8.8.8" > /etc/resolv.conf

补全挂载的配置文件

root@ubuntu:/# echo "/dev/sda2 / ext4 defaults 0 1" >> /etc/fstab
root@ubuntu:/# echo "/dev/sda1 /boot/efi vfat umask=0077,shortname=winnt 0 2" >> /etc/fstab
root@ubuntu:/# cat /etc/fstab
# UNCONFIGURED FSTAB FOR BASE SYSTEM
/dev/sda2 / ext4 defaults 0 1 
/dev/sda1 /boot/efi vfat umask=0077,shortname=winnt 0 2

安装dialog

root@ubuntu:/# apt install dialog

安装时区

 apt install tzdata
 
 Configuring tzdata
------------------

Please select the geographic area in which you live. Subsequent configuration questions will narrow this down by presenting a list of cities, representing the time zones in which they are located.

  1. Africa  2. America  3. Antarctica  4. Arctic  5. Asia  6. Atlantic  7. Australia  8. Europe  9. Indian  10. Pacific  11. US  12. Etc
Geographic area: 5

Please select the city or region corresponding to your time zone.

  1. Aden      9. Baghdad   17. Chita       25. Dushanbe     33. Irkutsk    41. Kashgar       49. Macau         57. Omsk        65. Riyadh         73. Tashkent     81. Urumqi
  2. Almaty    10. Bahrain  18. Choibalsan  26. Famagusta    34. Istanbul   42. Kathmandu     50. Magadan       58. Oral        66. Sakhalin       74. Tbilisi      82. Ust-Nera
  3. Amman     11. Baku     19. Chongqing   27. Gaza         35. Jakarta    43. Khandyga      51. Makassar      59. Phnom_Penh  67. Samarkand      75. Tehran       83. Vientiane
  4. Anadyr    12. Bangkok  20. Colombo     28. Harbin       36. Jayapura   44. Kolkata       52. Manila        60. Pontianak   68. Seoul          76. Tel_Aviv     84. Vladivostok
  5. Aqtau     13. Barnaul  21. Damascus    29. Hebron       37. Jerusalem  45. Krasnoyarsk   53. Muscat        61. Pyongyang   69. Shanghai       77. Thimphu      85. Yakutsk
  6. Aqtobe    14. Beirut   22. Dhaka       30. Ho_Chi_Minh  38. Kabul      46. Kuala_Lumpur  54. Nicosia       62. Qatar       70. Singapore      78. Tokyo        86. Yangon
  7. Ashgabat  15. Bishkek  23. Dili        31. Hong_Kong    39. Kamchatka  47. Kuching       55. Novokuznetsk  63. Qostanay    71. Srednekolymsk  79. Tomsk        87. Yekaterinburg
  8. Atyrau    16. Brunei   24. Dubai       32. Hovd         40. Karachi    48. Kuwait        56. Novosibirsk   64. Qyzylorda   72. Taipei         80. Ulaanbaatar  88. Yerevan
Time zone: 69


Current default time zone: 'Asia/Shanghai'
Local time is now:      Tue May 16 15:12:32 CST 2023.
Universal Time is now:  Tue May 16 07:12:32 UTC 2023.
Run 'dpkg-reconfigure tzdata' if you wish to change it.

Setting up tzdata-icu (2023c-4exp1ubuntu1) ...

安装systemd进程管理器 和 init进程

apt install systemd init

安装tar

apt install tar

安装最新Linux内核

这时我们会看到很多的依赖包下载下来了,439M+。

安装过程种会有很多报错,需要安装其他依赖。

root@ubuntu:/# apt install linux-image-6.2.0-21-generic linux-headers-6.2.0-21-generic
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  adduser busybox-initramfs cpio dmsetup gettext-base grub-common grub-gfxpayload-lists grub-pc grub-pc-bin grub2-common initramfs-tools initramfs-tools-bin initramfs-tools-core klibc-utils kmod
  libbrotli1 libdevmapper1.02.1 libefiboot1 libefivar1 libelf1 libfreetype6 libfuse3-3 libklibc libkmod2 libpng16-16 libssl3 libzstd1 linux-base linux-headers-6.2.0-21 linux-modules-6.2.0-21-generic
  os-prober systemd-hwe-hwdb ucf udev zstd
Suggested packages:
  liblocale-gettext-perl perl cron ecryptfs-utils libarchive-dev multiboot-doc grub-emu mtools xorriso desktop-base console-setup bash-completion fuse3 fdutils linux-doc | linux-source-6.2.0
  linux-tools linux-modules-extra-6.2.0-21-generic
The following NEW packages will be installed:
  adduser busybox-initramfs cpio dmsetup gettext-base grub-common grub-gfxpayload-lists grub-pc grub-pc-bin grub2-common initramfs-tools initramfs-tools-bin initramfs-tools-core klibc-utils kmod
  libbrotli1 libdevmapper1.02.1 libefiboot1 libefivar1 libelf1 libfreetype6 libfuse3-3 libklibc libkmod2 libpng16-16 libssl3 linux-base linux-headers-6.2.0-21 linux-headers-6.2.0-21-generic
  linux-image-6.2.0-21-generic linux-modules-6.2.0-21-generic os-prober systemd-hwe-hwdb ucf udev zstd
The following packages will be upgraded:
  libzstd1
1 upgraded, 36 newly installed, 0 to remove and 6 not upgraded.
Need to get 81.5 MB of archives.
After this operation, 439 MB of additional disk space will be used.
Do you want to continue? [Y/n]


安装NetworkManager网络管理


apt install network-manager

生成引导目录,安装efi引导

错误示范,和解决方法

# 出错示范,如果出现这个问题,需要一个带有EFI系系统,来修复这个efi,网络上种种使用bios修复,其实是使用了grub-bios引导。
# 解决方法是安装grub-pc-bin安装包,使用--removable 选项
root@ubuntu:/# grub-install --removable /dev/sda
Installing for i386-pc platform.
grub-install: warning: this GPT partition label contains no BIOS Boot Partition; embedding won't be possible.
grub-install: warning: Embedding is not possible.  GRUB can only be installed in this setup by using blocklists.  However, blocklists are UNRELIABLE and their use is discouraged..
grub-install: error: will not proceed with blocklists.


apt install grub-pc-bin
apt install grub-efi-amd64
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB --recheck --no-floppy


grub-install --target=x86_64-efi --bootloader-id=Shoulong --recheck --no-floppy

设置密码

passwd

重启测试

效果展示

可以看到根分区只有893M

在这里插入图片描述

总结脚本

快速挂载

mount /dev/sda2 /mnt/
mount /dev/sda1 /mnt/boot/efi/
for i in run sys proc dev dev/shm dev/pts; do echo "mount /$i"; mount --bind /$i /mnt/$i; done

最后,因为Linus大佬设计系统的兼容性真的是太好了,真的可以容器和宿主机之间随意变换。致敬大佬(鞠躬)。
这样就做成了不到800M+的一个系统,是不是比官方的mini版更加迷你呢?

有疑问或有需求或有工作推荐可以dd我。

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

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

相关文章

PBDF8WN、FPBJXDN、FPBMXDN插装式比例阀放大器

PBHB8WN、PBFB8WN、PBDB8WN、PBHF8WN、PBFF8WN、PBDF8WN、PBJB8WN、RPEILAN、RBAPXAN、RBANXAN、FPBGXDN、FPBDXDN、FPBJXDN、FPBMXDN、FPBFXDN、FPBIXDN、FREPXAN比例插装阀一种高精度液压控制元件,其采用了先进的比例控制技术,可以根据控制信号快速地调…

linux介绍

/ 是所有目录的源点目录结构整体是一棵倒挂的树bin:存放二进制可执行文件boot:存放系统引导时使用的各类文件dev:存放设备文件etc:存放系统配置文件home:存放系统用户的文件lib:存放系统运行所需的共享库和…

传输层:TCP协议

传输层中有两个重要的协议:TCP协议和UDP协议。本博文分享的是TCP协议,不仅分享其协议格式,特点等等,还有应答机制、超时传送机制、连接管理机制、滑动窗口、阻塞控制等等。 TCP协议 TCP全称为 "传输控制协议(Transmission C…

Python中的自定义函数创建方法和应用举例

Python中的自定义函数创建方法和应用举例 在Python语言中,函数是一组能够完成特定任务的语句模块,可分为内置函数、第三方模块函数和自定义函数。其中,内置函数是Python系统自带的函数;模块函数是NumPy等库中的函数。 1.自定义函…

Java【网络原理2】TCP 协议的三次握手和四次挥手到底是什么意思?

文章目录 前言一、三次握手三次握手的作用 二、四次挥手总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: 📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等 📗 Java数据结构: 顺序表, 链…

mysqlbinlog delete恢复成insert

不小心把数据删掉了 首先要拿到binlog文件 执行以下命令行 /usr/local/mysql/bin/mysqlbinlog --base64-outputdecode-rows --start-datetime“2023-05-19 09:01:32” --stop-datetime“2023-05-19 09:01:35” -v /Users/zylong/Downloads/mysql-bin.003178 --result-file/Use…

第一章 数据库操作

一、 数据库操作 1.1 创建数据库 创建数据库是指在数据库系统中划分一块空间,用来存储相应的数据,这是进行表操作的基础,也是数据库管理的基础在MySQL中创建数据库之前,可以使用show语句来显示当前已经存在的数据库,…

java基于springboot协同过滤算法的网上图书商城推荐系统m44xq2

开发环境 开发语言:Java 框架:springboot 技术:JSP JDK版本:JDK1.8 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏览器:谷歌浏览器功能介绍 Spring…

微服务—Redis实用篇-黑马头条项目用户签到功能(使用bitmap实现)与UV统计

微服务—Redis实用篇-黑马头条项目用户签到功能(使用bitmap实现)与UV统计 1、用户签到 1.1、用户签到-BitMap功能演示 我们针对签到功能完全可以通过mysql来完成,比如说以下这张表 用户一次签到,就是一条记录,假如有…

npm 账户的创建、测试、登录

目录 1、账户的创建 2、测试创建的账户 3、通过电子邮件接收一次性密码 3.1 使用一次性密码登录: 3.2 启用双因素身份验证: 3.3 无法访问电子邮件 1、账户的创建 如果您还没有npm用户帐户,您可以创建一个帐户,以便在公共注…

MATLAB 之 二维图形绘制的基本函数和辅助操作

文章目录 一、绘制二维曲线的基本函数1. plot 函数的基本用法2. 含多个输入参数的 plot 函数3. 含选项的 plot 函数4. 双纵坐标函数 plotyy 二、绘制绘制图像的辅助操作1. 图形标注2. 坐标控制3. 图形保持4. 图形窗口的分割 二维图形是将平面坐标上的数据点连接起来的平面图形。…

C++的cout详解

2023年5月20日,周六早上: 我发现我找不到非常详细的cout类的成员函数,只好自己写了。 不定期更新。 cout的继承关系 cout类继承自ostream类,ostream类继承自ios类,ios类继承自ios_base类 cout类拥有的所有成员函数 …

包图的画法

包图 1.包图 1.1概念 包图是UML中用来组织模型元素的模型元素。 可以把包图比作一个存放模型元素的箱子或者是容器,里面可以可以存放各种各样的模型元素。 包图中可以包含的信息主要有:类 构件 用例 结点 活动 状态 等其他的相关的模型元素。 1.2包…

秒杀场景checklist

在面试中经常碰到的问题,列下来备忘。

车载以太网 - SomeIP - 协议用例 - Messages_01

目录 Service Discovery Messages 1、验证Instance ID为0xFFFF时DUT需要返回该Serveice ID包含的所有Instance ID

chatgpt赋能Python-python3去掉空格

Python3去掉空格——让你的代码更整洁高效 在Python3编程中,去掉无用的空格可以使代码更具可读性和高效性。因此,在本文中,我们将介绍如何使用Python3去掉空格,包括字符串中的空格和代码文件中的空格。 字符串中的空格 在Pytho…

学系统集成项目管理工程师(中项)系列23a_信息系统集成及服务管理(上)

1. 提供的专业信息技术咨询服务、系统集成服务、技术支持服务、运行维护服务等工作 2. 信息技术咨询服务 2.1. 信息系统集成及服务的前端环节 2.2. 为企业提供信息化建设规划和解决方案 3. 原因 3.1. 不具备技术实力的系统集成商搅乱信息系统集成及服务市场 3.2. 一些建设…

chatgpt赋能Python-python3快捷键大全

Python3快捷键大全 介绍 Python是一种高级编程语言,广泛应用于科学计算、人工智能、网络编程、Web开发和数据分析等领域。Python具有简洁、易读、易学和可扩展等特点,因此成为了生产力非常高的编程语言之一。Python3是Python语言的最新版本&#xff0c…

印度和巴基斯坦网络优势和劣势的综合研究

由于网络空间在当今世界的重要性日益增加,各国已将网络安全放在首位并开发技能来保护其重要基础设施、数字资产和私人数据。 没有豁免适用于印度和巴基斯坦,这两个拥有动荡历史的核武器邻国。 这项研究深入比较了他们的网络能力,并评估了巴…

基于DBSCAN密度聚类的风电-负荷场景削减方法

​目录 ​ 1 主要内容 基于密度聚类的数据预处理: 场景提取: 算法流程: 2 部分程序 3 程序结果 4 下载链接 1 主要内容 该程序复现文章《氢能支撑的风-燃气耦合低碳微网容量优化配置研究》第三章内容,实现的是基于DBSCAN…