当前位置:   article > 正文

Docker Compose & Docker Swarm_docker swarm与compose

docker swarm与compose

卸载docker

yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

安装docker

yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install docker-ce docker-ce-cli containerd.io
systemctl start docker
  • 1
  • 2
  • 3
  • 4
  • 5

Docker Compose

简介

Docker

DockerFile build run 手动操作,单个容器!

微服务(谷粒商城,谷粒学院等)。100个微服务!依赖关系。

Docker Compose 来轻松高效的管理容器i。定义运行多个容器。

官方介绍

定义、运行多个容器。

YAML file 配置文件。

single command。 命令有哪些?

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
所有的环境都可以使用 Compose。
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.

三步骤:
Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
    • Dockerfile 保证我们的项目在任何地方可以运行。
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
    • services 什么是服务。
    • docker-compose.yml 这个文件怎么写?
  3. Run docker-compose up and Compose starts and runs your entire app.
    • 启动项目

作用:批量容器编排。

理解

Compose 是Docker官方的开源项目。需要安装!
Dockerfile让程序在任何地方运行。 web服务:redis、mysql、nginx … 多个容器。 run Compose

yml示例:

version: "3.9"  # optional since v1.27.0
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

docker-compose up 100 个服务不再需要一个一个运行。
Compose :重要的概念。

  • 服务services, 容器。应用。(web、redis、mysql…)
  • 项目project,一组关联的容器。 博客项目:web、mysql。(一个商城100个微服务,跑起来就是一个项目)

安装

1、下载

sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker- compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 这个可能快点!
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker- compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
  • 1
  • 2
  • 3
  • 4
  • 5

2、授权

sudo chmod +x /usr/local/bin/docker-compose
  • 1
[root@liushuipiaoxiang bin]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019
  • 1
  • 2
  • 3
  • 4
  • 5

学习要多看官网…
docker-compose

体验

地址:https://docs.docker.com/compose/gettingstarted/

python 应用。计数器应用。使用 redis!
1、应用 app.py

[root@liushuipiaoxiang composetest]# pwd
/home/composetest
$ mkdir composetest
$ cd composetest
  • 1
  • 2
  • 3
  • 4
import time
import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
[root@liushuipiaoxiang composetest]# vim requirements.txt
[root@liushuipiaoxiang composetest]# cat requirements.txt 
flask
redis
  • 1
  • 2
  • 3
  • 4

2、Dockerfile 应用打包为镜像

[root@liushuipiaoxiang composetest]# vim Dockerfile
[root@liushuipiaoxiang composetest]# cat Dockerfile 
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3、Docker-compose yaml文件 (定义整个服务,需要的环境。 web、redis) 完整的上线服务!

[root@liushuipiaoxiang composetest]# vim docker-compose.yml
[root@liushuipiaoxiang composetest]# cat docker-compose.yml 
version: "3"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4、启动 compose 项目(docker-compose up)
docker-compose up
docker-compose build

[root@liushuipiaoxiang ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS          PORTS                    NAMES
75eab71bfeb1   composetest_web   "flask run"              10 hours ago   Up 21 seconds   0.0.0.0:5000->5000/tcp   composetest_web_1
4c4d5f7a8187   redis:alpine      "docker-entrypoint.s…"   10 hours ago   Up 21 seconds   6379/tcp                 composetest_redis_1

  • 1
  • 2
  • 3
  • 4
  • 5
[root@liushuipiaoxiang ~]# curl localhost:5000
Hello World! I have been seen 1 times.
  • 1
  • 2

流程:

1、创建网络

2、执行 Docker-compose yaml

3、启动服务。
Docker-compose yaml
Creating composetest_web_1 … done
Creating composetest_redis_1 … done

1、文件名 composetest

2、服务

version: "3"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

有一些自动的默认规则

docker imgaes

[root@liushuipiaoxiang ~]# docker images
REPOSITORY        TAG          IMAGE ID       CREATED        SIZE
composetest_web   latest       b54c909104e6   10 hours ago   196MB
python            3.7-alpine   72e4ef8abf8e   3 weeks ago    41.1MB
redis             alpine       c678242f9116   3 weeks ago    31.6MB

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
[root@liushuipiaoxiang ~]# docker service ls
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.

  • 1
  • 2
  • 3

默认的服务名:文件名_服务名 _ num

未来有多个服务器。集群。A B… _num是副本数量

服务redis服务 => 4个副本。

集群状态。服务都不可能只有一个运行实例。 弹性、10个副本,HA 高并发。
kubectl service 负载均衡。

3、网络规则

[root@liushuipiaoxiang ~]# docker network ls
NETWORK ID     NAME                  DRIVER    SCOPE
108984bd63f0   bridge                bridge    local
020c07641ce2   composetest_default   bridge    local
763812038bfe   host                  host      local
12cc273b506f   mynet                 bridge    local
89935f772067   none                  null      local
e5fcf720f02f   redis                 bridge    local
[root@liushuipiaoxiang ~]# docker inspect composetest_default
[
    {
        "Name": "composetest_default",
        "Id": "020c07641ce2ebf410a52862220c54c7354c0c30f6da45b60d35d8904d96c9a5",
        "Created": "2021-01-07T23:34:08.261318795+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "4c4d5f7a818732e6fc8be7cc04a52e8164a957dd9f9c1bdc7517e1a49b78fc65": {
                "Name": "composetest_redis_1",
                "EndpointID": "944e22c4535401278f9b7f7069b92c296ce1650e0ca11e022e93b7a36b6e7eb9",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "75eab71bfeb154e6e30e2c13cd19e7d0c49fb331e3f70f541f9a90ca575e1fb1": {
                "Name": "composetest_web_1",
                "EndpointID": "b7ba19876fd28929cb02850f4e926006c89b569ee346765fb71ce34add0622c4",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "composetest",
            "com.docker.compose.version": "1.25.5"
        }
    }
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

10个服务 => 项目 (项目中的内容都在同个网络下。可以通过域名访问)

如果在同一个网络下,我们可以直接通过域名访问。如果一个ip为02挂了,再起一个06,名字一样,照样可以访问!
高可用!HA!
停止: docker-compose down 或者 ctrl+c

docker-compose

以前都是单个 docker run 启动容器。

docker-compose: 通过 docker-compose 编写 yaml配置文件、可以通过 compose 一键启动所有服
务,停止!

Docker小结:
1、Docker 镜像。 run => 容器
2、DockerFile 构建镜像(把服务打包)
3、docker-compose 启动项目(编排、多个微服务/环境)
4、Docker 网络

yaml 规则

k8s也要使用大量的yaml

docker-compose.yaml 核心。!

https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples

# 3层!
version: '' # 版本
services: # 服务
  服务1: web
    # 服务配置
    images
    build
    network
    .....
  服务2: redis
     ....
  服务3: redis
# 其他配置 网络/卷、全局规则
volumes:
networks:
configs:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述
学习,要掌握规律!

只要多写,多看。 compose.yaml 配置。!

1、官网文档
https://docs.docker.com/compose/compose-file/#specifying-durations

2、开源项目 compose.yaml
要部署redis、mysql、mq太麻烦了!

实战开源项目

部署博客

步骤:下载程序、安装数据库、配置…

compose部署应用 => 一键启动!

https://docs.docker.com/compose/wordpress/

1、下载项目(docker-compose.yaml)

[root@liushuipiaoxiang home]# mkdir my_wordpress/
[root@liushuipiaoxiang home]# cd my_wordpress/
[root@liushuipiaoxiang my_wordpress]# vim docker-compose.yml
[root@liushuipiaoxiang my_wordpress]# cat docker-compose.yml 
version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress
volumes:
    db_data: {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

2、如果需要文件。Dcokerfile
本项目不需要

3、文件准备齐全(直接一键启动项目!)
docker-compose up -d(后台启动)

[root@liushuipiaoxiang my_wordpress]# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                  NAMES
be3aadd04e81   wordpress:latest   "docker-entrypoint.s…"   21 seconds ago   Up 19 seconds   0.0.0.0:8000->80/tcp   my_wordpress_wordpress_1
23046bfcb02f   mysql:5.7          "docker-entrypoint.s…"   22 seconds ago   Up 21 seconds   3306/tcp, 33060/tcp    my_wordpress_db_1

  • 1
  • 2
  • 3
  • 4
  • 5

前台启动
docker -d
docker-compose up -d

学了docker后,一切都很简单!

必须掌握:

Linux docker k8s
docker基础, 原理 网络 服务 集群 错误排查 日志!

实战

1、编写项目微服务
controller

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author ZhaoZhiyue
 * @DATE 2021/1/9 - 12:18
 */
@RestController
public class HelloController {

    @Autowired
    StringRedisTemplate redisTemplate;

    @GetMapping("/hello")
    public String hello(){
        Long views =redisTemplate.opsForValue().increment("views");
        return "hello, kuangshen, thankyou, views:"+views;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

application.yml

server.port=8080
spring.redis.host=redis
  • 1
  • 2

Dockerfile:

FROM java:8

COPY *.jar /app.jar

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

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

docker-compose.yaml

version: '3.8'
services:
  zzyapp:
    build: .
    image: zzyapp
    depends_on:
      - redis
    ports:
      - "8080:8080"
  redis:
    image: "library/redis:alpine"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2、dockerfile 构建镜像
3、docker-compose.yaml 编排项目
4、丢到服务器 docker-compose up

[root@liushuipiaoxiang home]# cd  zzyapp/
[root@liushuipiaoxiang zzyapp]# pwd
/home/zzyapp
[root@liushuipiaoxiang zzyapp]# ll
total 25740
-rw-r--r-- 1 root root 26349265 Jan  9 12:36 demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root      179 Jan  9 12:36 docker-compose.yaml
-rw-r--r-- 1 root root      119 Jan  9 12:36 Dockerfile
[root@liushuipiaoxiang zzyapp]# docker-compose up

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

成功!
在这里插入图片描述

小结:
未来项目只要有 docker-compose 文件。 按照这个规则,启动编排容器!
公司: docker-compose。 直接启动。
网上开源项目: docker-compose 一键搞定。

假设项目要重新部署打包
docker-compose up --build # 重新构建!

总结:
一个工程会有多个服务,每个服务打包为一个容器!
项目 compose:三层

  • 工程 Porject
  • 服务 环境
  • 容器 运行实例! 对docker进一步封装!可以使用k8s管理容器。

Docker Compose 搞定!

Docker Swarm

集群
购买服务器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到此,服务器购买完毕!1主,3从!

4台机器安装 Docker

和我们单机安装一样
技巧:xshell 直接同步操作,省时间。!

工作模式

在这里插入图片描述
搭建集群

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
私网、公网!
172.24.82.149 用自己的!
在这里插入图片描述

初始化节点
docker swarm init
docker swarm join 加入 一个节点!

# 获取令牌
docker swarm join-token manager
docker swarm join-token worker```
  • 1
  • 2
  • 3

在这里插入图片描述
把后面的节点都搭建进去!
在这里插入图片描述
100台!
1、生成主节点 init
2、加入(管理者、worker)
目标:双主双从!

Raft协议

双主双从: 假设一个节点挂了!其他节点是否可以用!
Raft协议: 保证大多数节点存活才可以用。 只要>1 ,集群至少大于3台!
实验:
1、将docker1机器停止。宕机! 双主,另外一个主节点也不能使用了!
在这里插入图片描述
2、可以将其他节点离开

在这里插入图片描述
3、work就是工作的、管理节点操作! 3台机器设置为了管理节点。
十分简单:集群,可用!至少3个主节点。 至少> 1 台管理节点存活!
Raft协议: 保证大多数节点存活,才可以使用,高可用!

体会

弹性、扩缩容!集群!
以后告别 docker run!
docker-compose up! 启动一个项目。单机!
集群: swarm
命令:docker serivce
容器 => 服务!
容器 => 服务!=> 副本!
redis 服务 => 10个副本!(同时开启10个redis容器)
体验:创建服务、动态扩展服务、动态更新服务。

在这里插入图片描述
灰度发布:金丝雀发布!不能影响正常的使用!!
在这里插入图片描述

docker run 容器启动!不具有扩缩容器
docker service 服务! 具有扩缩容器,可以滚动更新、灰度发布!
  • 1
  • 2

查看服务 REPLICAS

在这里插入图片描述
动态扩缩容

在这里插入图片描述
服务,集群中任意的节点都可以访问。服务可以有多个副本动态扩缩容实现高可用!
弹性、扩缩容!
10台! 10000台! 多余的可以卖给别人! 虚拟化!
服务的高可用,任何企业,云!

在这里插入图片描述
移除!

docker service rm my-nginx
  • 1

docker swarm 其实并不难
只要会搭建集群、会启动服务、动态管理容器就可以了!

概念总结

swarm
集群的管理和编号。 docker可以初始化一个 swarm 集群,其他节点可以加入。(管理、工作者)
Node
就是一个docker节点。多个节点就组成了一个网络集群。(管理、工作者)
Service
任务,可以在管理节点或者工作节点来运行。核心。!用户访问!
Task
容器内的命令,细节任务!

在这里插入图片描述
逻辑是不变的(k8s)
命令 -> 管理 -> api -> 调度 -> 工作节点(创建Task容器维护创建!)

服务副本与全局服务

在这里插入图片描述

调整service以什么方式运行

--mode string
Service mode (replicated or global) (default "replicated")
docker service create --mode replicated --name mytom tomcat:7 默认的
docker service create --mode global --name haha alpine ping baidu.com
#场景?日志收集
每一个节点有自己的日志收集器,过滤。把所有日志最终再传给日志中心
服务监控,状态性能。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

拓展:网络模式: “PublishMode”: “ingress”
Swarm:
Overlay:
ingress : 特殊的 Overlay 网络! 负载均衡的功能! IPVS VIP!
虽然docker在4台机器上,实际网络是同一个! ingress 网络 ,是一个特殊的 Overlay 网络

在这里插入图片描述
整体!
k8s!

Docker Stack

在这里插入图片描述
docker-compose 单机部署项目!
Docker Stack部署,集群部署!

# 单机
docker-compose up -d wordpress.yaml
# 集群
docker stack deploy wordpress.yaml
# docker-compose 文件
version: '3.4'
services:
mongo:
image: mongo
restart: always
networks:
- mongo_network
deploy:
restart_policy:
condition: on-failure
replicas: 2
mongo-express:
image: mongo-express
restart: always
networks:
- mongo_network
ports:
- target: 8081
published: 80
protocol: tcp
mode: ingress
environment:
ME_CONFIG_MONGODB_SERVER: mongo
ME_CONFIG_MONGODB_PORT: 27017
deploy:
restart_policy:
condition: on-failure
replicas: 1
networks:
mongo_network:
external: true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

Docker Secret

安全!配置密码,证书!

在这里插入图片描述

Docker Config

配置
在这里插入图片描述
Docker下半场!
Docker Compose Swarm!
了解,学习方式:
网上找案例跑起来试试!查看命令帮助文档 --help, 官网!

拓展到K8S

云原生时代
必须精通k8s!!!
10台机器以上,优先考虑k8s!

Go语言!必须掌握! Java、Go!
docker和k8s都是go!
并发语言!
B语言 C 语言的创始人 。Unix创始人 V8
Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及CSP-style 并发计算。
go 有指针!
学习:入门-基础语法-高级对象-操作数据库-框架!
罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor、Russ Cox加入项目。Go是基于Inferno操作系统所开发的。Go于2009年11月正式宣布推出,成为开放源代码项目,并在Linux及Mac OS X平台上进行了实现,后来追加了Windows系统下的实现。在2016年,Go被软件评价公司TIOBE 选为“TIOBE 2016 年最佳语言”。 目前,Go每半年发布一个二级版本(即从a.x升级到a.y)
java => Go
zijie => Go

笔记为看狂神视频所记
视频地址(强烈推荐):
【狂神说Java】Docker最新超详细版教程通俗易懂

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/73528
推荐阅读
相关标签
  

闽ICP备14008679号