Openstack服务器平台搭建手册
PS:本片文章为摘抄文章,仅做学习和记录使用,原创作者不易,请支持原创作者!!谢谢!!
原创链接:https://blog.csdn.net/lj2023103338/article/details/133999474
Openstack版本:Q版本(chinaskills_cloud_iaas.iso)其他版本也可以
配置需求:一台交换机(能通外网的交换机,这里不做网络的配置),两台服务器(CPU,内存和硬盘等资源越大越好),装有CentOS系统的启动盘(这里使用CentOS-7-x86_64-DVD-1804.iso作为例子)
一、设备环境的配置
1.交换机的配置
为三层交换机配置vlan
<H3C>system-view # 进入系统视窗界面
System View: return to User View with Ctrl+Z.
[H3C]vlan 100 #创建vlan,100为vlanID(注意:记住这个vlanID),以vlan100为例,创建后会进入vlan视窗界面
[H3C-vlan100]int vlan 100 #进入vlan100的配置界面
[H3C-Vlan-interface100]ip address 10.2.12.9 255.255.254.0 #配置vlan100的IP和掩码(这个IP会被当做这个这个vlan内端口IP的内网网关)我们以10.2.12.9/23为例
[H3C-Vlan-interface100]qu #退出配置界面
[H3C]int range GigabitEthernet 1/0/1 to GigabitEthernet 1/0/2 #进入端口配置界面,根据实际情况来,这里我们以g1/0/1,g1/0/2端口为例,这两个端口将作为两台服务器的第一张网卡的接口
[H3C-if-range]port link-type access #端口连接模式转为access模式
[H3C-if-range]port access vlan 100 #端口划分到vlan100当中
[H3C-if-range]qu #退出接口配置界面
[H3C]int range GigabitEthernet 1/0/9 to GigabitEthernet 1/0/10 #进入端口配置界面,根据实际情况来,这里我们以g1/0/9,g1/0/10端口为例,这两个端口将作为两台服务器的第二张网卡的接口
[H3C-if-range]port link-type trunk #端口连接模式转为trunk模式
[H3C-if-range]port trunk permit vlan all #放行所有vlan
[H3C]sa sa fo #保存配置
Validating file. Please wait...
Saved the current configuration to mainboard device successfully.
2.网线连接
配置完交换机之后,就需要用网线将服务器等设备与交换机连接起来。将两台服务器的网口一连接到交换机的1-2口接上;将两台服务器的网口二连接到交换机的9-10接口上。(一般三层交换机的1-8接口为acces模式,9-16为trunk模式,17-24为access模式)
3.启动盘的配置
在电脑上获取CentOS-7-x86_64-DVD-1804.iso的镜像包(CentOS7.5),使用MultiBootUSB等启动盘制作工具,将安装镜像写入U盘。
4.启动服务器
服务器接上电源,插好网线,将启动盘插入服务器的USB接口中。开启电源,启动服务器。
安装系统(Install CentOS 7),等待一会后出现这个界面
语言尽量选择English,点击Continue
进入这个页面后选择INSTALLATION DESTINATION
点击勾选所需要的硬盘,注意,在使用启动盘安装系统时会在红框处出现额外的盘(我用的虚拟机提供的图片)并且名称为Flash Disk,那是我们的启动盘,切记不能勾选,否则会出现系统文件丢失的错误
接着在其他存储选项(Other Storage Options)中选择I will configure partitioning
,之后点击Done
swap可以给个2G
boot可以给个1G
根目录/
将全部都给它
**PS:**由于我们是多个盘合成的,所以会出现一个盘一个盘加的情况
这种情况只需要把 /
删除,重新配置就可
回到这个页面完成配置,日期&时间可以根据实际时间进行调整。完成配置,点击 Begin Installation
配置Root用户密码,点击done回到安装页面等待安装完毕。
安装完毕,点击重启。(两台服务器都需要安装)
5.IP配置
我们这里用10.2.12.0/23
这个网络地址进行IP的分配(IP地址根据实际情况进行分配)
节点 | 端口 | 网卡 | IP |
---|---|---|---|
Controller(控制节点) | g1/0/1 | 网卡一 | 10.2.12.10/23 |
Compute(计算接待你) | g1/0/2 | 网卡一 | 10.2.12.11/23 |
**注:**服务器只需要为网口一配置IP地址。由于CentOS 7版本的linux系统会根据不同的主板型号与网卡设备型号,赋予网卡不同的设备名称,所以我们在配置网卡的IP地址的时候,需要特别注意相应的网卡设备对应的实际名称。本文档以网卡一的设备名为enp61s0f0、网卡二的设备名为enp61s0f1为实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #Controller节点(根据实际情况来) [root@localhost ~] # vi /etc/sysconfig/network-scripts/ifcfg-enp61s0f0 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=static #dhcp修改为static DEFROUTE= yes IPV4_FAILURE_FATAL=no IPV6INIT= yes IPV6_AUTOCONF= yes IPV6_DEFROUTE= yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=enp61s0f0 UUID=54d5a377-db90-4f61-a434-fd34982e1284 DEVICE=enp61s0f0 ONBOOT= yes #no改为yes IPADDR=10.2.12.10 #IP地址 NETMASK=255.255.254.0 #子网掩码(也可以使用PREFIX=23) GATEWAY=10.2.13.254 #网关 DNS1=10.8.12.106 #DNS服务器地址 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #Compute节点 [root@localhost ~] # vi /etc/sysconfig/network-scripts/ifcfg-enp61s0f0 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=static #dhcp修改为static DEFROUTE= yes IPV4_FAILURE_FATAL=no IPV6INIT= yes IPV6_AUTOCONF= yes IPV6_DEFROUTE= yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=enp61s0f0 UUID=066f885c-33d5-4047-994e-38b6a0d84bc8 DEVICE=enp61s0f0 ONBOOT= yes #no改为yes IPADDR=10.2.12.11 #IP地址 NETMASK=255.255.254.0 #子网掩码(也可以使用PREFIX=23) GATEWAY=10.2.13.254 #网关 DNS1=10.8.12.106 #DNS服务器地址 |
IP配置好后重启网络
1 2 | #两台机子都要做 [root@localhost ~] # systemctl restart network |
二、Openstack平台部署
1.节点规划
节点 | IP |
---|---|
Controller(控制节点) | 10.2.12.10 |
Compute(计算节点) | 10.2.12.11 |
2.基础环境配置
远程工具连接
使用SecureCRT等远程工具进行连接
修改主机名以及配置主机名映射
1 2 3 4 5 6 7 | #两个节点都需要修改 #controller节点 [root@localhost ~] # hostnamectl set-hostname controller [root@localhost ~] # logout #compute节点 [root@localhost ~] # hostnamectl set-hostname compute [root@localhost ~] # logout |
1 2 3 4 5 6 7 | [root@controller ~] # vi /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 lo calhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 lo calhost6.localdomain6 10.2.12.12 controller #添加这两行,前面为两个主机的IP地址 10.2.12.17 compute #后面为两个主机的主机名 |
关闭防火墙以及Selinux
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [root@controller ~] # #systemctl stop firewalld && systemctl disable firewalld [root@controller ~] # #vi /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX=permissive # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enf orcing. # disabled - No SELinux policy is loaded. SELINUX=permissive #enforcing改为permissive # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only sel ected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted<em id = "__mceDel" style= "background-color: rgba(255, 255, 255, 1); font-family: "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px" > < /em > |
上传资源包
这里用到两个资源包,一个是Openstack包chinaskills_cloud_iaas.iso
,以及CentOS7的系统镜像包CentOS-7-x86_64-DVD-1804.iso
。我们第二个主机的yum源可以依靠ftp服务器实现所以只需上传至controller节点并配置好ftp服务器即可。
1 2 3 4 5 | #只需上传至controller节点 [root@controller ~] # ll -rw-------. 1 root root 1665 Jun 29 18:18 anaconda-ks.cfg -rw-r--r--. 1 root root 4470079488 Jun 29 19:38 CentOS-7-x86_64-DVD-1804.iso -rw-r--r--. 1 root root 3799093248 Jun 29 19:38 chinaskills_cloud_iaas.iso |
配置yum源
1 2 3 4 5 6 7 | [root@controller ~] # mkdir /opt/{centos,iaas} #创建centos和iaas目录 [root@controller ~] # mount -o loop CentOS-7-x86_64-DVD-1804.iso /mnt/ #挂载CentOS-7-x86_64-DVD-1804.iso镜像内容至/mnt/目录 [root@controller ~] # cp -rvf /mnt/* /opt/centos/ #拷贝/mnt/目录下的内容至/opt/centos/目录 [root@controller ~] # umount /mnt #取消挂载 [root@controller ~] # mount -o loop chinaskills_cloud_iaas.iso /mnt/ #挂载chinaskills_cloud_iaas.iso镜像内容至/mnt/目录 [root@controller ~] # cp -rvf /mnt/* /opt/iaas/ #拷贝/mnt/目录下的内容至/opt/iaas/目录 [root@controller ~] # umount /mnt #取消挂载 |
Controller节点的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #controller节点 [root@controller ~] # mv /etc/yum.repos.d/* /media/ #备份系统yum源 [root@controller ~] # vi /etc/yum.repos.d/local.repo #编写yum源文件 [centos] #源的名字 name=centos #源的名字 baseurl= file : ///opt/centos #源的地址,file:指本地文件 gpgcheck=0 #是否开启gpg检查,0为不开启,1为开启 enabled=1 #是否开机自启动,0为不开启,1为开启 [iaas] name=iaas baseurl= file : ///opt/iaas/iaas-repo gpgcheck=0 enabled=1 #设置完毕,保存文件 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #验证yum源配置 [root@controller ~] # yum clean all && yum repolist Loaded plugins: fastestmirror Cleaning repos: centos iaas Cleaning up everything Maybe you want: rm -rf /var/cache/yum , to also free up space taken by orphaned data from disabled or removed repos Cleaning up list of fastest mirrors Loaded plugins: fastestmirror Determining fastest mirrors centos | 3.6 kB 00:00 iaas | 2.9 kB 00:00 (1 /3 ): centos /primary_db | 3.1 MB 00:00 (2 /3 ): centos /group_gz | 166 kB 00:00 (3 /3 ): iaas /primary_db | 1.4 MB 00:00 repo id repo name status centos centos 3,971 iaas iaas 3,232 repolist: 7,203 |
1 2 3 4 | #安装vsftpd服务(即ftp服务) [root@controller ~] # yum -y install vsftpd [root@controller ~] # ehco anon_root=/opt >> /etc/vsftpd/vsftpd.conf #将anon_root=/opt这个内容追加写入至/etc/vsftpd/vsftpd.conf配置文件使得ftp服务的根目录为controller节点的/opt目录,这样我们第二个主机便可访问这个目录 [root@controller ~] # systemctl restart vsftpd && systemctl enable vsftpd #重启vsftpd服务并设置开机自启动 |
Compute节点的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #compute节点 [root@compute ~] # mv /etc/yum.repos.d/* /media/ #备份系统yum源 [root@compute ~] # vi /etc/yum.repos.d/local.repo #编写yum源文件 [centos] name=centos baseurl= ftp : //controller/centos #controller节点设置了ftp服务,所以compute节点使用ftp://controller/centos就可以访问对应目录(controller可以改为对应IP,因为添加了主机映射所以可以使用controller) gpgcheck=0 enabled=1 [iaas] name=iaas baseurl= ftp : //controller/iaas/iaas-repo gpgcheck=0 enabled=1 #设置完毕,保存文件 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #验证yum源配置 [root@compute ~] # yum clean all && yum repolist Loaded plugins: fastestmirror Cleaning repos: centos iaas Cleaning up everything Maybe you want: rm -rf /var/cache/yum , to also free up space taken by orphaned data from disabled or removed repos Cleaning up list of fastest mirrors Loaded plugins: fastestmirror Determining fastest mirrors centos | 3.6 kB 00:00 iaas | 2.9 kB 00:00 (1 /3 ): centos /group_gz | 166 kB 00:00 (2 /3 ): iaas /primary_db | 1.4 MB 00:00 (3 /3 ): centos /primary_db | 3.1 MB 00:00 repo id repo name status centos centos 3,971 iaas iaas 3,232 repolist: 7,203 |
配置openstack环境变量
1 2 3 | #两个节点安装iaas-xiandain [root@controller ~] # yum install -y iaas-xiandian [root@compute ~] # yum install -y iaas-xiandian |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | #controller节点配置openrc.sh文件 [root@controller ~] # vi /etc/xiandian/openrc.sh #--------------------system Config--------------------## #Controller Server Manager IP. example:x.x.x.x HOST_IP=10.2.12.10 #controller节点IP #Controller HOST Password. example:000000 HOST_PASS=000000 #Controller Server hostname. example:controller HOST_NAME=controller #controller节点主机名 #Compute Node Manager IP. example:x.x.x.x HOST_IP_NODE=10.2.12.11 #compute节点IP #Compute HOST Password. example:000000 HOST_PASS_NODE=000000 #Compute Node hostname. example:compute HOST_NAME_NODE=compute #compute节点主机名 #--------------------Chrony Config-------------------## #Controller network segment IP. example:x.x.0.0/16(x.x.x.0/24) network_segment_IP=10.2.12.0 /23 #网络地址IP #--------------------Rabbit Config ------------------## #user for rabbit. example:openstack RABBIT_USER=openstack #Password for rabbit user .example:000000 RABBIT_PASS=000000 #--------------------MySQL Config---------------------## #Password for MySQL root user . exmaple:000000 DB_PASS=000000 #--------------------Keystone Config------------------## #Password for Keystore admin user. exmaple:000000 DOMAIN_NAME=demo ADMIN_PASS=000000 DEMO_PASS=000000 #Password for Mysql keystore user. exmaple:000000 KEYSTONE_DBPASS=000000 #--------------------Glance Config--------------------## #Password for Mysql glance user. exmaple:000000 GLANCE_DBPASS=000000 #Password for Keystore glance user. exmaple:000000 GLANCE_PASS=000000 #--------------------Nova Config----------------------## #Password for Mysql nova user. exmaple:000000 NOVA_DBPASS=000000 #Password for Keystore nova user. exmaple:000000 NOVA_PASS=000000 #--------------------Neturon Config-------------------## #Password for Mysql neutron user. exmaple:000000 NEUTRON_DBPASS=000000 #Password for Keystore neutron user. exmaple:000000 NEUTRON_PASS=000000 #metadata secret for neutron. exmaple:000000 METADATA_SECRET=000000 #Tunnel Network Interface. example:x.x.x.x INTERFACE_IP=10.2.12.10 #本主机IP,必须一一对应 #External Network Interface. example:eth1 INTERFACE_NAME=enp61s0f1 #External Network The Physical Adapter. example:provider Physical_NAME=provider #First Vlan ID in VLAN RANGE for VLAN Network. exmaple:101 minvlan=1 #VLAN区间要将交换机所处的网段囊括进去,即100要在区间内 #Last Vlan ID in VLAN RANGE for VLAN Network. example:200 maxvlan=300 #--------------------Cinder Config--------------------## #Password for Mysql cinder user. exmaple:000000 CINDER_DBPASS=000000 #Password for Keystore cinder user. exmaple:000000 CINDER_PASS=000000 #Cinder Block Disk. example:md126p3 BLOCK_DISK= #不使用此服务,不进行磁盘分配 #--------------------Swift Config---------------------## #Password for Keystore swift user. exmaple:000000 SWIFT_PASS=000000 #The NODE Object Disk for Swift. example:md126p4. OBJECT_DISK= #不使用此服务,不进行磁盘分配 #The NODE IP for Swift Storage Network. example:x.x.x.x. STORAGE_LOCAL_NET_IP=10.2.12.11 #compute节点IP #--------------------Heat Config----------------------## #Password for Mysql heat user. exmaple:000000 HEAT_DBPASS=000000 #Password for Keystore heat user. exmaple:000000 HEAT_PASS=000000 #--------------------Zun Config-----------------------## #Password for Mysql Zun user. exmaple:000000 ZUN_DBPASS=000000 #Password for Keystore Zun user. exmaple:000000 ZUN_PASS=000000 #Password for Mysql Kuryr user. exmaple:000000 KURYR_DBPASS=000000 #Password for Keystore Kuryr user. exmaple:000000 KURYR_PASS=000000 #--------------------Ceilometer Config----------------## #Password for Gnocchi ceilometer user. exmaple:000000 CEILOMETER_DBPASS=000000 #Password for Keystore ceilometer user. exmaple:000000 CEILOMETER_PASS=000000 #--------------------AODH Config----------------## #Password for Mysql AODH user. exmaple:000000 AODH_DBPASS=000000 #Password for Keystore AODH user. exmaple:000000 AODH_PASS=000000 #--------------------Barbican Config----------------## #Password for Mysql Barbican user. exmaple:000000 BARBICAN_DBPASS=000000 #Password for Keystore Barbican user. exmaple:000000 BARBICAN_PASS=000000 #配置完成,保存<em id="__mceDel" style="background-color: rgba(255, 255, 255, 1); font-family: "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px"> </em> |
删除前面多余的#
可在底线命令模式下输入%s/^.//g
,也可使用%s/PASS=/PASS=000000/g
进行密码的快速配置
可以将controller节点的/etc/xiandian/openrc.sh
文件传输至compute节点
1 | [root@controller ~] # scp /etc/xiandian/openrc.sh compute:/etc/xiandian/openrc.sh |
注意:传输至compute节点后要将
#Tunnel Network Interface. example:x.x.x.x
INTERFACE_IP=10.2.12.10
中的INTERFACE_IP=10.2.12.10改为10.2.12.11与compute节点IP一一对应
3.安装Openstack各个组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | [root@controller ~] # cd /usr/local/bin #此处可以查看脚本 #执行iaas-pre-host.sh脚本 [root@controller ~] # iaas-pre-host.sh [root@compute ~] # iaas-pre-host.sh #安装完成后可重启(reboot)或者退出远程连接重进(ctrl+d) #执行iaas-install-mysql.sh脚本 [root@controller ~] # iaas-install-mysql.sh #执行iaas-install-keystone脚本 [root@controller ~] # iaas-install-keystone.sh #执行iaas-install-glance.sh脚本 [root@controller ~] # iaas-install-glance.sh #执行iaas-install-nova-controller.sh和iaas-install-nova-compute.sh脚本 [root@controller ~] # iaas-install-nova-controller.sh [root@compute ~] # iaas-install-nova-compute.sh #执行iaas-install-neutron-controller.sh和iaas-install-neutron-compute.sh脚本 [root@controller ~] # iaas-install-neutron-controller.sh [root@compute ~] # iaas-install-nova-compute.sh #执行iaas-install-dashboard.sh脚本 [root@controller ~] # iaas-install-dashboard.sh |
注意跑脚本的顺序以及跑脚本的对应主机是哪个,否则将无法搭建完成
打开浏览器访问网址 :http://10.2.12.10/dashboard (账号:admin,密码:000000)
三、Openstack平台的基础使用
1.创建外部网络
- 名称:可以随意填写(这里填了ExtNet)
- 项目:选择admin项目
- 供应商网络类型:选择VLAN
- 物理网络:使用我们在环境变量写的provider
- 段ID:使用我们的交换机配置好的VLAN100
- 启用管理员状态:选择启用
- 共享的:选择共享
- 外部网络:选择创建外部网络
- 创建子网:选择创建
-
子网名称:可以随意填写(这里填写ExtSNet)
-
网络地址:10.2.12.0/23(使用实际的网络地址)
-
IP版本:IPv4
-
网关IP:10.2.13.254(使用实际的路由网关IP)
这些可填可不填
-
激活dhcp:选择激活后能够从IP池自动分配IP自动分配IP
-
分配地址吃:自动分配地址的IP范围,不设置将会在设定的子网范围内进行随机分配(这里设置10.2.12.20,10.2.13.253)
-
DNS服务器:提供域名解析,写了多个会根据每行进行读取(每行一个)
-
主机路由:定义特定的目标网络活主机的访问路径
2.配置安全组
需要使创建的云主机能够使用SecrueCRT远程连接工具连接,所以安全组遵循三进三出
红框内是添加的安全组,点击右边的添加规则可以添加安全组规则,点击删除规则可以删除安全组规则
我们删除全部规则重新创建规则
选择规则
选择红框内的三种规则
三种规则入和出均添加一项,最终共六项规则.
3.创建云主机类型
- 名称:随意填写(可以根据所对应的资源填写)
- ID:填了就根据填写ID创建,否则将会自动生成
- VCPU数量:创建的cpu数量
- 内存:创建的内存大小
- 根磁盘:创建的磁盘大小
4.镜像上传
- 镜像名称:随意填写
- 文件:上传所需要使用的镜像文件
- 镜像格式:选择QCOW2格式
5.创建云主机
- 名称:随意填写
右边箭头点击可使用上传的镜像
右边的箭头点击可使用创建云主机类型
右边箭头点击可给云主机分配网络(分配完后创建会自动生成一个IP,也可使用网络接口固定接口IP)
右边箭头点击可以使用安全组(默认使用Default安全组)
点击创建实例,右边状态栏显示运行,没有错误便成功了.
四、常见报错
(11条消息) openstack常见错误总结_failed to initialize spice server_Junfei-Yang的博客-CSDN博客
(11条消息) 云计算|OpenStack|错误记录和解决方案(不定时更新)_openstack网络出错_晚风_END的博客-CSDN博客
…
出现常见报错可以查看上面这些网址
1.No valid host was found.
可能是因为模拟环境的问题导致创建时找不到可用主机,可以使用qemu模拟器进行创建
1 2 3 4 5 | #compute节点 [root@compute ~] # crudini --set /etc/nova/nova.conf libvirt virt_type qemu [root@compute ~] ##systemctl enable libvirtd.service openstack-nova-compute.service [root@compute ~] ##systemctl restart libvirtd.service openstack-nova-compute.service |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库