Java:90-Docker详解

Docker详解

虚拟化技术:
虚拟化技术是一种计算机资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等
予以抽象、转换后呈现出来,虚拟化技术打破了计算机实体结构间的,不可切割的障碍
使用户可以比原本的组态更好的方式,来应用这些资源
最直观一点的就是,我们平常购买云服务器,如阿里云服务器,他实际上也就是准备一个虚拟机给你使用的
即我们只操作其阿里云服务器的一部分,虚拟机也算是一种虚拟化技术的操作
虚拟化技术主要作用:
高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用
透明化底层物理硬件 软件跨环境迁移问题(代码的水土不服)
在一台主机上实现多个操作系统,关键技术就是硬件的虚拟化

在这里插入图片描述

什么是Docker :
首先,我们先来看几个问题:
1:合作开发的时候,在本机可以跑,别人的电脑跑不起来
这里我们拿Java Web应用程序举例,我们一个Java Web应用程序涉及很多东西,比如JDK、tomcat、spring等等
当这些其中某一项版本不一致的时候,可能就会导致应用程序跑不起来这种情况
Docker则将程序直接打包成镜像,直接运行在容器中即可
2:服务器自己的程序挂了,结果发现是别人程序出了问题把内存吃完了,自己程序因为内存不够才挂的
这种也是一种比较常见的情况,如果你的程序重要性不是特别高的话,公司基本上不可能让你的程序独享一台服务器的
这时候你的服务器就会跟公司其他人的程序共享一台服务器,所以不可避免地就会受到其他程序的干扰
导致自己的程序出现问题,Docker就很好解决了环境隔离的问题,别人程序不会影响到自己的程序
而具体的情况,可以这样理解,我们操作两个虚拟机
假设其中主机内存只有3g,两个虚拟机内存都设置为2g,其中一个虚拟机突然占满
导致你只能操作1g了,使得另外一个虚拟机可能资源不够用,从而可能导致突然就挂了
注意:一般虚拟机的内存设置是上限,其余没使用的,主机是可以使用的,或者说内存和硬盘都是使用主机
3:公司要弄一个活动,可能会有大量的流量进来,公司需要再多部署几十台服务器
在没有Docker的情况下,要在几天内部署几十台服务器,这对运维来说是一件非常折磨人的事
而且每台服务器的环境还不一定一样,就会出现各种问题,最后部署地头皮发麻
用Docker的话,我只需要将程序打包到镜像,你要多少台服务,我就给你跑多少容器,极大地提高了部署效率
官网地址:https://www.Docker.com,不同日期时间可能是不同的,因为他也会更新的,下面是我那时的官网

在这里插入图片描述

一般我们也这样说明:
Debug your app,not your environment! 
调试你的应用程序,而不是你的开发环境
一般对应给Docker的定位是一 个应用容器平台
Docker 是一个开源的应用容器引擎,诞生于 2013 年初,基于 Go 语言实现, dotCloud 公司出品(后改名为Docker Inc)
Docker 可以让开发者打包他们的应用,以及依赖包到一个轻量级、可移植的容器中
然后发布到任何 流行的 Linux 机器上,Docker容器是完全使用沙箱机制,相互隔离,性能开销也极低
从 17.03 版本之后,Docker分为 CE(Community Edition:社区版) 和 EE(Enterprise Edition:企业 版)
Docker通俗的讲是服务器中高性能的虚拟机,可以将一台物理机虚拟N多台虚拟机的机器,互相之间隔离,互不影响
想要搞懂Docker,其实看它的两句口号就行:
第一句,是"Build, Ship and Run"
也就是,“搭建、发送、运行”,三板斧
举个例子(网上有大多数的同样例子,这里就给出来我理解的):
我是修仙家族的族长,该家族被我经营多年,每个模式都被我经营完毕,比如功法阁,主事大厅,练武场等等
我们有一天,打败了另外一个修仙家族,他的地理位置非常好,比我们的家族好的多,于是我们就开始搬家
可是对应的功法阁,主事大厅,练武场等等建筑却需要我们重新建造,于是我决定动用我的修为,将他们的构造进行复制
然后到那里,我直接出手,凭空就出现了对应的功法阁,主事大厅,练武场,而这个凭空出手的方式也就是镜像的方式
网上的例子大多数是如下:
我来到一片空地,想建个房子,于是我搬石头、砍木头、画图纸,一顿操作,终于把这个房子盖好了

在这里插入图片描述

结果,我住了一段时间,想搬到另一片空地去,这时候,按以往的办法,我只能再次搬石头、砍木头、 画图纸、盖房子
但是,跑来一个老巫婆,教会我一种魔法,这种魔法,可以把我盖好的房子复制一份,做成"镜像",放在我的背包里

在这里插入图片描述

等我到了另一片空地,就用这个"镜像",复制一套房子,摆在那边,拎包入住

在这里插入图片描述

怎么样?是不是很神奇?
上面就是网上的大多数例子
所以,Docker的第二句口号就是:“Build once,Run anywhere(搭建一次,到处能用)”
就如上面的背包里的房子,可以放在任意地方
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中
然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口
特点:
标准化交付:Docker将应用打包成标准化单元,用于交付、部署
轻量级:容器及包含了软件运行所需的所有环境,而且非常轻量级
高可靠(高可用):容器化的应用程序,可以在任何Linux环境中始终如一的运行
隔离性:容器化的应用程序,具备隔离性,这样多团队可以共享同一Linux系统资源

在这里插入图片描述

容器与虚拟机比较:
下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见Docker是在操作系统层面上实现虚拟化
直接复用本地主机的操作系统,而传统方式则是在硬件层面实现
所以就是说Docker是使用主机的操作系统,而虚拟机是使用他自己的操作系统(我们操作的那个镜像,来决定的生成操作系统)
也就是说,Docker免去了大的镜像文件(也可以说是操作系统,但他可以指定)

在这里插入图片描述

下面的容器,可以看成是Docker(其他的一般是对应的镜像实体,如后面的容器解释,所以这里是不一样的,所以提示一下)
而正是因为镜像的存在,所以一般有一定的区别

在这里插入图片描述

由于Docker的运行环境是Linux操作系统,所以我们也通常需要先操作虚拟机然后操作Docker
一般像Unix操作系统也可以,Mac苹果电脑一般是操作Unix操作系统的,所以可以不用安装虚拟机
而大多数是Windows,所以需要安装虚拟机然后操作Docker
相同:容器和虚拟机都是虚拟化技术,具备资源隔离和分配优势
不同:
Docker虚拟化的是操作系统,虚拟机虚拟化的是硬件,所以在某种层面可以将docker就看成一个单独的linux来操作就行了(因为操作系统一样,但是也需要先存在硬件的模拟,所以docker在模拟的虚拟机中)
但也只是模拟,具体还是需要真实的硬件或者操作系统的
虽然虚拟机是更加的底层,但却是他自己的操作系统,而不是本机,自然一般结合性不好,所以性能也就不好
传统虚拟机可以运行不同的操作系统(在创建虚拟机时,可以看到有指定操作系统界面的)
Docker主要运行同一类操作系统(Linux)
比较上面两张图,我们发现虚拟机是携带操作系统,本身很小的应用程序却因为携带了操作系统而变得非常大,很笨重
Docker是不携带操作系统的(和宿主机共用),所以Docker的应用就非常的轻巧
Docker 基本概念:

在这里插入图片描述

宿主机:安装Docker守护进程(也就是安装Docker的)的Linux服务器,称之为宿主机
镜像(Image):Docker 镜像,就相当于是一个 root 文件系统
除了提供容器运行时所需的程序、 库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数
容器(Container):镜像运行(或者说安装,安装后也就是镜像创建容器后,一般操作 -i 参数来运行)之后的实体
镜像和容器的关系,就像是面向对象程序设计中的类和对 象一样
镜像是静态的定义,容器是镜像运行时(或者说安装,也可以说成镜像创建容器)的实体
容器可以被创建、启动(运行)、停止、删除、暂停 等
仓库(Repository):仓库可看成一个镜像控制中心,用来保存镜像(我们可以存放在https://hub.docker.com/里面,但需要搭建)
举例: 上面的例子里面,那个放在包里的"镜像",就是Docker镜像
而我的背包,就是Docker仓库,我在空地 上,用魔法造好的房子
就是一个Docker容器(安装好的镜像,也就是镜像创建好的容器)
即镜像的安装可以称为容器,而不安装,就是镜像,所以容器可以说是对应的镜像的运行的地方(一般安装后就会有)
即具体流程是:先从仓库拿镜像,当我们获取这个镜像时
安装后,就会出现容器,当然我们可以启动,如创建时命令里面操作-i,或者创建后手动的操作启动命令
实际上安装后一般操作 -i 参数来运行,否则就是创建,该安装也就是操作创建容器的命令,看起来有像是运行一样的命令
启动后,这时我们就可以操作访问信息了,比如连接mysql,启动那么也就是相当于启动了对应的服务器的服务
比如mysql服务(可能也需要手动启动,镜像问题)
但是有些需要手动启动的,一般需要我们来操作,比如tomcat的启动(可能也不需要手动启动,镜像问题)
所以一般与镜像有关,所以说有些不需要,而有些需要,可以自己使用ps命令在容器查看
但可能ps命令也没有,或者文件也没有,那么就需要换镜像了
可能是操作维护过的,不同的时间是不同的,操作维护,所以可能以后又可以
具体看自己如何操作吧(在后面的学习中,你会体会到为什么要这样说明了,到那时,你可以试着换版本测试就会知道了)
这里多次提到镜像问题,对于镜像问题,在后面会多次说明,也就是说,如果出现了与后面解释不同的情况
那么一般是镜像的问题,所以对应的解释并不是绝对的,你可以跳过
注意:字面的说明并不能完全的解决你的疑惑,可以在后面的实操中来体会
但要注意:容器是可以有多个的,即可用执行多个镜像,且互相隔离,也可以反过来变成镜像
说白了,这个Docker镜像,是一个特殊的文件系统,它除了提供容器运行时所需的程序、库、资源、配 置等文件外
还包含了一些为运行时准备的一些配置参数(例如环境变量),镜像不包含任何动态数据,其内容在构建之后也不会被改变
也就是说,每次变出房子,房子是一样的,但生活用品之类的,都是不管的
谁住谁负责添置, 每一个镜像可以变出一种房子,那么,我可以有多个镜像呀!
也就是说,我盖了一个欧式别墅,生成了镜像,另一个哥们可能盖了一个中国四合院,也生成了镜像
还有哥们,盖了一个非洲茅草屋,也生成了镜像 这么一来,我们可以交换镜像,你用我的,我用你的,是不是就很爽

在这里插入图片描述

于是乎,就变成了一个大的公共仓库,负责对Docker镜像进行管理的,是Docker Registry服务(类似仓库管理员)
不是任何人建的任何镜像都是合法的,如万一有人盖了一个有问题的房子呢?
所以,Docker Registry服务对镜像的管理是非常严格的,最常使用的Registry公开服务,是官方的Docker Hub
这也是默认的 Registry,并拥有大量的高质量 的官方镜像
Docker安装与启动:
本地电脑安装虚拟机,虚拟机搭配Linux操作系统,在Linux操作系统上安装Docker容器
这里直接给出对应的安装好的虚拟机:
链接:https://pan.baidu.com/s/1VWSB3AgmxzJMevxYgNTfgw
提取码:alsk
我们在VMware直接打开即可
准备工作:确保Linux系统能够连接网络,因为Docker的镜像下载一般需要联网(远程的下载)
调整虚拟网络编辑器:
1:桥接模式的虚拟机,就像一个在路由器"民政局"那里"上过户口"的成年人
有自己单独的居住地址,虽然和主机住在同一个大院里,但好歹是有户口的人,可以大摇大摆地直接和外面通信
2:NAT模式的虚拟机,纯粹就是一个没上过户口的黑户,路由器"民政局"根本不知道有这么个人
自 然也不会主动和它通信,即使虚拟机偶尔要向外面发送点的信件,都得交给主机以主机的名义转发出去
主机还专门请了一位叫做NAT的老大爷来专门负责这些虚拟机的发信、收信事宜
3:仅主机模式的虚拟机,纯粹是一个彻彻底底的黑奴,不仅没有户口、路由器"民政局"不知道这么 号人
还被主机关在小黑屋里,连信件也不准往外发
其中这个仅主机模式能够保障我们在拔掉网线的情况下继续连接我们的虚拟机,不依靠公网连接
而是 依靠物理机和虚拟机的关系连接,在断网的情况下,利用这个模式,我们可以继续连接虚拟机,实现我 们的操作
对应的网卡设置,可以到55章博客里查看,也可以查看百度
打开虚拟机文件:
由于是已经操作好的虚拟机,所以对应的镜像已经操作完毕了,即这时就算你修改镜像文件或者不存在,那么也是可以启动的
即镜像只在第一次启动时,操作的,后续就基本不会操作了,但至少需要一个文件指定(就算不存在)
不写盘符默认虚拟机打开的那个当前路径(自己测试就知道了)
但不能只写盘符,需要指定一个(就算不存在)
如果出现如下:

在这里插入图片描述

我们点击我已经移动该虚拟机,具体的选项作用在78章博客有解释
然后操作默认即可
对应的,用户名是root,密码是lagou
记住与windows不同,是区分大小写的,在创建文件时,可以明显的看到区别,之前说明过了
修改对应的网卡,修改如下:
IPADDR=192.168.164.140  #注意:这里用自己的对应ip范围,ip在网络上的位置 ipaddr
#一般DHCP会给你指定一个范围,他指定对应的分配ip范围,虽然一般是路由器分配,这里一般由主机分配
#当然,若你自己配置了,那么自然使用自己配置的,所以这里若是192.168.164.10,也可以
GATEWAY=192.168.164.2 #网关网络到其他网络需要的口子,可以叫做路由器 gatewar,记得使用自己的
然后重启网络服务,service network restart,使得设置成效
然后使用ping www.baidu.com进行测试,若可以ping通,则代表有网络了
连接到虚拟机:
使用Xshell连接即可,具体方式看55章博客
这里若使用ifconfig查询不了网络信息,需要使用ip addr来查询网络信息
安装:
Docker官方建议在Ubuntu(操作系统)中安装Docker软件,因为Docker基于Ubuntu发布
而且Docker出现问题时,Ubuntu系统版本的一般是先打补丁。很多版本在CentOS中,是不支持更新最新补丁包的
没有好的解决方案
但是,由于我们学习的环境都使用CentOS,因此,这里我们将Docker安装到CentOS上
注意,一定安 装在CentOS 7.x及以上的版本,CentOS6.x的版本中可能有Bug!
可能使得docker命令操作失败或者运行(启动)失败
上面的虚拟机就是操作了CentOS 7.x及以上的版本
接下来我们进行安装:
1:查看电脑上已经已经安装Docker
yum list installed | grep docker #yum list installed查看我们安装的信息,使用|进行过滤,即查看docker的信息
如果出现如下:

在这里插入图片描述

代表是安装的,即该虚拟机是帮我们自行操作安装的,如果没有的话,操作如下:
2:安装docker(注意:随着时间的推移,可能后面的操作是有变化的,所以当我们执行后面时,可能并不会成功,比如启动docker,当然了,到那时,我们看对应的状态信息或者日志信息的内容,然后百度查看解决即可)
yum -y install docker #-y代表自动选择yes,即按照,不用我们手动的选择
3:安装后查看docker版本
docker -v
安装好后,再次安装一般不是更新,而是安装失败
Docker守护进程相关命令:
概要:
1:启动docker服务
2:停止docker服务
3:重启docker服务
4:查看docker服务状态
5:开机启动docker服务
6:查看docker概要信息
详解:
systemctl命令是系统服务管理器指令
展示docker的容器运行状态(需要有启动服务,否则会有对应的提示,但也要有运行的容器,否则只有属性):
docker ps
启动docker服务:
systemctl start docker #再次多次启动不会操作
停止docker服务:
systemctl stop docker
重启docker服务:
systemctl restart docker #相当于先关闭,在启动,若对于启动中来说,所以相对于systemctl start docker会慢一点
#但若对于关闭中来说,差不多,但还是会慢(相对于启动中来说,变快了),会判断的是否关闭造成的

在这里插入图片描述

查看docker服务状态:
systemctl status docker

在这里插入图片描述

在这里插入图片描述

开机启动(自启)docker服务:
systemctl enable docker #一般第一次他会创建一个东西,用来自启动的,当然,再次执行,就不会了
查看docker概要信息:
docker info

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

查看镜像数:
docker images #这里看上面的图知道,是6个镜像,一般是没有镜像的
#但这里我们是事先安装好并操作的虚拟机,所以有他操作的镜像,一般第一次安装是没有镜像的

在这里插入图片描述

查看docker帮助文档:
docker --help
镜像加速的2个方案 :
默认情况,将从docker hub(https://hub.docker.com/)下载docker镜像太慢,一般都会配置镜像加速器
方案一:中科大
中国科学技术大学(ustc)是老牌的linux镜像服务提供者了,还在遥远的ubuntu 5.04版本的时候就在用
ustc的docker镜像加速器速度很快,ustc docker mirror的优势之一就是不需要注册,是真正的公共服务
https://lug.ustc.edu.cn/wiki/mirrors/help/docker
编辑该文件:
vim /etc/docker/daemon.json  #对应的vim好像没有,那么使用vi即可
在该文件中输入如下内容:
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
方案二:阿里云
如果中科大镜像加载速度很慢,建议配置阿里云镜像加速,这个镜像仓库如果不好使
可以自己从阿里云上申请(百度搜索如何操作即可)速度杠杠的
比如得到的地址的对应内容如下:
{
  "registry-mirrors": ["https://3ad96kxd.mirror.aliyuncs.com"]
}
这个必须要注册,每个人分配一个免费的docker镜像加速地址,速度极快
这里我们使用中科大的,不需要注册
配置完成记得刷新配置
sudo systemctl daemon-reload #更新文件的加载,即生效,之后,需要我们重启,获得
#如果只重启,那么会操作默认加载的,即不是修改的生效,所以需要这个命令
sudo systemctl restart docker
Docker常用命令 :

在这里插入图片描述

镜像相关命令 :
概要:
1:查看镜像
2:搜索镜像
3:拉取镜像
4:删除镜像
在操作镜像之前,首先需要启动docker,否则从哪里操作镜像呢,你说是吧
且若操作了上面的两个方案的镜像地址,那么对应的拉取和搜索基本是很快的
注意:他们只是加速,本质上地址还是原来的https://hub.docker.com/地址,即从该地址进行拉取和搜索的
你可以进行测试,发现,是否使用加速器,对应的搜索的镜像都是一样的结果
详解:
查看镜像:
查看本地所有镜像:
docker images

在这里插入图片描述

上面的5个属性从左到右分别代表:
1:镜像名称
2:版本信息(latest代表最新的)
3:镜像ID(唯一表示,因为名称是可以重复的,如两个tomcat,只是版本不同,所以用这个表示唯一,通常是操作删除的),虽然他对于其他的镜像来说是唯一,但若是拉取同一个镜像,那么他还是相同的,即对于一个镜像来说是唯一,而不是随机生成的
4:创建时间
5:文件大小
这些镜像都是存储在Docker宿主机的/var/lib/docker目录下
搜索镜像:
如果你需要从网络中查找需要的镜像,可以通过以下命令搜索
注意,必须确保当前系统能联网(因为是远程操作的,需要经过网络)
docker search 镜像名称

在这里插入图片描述

上面的5个属性从左到右分别代表:
1:名称
2:镜像描述
3:用户评价或者说是点赞数(一般越多就代表该镜像越好)
4:是否官方发布
5:自动构建
他们并没有对应的版本信息,可以去https://hub.docker.com/地址查看即可,至于访问,就要看自己的网络了
具体查看如下:
以tomcat为例子

在这里插入图片描述

在这里插入图片描述

点击tomcat,后面到如下,这里就是版本的操作了(右边可以复制命令)
拉取镜像 :
拉取镜像:从Docker仓库下载镜像到本地,镜像名称格式为 名称:版本号
如果版本号不指定则是最新的 版本,如果不知道镜像版本,可以去docker hub 搜索对应镜像查看
docker pull 镜像名称 #若是相同的,会提示已经拉取了,可能拉取过程中,会停顿,一般网络问题,可以重试
#如果终止,那么不会有对应的镜像,相当于回退了,或者说删除了
#一般拉取时,会先创建对应的id,停止的话,然后操作删除id
指定版本的,例如,我要下载centos7镜像:
docker pull centos:7 #7一般代表7.0,但显示只是7,可以通过https://hub.docker.com/地址查看
删除镜像 :
按镜像ID删除镜像
docker rmi 镜像ID
删除所有镜像
删除之前要确认此镜像已经没有被容器在使用,如果存在对应的docker容器(无论是否运行),删除会报错
一般出现如下:“Error response from daemon: conflict: unable to delete 47c156f4d4e3 (cannot be forced) - image is being used by running container f7e490e1d8bf”
即删除镜像ID为47c156f4d4e3的存在有容器ID为f7e490e1d8bf,不可删除
docker images -q   #查看所有镜像的ID
docker rmi `docker images -q`  #批量删除镜像,-q代表只显示对应的镜像id
#反引号的作用就是将反引号内的Linux命令先执行,然后依次将执行结果操作,所以这里会执行多次
#而其他的单引号和双引号只是操作名称而已(一般是省略他们的引号,以及当成一体)
#当然一体的作用,一般是操作分开的字母,当然,一般双引号可以替换对应的变量,而单引号不可,具体可以到55章博客查看
在这里开始,一般的命令的说明操作与镜像有关(可能也与宿主机或者本机有关,但后面并不说明,因为镜像是主要的)
自己看后面即可
容器相关命令:
概要:
1:查看容器
2:创建容器:交互式、守护式
3:进入容器
4:启动容器
5:停止容器
6:删除容器
详解:
查看容器:
查看正在运行的容器(没有运行的不会查看):
docker ps

在这里插入图片描述

这里还没有按照容器,自然什么都没有
上面的7个属性从左到右分别代表:
1:容器ID,无论是运行同一个镜像还是其他镜像,基本不会相同
2:镜像创建名称,即后面创建的"镜像名称:标签"
当然,若是之间的名称,那么是操作最新的,如果没有,则会拉取最新的然后创建,如果是镜像ID,那么也是直接的创建
自己测试就知道了
3:命令
4:创建时间
5:运行状态及运行时间
6:占用的端口情况
7:容器名称(一般可以自定义,一般定义为 “镜像名称_Version” ,及名称加上版本号,比如 tomcat_8.5)
后面创建容器的操作中,有操作容器名称的参数
查看所有容器(查看正在运行的和已经停止运行的):
这里还没有按照容器,自然什么都没有,无论是运行(启动)的还是没有运行(启动)的
docker ps -a
docker ps -all
#两个效果一样
#如果加上-q,代表只显示对应的容器ID,即也可以操作多次的删除,与前面的docker rmi `docker images -q`一样的操作
查看最后一次运行的容器:
docker ps -l
查看停止的容器(没有停止的不会查看):
docker ps -f status=exited #很严谨的,不能是Exited,因为这里是linux,代表他们是不同的,而不是windows
创建与启动容器:

在这里插入图片描述

创建容器命令:
docker run 参数 镜像名称(或者单独镜像ID):镜像标签(也就是版本) /bin/bash
#单独的镜像ID也就是只有镜像ID,以后说明镜像ID时,基本都是单独的,即看成单独的
创建(或者说安装)容器常用的参数说明:
## 命令参数详解

-i:表示运行容器,如果不加该参数那么只是通过镜像创建容器,而不启动
如果没有加i,而加上了/bin/bash或者不加上
那么就可能启动不了了(一般与镜像有关),如果加上了,一般需要使用exit退出
虽然并没有对应的命令行出现,即伪终端出现,自己测试就知道了(一般与镜像有关)

-t:表示容器启动后会进入其命令行,加入it这两个参数后,容器创建就能登录进去
即分配一个伪终端(即加上it两个参数,创建后就会自动进去容器),如果退出伪终端,会使得容器停止

-d:在run后面加上-d参数,则会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器)

--name:为创建的容器命名
#比如:--name=jj 命名为jj,而不是操作随机的唯一(一般操作了时间戳来生成的)

-v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录)
可以使用多个-v做多个目录或文件映射,注意:最好做目录映射,在宿主机上做修改,然后共享到容器上
相当于我操作写在宿主机的对应的目录信息,会同步到容器的对应目录上,比如创建文件或者目录
#比如:-v /home/test:/home

-p:表示端口映射,前者是宿主机端口,后者是容器内的映射端口,可以使用多个-p做多个端口映射,例如:
可以将Docker中Tomcat容器的8080端口映射到宿主机上的某一个端口8080
那么以后访问tomcat只需要:http://宿主机的IP:8080/,即访问宿主机的8080就相当于访问容器里的8080
也就是实现了访问容器的服务器
#比如:-p 5000:80

进入容器之后,初始化执行的命令:/bin/bash
这个命令可写可不写,但最好写上,因为写上基本是没有问题的,而不写可能有问题
一般可能与镜像有关(因为镜像是维护的,不同时间段可能是不同的)

1:交互式容器
使用交互式运行容器,容器运行后直接进入到容器内部,退出容器内部后(ctrl+c退出)
容器会直接关闭,注意只有第一次才会这样
以后再启动容器就是一个守护式的,即就算关闭也只是命令行,而不是会使得容器关闭了
docker run -it --name=容器名称 镜像名称:标签 /bin/bash
#或者
docker run --name=容器名称 -it 镜像名称:标签 /bin/bash

#注意:如果不是"镜像名称:标签"
#当然并不是所有的该组合可以,比如tomcat:8.5,他也需要加上/bin/bash和-i
#一般可能与镜像有关,因为镜像是维护的,不同时间段可能是不同的
#即其他的单独的或组合的可能也可以不加(比如redis和mysql,即他们这里后面并没有写上版本)
#但以镜像为主,所以说并不是绝对的
#一般情况下其他的组合(镜像名称,镜像名称必定是组件因为默认是latest)或者单独(比如单独的镜像ID)
#那么/bin/bash一般要加上,且-i参数也必须加上
#否则启动不了(相当于一直关闭的),自己测试时就知道了,无论是否是-t还是-d都是如此
#当然出现这种情况可能是其他的原因,若启动不了,那么一般是上面的情况,注意即可

#所以说/bin/bash最好写上,或者说,-it或者-id他们最好和/bin/bash一起加上,这样,基本不会出现问题
#所以说,后面最好这样写,即这就是为什么大多数的创建容器中,都是他们的组合的原因

#测试:docker run -it --name=jj tomcat:latest /bin/bash,这个latest可以不加,因为默认是最新的
#即不加就是默认加上latest
#就算加上了,也需要加上/bin/bash,这里是特殊的(自然也是镜像的问题)

#其中"镜像名称:标签",可以是单独的镜像名称和id
#但如果没有对应的镜像,它会帮你拉取后,然后进行创建
#比如:docker run --name=kk -it tomcat /bin/bash

#最后注意:--name=容器名称,中这个容器名称,至少是两个字符,比如--name=h,和--name=hh
#那么第一个创建不了,第二个可以


#删除容器,使用docker rm 容器ID(或者容器名称),注意:不能删除正在运行的容器
#比如:docker rm dee865b3d9c7 后面可以指定多个,比如docker rm jj jk ll 删除jj jk ll这三个名称的容器
#当然,这是大多数的允许的操作,自己注意即可

#容器可以多多创建,只要名称不同,就可以,无论是否是同一个镜像,所以名称也是唯一
#因为相同的名称不能创建,这也使得名称也可以与容器ID一样的操作删除和启动和关闭,或者说是有一样的操作
#即能操作容器ID的那么容器名称也可以在该位置进行操作
这时我们通过ps命令查看(除了第一次),发现可以看到创建的容器,状态为启动状态
退出当前运行的容器
一般是加上了 /bin/bash 的那个命令行那么操作该命令,即加上 /bin/bash 会多出对应的镜像运行的命令行:
exit #注意ctrl+c在这里不能退出
2:守护式容器
docker run -di --name=容器名称 镜像名称(或单独的镜像ID):标签 /bin/bash 
#注意:参数不要放在镜像名称后面,都在是不会有启动的操作(基本是创建容器,在关闭状态,自己测试即可)
#比如:docker run -di tomcat
#不加上--name,那么会默认给你一个名称,且也是唯一的(基本不会使得相同,可能与时间戳有关)

#当-d和-t同时存在时,那么操作-d
3:登录容器/进入容器的目录(前提是要运行,即先启动)
docker exec -it 容器名称 (或者容器ID) /bin/bash 
#这个it代表是exec的参数,而不是docker的参数,这里要注意
#所以必须加上(实际上只需要t即可),但it使得ctrl+c不可以退出
#但没有i,那么基本什么都操作不了,比如ls和exit,只能ctrl+c退出了
#命令行一般是root@04a0c81c1379:/usr/local/tomcat#,其中04a0c81c1379代表容器ID
#其中对应的目录是镜像安装(容器)的初始目录(不同的镜像容器,该初始目录不同,比如centos一般是根目录)
#而不是宿主机的目录,所以要注意,当然也有可能不同的镜像容器的命令行可能也是不同的,比如mysql,比如是bash-4.2#
#我们可以看到他的命令行与linux大致相同,实际上也就看成一个linux,所以他也基本可以操作linux的命令
#或者我们将该容器就看成linux,后续基本是这样的理解
#就将容器的启动看成是多出来一个linux
#里面可能进行了一些操作,比如使得默认启动什么,也可能并没有操作,那么我们一般需要手动的启动了
注意:这里的登陆容器之后执行的脚本/bin/bash必须写,因为我们需要命令行,即规定要加上
停止与启动容器:
停止容器:
docker stop 容器名称(或者容器ID)  
#可能会卡住,等待一会或者ctrl+c多次的操作即可
#也或者可能虽然卡住了,但可能实际上我们ctrl+c退出时,也停止了,查看即可
启动容器:
docker start 容器名称(或者容器ID)
#若start变成restart则代表重启,对于大多数的stop和start来说,基本都会有restart命令,即重启命令
#即restart代表了stop和start两个命令的结合,或者说restart代表先执行stop然后执行start的意思
#虽然再次的执行start没有错误(但是只是返回,并没有启动,即重启),其中restart有明显的停顿,当然如果是关闭状态
#自然停顿与start少(但还是慢一点,因为判断了stop状态)
文件拷贝:
如果我们需要将宿主机的文件拷贝到容器内可以使用cp命令:
docker cp 需要拷贝的文件或目录 容器名称:容器目录

#新建一个空文件
touch latou.html

#拷贝到tomcat容器的webapps目录下
docker cp lagou.html 59b35c0bbe6d:/usr/local/tomcat/webapps 
#注意:若容器没有对应的目录,一般会提示你没有目录(文件和目录都可以拷贝),对应的只会表示目录
#如果没有提示,那么说明是帮你创建了(一般是一个目录的没有,如/usr/local/tomcat/webappskk)
#即webappskk没有,后面的不能加上/以及其他目录,否则不会创建,说明没有,这样一般会给你创建webappskk
#但之所以这样,是因为cp命令的作用,即这样就算是复制并重新命名的意思了(54章博客里有)
#但一般情况下,需要加上-r使用复制目录,但这里的dockr不需要(大概是他的参数或者本身的原因)
#所以通常会提示你,即一般需要自己创建
#其中59b35c0bbe6d是容器ID(记得写上自己的),无论是否启动都会加上去,当然也可以是容器名称

#切换到tomcat容器中查看
docker exec -it 容器ID(或者容器名称) /bin/bash
也可以将文件从容器内拷贝出来:
docker cp 容器名称(或者容器ID):容器目录 需要拷贝的文件或目录

#比如
#将copy到tomcat容器的文件再copy出来
docker cp 59b35c0bbe6d:/usr/local/tomcat/webapps/lagou.html ./
#对应的/usr/local/tomcat/webapps/lagou.html中第一个/代表在根目录下,实际上也默认在根目录下,所以可以不写
目录挂载:
我们可以在创建容器的时候(注意是在创建容器的时候),将宿主机的目录与容器内的目录进行映射
这样我们就可以通过修改宿主 机某个目录的文件从而去影响容器
创建容器 添加-v参数 后边为 宿主机目录:容器目录 例如:
docker run -di -v /usr/local/myhtml:/usr/local/myhtml --name=mycentos3 centos:7
#注意:宿主机的这个目录,默认是在根目录,如果没有那么就都会进行创建(无论是否是多目录)
#且对应的容器目录,若有不存在的目录,会进行都创建(无论是否是多目录)
#实际上创建也只是操作了对应的mkdir或者相关操作而已
#宿主机中的该命令,可能会使得容器也进行操作吧,大概是宿主机和容器有一定的联系
#当然这是底层的操作,所以了解即可

#注意:对应的必须是/开头(即绝对路径),否则会报错

#其中若宿主机的目录是单独的,即如oo:/r,其中oo就是单独的,那么宿主机不会出现创建(容器可能会创建),且不会同步
当我们操作对应的目录时,如在宿主机对应目录创建文件aa,那么对应映射的目录下,会同步到aa的,自己可以进行测试
查看容器IP地址 :
我们可以通过以下命令查看容器运行的各种数据:
docker inspect 容器名称(容器ID)
对应的信息可以找到如下内容
一般ip地址都是如下,从172.17.0.2开始,当有其他的时,就加1,即172.17.0.3
Mac地址也是从02:42:ac:11:00:02开始,当有其他的时,就加1,即02:42:ac:11:00:03
但对应的其他的地址信息,如172.17.0或者02:42:ac:11:00是可能不同的,大概与对应的docker版本或者镜像有关
当然,你可以自己测试,但实际上这里了解即可

在这里插入图片描述

也可以直接执行下面的命令直接输出IP地址:
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称(容器ID)
但是我们直接的ping是ping不通的,就算是端口映射也是如此,具体方式可以到百度上查找
但一般端口的映射是对应端口的操作,操作如下:
#比如执行如下命令来创建容器:
docker run -p 宿主机端口:容器的端口 -di --name=jj tomcat /bin/bash
操作后,我们操作访问宿主机的该端口,那么就相当于操作访问容器的对应端口了
删除容器:
删除指定的容器,正在运行的容器无法删除
#删除容器docker rm 容器名称(可以是容器ID,容器名称不会相同,所以不用担心相同的结果)
#删除镜像docker rmi 镜像ID(只能是镜像ID,没有镜像名称)
Docker数据卷:
数据卷概述:
数据卷是宿主机中的一个目录或文件,当容器目录和数据卷目录绑定后,对方的修改会立即同步
一个数据卷可以被多个容器同时挂载,一个容器也可以被挂载多个数据卷
简单来说数据卷本质其实是共享文件夹,是宿主机与容器间数据共享的桥梁
数据卷作用:
1:容器数据持久化
2:外部机器和容器间接通信
3:容器之间数据交换
数据卷配置方式:
1个容器挂载1个数据卷:
创建启动容器时,使用 –v 参数 设置数据卷(前面操作过了)
docker run ... –v 宿主机目录(注意是目录,而不是文件):容器内目录(注意是目录,而不是文件) ... 
注意事项:
1:目录必须是绝对路径
2:如果宿主机目录不存在,会自动创建
3:可以挂载多个数据卷
比如:
docker run -v /ppp:/pp -v /ppp:/pp -v /ppp:/op -it --name=jj tomcat /bin/bash
#其中一个/ppp同步给/pp和/op,但是发现有两个/pp,其中后者覆盖前者,也就是只有一个/pp
#但是不能是多个宿主机目录,同时操作一个容器目录,否则创建不了

#当然,端口也可以这样,但宿主机的端口只能对应一个,而不能对应多个,因为占用了该端口
#但容器的端口可以对应多个宿主机端口(也可以是不同容器对应不同宿主机端口,我们也通常这样操作)
#这里与上面的目录是有点相反的
#最后注意:先目录对应,然后再启动,也就是说,再启动之前,目录就已经对应了,即目录就已经同步了,然后再操作启动
#这里要注意
案例:
#拉取centos镜像
docker pull centos:7
#安装启动容器并挂载
docker run -di --name=c1 -v /root/host_data1:/root/c1_data centos:7 /bin/bash

在这里插入图片描述

查看容器已挂载的数据卷(数据卷可以看成与容器同步的目录):
我们可以通过以下命令,查看容器中挂载的数据卷
docker inspect 容器名称(容器ID) 

在这里插入图片描述

1个容器挂载多个数据卷:
我们可以通过以下命令,挂载多个数据卷
docker run -di --name=c1 -v /root/host_data1:/root/c1_data1 -v /root/host_data2:/root/c1_data2 centos:7 /bin/bash
#当然,同一个宿主机目录可以对应多个,但容器目录不能对应多个宿主机,在创建时,就会报错的
#因为总不能让宿主机的目录会因为容器,而形成了对应的同步吧,这是非常危险的,万一可以,那么按照谁的文件为主呢
#实际上无论根据顺序什么为主,那么另外一个文件,自然被覆盖,那么也就会使得如果你操作了主要的文件
#那么可能会使得该文件被覆盖,使得原来的主文件都没有了,特别的是系统文件,所以不能使得容器目录对应多个宿主机目录
#这是根据实际情况出发的
虽然前面说明过了
多个容器挂载1个数据卷(简称从容器里,变成跨容器):
多个容器挂载1个数据卷,实现数据共享
docker run -di --name=c2  -v /root/host_data_common:/root/c2_data centos:7
docker run -di --name=c3  -v /root/host_data_common:/root/c3_data centos:7

在这里插入图片描述

多个容器挂载1个容器(这个容器挂载1个数据卷):
##创建启动c3数据卷容器,使用 –v 参数 设置数据卷
docker run -di --name=c3 -v /root/host_data_common:/root/c3_data centos:7 /bin/bash
##创建启动 c1 c2 容器,使用 –-volumes-from 参数 设置数据卷
docker run -di --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run -di --name=c2 --volumes-from c3 centos:7 /bin/bash
#设置后,那么相当于这个:
docker run -di --name=c1 --volumes-from c3 centos:7 /bin/bash
#变成了
docker run -di --name=c1 -v /root/host_data_common:/root/c3_data centos:7 /bin/bash
#所以简单来说,就是拿取对应的c3容器的-v的配置
#所以你删除对应的宿主机目录,那么他会创建
#但要注意:如果是已经挂载了,然后删除对应宿主机目录,那么对应的容器目录虽然不会删除
#但内容清空,且他们之间不会同步了,无论是否再次创建进行操作
#且也使得对应的容器目录不能进行操作了,比如创建文件或者目录或者删除他

#可能是对应的什么占用吧,具体可以百度,一般是挂载的容器的对应宿主机目录没有了,需要卸载联系

#当然,既然是同步,自然除了宿主机可以同步给容器外,容器也会同步给宿主机
#因为同步基本都是双向的,自己测试就知道了





#最后:说明一下问题,再创建之前,如果指定操作的容器目录有数据(比如/ppp:/usr/local/tomcat/)
#那么宿主机的目录是覆盖容器的目录吗,答:是覆盖,即容器的目录是宿主机的目录内容
#所以也最好不要操作容器的主要目录,而是我们操作创建的(最好偏门一点)
#我们也可以先随便创建一个容器,看看目录结构,然后再重新的仔细操作

在这里插入图片描述

在Docker中部署软件:
注意:不同的镜像操作可能不同,比如可能没有帮你启动服务,或者没有文件,或者需要自己启动操作
但是因为维护,所以我们需要自己到容器里查看信息并解决,或者换个镜像启动(最好是老版本的,基本不会维护,即稳定)
MySQL部署
实现步骤:
1:搜索MySQL镜像
2:拉取MySQL镜像
3:创建容器、设置端口映射、设置数据卷
4:进入容器操作mysql
5:使用Navicat连接MySQL
实现过程:
搜索mysql镜像:
docker search mysql
既然是搜索,那么自然的并不是所有的框架或者中间件或者工具等等,都有镜像的,注意即可,只要你能搜索到,那么基本就可以拉取
拉取mysql镜像,自然并不是所有的都可以拉取,比如docker pull mysql:5.7777777777,夸张一点,来验证(●ˇ∀ˇ●):
docker pull mysql:5.7
创建容器,设置端口映射、目录映射:
docker run -di --name=mysql -p 3307:3306 -v /root/mysql/logs:/logs -v /root/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

参数说明:
-p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口,即我们访问宿主机的3307端口也就是访问容器的3306端口
即跳级的访问,虽然这样可以跳级,但ping通容器却操作不了,因为直接的访问是访问不了的,可能需要其他操作,具体可以百度
-v /root/mysql/logs:/logs:将主机目录(/root/mysql)下的 logs 目录挂载到容器中的 /logs日志目录
-v /root/mysql/data:/var/lib/mysql :将宿主机目录(/root/mysql)下的data目录挂载到容器的 /var/lib/mysql 数据目录
-e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码
进入容器,操作mysql:
docker exec -it mysql /bin/bash
因为我们做了端口映射,所以连接的是192.168.164.10:3307,其中对应的需要是自己的虚拟机地址
可能需要启动,但这里并不需要
Tomcat部署:
实现步骤:
1:搜索Tomcat镜像
2:拉取Tomcat镜像
3:创建容器、设置端口映射、设置数据卷
4:向Tomcat中部署服务
5:使用外部机器访问Tomcat,测试部署服务
实现过程:
搜索tomcat镜像:
docker search tomcat
拉取tomcat镜像:
docker pull tomcat:7-jre7
创建容器,设置端口映射、目录映射:
docker run -di --name=c_tomcat -p 8080:8080 -v /root/tomcat/webapps:/usr/local/tomcat/webapps tomcat:7-jre7 /bin/bash
#注意:不同的tomcat的操作可能不同,且文件可能也是不同的
#其他的版本可以自己进行测试,一般可能与镜像有关((因为镜像是维护的,不同时间段可能是不同的,可以百度进行操作)
#但这里的7-jre7需要先启动tomcat的bin下面的startup.sh(执行./startup.sh即可),然后访问即可
#其他的可以百度看看,但大多数都是如此(可能其他版本不让你启动,一般是镜像不同了,即维护了,可以百度查看问题)
#如果是创建了ROOT,那么默认访问ROOT里面的内容,比如在webapps下,创建ROOT,然后在里面创建a文件
#访问192.168.164.10:8080/a即可,如果是192.168.164.10:8080/ROOT/a
#那么实际上是在webapps下,即这样/ROOT/ROOT/a,即ROOT里面需要再有ROOT,然后有a
#所以默认加上ROOT的,如果是其他的不是ROOT的文件,比如在webapps下,创建ggg,然后在里面创建a文件
#即是192.168.164.10:8080/ggg/a,那么就是访问ggg/a,没有ROOT的加上,所以ROOT这个目录是特殊的
#tomcat一般都是如此(所以无论是我们主机里面的还是宿主机的还是容器的基本都是这样),这里了解即可
参数说明:
-p 8080:8080:将容器的8080端口映射到主机的8080端口
-v /root/tomcat/webapps:/usr/local/tomcat/webapps:将主机目录(/root/tomcat/webapps)挂载到容器的webapps
再对应的宿主机的/root/tomcat/webapps下,创建ss文件,随便输入什么数据
使用外部机器访问Tomcat,测试部署服务
注意:需要先进行启动tomcat
那么既然是再运行中,那么为什么可以修改文件使得改变呢,即部署的时候进行改变了
答:部署的文件的确是不能改变,但也只是针对于放在内存里说的(比如说,只会读取一次)
而会访问项目的文件的是可以改变的(比如静态文件,如html),所以我们可以添加内容
Nginx部署:
实现步骤:
搜索Nginx镜像:
docker search Nginx #默认操作的都是小写,即nginx,一般根据目录一路找(优先nginx本身,自己看就知道了)
拉取Nginx镜像:
docker run -di --name=mynginx -p 80:80 nginx:1.17 /bin/bash
测试访问:http://192.168.164.10:80
一般也需要启动,即到/usr/sbin/,里面执行" ./nginx "即可,我找到的,可能不同镜像位置不同
Redis部署:
实现步骤:
1:搜索Redis镜像
2:拉取Redis镜像
3:创建容器、设置端口映射
4:使用外部机器连接Redis,测试
实现过程:
搜索redis镜像:
docker search redis
拉取redis镜像:
docker pull redis
创建容器,设置端口映射:
docker run -id --name=c_redis -p 6379:6379 redis /bin/bash
使用外部机器连接redis,测试
这里一般并不需要启动,直接测试,如果需要启动
可以找到对应的文件来启动(一般在 usr/local/bin 里面,具体启动可以直接执行redis-server即可,虽然是后台运行)
测试工具在80章博客里可以找到
该工具,若是对应的连接没有的话,等待一会就会有提示的(一直加载中),具体的流程,在你下载好之后,很容易知道的
迁移与备份:
应用场景:
开发环境Docker,在Docker中安装很多的容器,进行对应的配置,将Docker中的运行的容器持久化 为镜像
将对应的镜像安装到生产环境中
1:将开发环境下的Docker中对应的容器持久化为镜像
2:将镜像保存为一个压缩包,发送到生产环境服务器中
3:生产环境中需要将压缩包–>镜像–>容器
以redis为例子
容器保存为镜像:
我们可以通过以下命令将容器保存为镜像
docker commit {容器名称/容器ID} {镜像名称}:{镜像标签}
#即docker commit {容器名称/容器ID} {ImageName} : {Tag} 
#无论是在运行的还是不在运行的,都只是操作容器
#注意:这个镜像名称只会在名称,不会操作镜像的ID
#最后,其中镜像名称和镜像标签(版本)基本可以随便写,但为了好查看和以后的操作
#所以也最好按照版本写(或者就是拉取的镜像名称和镜像版本信息)

#既然基本可以随便写,那么就会有相同的名称和标签,如果相同,那么就覆盖,但该覆盖是覆盖名称和标签
#即原来的名称和标签都变成了<none>,而不是真正的覆盖,自己测试就知道了
#由于这里是创建,所以基本是多出了<none>

# 例如
docker commit dbc261edcdff redis:version_lagou_1.0.0 #如果不写版本,默认是latest版本,即最新的
镜像标签如果不写默认为latest
镜像备份:
我们可以通过以下命令将镜像保存为tar 文件
docker save -o {压缩包存放路径} {镜像名称/镜像ID}

# 举例
docker save -o redis.tar redis:version_lagou_1.0.0 #当然可以指定全名,因为默认的镜像名称是latest的
#当然需要存在,否则会提示报错的
#需要知道具体文件,不能是./或者不写,默认从当前路径开始,如果没有对应的文件,会创建
#所以这里会创建redis.tar然后放入内容
#当然加上/使得绝对路径也可
#若存在对应的文件,那么会进行覆盖
#压缩包在生产环境下会还原为一个image(镜像),还原之后的name和tag
#就是压缩的这些,即redis:version_lagou_1.0.0 
# -o :输出到的文件,且只能写在对应的文件前面和命令后面
#这是指定的命令(即不能随便放位置,需要在操作的文件之前)
镜像恢复与迁移:
首先我们先删除掉对应的镜像 然后执行此命令进行恢复,如果不删除,则会覆盖镜像,相同的多次执行则是覆盖
不同的文件但镜像相同,则是覆盖名称和版本
这由于不是创建,那么覆盖的话,会使得对应的< none>变回来,另外一个变成< none>
docker load -i {备份的镜像文件}

# 举例
docker load -i redis.tar
#这样使得版本不同,一般该操作的镜像可以使得省略/bin/bash


# -i :指定导入的文件

#至此,该文件实际上也可以发送给其他的虚拟机,只要他操作上面的,那么也就有对应的镜像了,也就可以直接的操作
#通常该镜像是我们自己操作的多次,里面有对应的配置,实际上也就是我们项目的服务器,所以也就实现了迁移
执行后再次查看镜像,可以看到镜像已经恢复,可以再次运行测试:
docker run -it --name=hhh -p 6379:6379 c3f51ed39c4e /bin/bash
再次测试,发现也仍然可以
至此操作完成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值