Docker学习-狂神版

Docker命令

1.Docker的安装

查看系统的内核:uname -r
3.10.0-1160.45.1.el7.x86_64

查看系统配置: cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

卸载旧的版本:yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
                  
 下载需要的安装包:yum install -y yum-utils
 
 设置镜像仓库(阿里云)
 # 设置阿里云的Docker镜像仓库
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
    
#更新yum软件包索引
yum makecache fast

#安装docker相关的配置(docker-ce 是社区版,docker-ee 企业版)
yum install docker-ce docker-ce-cli containerd.io

#启动Docker
systemctl start docker
# 查看当前版本号,是否启动成功
docker version

# 设置开机自启动
systemctl enable docker

#搜索镜像
docker search mysql
#拉取镜像
docker pull mysql:5.7

#查看下载的镜像
docker images

2.Docker的卸载

# 1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
# 2. 删除资源  . /var/lib/docker是docker的默认工作路径
rm -rf /var/lib/docker

3.配置阿里云镜像加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://axvfsf7e.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

4.Docker常用命令

docker version          #查看docker的版本信息
docker info             #查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help       #帮助命令(可查看可选的参数)
docker COMMAND --help

5.镜像命令

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    bf756fb1ae65   11 months ago   13.3kB

#解释:
1.REPOSITORY  镜像的仓库源

2.TAG  镜像的标签

3.IMAGE ID 镜像的id

4.CREATED 镜像的创建时间

5.SIZE 镜像的大小


# 可选参数

-a/--all 列出所有镜像

-q/--quiet 只显示镜像的id

6.搜索镜像

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   10308     [OK]
mariadb                           MariaDB is a community-developed fork of MyS…   3819      [OK]
mysql/mysql-server                Optimized MySQL Server Docker images. Create…   754                  [OK]
percona                           Percona Server is a fork of the MySQL relati…   517       [OK]
centos/mysql-57-centos7           MySQL 5.7 SQL database server                   86
mysql/mysql-cluster               Experimental MySQL Cluster Docker images. Cr…   79
centurylink/mysql                 Image containing mysql. Optimized to be link…   60                   [OK]


#可选参数

Search the Docker Hub for images

Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output
      
      
#搜索收藏数大于3000的镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10308     [OK]
mariadb   MariaDB is a community-developed fordockerk of MyS…   3819      [OK]

7.拉取镜像

#拉取镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull mysql
#指定版本下载
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull mysql:5.7

8.删除镜像

#1.删除指定的镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  镜像id
#2.删除多个镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  镜像id 镜像id 镜像id
#3.删除全部的镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  $(docker images -aq)

#删除所有容器
docker rm -f $(docker ps -a -q)

9.容器命令

#拉取一个centos镜像
docker pull centos

#运行容器
docker run [可选参数] image

#参数说明
--name="名字"           指定容器名字
-d                     后台方式运行
-it                    使用交互方式运行,进入容器查看内容
-p                     指定容器的端口
(
-p ip:主机端口:容器端口  配置主机端口映射到容器端口
-p 主机端口:容器端口
-p 容器端口
)
-P                     随机指定端口(大写的P)

#运行并且进入容器centos
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -it centos /bin/bash
[root@bd1b8900c547 /]# ls      
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

#退出容器命令:
exit

#列出运行过的容器命令:
docker ps
     # 列出当前正在运行的容器
-a   # 列出所有容器的运行记录
-n=? # 显示最近创建的n个容器
-q   # 只显示容器的编号

#删除容器命令
docker rm 容器id                 #删除指定的容器,不能删除正在运行的容器,强制删除使用 rm -f
docker rm -f $(docker ps -aq)   #删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器

#启动和停止容器命令
docker start 容器id          #启动容器
docker restart 容器id        #重启容器
docker stop 容器id           #停止当前运行的容器
docker kill 容器id           #强制停止当前容器

#查看docker网络
docker network ls

10.其他常用命令

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker logs --help

Usage:  docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
  -n, --tail string    Number of lines to show from the end of the logs (default "all")
  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

常用:
docker logs -tf 容器id
docker logs --tail number 容器id #num为要显示的日志条数


#docker容器后台运行,必须要有一个前台的进程,否则会自动停止
#编写shell脚本循环执行,使得centos容器保持运行状态
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d centos /bin/sh -c "while true;do echo hi;sleep 5;done"
c703b5b1911ff84d584390263a35707b6024816e1f46542b61918a6327a570dc
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
c703b5b1911f   centos    "/bin/sh -c 'while t…"   13 seconds ago   Up 10 seconds             pedantic_banach
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker logs -tf --tail 10 c703b5b1911f

#查看容器中进程信息
docker top c703b5b1911f

#查看容器的元数据
docker inspect 容器id

#进入当前正在运行的容器
docker exec -it 容器id /bin/bash(容器目录)

#进入容器后可查看进程
ps -ef

#进入容器方式二
docker exec 进入容器后开启一个新的终端,可以在里面操作
docker attach 进入容器正在执行的终端,不会启动新的进程

#拷贝操作
#拷贝容器的文件到主机中
docker cp 容器id:容器内路径  目的主机路径

#拷贝宿主机的文件到容器中
docker cp 目的主机路径 容器id:容器内路径

#查看镜像信息
docker image inspect nginx:latest

11.提交镜像

#使用docker commit命令提交容器称为一个新的版本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -m="add webapps" -a="Ethan" 2a3bf3eaa2e4 mytomcat:1.0
#启动镜像
docker run -it tomcat /bin/bash


12.nginx部署

#搜索并下载镜像
docker search nginx
docker pull nginx

#运行测试
docker run -d --name nginx01 -p 3344:80 nginx
-d 后台运行
--name 给容器命名
-p 3344:80 将宿主机的端口3344映射到该容器的80端口

13.Docker容器数据卷

#运行容器,指定挂载数据卷命令
docker run -it -v 主机目录:容器目录
docker run -it -v /home/test:/home centos /bin/bash

14.MySql同步数据

#第一步,查看镜像
docker search mysql
#第二步,拉取镜像
docker pull mysql:5.7
#第三步,启动mysql镜像
docker run -d -p 6603:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
-d 后台运行
-p 端口映射
-v 数据卷挂载
-e 环境配置
--name 容器名字
#在本地测试创建一个数据库,查看一下我们映射的路径是否有数据库

#将容器的mysql删除,挂载在本地的数据卷依旧不会丢失,实现了容器持久化。

15.具名和匿名挂载

#匿名挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx
-v :容器内路径

#查看所有数据卷情况(匿名)
docker volume ls
#这里发现,这种就是匿名挂载,我们在-v只写了容器内路径,没有写容器外路径。

#具名挂载
docker run -d -P --name nginx02 -v 卷名:容器内路径(/开头) 
docker run -d -P --name nginx02 -v juming-docker:/etc/nginx nginx

#查看数据卷信息
docker volume inspect 数据卷名
[
    {
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": {},
        "Scope": "local"
    }
]
#所有的docker容器内的卷,没有指定目录的情况下都在/var/lib/docker/volume/xxx

#拓展 通过-v容器内路径:ro rw改变读写权限
ro readonly #只读
rw readwrite #可读可写

#一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
#ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!

16.DockerFile

#DockerFile就是用来构建docker镜像的构建文件(命令、脚本) 通过这个脚本可以生成镜像
#镜像是一层一层的,脚本一个个的命令,每个命令都是一层

#创建一个dockerfile文件,名字可以随机 建议 Dcokerfile
#文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]

CMD echo "-----end-----"
CMD /bin/bash

[root@VM-4-13-centos docker-test-volume]# pwd
/home/docker-test-volume
[root@VM-4-13-centos docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t dhn/centos:1.0 .
Sending build context to Docker daemon 2.048 kB
Step 1/4 : FROM centos
 ---> 5d0da3dc9764
Step 2/4 : VOLUME volume01 volume02
 ---> Running in d68e1354537b
 ---> f5b9ff46a20a
Removing intermediate container d68e1354537b
Step 3/4 : CMD echo "-----end-----"
 ---> Running in b0ff206f7238
 ---> 7386e354ad82
Removing intermediate container b0ff206f7238
Step 4/4 : CMD /bin/bash
 ---> Running in e028488641eb
 ---> 0f90c710b2c2
Removing intermediate container e028488641eb
Successfully built 0f90c710b2c2


#运行自己写的镜像
[root@VM-4-13-centos docker-test-volume]# docker run -it 0f90c710b2c2 /bin/bash
[root@a41781afde39 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01	volume02
[root@a41781afde39 /]# ls -l
total 56
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  360 May  2 14:12 dev
drwxr-xr-x   1 root root 4096 May  2 14:12 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Sep 15  2021 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 139 root root    0 May  2 14:12 proc
dr-xr-x---   2 root root 4096 Sep 15  2021 root
drwxr-xr-x   1 root root 4096 May  2 14:12 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Mar 14 15:42 sys
drwxrwxrwt   7 root root 4096 Sep 15  2021 tmp
drwxr-xr-x  12 root root 4096 Sep 15  2021 usr
drwxr-xr-x  20 root root 4096 Sep 15  2021 var
drwxr-xr-x   2 root root 4096 May  2 14:12 volume01 #这个目录就是我们生成镜像的时候自动挂载饿得,数据卷目录
drwxr-xr-x   2 root root 4096 May  2 14:12 volume02

[root@a41781afde39 /]# cd volume01
[root@a41781afde39 volume01]# touch container.txt 
[root@a41781afde39 volume01]# ls
container.txt
#测试刚刚挂载出去的数据卷
[root@VM-4-13-centos data]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
a41781afde39        0f90c710b2c2        "/bin/bash"              2 minutes ago       Up 2 minutes                                eloquent_torvalds
35878fd4a335        nginx               "/docker-entrypoin..."   38 minutes ago      Up 38 minutes       0.0.0.0:32769->80/tcp   nginx02
e6de4aab07f9        nginx               "/docker-entrypoin..."   2 hours ago         Up 2 hours          0.0.0.0:32768->80/tcp   nginx01
[root@VM-4-13-centos data]# docker inspect a41781afde39
[
    {
        "Id": "a41781afde398c2437d68b2d9c0d3544633a99dc9d59ef2e10091a0128fae519",
        "Created": "2022-05-02T14:12:41.60902848Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 20780,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-05-02T14:12:41.896788939Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:0f90c710b2c2b4ba567ec25e9466208c3b1bb2f710fdfd90aba0b6dbd26b23a8",
        "ResolvConfPath": "/var/lib/docker/containers/a41781afde398c2437d68b2d9c0d3544633a99dc9d59ef2e10091a0128fae519/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/a41781afde398c2437d68b2d9c0d3544633a99dc9d59ef2e10091a0128fae519/hostname",
        "HostsPath": "/var/lib/docker/containers/a41781afde398c2437d68b2d9c0d3544633a99dc9d59ef2e10091a0128fae519/hosts",
        "LogPath": "",
        "Name": "/eloquent_torvalds",
        "RestartCount": 0,
        "Driver": "overlay2",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "journald",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "docker-runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DiskQuota": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": -1,
            "OomKillDisable": false,
            "PidsLimit": 0,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0
        },
        "GraphDriver": {
            "Name": "overlay2",
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/0c29be17707c9f49542e11b380373d0af3f3124921bac928f4c41e4b5f23a431-init/diff:/var/lib/docker/overlay2/6ee6051244905c7a3e53742c77d4bfe2166b5ce7cf82d4c68d082be14465b4d1/diff",
                "MergedDir": "/var/lib/docker/overlay2/0c29be17707c9f49542e11b380373d0af3f3124921bac928f4c41e4b5f23a431/merged",
                "UpperDir": "/var/lib/docker/overlay2/0c29be17707c9f49542e11b380373d0af3f3124921bac928f4c41e4b5f23a431/diff",
                "WorkDir": "/var/lib/docker/overlay2/0c29be17707c9f49542e11b380373d0af3f3124921bac928f4c41e4b5f23a431/work"
            }
        },
        "Mounts": [
            {
                "Type": "volume",
                "Name": "f5e18905fee47930cba28ae2b41bdd3a0b30ab5724bba83cc08fc285a299912b", 
                "Source": "/var/lib/docker/volumes/f5e18905fee47930cba28ae2b41bdd3a0b30ab5724bba83cc08fc285a299912b/_data", #外部的数据卷地址
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "12d1f58f7a71bc20a593eeda9d2b3c2f2f7082ebf5744d0269a1c1e7aa006931",
                "Source": "/var/lib/docker/volumes/12d1f58f7a71bc20a593eeda9d2b3c2f2f7082ebf5744d0269a1c1e7aa006931/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "a41781afde39",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "0f90c710b2c2",
            "Volumes": {
                "volume01": {},
                "volume02": {}
            },
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "3f6d8cde8f44ded7e20fe2ac03953c460ad9639014cdab90fbc8e6324c36e50a",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/3f6d8cde8f44",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "969b87a8e9c9288c99d57233bc47017cde36fac6f3eddba442e9aa1196b5a9c4",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.4",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:04",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "e4e0c7d67cab324b9c72318766d059e0d731b64bc23bcffa5260746f7c9e970e",
                    "EndpointID": "969b87a8e9c9288c99d57233bc47017cde36fac6f3eddba442e9aa1196b5a9c4",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.4",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:04"
                }
            }
        }
    }
]
[root@VM-4-13-centos volumes]# cd /var/lib/docker/volumes/f5e18905fee47930cba28ae2b41bdd3a0b30ab5724bba83cc08fc285a299912b/_data
[root@VM-4-13-centos _data]# ls
container.txt
#同步成功!

17.数据卷容器

#进入自己创建的镜像
docker run -it --name docker01 dhn/centos:1.0
#不退出运行 ctrl+p+q
#创建docker02 继承docker01
docker run -it --name docker02 --volumes-from docker01 镜像ID
#--volumes-from 通过他可以进行容器间的共享
例如 docker run -it --name docker02 --volumes-from docker01 0f90c710b2c2
#然后运行docker01,在docker01的volume01中创建一个docker01文件
docker attach docker01的id
cd volume01
touch docker01
#再去docker02中查看,可以看到docker01上的内容同步到docker02上

#删除docker01后,docker02的文件还在
docker rm -f docker01的ID
#docker02中的数据还在

#多个mysql实现数据共享
docker run -d -P 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
#创建子mysql02
docker run -d -P 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7


#结论:容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。

18.DockerFile构建过程

#基础知识
1、每个保留关键字(指令)都是必须是大写字母
2、指令从上到下顺序执行
3#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交。
DockerFile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单。
DockerFile:构建文件,定义一切的步骤,源代码。
DcokerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品。
Docker容器:容器就是镜像运行起来提供的服务器。
#指令
FROM 	    #基础镜像,一切从这里构建
MAINTAINER	#镜像是谁写的,姓名+邮箱
RUN		    #镜像构建的时候需要运行的命令
ADD			#步骤:tomcat镜像,这个tomcat压缩包,添加内容
WORKDIR		#镜像工作目录 /bin/bash
VOLUME		#容器卷,挂载在目录
EXPOSE		#指定暴露端口配置
CMD			#指定这个容器启动的时候要运行的命令,只有最后一个会生效,会被替代
ENTRYPOINT	 #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD		 #当构建一个被继承DockerFile 这个时候会运行ONBUILD的指令,触发指令
COPY		 #类似ADD,将我们文件拷贝到镜像中
ENV		 	 #构建的时候设置环境变量

19.DockerFile实战

DockerHub中99%镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行的构建

#官方的centos镜像
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /

LABEL \
    org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20201113" \
    org.opencontainers.image.title="CentOS Base Image" \
    org.opencontainers.image.vendor="CentOS" \
    org.opencontainers.image.licenses="GPL-2.0-only" \
    org.opencontainers.image.created="2020-11-13 00:00:00+00:00"

CMD ["/bin/bash"]
#1、自己从centos上增加命令功能
FROM centos:7
MAINTAINER dhn<111@qq.com>
WORKDIR  $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash

#2、通过这个文件构建镜像
#命令 docker build -f dockerfile文件路径 -t 镜像名:[tag]
docker build -f mydockerfile-centos -t mycentos:0.1 .

#查看镜像
[root@VM-4-13-centos ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mycentos            0.1                 f0ece28faf17        2 minutes ago       591 MB
<none>              <none>              3835e8f1778a        5 minutes ago       231 MB
dhn/centos          1.0                 0f90c710b2c2        21 hours ago        231 MB
tomcat02            1.0                 4cef0bf76907        44 hours ago        684 MB
docker.io/nginx     latest              605c77e624dd        4 months ago        141 MB
docker.io/tomcat    9.0                 b8e65a4d736d        4 months ago        680 MB
docker.io/tomcat    latest              fb5657adc892        4 months ago        680 MB
docker.io/mysql     5.7                 c20987f18b13        4 months ago        448 MB
docker.io/centos    7                   eeb6ee3f44bd        7 months ago        204 MB
docker.io/centos    latest              5d0da3dc9764        7 months ago        231 MB
#运行我们新创建的mycentos:0.1
docker run -it mycentos:0.1
[root@4dc1e629584a local]# pwd
/usr/local
#可以看到正在运行在了我们提前设置的/usr/local ENV MYPATH /usr/local
#进入镜像后有vim和ifconfig命令

20.CMD和ENTRYPOINT的区别

#1.CMD 覆盖
#构建CMD测试
vim docker-cmd-test

FROM centos:7
CMD ["ls","-a"]

#构建cmdtest容器
docker build -f docker-cmd-test -t cmdtest .

#运行镜像
docker run cmdtest的id

#想追加一个命令 -l ls -al
[root@VM-4-13-centos dockerfile]# docker run 2f436d2a2478 -l
container_linux.go:290: starting container process caused "exec: \"-l\": executable file not found in $PATH"
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:290: starting container process caused "exec: \"-l\": executable file not found in $PATH".

#cmd的清理下 -l 替换了CMD["ls","-a"]命令,-l不是命令所有报错。
#2.ENTRYPOINT 追加
 vim dockerfile-cmd-entrypoint
FROM centos:7
ENTRYPOINT ["ls","-a"]

#构建entrypointtest容器
docker build -f docker-entrypoint-test -t entrypoint-test .

#可以进行追加
docker run 03d20d52ca6a -l

21.实战:Tomcat镜像

#1.准备tomcat压缩包
yum -y install tomcat
#编写dockerfile文件,官方命名Dockerfile,build会自动寻找这个文件,就不需要-f指定了
#在/home/dhn/tomcat下
touch readme.txt
#2.编写Dockerfile
vim Dockerfile
FROM centos:7
MAINTAINER dhn<111@qq.com>

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u301-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.62.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local

WORKDIR $MYPATH


ENV JAVA_HOME /usr/local/jdk1.8.0_301
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.62
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.62
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080
 
CMD /usr/local/apache-tomcat-9.0.62/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.62/bin/logs/catalina.out

#3.构建镜像
docker build -t diytomcat .

#4.启动镜像
docker run -d -p 9090:8080 --name dhntomcat -v /home/dhn/tomcat/test:/usr/local/apache-tomcat-9.0.62/webapps/test -v /home/dhn/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.62/logs diytomcat

#5.进入容器,本地的项目和容器里面的目录是同步的
docker exec -it 5be6298fbbc4f /bin/bash

#6.发布项目(由于做了卷挂载,我们直接在本地编写项目即可)
#可以外部访问101.43.105.40:9090/test

22.发布镜像

#1.登录dockerhup,这里是官方
docker login -u dhn9132
[root@VM-4-13-centos ~]# docker login -u dhn9132
Password: 
Login Succeeded
#2.先改镜像的tag
docker tag diytomcat dhn9132/diytomcat:1.0 #必须前面带dockerhup的用户名
#提交镜像
docker push dhn9132/diytomcat:1.0

1.进入阿里云,找到容器镜像服务

2.创建命名空间

3.创建镜像空间

4.浏览阿里云

#将镜像推送到Registry
docker login --username=嘻嘻嘻哈哈2 registry.cn-shanghai.aliyuncs.com
#给镜像生成版本号
docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/dhntest/dhn-test:[镜像版本号]
#发布镜像到阿里云
docker push registry.cn-shanghai.aliyuncs.com/dhntest/dhn-test:[镜像版本号]

#退出仓库
docker logout

23.Docker网络

#首先,运行一个镜像,若镜像没有就会去pull
docker run -d -P --name tomcat01 tomcat:7 #版本不是7的话会出现OCI runtime exec failed
#然后进入容器进行访问ip addr,查看容器的内部网络地址,发现容器启动的时候会得到一个eth0@if262 ip地址,docker分配的.
docker exec -it tomcat01 ip addr
[root@VM-4-13-centos ~]# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
98: eth0@if99: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever

#linux可以ping容器内的ip
[root@VM-4-13-centos ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.035 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.032 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.046 ms

#再启动一个tomcat02容器
docker run -d -P --name tomcat02 tomcat:7
Docker容器完成bridge网络配置的过程如下:

在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth65f9这样类似的名字命名,并将这个网络设备加入到docker0网桥中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。


#测试tomcat01和tomcat02是否可以ping通
[root@VM-4-13-centos ~]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.100 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.087 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.060 ms
#显然可以

#查看ip addr后可以发现有几个veth连通的ip

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2kDF6JHY-1651761336194)(C:\Users\IronMan\Desktop\CSDN博客\Docker命令.assets\image-20220504171151326.png)]

24.容器互联 --link

#tomcat02无法ping通tomcat01名
[root@VM-4-13-centos ~]# docker exec -it tomcat02 ping tomcat02
ping: tomcat02: Name or service not known
#解决:在运行时使用--link连接两个容器
docker run -d -P --name tomcat03 --link tomcat02 tomcat:7
[root@VM-4-13-centos ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.113 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.076 ms
#--link可以解决网络联通问题
#反向不能ping通
[root@VM-4-13-centos ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
#查看tomcat03的主机配置
[root@VM-4-13-centos ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.3	tomcat02 2b22ead2f668 #这里连接tomcat02
172.17.0.4	380dc9e6ec0f

25.自定义网络

查看所有docker网络

网络模式

bridge:桥接 docker(默认,自己创建的也使用bridge)
none: 不配置网络
host: 和宿主机共享网络
container: 容器网络联通(用得少,局限很大)
#我们直接启动的命令 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat:7
docker run -d -P --name tomcat01 --net bridge tomcat:7

#docker0特点:默认bridge,域名不能访问,--link可以打通连接
#我们可以自定义一个网络
#  --driver bridge 桥接模式
# --subnet 192.168.0.0/16 子网地址
# --gateway 192.168.0.1 网关
docker netwrok create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@VM-4-13-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
1ef7dbcf18592952765a3b524a2fc3ca91f73b72bd8c951eb77e00ecea3a65de
[root@VM-4-13-centos ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
e4e0c7d67cab        bridge              bridge              local
73689a212ace        host                host                local
1ef7dbcf1859        mynet               bridge              local
d253a83a0835        none                null                local
#查看mynet的网络配置
[root@VM-4-13-centos ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "1ef7dbcf18592952765a3b524a2fc3ca91f73b72bd8c951eb77e00ecea3a65de",
        "Created": "2022-05-05T11:34:38.042973038+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
#用自己配置的网络运行tomcat
docker run -d -P --name tomcat-net-01 --net mynet tomcat:7

#再创建一个tomcat-net-02测试访问ping
[root@VM-4-13-centos ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat:7
5292aa86418252459d28489e4d10e9239ec65d6d8698cf283e2c07ab84ab9103
#测试两个网络是否能ping通
[root@VM-4-13-centos ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.092 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.081 ms
#现在不使用--link,使用自定义网络可以ping名字
#测试打通tomcat01 - mynet
docker network connect mynet tomcat01
#联通后就是将tomcat01放在了tomcat-net网络下
docker network inspect mynet
 "Internal": false,
        "Attachable": false,
        "Containers": {
            "1193cf345664901138fb8c177df5155a012e73a86623a5347cfced9a90984f76": {
                "Name": "tomcat01",
                "EndpointID": "6530e7d3a0115d62c1e56b36fb72072d568153fc3e12c53412f5db50c4d2b4e4",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "23feb979ec361a0ece0bbb542976525dd4fbf57d6976e67ad39105a3b24dd077": {
                "Name": "tomcat-net-01",
                "EndpointID": "328281973c757c0180c8a3cac40e760bafea34df2d85bf45729e7bc616a871f6",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "5292aa86418252459d28489e4d10e9239ec65d6d8698cf283e2c07ab84ab9103": {
                "Name": "tomcat-net-02",
                "EndpointID": "239f380de53dfcc6007cf29fd14348f919b3982a3d68a32a5e26b2392fe7d204",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
#一个容器两个ip地址,如阿里云服务:公网ip,私网ip
[root@VM-4-13-centos ~]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.062 ms

结论:假设要跨网络操作别人,就需要使用docker network connect连通

26.实战:部署Redis集群

#创建redis网卡
docker network create redis --subnet 172.38.0.0/16
#通过脚本创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379 
bind 0.0.0.0
cluster-enabled yes 
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done


#第1个Redis容器
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
    -v /mydata/redis/node-1/data:/data \
    -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第2个Redis容器
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
    -v /mydata/redis/node-2/data:/data \
    -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第3个Redis容器
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
    -v /mydata/redis/node-3/data:/data \
    -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第4个Redis容器
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
    -v /mydata/redis/node-4/data:/data \
    -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第5个Redis容器
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
    -v /mydata/redis/node-5/data:/data \
    -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第6个Redis容器
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
    -v /mydata/redis/node-6/data:/data \
    -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

27.SpringBoot微服务打包Docker镜像

1.在idea中打包一个idea项目

在这里插入图片描述

2.编写Dockerfile

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

3.将打包好的jar和Dockerfile放在服务器下的/home/idea下

4.build服务器上的Dockerfile

cd /home/idea
#build项目
docker build -t dhn-docker-test .
#查看镜像
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# docker images
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
dhn-docker-test   latest    b2e423afedea   3 seconds ago   661MB
tomcat            7         9dfd74e6bc2f   10 months ago   533MB
java              8         d23bdf5b1b1b   5 years ago     643MB
#运行镜像
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# docker run -d -P --name dhn-springboot-web dhn-docker-test
1ff8a24468caef5bafb6a07c47fc69d8e9c24e8297e80d3e56644f3af7d150c3
#查看容器并且访问请求
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS         PORTS                                         NAMES
1ff8a24468ca   dhn-docker-test   "java -jar /app.jar …"   6 seconds ago   Up 4 seconds   0.0.0.0:49153->8080/tcp, :::49153->8080/tcp   dhn-springboot-web
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# curl localhost:49153
{"timestamp":"2022-05-05T14:28:31.205+00:00","status":404,"error":"Not Found","path":"/"}[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# 
#访问hello请求
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# curl localhost:49153/hello
hello

的Dockerfile

cd /home/idea
#build项目
docker build -t dhn-docker-test .
#查看镜像
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# docker images
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
dhn-docker-test   latest    b2e423afedea   3 seconds ago   661MB
tomcat            7         9dfd74e6bc2f   10 months ago   533MB
java              8         d23bdf5b1b1b   5 years ago     643MB
#运行镜像
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# docker run -d -P --name dhn-springboot-web dhn-docker-test
1ff8a24468caef5bafb6a07c47fc69d8e9c24e8297e80d3e56644f3af7d150c3
#查看容器并且访问请求
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS         PORTS                                         NAMES
1ff8a24468ca   dhn-docker-test   "java -jar /app.jar …"   6 seconds ago   Up 4 seconds   0.0.0.0:49153->8080/tcp, :::49153->8080/tcp   dhn-springboot-web
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# curl localhost:49153
{"timestamp":"2022-05-05T14:28:31.205+00:00","status":404,"error":"Not Found","path":"/"}[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# 
#访问hello请求
[root@iZbp1ehco2fi1jmdi2fzyfZ idea]# curl localhost:49153/hello
hello
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值