图片 14

创设镜像,image的底子上创造自定义的image

Posted by

对于docker用户来说,自己创建镜像较复杂,因为几乎所有的数据库,中间件,软件都有现成的。我们只需要下载并做些配置就可以了。
但是如果我们找不到现成的镜像或者在镜像中加入特定的功能的话就需要我们自己手动构造镜像了

方法一:docker commit


Docker提供了两种镜像的方法:

  1. 跑一个basic image,docker新建了一个容器

    root@ubuntu:/home/thm/docker/test# docker run -i -t tanghuimin0713/ubuntu_amd64:14.04 /bin/bash
    WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can’t use it. Using default external servers : [8.8.8.8 8.8.4.4]
    root@5d807872b2ba:/#

  2. 在容器内安装apache2

    root@5d807872b2ba:/# apt-get update
    Ign trusty InRelease
    Hit trusty Release.gpg
    Hit trusty Release
    Hit trusty/main i386 Packages
    Get:1 trusty/main Translation-en [762 kB]
    Fetched 762 kB in 34s (22.1 kB/s)
    Reading package lists… Done
    root@5d807872b2ba:/#
    root@5d807872b2ba:/# apt-get install apache2
    Reading package lists… Done
    Building dependency tree… Done
    The following extra packages will be installed:


  3. 退出容器,将刚才装了apache的容器创建成一个新的image

    root@5d807872b2ba:/# exit
    exit
    root@ubuntu:/home/thm/docker/test#
    root@ubuntu:/home/thm/docker/test# docker ps -l
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    5d807872b2ba tanghuimin0713/ubuntu_amd64:14.04 /bin/bash 7 minutes ago Exit 0 nostalgic_heisenberg
    root@ubuntu:/home/thm/docker/test# docker commit 5d807872b2ba tanghuimin0713/ubuntu_amd64_apache2:14.04
    e7df0b3ab526c83098d54e826b4e8e1f2c6efbe0a2511c3b06b79723bacfff52
    root@ubuntu:/home/thm/docker/test# docker images
    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
    tanghuimin0713/ubuntu_amd64_apache2 14.04 e7df0b3ab526 3 seconds ago 248.1 MB
    scratch latest 6e1aa483880d About an hour ago 0 B
    tanghuimin0713/ubuntu_amd64 14.04 6cfee0d4349b 4 hours ago 216.8 MB
    tanghuimin0713/ubuntu_amd64 latest 6cfee0d4349b 4 hours ago 216.8 MB
    tanghuimin0713/ubuntu_i386 14.04 ee57f53fe012 5 hours ago 216.8 MB
    tanghuimin0713/ubuntu_i386 latest ee57f53fe012 5 hours ago 216.8 MB
    ubuntu 14.04 c4ff7513909d 9 days ago 225.4 MB
    ubuntu trusty c4ff7513909d 9 days ago 225.4 MB
    ubuntu 14.04.1 c4ff7513909d 9 days ago 225.4 MB
    ubuntu latest c4ff7513909d 9 days ago 225.4 MB
    ubuntu 14.10 75204fdb260b 9 days ago 230.1 MB
    ubuntu utopic 75204fdb260b 9 days ago 230.1 MB
    ubuntu 12.04 822a01ae9a15 9 days ago 108.1 MB
    ubuntu 12.04.5 822a01ae9a15 9 days ago 108.1 MB
    ubuntu precise 822a01ae9a15 9 days ago 108.1 MB
    ubuntu 12.10 c5881f11ded9 9 weeks ago 172.2 MB
    ubuntu quantal c5881f11ded9 9 weeks ago 172.2 MB
    ubuntu 13.04 463ff6be4238 9 weeks ago 169.4 MB
    ubuntu raring 463ff6be4238 9 weeks ago 169.4 MB
    ubuntu 13.10 195eb90b5349 9 weeks ago 184.7 MB
    ubuntu saucy 195eb90b5349 9 weeks ago 184.7 MB
    jamtur01/puppetmaster latest 99200e07340a 11 weeks ago 312.4 MB
    ubuntu 10.04 3db9c44f4520 4 months ago 183 MB
    ubuntu lucid 3db9c44f4520 4 months ago 183 MB
    root@ubuntu:/home/thm/docker/test#

  4. run一下刚刚新创建的image,看看container内是否存在刚刚安装的apache2

    root@ubuntu:/home/thm/docker/test# docker run -t -i tanghuimin0713/ubuntu_amd64_apache2:14.04 /bin/bash
    WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can’t use it. Using default external servers : [8.8.8.8 8.8.4.4]
    root@081572d422c7:/#
    root@081572d422c7:/#
    root@081572d422c7:/# apache
    apache2 apache2ctl apachectl

  5. 将新创建的image同步到docker hub

上一篇:Docker的那些事儿—基于运行的容器状态生成新的镜像,即docker
commit(10)

1 docker
commit命令

docker push
tanghuimin0713/ubuntu_amd64_apache2


2
Dockerfile命令

 

前面无论是说到测试镜像还是Base镜像,一直在反复提到一个词:Dockerfile。

首先来看下docker
commit命令的使用方法:

方法二:Dockerfile

下面我们演示如何根据Dockerfile构建镜像:

第一步:安装一个ubuntu的容器。使用run命令的时候如果找不到这个容器会自动下载

1.
在一个空目录下创建Dockerfile,并在Dockerfile中写入如下类似批处理的语句

1、创建mydockerfile目录

root@zhf-linux:/var/lib/docker# docker run -it
ubuntu

root@ubuntu:/home/thm/docker/test# touch Dockerfile
root@ubuntu:/home/thm/docker/test# vim Dockerfile 

  1 FROM tanghuimin0713/ubuntu_amd64:14.04
  2 RUN apt-get update
  3 RUN apt-get install -y nginx
  4 RUN echo "Hi, I am in your container" > /usr/share/nginx/html/index.html
  5 EXPOSE 80

2、进入mydockerfile目录,创建Dockerfile文件,内容如下:

Unable to find image
‘ubuntu:latest’ locally

Dockerfile中相关命令解释:

图片 1

latest: Pulling from
library/ubuntu

FROM: 以”tanghuimin0713/ubuntu_amd64:14.04″为basic image运行一个container;

3、使用docker build -t ubuntu-ssh-dockerfile:v1.0 .构建镜像

aef6d0613937: Pull complete

RUN: 在container中执行命令;

-t 指定新的镜像名字,:v1.0为镜像指定tag,指定Dockerfile文件所在路径。

83de9eba49f1: Pull complete

EXPOSE: 将镜像的80端口暴露在外,这样容器外可以看到这个端口并与其通信;

注意:Dockerfile文件名不一定必须叫Dockerfile。如果你的Dockerfile文件名不是Dockerfile,需要加-f参数指定你的Dockerfile文件。如果没有-f参数,docker默认去寻找Dockerfile这个文件

9087439057e1: Pull complete

  1. docker build创建image

    root@ubuntu:/home/thm/docker/test#
    root@ubuntu:/home/thm/docker/test# docker build -t=”tanghuimin0713/ubuntu_amd64_nginx:14.04″ .
    Uploading context 2.56 kB
    Uploading context
    Step 0 : FROM tanghuimin0713/ubuntu_amd64:14.04
    —> 6cfee0d4349b
    Step 1 : RUN apt-get update
    —> Running in dedead78ac76
    Ign trusty InRelease
    Hit trusty Release.gpg
    Hit trusty Release
    Hit trusty/main i386 Packages
    Get:1 trusty/main Translation-en [762 kB]
    Fetched 762 kB in 2min 16s (5571 B/s)
    Reading package lists…
    —> 3af4720f8ec3
    Step 2 : RUN apt-get install -y nginx
    —> Running in e6a4a63286fe
    Reading package lists…
    Building dependency tree…
    The following extra packages will be installed:



    Processing triggers for libc-bin (2.19-0ubuntu6) …
    Processing triggers for sgml-base (1.26+nmu4ubuntu1) …
    —> 409a0d5cd91b
    Step 3 : RUN echo “Hi, I am in your container” > /usr/share/nginx/html/index.html
    —> Running in 783d8789509c
    —> 9a5d96a41a0b
    Step 4 : EXPOSE 80
    —> Running in a2e24fc2d4b9
    —> 6cd5691b7c8c
    Successfully built 6cd5691b7c8c
    Removing intermediate container dedead78ac76
    Removing intermediate container e6a4a63286fe
    Removing intermediate container 783d8789509c
    Removing intermediate container a2e24fc2d4b9
    root@ubuntu:/home/thm/docker/test#

图片 2

45d36c0ac9f9: Pull complete

3.  查看image是否创建成功

图片 3

e991b5792ff6: Pull complete

root@ubuntu:/home/thm/docker/test# docker images
REPOSITORY                          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
tanghuimin0713/ubuntu_amd64_nginx   14.04               6cd5691b7c8c        30 seconds ago      259.2 MB
scratch                             latest              6e1aa483880d        2 hours ago         0 B
tanghuimin0713/ubuntu_amd64         14.04               6cfee0d4349b        5 hours ago         216.8 MB
tanghuimin0713/ubuntu_amd64         latest              6cfee0d4349b        5 hours ago         216.8 MB
tanghuimin0713/ubuntu_i386          14.04               ee57f53fe012        6 hours ago         216.8 MB
tanghuimin0713/ubuntu_i386          latest              ee57f53fe012        6 hours ago         216.8 MB
ubuntu                              14.04.1             c4ff7513909d        9 days ago          225.4 MB
ubuntu                              14.04               c4ff7513909d        9 days ago          225.4 MB
ubuntu                              latest              c4ff7513909d        9 days ago          225.4 MB
ubuntu                              trusty              c4ff7513909d        9 days ago          225.4 MB

分析上述docker build的构建过程:

Digest:
sha256:ec0e4e8bf2c1178e025099eed57c566959bb408c6b478c284c1683bc4298b683

  1. run一下新创建的image

    root@ubuntu:/home/thm/docker/test# docker run -i -t tanghuimin0713/ubuntu_amd64_nginx:14.04 /bin/bash
    root@45494a615738:/#
    root@45494a615738:/# which nginx
    /usr/sbin/nginx


Status: Downloaded newer
image for ubuntu:latest

nginx命令是存在的,成功。

Sending buildcontext to Docker daemon  2.048kB

第二步:进入容器。 ecb05acfdb66是容器ID

  1. 将新创建的image同步到docker hub

Step 1/3: From ubuntu    #获取ubuntu镜像

root@zhf-linux:/home/zhf#
docker run -it ubuntu

docker push
tanghuimin0713/ubuntu_amd64_nginx:14.04

—> 00fd29ccc6f1        #镜像ID为00fd29ccc6f1

root@ecb05acfdb66:/#

Step 2/3 : RUNapt-get update && apt-get install -y openssh-server

第三步:安装vim.
可以看到VIM并没有安装

—> Running in 18c5f04edaed 
#以00fd29ccc6f1镜像,运行临时容器,ID为18c5f04edaed

root@ecb05acfdb66:/#
vim

#开始在容器内执行apt-get update命令

bash: vim: command not
found

Get:1 xenial-security InRelease [102
kB]

安装vim的时候提示找不到vim

Get:2 xenial InRelease [247 kB]

root@ecb05acfdb66:/#
apt-get install -y vim

Reading package lists…
Done

Building dependency tree

#开始在容器内执行apt-get install -y openssh-server命令

Reading state
information… Done

Reading packagelists…

E: Unable to locate package
vim

Reading packagelists…

这是由于软件源没有更新的原因,执行下apt-get update
得到最新的软件包 再次执行apt-get install
vim就可以成功的安装了

Buildingdependency tree…

安装完成后docker
ps可以看到当前正在运行的容器

Reading stateinformation…

root@zhf-linux:/home/zhf#
docker ps

The followingadditional packages will be installed:

CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES

ecb05acfdb66 ubuntu
“/bin/bash” 34 minutes ago Up 34 minutes
sleepy_brahmagupta

sleepy_brahmagupta是Docker为容器随即分配的名字

Running hooks in/etc/ca-certificates/update.d…

第四步:重新开启一个终端保存新镜像:新镜像名为ubuntu-with-vi

done.

root@zhf-linux:/home/zhf#
docker commit sleepy_brahmagupta ubuntu-with-vi

Processingtriggers for systemd (229-4ubuntu21) …

sha256:a8ad90906fcc274df1b9072c690e1c6b8561aeb8d986e0f9caa649ca954ffcd8

Removing

从size来看镜像因为安装了软件而变大了。

intermediate container 18c5f04edaed #删除临时容器

root@zhf-linux:/home/zhf#
docker images

—> 4296009b93f2#生成新的镜像,镜像ID为4296009b93f2

REPOSITORY TAG IMAGE ID
CREATED SIZE

Step 3/3: CMD [“/bin/bash”]

ubuntu-with-vi latest
a8ad90906fcc 54 seconds ago 205 MB

—> Running in 396ff094f760  #以4296009b93f2镜像,运行新的临时容器

ubuntu latest fb14c85f88d3
5 days ago 109 MB

Removing

httpd latest 7659d5a9a057 8
weeks ago 189 MB

intermediate container 396ff094f760 #删除临时容器

hello-world latest
abd130ec0722 4 months ago 665 kB

—> 91bf8ac8749e#生成新的镜像,镜像ID为91bf8ac8749e

第五步:进入新镜像执行vim命令:

Successfully built91bf8ac8749e  #构建出最终的镜像

root@zhf-linux:/home/zhf#
docker run -it ubuntu-with-vi

Successfully tagged ubuntu-ssh-dockerfile:v1.0 #为镜像打上标签

root@189eac7e1d60:/# which
vim


/usr/bin/vim

镜像是一层层叠加起来的,这和我们之前讲到的是一致的。

这就是docker
commit创建新镜像的方法。这种方法效率低而且可重复性很弱。比如要在其他操作系统镜像中加入vi还要重复前面所有的步骤。下面就来看下采用dockerfile的方法

查询本地构建的镜像

第一步:首先创建Dockerfile,内容如下。 命令必须大写

图片 4

FROM
ubuntu

验证新镜像

RUN apt-get update &&
apt-get install -y vim

图片 5

第二步:执行命令root@zhf-linux:/home/zhf/docker# docker build -t
ubuntu-with-vi-dockerfile .

图片 6

Dockerfile
中的 ADD、COPY
等命令可以将 build context
中的文件添加到镜像。此例中,build context
为当前目录/home/zhf/docker,该目录下的所有文件和子目录都会被发送给
Docker
daemon。

从docker history,也印证了我们上述的分析(从下向上看)

第三步:完成创建

继续修改Dockerfile文件内容如下:

root@zhf-linux:/home/zhf/docker# docker build -t
ubuntu-with-vi-dockerfile .

图片 7

Sending build context to
Docker daemon 2.048 kB

图片 8

Step 1/2 : FROM
ubuntu

为啥这次构建这么快?原因是docker在build镜像时使用了缓存。第二步Using
cache就是。可以对比下第一次的构建过程。

—>
fb14c85f88d3

如果不想使用缓存,可以加–no-cache参数

Step 2/2 : RUN apt-get
update && apt-get install -y vim

图片 9

—> Running in
d46f693665cd

如果不想每一步创建的临时容器都删除,可以加–rm=false。默认该参数是true

Get:1
xenial-security InRelease [102
kB]

图片 10

Get:2
xenial InRelease [247
kB]

图片 11

Get:3
xenial-security/universe Sources
[56.7 kB]

图片 12

Get:4
xenial-security/main i386 Packages
[473 kB]

可见第4、5步创建的临时容器并没有被删除掉。其他参数请参考docker build
–help。

Get:5
xenial-updates InRelease [102
kB]


Get:6
xenial-backports InRelease [102
kB]

下一篇:Docker的那些事儿—docker commit与docker
build比较(12)

Get:7
xenial/universe Sources [9802
kB]


Get:8
xenial-security/restricted i386
Packages [13.0 kB]

图片 13

Get:9
xenial-security/universe i386 Packages
[198 kB]

Get:10
xenial-security/multiverse i386
Packages [3674 B]

Get:11
xenial/main i386 Packages [1552
kB]

Get:12
xenial/restricted i386 Packages [14.5
kB]

Get:13
xenial/universe i386 Packages [9804
kB]

Get:14
xenial/multiverse i386 Packages [172
kB]

Get:15
xenial-updates/universe Sources [233
kB]

Get:16
xenial-updates/main i386 Packages [827
kB]

Get:17
xenial-updates/restricted i386 Packages
[13.7 kB]

Get:18
xenial-updates/universe i386 Packages
[680 kB]

Get:19
xenial-updates/multiverse i386 Packages
[17.3 kB]

Get:20
xenial-backports/main i386 Packages
[5166 B]

Get:21
xenial-backports/universe i386 Packages
[7149 B]

Fetched 24.4 MB in 4min 36s
(88.4 kB/s)

Reading package lists…
(中间过程省略)

.

.

.

.

.

Processing triggers for
libc-bin (2.23-0ubuntu9) …

—>
4ab7bb9b7cb4

Removing intermediate
container d46f693665cd

Successfully built
4ab7bb9b7cb4

从上面可以看到步骤大致为几步:

1
执行FROM,将ubuntu作为镜像。ID=fb14c85f88d3

2
执行RUN安装VIM

3 启动
ID=d46f693665cd的临时容器,在容器中通过apt-get安装vim

4
安装成功后,将容器保存为镜像。ID=4ab7bb9b7cb4并且删除了ID=d46f693665cd的临时容器

通过docker
images查看

root@zhf-linux:/home/zhf/docker# docker
images

REPOSITORY TAG IMAGE ID
CREATED SIZE

ubuntu-with-vi-dockerfile
latest 4ab7bb9b7cb4 6 minutes ago 205 MB

ubuntu-with-vi latest
a8ad90906fcc 23 minutes ago 205 MB

ubuntu latest fb14c85f88d3
5 days ago 109 MB

httpd latest 7659d5a9a057 8
weeks ago 189 MB

hello-world latest
abd130ec0722 4 months ago 665 kB

root@3514d5772446:/# which
vim

/usr/bin/vim

也可以通过docker
history来查看Dockerfile的执行过程

root@zhf-linux:/home/zhf#
docker history ubuntu-with-vi-dockerfile

IMAGE CREATED CREATED BY
SIZE COMMENT

4ab7bb9b7cb4 2 days ago
/bin/sh -c apt-get update && apt-get insta… 96 MB

fb14c85f88d3 8 days ago
/bin/sh -c #(nop) CMD [“/bin/bash”] 0 B

<missing> 8 days ago
/bin/sh -c mkdir -p /run/systemd && echo ‘… 7 B

<missing> 8 days ago
/bin/sh -c sed -i ‘s/^#\s*\(deb.*universe\… 2.76 kB

<missing> 8 days ago
/bin/sh -c rm -rf /var/lib/apt/lists/* 0 B

<missing> 8 days ago
/bin/sh -c set -xe && echo ‘#!/bin/sh’ >… 745 B

<missing> 8 days ago
/bin/sh -c #(nop) ADD file:db6281c0035641a… 109 MB

和ubuntu的来比较一下,ubuntu-with-vi-dockerfile
与 ubuntu
镜像相比,确实只是多了顶部的一层 35ca89798937,由 apt-get
命令创建,大小为 97.07MB。docker history
也向我们展示了镜像的分层结构,每一层由上至下排列。

root@zhf-linux:/home/zhf#
docker history ubuntu

IMAGE CREATED CREATED BY
SIZE COMMENT

fb14c85f88d3 8 days ago
/bin/sh -c #(nop) CMD [“/bin/bash”] 0 B

<missing> 8 days ago
/bin/sh -c mkdir -p /run/systemd && echo ‘… 7 B

<missing> 8 days ago
/bin/sh -c sed -i ‘s/^#\s*\(deb.*universe\… 2.76 kB

<missing> 8 days ago
/bin/sh -c rm -rf /var/lib/apt/lists/* 0 B

<missing> 8 days ago
/bin/sh -c set -xe && echo ‘#!/bin/sh’ >… 745 B

<missing> 8 days ago
/bin/sh -c #(nop) ADD file:db6281c0035641a… 109 MB

下面继续看下docker的缓存,Dockerfile的内容如下:

FROM
ubuntu

RUN apt-get update &&
apt-get install -y vim

COPY Dockerfile
/

执行结果:

root@zhf-linux:/home/zhf/docker# docker build -t
ubuntu-with-v-dockerfile_2 .

Sending build context to
Docker daemon 2.048 kB

Step 1/3 : FROM
ubuntu

—>
fb14c85f88d3

Step 2/3 : RUN apt-get
update && apt-get install -y vim

—> Using
cache

—>
4ab7bb9b7cb4

Step 3/3 : COPY Dockerfile
/

—>
03943952ca8b

Removing intermediate
container a9f1c9e81ea6

Successfully built
03943952ca8b

1
首先确保执行docker
build命令的路径下的Dockerfile存在,也就是这个例子中的/home/zhf/docker存在Dockerfile

2
在第二步的RUN命令中镜像ID=4ab7bb9b7cb4和之前ubuntu-with-vi-dockerfile中的是一样的

图片 14

 

由于之前使用过相同的RUN指令,这次直接使用缓存中的镜像4ab7bb9b7cb4

3
启动临时容器,复制testfile,提交新的镜像层03943952ca8b并且删除临时容器

我们再做一个实验,如果将Dockerfile中的执行顺序改变一下看下运行结果是什么

我们将COPY命令和RUN命令调换一下顺序

FROM
ubuntu

COPY Dockerfile
/

RUN apt-get update &&
apt-get install -y vim

执行结果:可以看到在复制文件的时候运行的是一个新的镜像层。

Sending build context to
Docker daemon 2.048 kB

Step 1/3 : FROM
ubuntu

—>
fb14c85f88d3

Step 2/3 : COPY Dockerfile
/

—>
30ee5666cc73

Removing intermediate
container fcc01972c127

Step 3/3 : RUN apt-get
update && apt-get install -y vim

—> Running in
1be3495fdfb1

Get:1
xenial-security InRelease [102
kB]

Get:2
xenial InRelease [247
kB]

Get:3
xenial-security/universe Sources
[56.7 kB]

Get:4
xenial-updates InRelease [102
kB]

Get:5
xenial-backports InRelease [102
kB]

Get:6
xenial-security/main i386 Packages
[474 kB]

Get:7
xenial/universe Sources [9802
kB]

Get:8
xenial-security/restricted i386
Packages [13.0 kB]

Get:9
xenial-security/universe i386 Packages
[198 kB]

Get:10
xenial-security/multiverse i386
Packages [3674 B]

Fetched 24.4 MB in 5min 55s
(68.8 kB/s)

Reading package
lists…

Reading package
lists…

Building dependency
tree…

Reading state
information…

The following additional
packages will be installed:

file libexpat1 libgpm2
libmagic1 libmpdec2 libpython3.5
libpython3.5-minimal

libpython3.5-stdlib
libsqlite3-0 libssl1.0.0 mime-support vim-common

vim-runtime

Suggested
packages:

gpm ctags vim-doc
vim-scripts vim-gnome-py2 | vim-gtk-py2 |
vim-gtk3-py2

| vim-athena-py2 |
vim-nox-py2

The following NEW packages
will be installed:

file libexpat1 libgpm2
libmagic1 libmpdec2 libpython3.5
libpython3.5-minimal

libpython3.5-stdlib
libsqlite3-0 libssl1.0.0 mime-support vim
vim-common

vim-runtime

0 upgraded, 14 newly
installed, 0 to remove and 0 not upgraded.

Need to get 12.2 MB of
archives.

After this operation, 58.2
MB of additional disk space will be used.

Get:1
xenial/main i386 libgpm2 i386
1.20.4-6.1 [16.0 kB]

Get:2
xenial/main i386 libmagic1 i386
1:5.25-2ubuntu1 [222 kB]

Get:3
xenial/main i386 file i386
1:5.25-2ubuntu1 [21.1 kB]

Get:4
xenial-updates/main i386 libexpat1 i386
2.1.0-7ubuntu0.16.04.3 [74.1 kB]

.

.

.

.

Processing triggers for
libc-bin (2.23-0ubuntu9) …

—>
3950939de1c3

Removing intermediate
container 1be3495fdfb1

Successfully built 3950939de1c3

Dockerfile
中每一个指令都会创建一个镜像层,上层是依赖于下层的。无论什么时候,只要某一层发生变化,其上面所有层的缓存都会失效。
也就是说,如果我们改变 Dockerfile
指令的执行顺序,或者修改或添加指令,都会使缓存失效。

相关文章

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注