docker命令

开始

  • 官方文档

docker install

  • 基础环境
root@localhost:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.2 LTS
Release:        20.04
Codename:       focal
  • 配置安装源
#1、 添加源
echo "deb https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

#2、添加密钥
wget -qO - "https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu//gpg" | apt-key add -
  • 安装docker
apt-get install docker-ce docker-ce-cli containerd.io
  • 配置镜像加速
#1、创建目录
sudo mkdir -p /etc/docker

#2、添加镜像加速
#阿里云注册后可以免费添加私人加速器
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://dsar4zay.mirror.aliyuncs.com"]
}
EOF

#3、重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker
  • 查看版本
root@localhost:~# docker version
Client: Docker Engine - Community
 Version:           20.10.5
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        55c4c88
 Built:             Tue Mar  2 20:18:20 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.5
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       363e9a8
  Built:            Tue Mar  2 20:16:15 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.4
  GitCommit:        05f951a3781f4f2c1911b05e61c160e9c30eaa8e
 runc:
  Version:          1.0.0-rc93
  GitCommit:        12644e614e25b05da6fd08a38ffa0cfe1903fdec
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
  • 运行hello-world
root@localhost:~# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
  • 卸载docker
#1、卸载docker
apt-get purge docker-ce docker-ce-cli containerd.io

#2、删除镜像目录
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

)

镜像命令

docker images

docker images [OPTIONS] [REPOSITORY[:TAG]]

root@localhost:~# docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    d1165f221234   4 weeks ago   13.3kB

#解释
REPOSITORY		镜像的仓库源
TAG				镜像的标签
IMAGE ID		镜像的ID号
CREATED			镜像创建的时间
SIZE			镜像的大小

#可选项

  -a, --all		Show all images
  -q, --quiet	Only show image IDs

root@localhost:~# docker images -aq
d1165f221234

docker search

docker search [OPTIONS] TERM

root@localhost:~# docker search mariadb | head -n 2
NAME                                   DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mariadb                                MariaDB Server is a high performing open sou…   4020      [OK]

#解释
NAME			镜像名字
DESCRIPTION		镜像描述
STARS			镜像点赞数
OFFICIAL		DOCKER官方镜像
AUTOMATED		自动构建

#可选项

  -f, --filter filter   Filter output based on conditions provided

root@localhost:~# docker search mysql -f STARS=4000
root@localhost:~# docker search mysql --filter=STARS=4000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10696     [OK]
mariadb   MariaDB Server is a high performing open sou…   4020      [OK]

docker pull

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

root@localhost:~# docker pull mariadb
Using default tag: latest										#若不给tag默认为latest
latest: Pulling from library/mariadb
da7391352a9b: Pull complete										#分层下载,docker images的核心,联合文件系统
14428a6d4bcd: Pull complete
2c2d948710f2: Pull complete
22776aa82430: Pull complete
90e64230d63d: Pull complete
f30861f14a10: Pull complete
e8e9e6a3da24: Pull complete
420a23f08c41: Pull complete
bd73f23de482: Pull complete
a8690a3260b7: Pull complete
4202ba90333a: Pull complete
a33f860b4aa6: Pull complete
Digest: sha256:cdc553f0515a8d41264f0855120874e86761f7c69407b5cfbe49283dc195bea8		#签名
Status: Downloaded newer image for mariadb:latest
docker.io/library/mariadb:latest								#真实地址

#等价于
docker pull mariadb
docker pull docker.io/library/mariadb:latest

#指定版本
root@localhost:~# docker pull mariadb:10.4
10.4: Pulling from library/mariadb
da7391352a9b: Already exists									#之前mariadb下载后,这几层已不用在下载,联合文件系统的特性
14428a6d4bcd: Already exists
2c2d948710f2: Already exists
22776aa82430: Already exists
90e64230d63d: Already exists
f30861f14a10: Already exists
e8e9e6a3da24: Already exists
420a23f08c41: Already exists
bd73f23de482: Already exists
8dd7f0f336d9: Pull complete
1d455564f5ab: Pull complete
8d384b4810a9: Pull complete
ce2e7c2c7df1: Pull complete
Digest: sha256:b6d48e55556ef9f9fe66d2cf7c8c69badca70de5fe25c4e018e4a15851dbdf66
Status: Downloaded newer image for mariadb:10.4
docker.io/library/mariadb:10.4

docker rmi

docker rmi [OPTIONS] IMAGE [IMAGE...]

#可选项

  -f, --force      Force removal of the image

docker rmi -f $(docker images -aq)							#递归删除所有镜像
root@localhost:~# docker rmi $(docker images -aq)
Untagged: mariadb:10.4
Untagged: mariadb@sha256:b6d48e55556ef9f9fe66d2cf7c8c69badca70de5fe25c4e018e4a15851dbdf66
Deleted: sha256:5b89851205aa235471ff68c8daf0701fae60ecb17c385246699e51f5c0eed3ff
Deleted: sha256:57a095422123c0bb33cb450a1e812cc8ba7ad2e1f1cf3201bcb557f83236c569
Deleted: sha256:79c1c48c97225f7ef82aa710829803b35405aff853fc024dbe3b3c16da03d473
Deleted: sha256:a0369dff50e98e5b78d8a22b0cff771ebce22a06b04e1efd88d8248f3d5c4460
Deleted: sha256:9c3a91617762bd6f15a7e7c2909f1d16a6a5ebd2f011d3b1cc779e1e0becd597
Untagged: mariadb:latest
Untagged: mariadb@sha256:cdc553f0515a8d41264f0855120874e86761f7c69407b5cfbe49283dc195bea8
Deleted: sha256:3a348a04a8159339ed3ca053ea925f854252e6a6c3df6fa82c17625d1026f18b
Deleted: sha256:f0f02aab2bd606af792a0f304ffbb190ebbd64370b3501c13bf23378588b1d4c
Deleted: sha256:5e7d1c43291d0e6505a3d30e1163c209cc81aebeefd0ad8c964bf7333c111a26
Deleted: sha256:0f8d69f94beee0fb593355e4f9f4cb3a754a1812d506bffb0a26c3360b11df20
Deleted: sha256:2ee4afccb4fac4a239b8b941c05897dfde2f9dacd051d8e0b506bd2cb74356bb
Deleted: sha256:34a6868c0a05ae49b144e0faacd573033e9eca390902b922ccec8e29febf3649
Deleted: sha256:57b6fb9dd5e76684053e2b2d82460fc0d138fc6dcfde6890b6b57158bb35696e
Deleted: sha256:9b0e98778011e2d935c2c54c27a443cbd2f44414b999f06f598d0c56cbacc74b
Deleted: sha256:a70f01e6724abf5ed3936b62268805f209149678aa65be619731628a21fda6e6
Deleted: sha256:fd2d6028c78d798c9a9756c7b94ed1edb05f180ab38ee3cb8bc91e56f1b5facb
Deleted: sha256:9386795d450ce06c6819c8bc5eff8daa71d47ccb9f9fb8d49fe1ccfb5fb3edbe
Deleted: sha256:3779241fda7b1caf03964626c3503e930f2f19a5ffaba6f4b4ad21fd38df3b6b
Deleted: sha256:bacd3af13903e13a43fe87b6944acd1ff21024132aad6e74b4452d984fb1a99a
Untagged: hello-world:latest
Untagged: hello-world@sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Deleted: sha256:d1165f2212346b2bab48cb01c1e39ee8ad1be46b87873d9ca7a4e434980a7726

容器命令

有了镜像才能创建容器,下载一个ubuntu测试学习

docker pull ubuntu

docker run

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

#可选项

  --name string                        Assign a name to the container
  -d, --detach                         Run container in background and print container ID
  -e, --env list                       Set environment variables
      --env-file list                  Read in a file of environment variables
        docker exec 容器ID/NAME env    查看容器可设置的环境变量
  -i, --interactive                    Keep STDIN open even if not attached
      --restart policy                 Restart policy to apply when a container exits (default "no")
        --restart no                       默认策略,在容器退出时不重启容器
        --restart on-failure               容器非正常退出时(退出状态非0),才会重启容器
        --restart on-failure[:max-retries] 容器非正常退出时重启容器,最多重启max-retries次
        --restart always                   容器退出时总是重启容器
        --restart unless-stopped           容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
  -t, --tty                            Allocate a pseudo-TTY
  -p, --publish list                   Publish a container's port(s) to the host
    -p 容器端口
    -p 主机端口 : 容器端口
    -p ip:主机端口 : 容器端口
  -P, --publish-all                    Publish all exposed ports to random ports

#启动并进入容器
root@localhost:~# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ubuntu       latest    f643c72bc252   4 months ago   72.9MB

root@localhost:~# docker run -it ubuntu /bin/bash
root@cb6e829f91fe:/# 

#退出容器
exit			#退出并停止容器
crtl + p + q	#退出不停止容器

#后台运行容器
root@localhost:~# docker run -d ubuntu
30db0b012a19aa04886ad3a5763b8e534ef0ee3e3230c51584847717dfedaf62
root@localhost:~# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
#说明,可以看见容器后台运行后就停止了,因为docker发现容器里面并没有一个前台进程,就会自动停止

docker ps

docker ps [OPTIONS]

  -a, --all             Show all containers (default shows just running)
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print containers using a Go template
  -n, --last int        Show n last created containers (includes all states) (default -1)
  -l, --latest          Show the latest created container (includes all states)
      --no-trunc        Don't truncate output
  -q, --quiet           Only display container IDs
  -s, --size            Display total file sizes

#显示当前正在运行的容器
root@localhost:~# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

#显示当前正在运行的容器+历史运行过的容器
root@localhost:~# docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS                     PORTS     NAMES
cb6e829f91fe   ubuntu         "/bin/bash"   11 minutes ago   Exited (0) 3 minutes ago             quizzical_jennings
21cef3df3fe9   d1165f221234   "/hello"      3 hours ago      Exited (0) 3 hours ago               pensive_chaum

#显示最近的1个容器
root@localhost:~# docker ps -a -n=1
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
d276013ba3e9   ubuntu    "/bin/bash"   4 minutes ago   Exited (0) 4 minutes ago             gifted_burnell

#仅显示容器id
root@localhost:~# docker ps -aq
d276013ba3e9
cb6e829f91fe
21cef3df3fe9

docker rm

docker rm [OPTIONS] CONTAINER [CONTAINER...]

  -f, --force     Force the removal of a running container (uses SIGKILL)

#删除一个容器
docker rm 容器id

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

docker start
docker restart
docker stop
docker kill

docker start [OPTIONS] CONTAINER [CONTAINER...]
docker restart [OPTIONS] CONTAINER [CONTAINER...]
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker kill [OPTIONS] CONTAINER [CONTAINER...]

docker logs

docker logs [OPTIONS] CONTAINER

      --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)

# 运行容器
root@localhost:~# docker run -d --name myUbuntu ubuntu /bin/bash -c 'while true;do echo "alcard";sleep 1;done'
0d046750f5514e2588310850a26088d8459257070aa73703962dbd95abecfeb5
root@localhost:~# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
0d046750f551   ubuntu    "/bin/bash -c 'while…"   2 seconds ago   Up 2 seconds             myUbuntu

#查看日志
root@localhost:~# docker logs -ft --tail 10 myUbuntu
2021-04-04T14:09:59.485564458Z alcard
2021-04-04T14:10:00.488720268Z alcard
2021-04-04T14:10:01.491096602Z alcard
2021-04-04T14:10:02.492541824Z alcard
2021-04-04T14:10:03.495275409Z alcard
2021-04-04T14:10:04.496861206Z alcard
2021-04-04T14:10:05.498977372Z alcard
2021-04-04T14:10:06.501323937Z alcard
2021-04-04T14:10:07.504982806Z alcard
2021-04-04T14:10:08.510445588Z alcard
2021-04-04T14:10:09.511829081Z alcard
2021-04-04T14:10:10.515584923Z alcard
2021-04-04T14:10:11.517707824Z alcard
2021-04-04T14:10:12.520339488Z alcard

docker top

docker top CONTAINER [ps OPTIONS]

#查看容器的进程
root@localhost:~# docker top myUbuntu
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                160937              160906              0                   14:09               ?                   00:00:00            /bin/bash -c while true;do echo "alcard";sleep 1;done
root                161890              160937              0                   14:11               ?                   00:00:00            sleep 1

docker inspect

docker inspect [OPTIONS] NAME|ID [NAME|ID...]

  -f, --format string   Format the output using the given Go template
  -s, --size            Display total file sizes if the type is container
      --type string     Return JSON for specified type

#获取容器/镜像的元数据
#查看容器最近一次重启时间
root@localhost:~# docker inspect -f "{{ .State.StartedAt }}" myUbuntu
2021-04-05T00:58:05.13049113Z

docker exec

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

  -e, --env list             Set environment variables
      --env-file list        Read in a file of environment variables
  -i, --interactive          Keep STDIN open even if not attached
  -t, --tty                  Allocate a pseudo-TTY

#进入正在运行的容器,会开启一个新的tty
root@localhost:~# docker exec -it myUbuntu /bin/bash
root@0d046750f551:/# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 14:09 ?        00:00:00 /bin/bash -c while true;do echo "alcard";sleep 1;done
root         837       0  0 14:23 pts/0    00:00:00 /bin/bash
root         854       1  0 14:23 ?        00:00:00 sleep 1
root         855     837  0 14:23 pts/0    00:00:00 ps -ef

docker attach

docker attach [OPTIONS] CONTAINER

#进入正在运行的容器,不会开启一个新的tty
root@localhost:~# docker attach myUbuntu
alcard
alcard
alcard
……

docker cp

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

  -a, --archive       Archive mode (copy all uid/gid information)
  -L, --follow-link   Always follow symbol link in SRC_PATH

#从主机cp到容器
root@localhost:~# touch alucard.sh
root@localhost:~# docker cp alucard.sh myUbuntu:/home/
root@localhost:~# docker exec myUbuntu /bin/bash -c "ls /home/"
alucard.sh

#从容器cp到主机
root@localhost:~# docker cp myUbuntu:/home/alucard.sh 
root@localhost:~# docker cp myUbuntu:/home/alucard.sh ./test.sh
root@localhost:~# ls
alucard.sh  test.sh

# cp是一个手动过程,后期使用 -v 卷的技术,实现自动同步

docker stats

docker stats [OPTIONS] [CONTAINER...]

  -a, --all             Show all containers (default shows just running)

root@localhost:~# docker stats myUbuntu
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O     PIDS
0d046750f551   myUbuntu   0.17%     4.254MiB / 3.816GiB   0.11%     1.11kB / 0B   8.76MB / 0B   2

root@localhost:~# docker stats -a
CONTAINER ID   NAME            CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O     PIDS
0d046750f551   myUbuntu        0.17%     4.512MiB / 3.816GiB   0.12%     1.32kB / 0B   8.76MB / 0B   2
30db0b012a19   silly_wozniak   0.00%     0B / 0B               0.00%     0B / 0B       0B / 0B       0

分层原理

在这里插入图片描述

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel,Linux刚启动时会加bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸bootfs。

rootfs(root file system)在 bootfs之上。包含的就是典型 Linux系统中的 /dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如 Ubuntu,Centos等等。

在这里插入图片描述
从上图可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

在这里插入图片描述
所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。

文件操作

文件操作说明
添加文件在容器中创建文件时,新文件被添加到容器层中。
读取文件在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存。
修改文件在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
删除文件在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。(只是记录删除操作)

只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。

这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

AUFS
在这里插入图片描述
AUFS 是一种 UnionFS:是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

简单试验下 AUFS 的使用

#1、创建两个文件夹代表只读层以及读写层。
root@localhost:~# mkdir readLayer
root@localhost:~# echo "original read file content" >> readLayer/readFile
root@localhost:~# mkdir writeLayer
root@localhost:~# echo "original write file content" >> writeLayer/writeFile

#2、将两个文件夹进行联合挂载。令中默认dirs后第一个文件夹为读写权限,之后的文件夹为只读权限。
root@localhost:~# mkdir unionFs
root@localhost:~# mount -t aufs -o dirs=./writeLayer:./readLayer none ./unionFs

#3、查看unionFs,发现已经有了readFile、writeFile
root@localhost:~# ls unionFs/
readFile  writeFile

#4、分别修改读写和只读层
root@localhost:~/unionFs# echo "edit writeable file" >> writeFile
root@localhost:~/unionFs# echo "edit readonly file" >> readFile

#5、验证
#可发现联合挂载下的文件都已改变
root@localhost:~/unionFs# cat writeFile
original write file content
edit writeable file
root@localhost:~/unionFs# cat readFile
original read file content
edit readonly file
#可以发现原读写层已改变,而只读成未变
root@localhost:~/unionFs# cat ../writeLayer/writeFile
original write file content
edit writeable file
root@localhost:~/unionFs# cat ../readLayer/readFile
original read file content

#成功模拟了只读层、读写层的联合使用,Docker的镜像分层也是此原理,只是实现更加复杂。

docker commit

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

  -a, --author string    Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
  -c, --change list      Apply Dockerfile instruction to the created image
  -m, --message string   Commit message
  -p, --pause            Pause container during commit (default true)

#1、启动一个tomcat
root@localhost:~# docker run -d --name tomcat01 -p 8080:8080 tomcat
#2、进入容器
root@9b3cf4218d2d:/usr/local/tomcat# cp -fr webapps.dist/* webapps/
#3、提交容器为镜像
root@localhost:~# docker commit -a="alucard" -m="add webapps app" tomcat01 tomcat_alucard
root@localhost:~# docker images
REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
tomcat_alucard   latest    8d133cf3ebd6   5 seconds ago   654MB
tomcat           latest    040bdb29ab37   2 months ago    649MB
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值