Virtualization——虚拟化技术

虚拟化技术

一:虚拟化简介

1.什么是虚拟化

虚拟化(Virtualization)技术最早出现在 20 世纪 60 年代的 IBM 大型机系统,在70年代的 System 370 系列中逐渐流行起来,这些机器通过一种叫虚拟机监控器(Virtual Machine Monitor,VMM)的程序在物理硬件之上生成许多可以运行独立操作系统软件的虚拟机(Virtual Machine)实例。随着近年多核系统、集群、网格甚至云计算的广泛部署,虚拟化技术在商业应用上的优势日益体现,不仅降低了 IT 成本,而且还增强了系统安全性和可靠性。
虚拟化是一个广义的术语,对于不同的人来说可能意味着不同的东西,这要取决他们所处的环境。在计算机科学领域中,虚拟化代表着对计算资源的抽象,而不仅仅局限于虚拟机的概念。例如对物理内存的抽象,产生了虚拟内存技术,使得应用程序认为其自身拥有连续可用的地址空间(Address Space),而实际上,应用程序的代码和数据可能是被分隔成多个碎片页或段),甚至被交换到磁盘、闪存等外部存储器上,即使物理内存不足,应用程序也能顺利执行。

2.虚拟化分类
平台虚拟化(Platform Virtualization),针对计算机和操作系统的虚拟化。
资源虚拟化(Resource Virtualization),针对特定的系统资源的虚拟化,比如内存、存储、网络资源等。
应用程序虚拟化(Application Virtualization),包括仿真、模拟、解释技术等。
虚拟化主要是指平台虚拟化技术,通过使用控制程序(Control Program,也被称为 Virtual Machine Monitor 或Hypervisor),隐藏特定计算平台的实际物理特性,为用户提供抽象的、统一的、模拟的计算环境(称为虚拟机)。虚拟机中运行的操作系统被称为客户机操作系统(Guest OS),运行虚拟机监控器的操作系统被称为主机操作系统(Host OS),当然某些虚拟机监控器可以脱离操作系统直接运行在硬件之上(如 VMWARE 的 ESX 产品)。运行虚拟机的真实系统我们称之为主机系统。

部分虚拟化(Partial Virtualization)
VMM 只模拟部分底层硬件,因此客户机操作系统不做修改是无法在虚拟机中运行的,其它程序可能也需要进行修改。在历史上,部分虚拟化是通往全虚拟化道路上的重要里程碑,最早出现在第一代的分时系统 CTSS 和 IBM M44/44X 实验性的分页系统中。
全虚拟化(Full Virtualization)
全虚拟化是指虚拟机模拟了完整的底层硬件,包括处理器、物理内存、时钟、外设等,使得为原始硬件设计的操作系统或其它系统软件完全不做任何修改就可以在虚拟机中运行。操作系统与真实硬件之间的交互可以看成是通过一个预先规定的硬件接口进行的。全虚拟化 VMM 以完整模拟硬件的方式提供全部接口(同时还必须模拟特权指令的执行过程)。比较著名的全虚拟化 VMM 有 Microsoft Virtual PC、VMware Workstation、Sun Virtual Box、Parallels Desktop for Mac 和 QEMU。
超虚拟化(Paravirtualization)
这是一种修改 Guest OS 部分访问特权状态的代码以便直接与 VMM 交互的技术。在超虚拟化虚拟机中,部分硬件接口以软件的形式提供给客户机操作系统,这可以通过 Hypercall(VMM 提供给 Guest OS 的直接调用,与系统调用类似)的方式来提供。例如,Guest OS 把切换页表的代码修改为调用 Hypercall 来直接完成修改影子 CR3 寄存器和翻译地址的工作。由于不需要产生额外的异常和模拟部分硬件执行流程,超虚拟化可以大幅度提高性能,比较著名的 VMM 有 Denali、Xen。

硬件辅助虚拟化(Hardware-Assisted Virtualization)
硬件辅助虚拟化是指借助硬件(主要是主机处理器)的支持来实现高效的全虚拟化。例如有了 Intel-VT 技术的支持,Guest OS 和 VMM 的执行环境自动地完全隔离开来,Guest OS 有自己的““套寄存器”,可以直接运行在最高级别。因此在上面的例子中,Guest OS 能够执行修改页表的汇编指令。Intel-VT 和 AMD-V 是目前 x86 体系结构上可用的两种硬件辅助虚拟化技术。
这种分类并不是绝对的,一个优秀的虚拟化软件往往融合了多项技术。例如 VMware Workstation 是一个著名的全虚拟化的 VMM,但是它使用了一种被称为动态二进制翻译的技术把对特权状态的访问转换成对影子状态的操作,从而避免了低效的 Trap-And-Emulate 的处理方式,这与超虚拟化相似,只不过超虚拟化是静态地修改程序代码。对于超虚拟化而言,如果能利用硬件特性,那么虚拟机的管理将会大大简化,同时还能保持较高的性能。

二:KVM基础

1.简介
从rhel6开始使用 直接把kvm的模块做成了内核的一部分
KVM 针对运行在 x86 硬件上的、驻留在内核中的虚拟化基础结构。KVM 是第一个成为原生 Linux 内核(2.6.20)的一部分的 hypervisor,它是由 Avi Kivity 开发和维护的,现在归 Red Hat 所有。
这个 hypervisor 提供 x86 虚拟化,同时拥有到 PowerPC® 和 IA64 的通道。另外,KVM 最近还添加了对对称多处理(SMP)主机(和来宾)的支持,并且支持企业级特性,比如活动迁移(允许来宾操作系统在物理服务器之间迁移)。
KVM 是作为内核模块实现的,因此 Linux 只要加载该模块就会成为一个hypervisor。KVM 为支持 hypervisor 指令的硬件平台提供完整的虚拟化(比如 Intel® Virtualization Technology [Intel VT] 或 AMD Virtualization [AMD-V] 产品)。KVM 还支持准虚拟化来宾操作系统,包括 Linux 和 Windows®。
这种技术由两个组件实现。第一个是可加载的 KVM 模块,当在 Linux 内核安装该模块之后,它就可以管理虚拟化硬件,并通过 /proc 文件系统公开其功能。第二个组件用于 PC 平台模拟,它是由修改版 QEMU 提供的。QEMU 作为用户空间进程执行,并且在来宾操作系统请求方面与内核协调。

2.安装
查看CPU是否支持VT技术:

[root@xingdian ~]# cat /proc/cpuinfo | egrep 'vmx|svm'

安装:

[root@xingdian ~]# yum install *qemu* *virt* *kvm* -y

启动服务:

centos7:
[root@xingdian ~]# systemctl start libvirtd

查看kvm模块加载:

[root@xingdian ~]# lsmod | grep kvm
kvm_intel 53484 3
kvm 316506 1 kvm_intel

图形模式安装guest os:

[root@xingdian ~]# yum -y install virt-manager

2.命令行的方式安装虚拟机
模板镜像+配置文件
1.拷贝模板镜像和配置文件

[root@xingdian ~]# cp /var/lib/libvirt/images/vm2.qcow2 /var/lib/libvirt/images/vm3.qcow2
[root@xingdian ~]# cp /etc/libvirt/qemu/vm2.xml /etc/libvirt/qemu/vm3.xml

2.修改配置文件

[root@xingdian ~]# vim /etc/libvirt/qemu/vm3.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
virsh edit xingdian-1
or other application using the libvirt API.
-->
<domain type='kvm'>
<name>xingdian-1</name>
<uuid>fe831f0e-2676-4a26-81a7-aacdf07c670e</uuid>
<memory unit='KiB'>3072000</memory>
<currentMemory unit='KiB'>3072000</currentMemory>
<vcpu placement='static'>2</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
</features>
<cpu mode='custom' match='exact' check='full'>
<model fallback='forbid'>SandyBridge-IBRS</model>
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='xsaveopt'/>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/xingdian-1.qcow2'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<target dev='hda' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='usb' index='0' model='ich9-ehci1'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci3'>
<master startport='4'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/>
</controller>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='virtio-serial' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<interface type='network'>
<mac address='52:54:00:17:54:16'/>
<source network='xingdian-2'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
<address type='virtio-serial' controller='0' bus='0' port='2'/>
</channel>
<input type='tablet' bus='usb'>
<address type='usb' bus='0' port='1'/>
</input>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='spice' autoport='yes'>
<listen type='address'/>
<image compression='off'/>
</graphics>
<sound model='ich6'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</sound>
<video>
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='2'/>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='3'/>
</redirdev>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</memballoon>
</devices>
</domain>

3.创建虚拟机:

[root@xingdian ~]# virsh define /etc/libvirt/qemu/vm2.xml

3.配置文件
必须修改的选项:(使用)
虚拟机名称
uuid
磁盘镜像文件名称
mac地址
可以通过配置文件修改的内容:
虚拟机名称
uuid
磁盘镜像文件名称
mac地址
cpu
memory
disk
network
cdrom

4.基本命令
虚拟机的组成部分:
1.虚拟机配置文件

[root@localhost qemu]# ls /etc/libvirt/qemu
centos7.0.xml centos7.xml networks

2.储存虚拟机的介质

[root@localhost qemu]# ls /var/lib/libvirt/images/
centos7.0.qcow2

查看:
查看虚拟机:

[root@qf-xingdian images]# virsh list
Id Name State
----------------------------------------------------
[root@qf-xingdian images]# virsh list --all
Id Name State
----------------------------------------------------
- harbor-2 shut off
- server-1 shut off
- xingdian-1 shut off
- xingdian-2 shut off
- xingdian-3 shut off

查看kvm虚拟机配置文件:

[root@qf-xingdian images]# virsh dumpxml xingdian-1

将node4虚拟机的配置文件保存至node6.xml:

[root@qf-xingdian ~]# virsh dumpxml node4 > /etc/libvirt/qemu/node6.xml

修改node6的配置文件:

[root@qf-xingdian ~]# virsh edit node6

如果直接用vim编辑器修改配置文件的话,需要重启libvirtd服务
启动:

[root@localhost ~]# virsh start vm1
Domain vm1 started

暂停虚拟机:

[root@localhost ~]# virsh suspend vm_name

恢复虚拟机:

[root@localhost ~]# virsh resume vm_name

关闭:

[root@localhost ~]# virsh shutdown vm1
Domain vm1 is being shutdown

重启:

[root@localhost ~]# virsh reboot vm1
Domain vm1 is being reboote

重置:

[root@localhost ~]# virsh reset vm1
Domain vm1 was reset

删除虚拟机:

[root@localhost ~]# virsh undefine vm2
Domain vm2 has been undefined

注意:虚拟机在开启的情况下undefine是无法删除的
连接虚拟机的方法:
1.使用virt-viewer图形连接已启动的虚拟机

[root@localhost ~]# virt-viewer vm1

5.虚拟机克隆

  • 1.图形界面:

    关闭要克隆的虚拟机,右键点击虚拟机选择Clone

  • 2.字符终端,命令克隆:

[root@localhost ~]# virt-clone -o vm1 --auto-clone
WARNING 设置图形设备端口为自动端口,以避免相互冲突。
正在分配 'vm1-clone.qcow2' | 6.0 GB 00:00:05
成功克隆 'vm1-clone'。
-o origin
[root@localhost ~]# virt-clone -o vm1 -n vm2 --auto-clone
WARNING 设置图形设备端口为自动端口,以避免相互冲突。
正在分配 'vm2.qcow2' | 6.0 GB 00:00:06
成功克隆 'vm2'[root@localhost ~]# virt-clone -o vm1 -n vm2 -f /var/lib/libvirt/images/vm2.img
正在克隆 vm1.img | 8.0 GB 01:03
Clone 'vm2' created successfully.

6.存储池
概念:
kvm必须要配置一个目录当作他存储磁盘镜像(存储卷)的目录,我们称这个目录为存储池
默认存储池:
/var/lib/libvirt/images/

1.创建基于文件夹的存储池(目录)
[root@xingdian ~]# mkdir -p /home/vmfs
2.定义存储池与其目录
[root@xingdian ~]# virsh pool-define-as vmdisk --type dir --target /home/vmfs/
Pool vmdisk defined
3.创建已定义的存储池
(1)创建已定义的存储池
[root@xingdian ~]# virsh pool-build vmdisk
Pool vmdisk built
(2)查看已定义的存储池,存储池不激活无法使用。
[root@xingdian ~]# virsh pool-list --all
Name State Autostart
-------------------------------------------
default active yes
vmdisk inactive no
4.激活并自动启动已定义的存储池
[root@xingdian ~]# virsh pool-start vmdisk
Pool vmdisk started
[root@xingdian ~]# virsh pool-autostart vmdisk
Pool vmdisk marked as autostarted
这里vmdisk存储池就已经创建好了,可以直接在这个存储池中创建虚拟磁盘文件了。

三:KVM网络

KVM虚拟机网络配置一般的两种方式:
NAT:
(默认上网) 虚拟机利用host机器的ip进行上网.对外显示一个ip
Bridge:
将虚拟机桥接到host机器的网卡上,guest和host机器都通过bridge上网.对外不同的ip
Host-Only:
在Host-Only模式下,虚拟网络是一个全封闭的网络,它唯一能够访问的就是主机。其实Host-Only网络和NAT网络很相似,不同的地方就是Host-Only网络没有NAT服务,所以虚拟网络不能连接到Internet。主机和虚拟机之间的通信是通过VMware Network Adepter VMnet1虚拟网卡来实现的。
1.nat模式
原理:
NAT方式是kvm安装后的默认方式。它支持主机与虚拟机的互访,同时也支持虚拟机访问互联网,但不支持外界访问虚拟机。
检查当前的网络设置:

[root@qf-xingdian ~]# virsh net-list --all
Name State Autostart Persistent
----------------------------------------------------------
default active yes yes
xingdian-1 active yes yes
xingdian-2 active yes yes

default是宿主机安装虚拟机支持模块的时候自动安装的
检查当前的网络接口:

[root@qf-xingdian ~]# ifconfig
enp0s25: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
ether 00:21:cc:be:02:60 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 20 memory 0xf2500000-f2520000
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 30326 bytes 29500363 (28.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 30326 bytes 29500363 (28.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:5d:40:08 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

其中virbr0是由宿主机虚拟机支持模块安装时产生的虚拟网络接口,也是一个switch和bridge,负责把内容分发到各虚拟机。
网络拓扑图:

在这里插入图片描述

图上可以看出,虚拟接口和物理接口之间没有连接关系,所以虚拟机只能在通过虚拟的网络访问外部世界,无法从网络上定位和访问虚拟主机。
virbr0是一个桥接器,接收所有到网络192.168.122.*的内容。从下面命令可以验证:

[root@qf-xingdian ~]# brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.5254005d4008 yes virbr0-nic
virbr1 8000.525400876cc7 yes virbr1-nic
virbr2 8000.525400646e44 yes virbr2-nic

创建:
图形化界面
命令方式
定义一个虚拟网络

[root@qf-xingdian ~]# cat /etc/libvirt/qemu/networks/xingdian-3.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
virsh net-edit xingdian-3
or other application using the libvirt API.
-->
<network>
<name>xingdian-3</name>
<uuid>baff2f58-f5df-4cd8-93ff-4b89bf807003</uuid>
<forward mode='nat'/>
<bridge name='virbr3' stp='on' delay='0'/>
<mac address='52:54:00:87:3c:c7'/>
<domain name='xingdian-1'/>
<ip address='10.0.3.1' netmask='255.255.255.0'>
<dhcp>
<range start='10.0.3.2' end='10.0.3.254'/>
</dhcp>
</ip>
</network>
创建网络
[root@qf-xingdian ~]# virsh net-define /etc/libvirt/qemu/networks/xingdian-3.xml
设置为开机启动
[root@qf-xingdian networks]# virsh net-autostart xingdian-3
Network xingdian-3 marked as autostarted
启动网络
[root@qf-xingdian networks]# virsh net-start xingdian-3
Network xingdian-3 started
网络启动后可以用命令brctl show 查看和验证。
修改/etc/sysctl.conf中参数,允许ip转发:
net.ipv4.ip_forward=1 2.bridge桥接

Bridge方式配置出来的接口对NAT方式没有影响,因为NAT方式并没有使用物理网卡。但作为客户机,只能选择其中的一种。
创建桥接器

# cat /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
NM_CONTROLLED=no
TYPE=Bridge
BOOTPROTO=static
IPADDR=192.168.0.230
PREFIX=24
GATEWAY=192.168.1.254
DNS1=8.8.8.8
ONBOOT=yes
USERCTL=no
DELAY=0

将物理接口桥接到桥接器

# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NM_CONTROLLED=no
TYPE=Ethernet
BOOTPROTO=static
ONBOOT=yes
USERCTL=no
BRIDGE=br0

重启加载网络服务

# systemctl restart network

查看当前桥接情况

# brctl show

四:IT系统架构发展

在这里插入图片描述

三个阶段:
1. 物理机架构
这一阶段,应用部署和运行在物理机上。 比如企业要上一个ERP系统,如果规模不大,可以找3台物理机,分别部署Web服务器、应用服务器和数据库服务器。 如果规模大一点,各种服务器可以采用集群架构,但每个集群成员也还是直接部署在物理机上。 我见过的客户早期都是这种架构,一套应用一套服务器,通常系统的资源使用率都很低,达到20%的都是好的。

2. 虚拟化架构
摩尔定律决定了物理服务器的计算能力越来越强,虚拟化技术的发展大大提高了物理服务器的资源使用率。 这个阶段,物理机上运行若干虚拟机,应用系统直接部署到虚拟机上。 虚拟化的好处还体现在减少了需要管理的物理机数量,同时节省了维护成本。

3. 云计算架构
虚拟化提高了单台物理机的资源使用率,随着虚拟化技术的应用,IT环境中有越来越多的虚拟机,这时新的需求产生了: 如何对IT环境中的虚拟机进行统一和高效的管理。 有需求就有供给,云计算登上了历史舞台。

云计算分类

IaaS(Infrastructure as a Service)
提供的服务是虚拟机。IaaS 负责管理虚机的生命周期,包括创建、修改、备份、启停、销毁等。使用者从云平台得到的是一个已经安装好镜像(操作系统+其他预装软件)的虚拟机。使用者需要关心虚机的类型(OS)和配置(CPU、内存、磁盘),并且自己负责部署上层的中间件和应用。
IaaS 的使用者通常是数据中心的系统管理员。典型的 IaaS 例子有 AWS、Rackspace、阿里云等

PaaS(Platform as a Service)
提供的服务是应用的运行环境和一系列中间件服务(比如数据库、消息队列等)。使用者只需专注应用的开发,并将自己的应用和数据部署到PaaS环境中。PaaS负责保证这些服务的可用性和性能。
PaaS的使用者通常是应用的开发人员,典型的 PaaS 有 Google App Engine、IBM BlueMix 等

SaaS(Software as a Service)
提供的是应用服务,使用者只需要登录并使用应用,无需关心应用使用什么技术实现,也不需要关系应用部署在哪里。
SaaS的使用者通常是应用的最终用户,典型的 SaaS 有 Google Gmail、Salesforce 等

dSaaS (data-storage-as-a-Service)
提供的是存储服务,dSaaS 是为用户提供一个巨大高可用的网盘,并且此网盘可以被用户随时随地访问.
典型的 dSaaS 有Amazon S3

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值