pod的基本介绍| harbor仓库的搭建 tomcat镜像拉取

pod的基本介绍| harbor仓库的搭建 tomcat镜像拉取

  • 一 Pod基础概念:
  • 二 通常把Pod分为两类:
  • 三 Pod容器的分类:
  • 四 应用容器(Maincontainer)
  • 五 镜像拉取策略(image PullPolicy)
  • 六 部署 harbor 创建私有项目
    • 6.1 安装docker和harbor仓库 192.168.10.40
    • 6.2 在node节点 192.168.10.20,192.168.10.30
    • 6.3 在master节点上192.168.10.10

一 Pod基础概念:

Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的,例如,用于管理Pod运行的StatefulSet和Deployment等控制器对象,用于暴露Pod应用的Service和Ingress对象,为Pod提供存储的PersistentVolume存储资源对象等。

//在Kubrenetes集群中Pod有如下两种使用方式:
●一个Pod中运行一个容器。“每个Pod中一个容器”的模式是最常见的用法;在这种使用方式中,你可以把Pod想象成是单个容器的封装,kuberentes管理的是Pod而不是直接管理容器。

●在一个Pod中同时运行多个容器。一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位,比如一个容器共享文件,另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。

一个Pod下的容器必须运行于同一节点上。现代容器技术建议一个容器只运行一个进程,该进程在容器中PID命令空间中的进程号为1,可直接接收并处理信号,进程终止时容器生命周期也就结束了。若想在容器内运行多个进程,需要有一个类似Linux操作系统init进程的管控类进程,以树状结构完成多进程的生命周期管理。运行于各自容器内的进程无法直接完成网络通信,这是由于容器间的隔离机制导致,k8s中的Pod资源抽象正是解决此类问题,Pod对象是一组容器的集合,这些容器共享Network、UTS及IPC命令空间,因此具有相同的域名、主机名和网络接口,并可通过IPC直接通信。

Pod资源中针对各容器提供网络命令空间等共享机制的是底层基础容器pause,基础容器(也可称为父容器)pause就是为了管理Pod容器间的共享操作,这个父容器需要能够准确地知道如何去创建共享运行环境的容器,还能管理这些容器的生命周期。为了实现这个父容器的构想,kubernetes中,用pause容器来作为一个Pod中所有容器的父容器。这个pause容器有两个核心的功能,一是它提供整个Pod的Linux命名空间的基础。二来启用PID命名空间,它在每个Pod中都作为PID为1进程(init进程),并回收僵尸进程。

//pause容器使得Pod中的所有容器可以共享两种资源:网络和存储。
●网络:
每个Pod都会被分配一个唯一的IP地址。Pod中的所有容器共享网络空间,包括IP地址和端口。Pod内部的容器可以使用localhost互相通信。Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)。

●存储:
Pod可以指定多个共享的Volume。Pod中的所有容器都可以访问共享的Volume。Volume也可以用来持久化Pod中的存储资源,以防容器重启后文件丢失。

//总结:
每个Pod都有一个特殊的被称为“基础容器”的Pause容器。Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或者多个紧密相关的用户应用容器。

//kubernetes中的pause容器主要为每个容器提供以下功能:
●在pod中担任Linux命名空间(如网络命令空间)共享的基础;
●启用PID命名空间,开启init进程。

//Kubernetes设计这样的Pod概念和特殊组成结构有什么用意?????
●原因一:在一组容器作为一个单元的情况下,难以对整体的容器简单地进行判断及有效地进行行动。比如,一个容器死亡了,此时是算整体挂了么?那么引入与业务无关的Pause容器作为Pod的基础容器,以它的状态代表着整个容器组的状态,这样就可以解决该问题。

●原因二:Pod里的多个应用容器共享Pause容器的IP,共享Pause容器挂载的Volume,这样简化了应用容器之间的通信问题,也解决了容器之间的文件共享问题。

二 通常把Pod分为两类:

●自主式Pod 
这种Pod本身是不能自我修复的,当Pod被创建后(不论是由你直接创建还是被其他Controller),都会被Kuberentes调度到集群的Node上。直到Pod的进程终止、被删掉、因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在那个Node上。Pod不会自愈。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。

●控制器管理的Pod
Kubernetes使用更高级的称为Controller的抽象层,来管理Pod实例。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。例如,如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上。虽然可以直接使用Pod,但是在Kubernetes中通常是使用Controller来管理Pod的。

三 Pod容器的分类:

1、基础容器(infrastructure container)
维护整个 Pod 网络和存储空间
node 节点中操作
启动一个Pod时,k8s会自动启动一个基础容器
cat /opt/kubernetes/cfg/kubelet
......
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"

//每次创建 Pod 时候就会创建,运行的每一个Pod都有一个 pause-amd64 的基础容器自动会运行,对于用户是透明的
docker ps -a
registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0   "/pause"

2、初始化容器(initcontainers)
Init容器必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法。
Init 容器与普通的容器非常像,除了以下两点:
●Init 容器总是运行到成功完成为止

●每个 Init 容器都必须在下一个 Init 容器启动之前成功完成启动和退出
如果 Pod 的 Init 容器失败,k8s 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的重启策略(restartPolicy)为 Never,它不会重新启动。

lnit 的容器作用
因为init容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:
●Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。例如,没有必要仅为了在安装过程中使用类似 sed、 awk、 python 或 dig 这样的工具而去FROM 一个镜像来生成一个新的镜像。

●Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。

●应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。

●Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。

●由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,
直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。

四 应用容器(Maincontainer)



官网示例:
https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/

vim myapp-pod-01.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

这个例子是定义了一个具有 2 个 Init 容器的简单 Pod。 第一个等待 myservice 启动, 第二个等待 mydb 启动。 一旦这两个 Init容器都启动完成,Pod 将启动 spec 中的应用容器。

在这里插入图片描述

1应用yaml文件  
kubectl apply -f myapp-pod-01.yaml 
2 
kubectl describe pod myapp-pod

kubectl logs myapp-pod -c init-myservice

请添加图片描述
请添加图片描述

1 编辑myserver.yaml文件
vim myservice.yaml
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
2 创建myservice的pod	
kubectl create -f myservice.yaml
3 查看svc
kubectl get svc

kubectl get pods -n kube-system
4 查看pod节点
kubectl get pods

在这里插入图片描述
请添加图片描述

1 编辑mydb.yaml文件
vim mydb.yaml
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
2 运行yaml文件	
kubectl create -f mydb.yaml

3 获取pod信息
kubectl get pods

在这里插入图片描述
请添加图片描述

五 镜像拉取策略(image PullPolicy)

Pod 的核心是运行容器,必须指定容器引擎,比如 Docker,启动容器时,需要拉取镜像,k8s 的镜像拉取策略可以由用户指定:
1、IfNotPresent:在镜像已经存在的情况下,kubelet 将不再去拉取镜像,仅当本地缺失时才从仓库中拉取,默认的镜像拉取策略
2、Always:每次创建 Pod 都会重新拉取一次镜像;
3、Never:Pod 不会主动拉取这个镜像,仅使用本地镜像。
注意:对于标签为“:latest”的镜像文件,其默认的镜像获取策略即为“Always”;而对于其他标签的镜像,其默认策略则为“IfNotPresent”。

官方示例:
https://kubernetes.io/docs/concepts/containers/images

1 创建测试案例
mkdir /opt/demo
cd /opt/demo

vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-test1
spec:
  containers:
    - name: nginx
      image: nginx
      imagePullPolicy: Always
      command: [ "echo", "SUCCESS" ]
2 创建pod
kubectl create -f pod1.yaml

3 查看pod节点状态
kubectl get pods -o wide

4 kubectl describe pod pod-test1

请添加图片描述
请添加图片描述
请添加图片描述

1 修改 pod1.yaml 文件
cd /opt/demo
vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-test1
spec:
  containers:
    - name: nginx
      image: nginx:1.14							#修改 nginx 镜像版本
      imagePullPolicy: Always
      #command: [ "echo", "SUCCESS" ]			#删除

2 删除原有的资源
kubectl delete -f pod1.yaml 

3 更新资源
kubectl apply -f pod1.yaml 

4 查看 Pod 状态
kubectl get pods -o wide

请添加图片描述
请添加图片描述

六 部署 harbor 创建私有项目

6.1 安装docker和harbor仓库 192.168.10.40

1 在 Docker harbor 节点(192.168.10.40)上操作
systemctl stop firewalld.service
systemctl disable firewalld.service
setenforce 0

yum install -y yum-utils device-mapper-persistent-data lvm2 
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
yum install -y docker-ce
systemctl start docker.service
systemctl enable docker.service
docker version

2 上传 docker-compose 和 harbor-offline-installer-v1.2.2.tgz 到 /opt 目录中
cd /opt
chmod +x docker-compose
mv docker-compose /usr/local/bin/

3 部署 Harbor 服务
tar zxvf harbor-offline-installer-v1.2.2.tgz -C /usr/local/
vim /usr/local/harbor/harbor.cfg
--5行--修改,设置为Harbor服务器的IP地址或者域名
hostname = 192.168.10.40

cd /usr/local/harbor/
在配置好了 harbor.cfg 之后,执行 ./prepare 命令,为 harbor 启动的容器生成一些必要的文件(环境)
./install.sh

5 在 Harbor 中创建一个新项目
(1)浏览器访问:http://192.168.10.40 登录 Harbor WEB UI 界面,默认的管理员用户名和密码是 admin/Harbor12345
(2)输入用户名和密码登录界面后可以创建一个新项目。点击“+项目”按钮
(3)填写项目名称为“kgc-project”,点击“确定”按钮,创建新项目

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
在这里插入图片描述

6.2 在node节点 192.168.10.20,192.168.10.30

1 在每个 node 节点配置连接私有仓库(注意每行后面的逗号要添加)
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "insecure-registries":["192.168.10.40"]
}
EOF

systemctl daemon-reload
systemctl restart docker

2 在每个 node 节点登录 harbor 私有仓库
docker login -u admin -p Harbor12345 http://192.168.10.40 

3 在一个 node 节点下载 Tomcat 镜像进行推送
docker pull tomcat:8.0.52
docker images

docker tag tomcat:8.0.52 192.168.10.40/kgc-project/tomcat:v1
docker images

docker push 192.168.10.40/kgc-project/tomcat:v1

请添加图片描述
请添加图片描述
请添加图片描述

node节点查看登陆凭据
cat /root/.docker/config.json | base64 -w 0			#base64 -w 0:进行 base64 加密并禁止自动换行

在这里插入图片描述

6.3 在master节点上192.168.10.10

1 创建 harbor 登录凭据资源清单,用于 K8S 访问 Harbor 私服拉取镜像所需要的密钥权限凭证 secret 资源
vim harbor-pull-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: harbor-pull-secret
data:
.dockerconfigjson:ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEwLjQwIjogewoJCQkiYXV0aCI6ICJZV1J0YVc0NlNHRnlZbTl5TVRJek5EVT0iCgkJfQoJfQp9
type: kubernetes.io/dockerconfigjson


2 创建 secret 资源
kubectl create -f harbor-pull-secret.yaml

3 查看 secret 资源
kubectl get secret

请添加图片描述
请添加图片描述

创建资源从 harbor 中下载镜像
cd /opt/demo
vim tomcat-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-tomcat
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-tomcat
  template:
    metadata:
      labels:
        app: my-tomcat
    spec:
      imagePullSecrets:						#添加 K8S 访问 Harbor 私服拉取镜像所需要的 secret 资源选项
      - name: harbor-pull-secret			#指定 secret 资源名称
      containers:
      - name: my-tomcat
        image: 192.168.10.40/kgc-project/tomcat:v1		#指定 harbor 中的镜像名
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-tomcat
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 31111
  selector:
    app: my-tomcat

在这里插入图片描述

1 删除之前在 node 节点192.168.10.30下载的 Tomcat 镜像
docker rmi tomcat:8.0.52
docker rmi 192.168.10.40/kgc-project/tomcat:v1
docker images


2 matser192.168.10.10创建资源
kubectl create -f tomcat-deployment.yaml

3 查看资源
kubectl get pods

4 查看 Pod 的描述信息,可以发现镜像时从 harbor 下载的
kubectl describe pod my-tomcat-6464c6bdf6

5 登录web页面查看harbor镜像的下载次数 发现增加了

请添加图片描述

请添加图片描述
请添加图片描述

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/20820.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC高手进阶

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

解密Netty中的Reactor模式

文章目录 单线程Reactor模式多线程Reactor模式Reactor模式中IO事件的处理流程Netty中的通道ChannelNetty中的反应器ReactorNetty中的处理器HandlerNetty中的通道Channel和处理器Handler的协作组件Pipeline Reactor(反应器)模式是高性能网络编程在设计和架构方面的基础模式.Doug…

Science文章复现(Python):图1 - Aircraft obs(机载的观测 CO2)

之前有写过science文章后处理的复现Science文章复现&#xff08;Python&#xff09;&#xff1a;在机载观测中明显的强烈南大洋碳吸收 在这里是针对图细节的理解&#xff1a; 首先需要下载这个项目 https://github.com/NCAR/so-co2-airborne-obs 这里的环境配置会比较麻烦 con…

00后卷起来,真没我们老油条什么事了···

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。 这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。…

【刷题之路】LeetCode 232. 用栈实现队列

【刷题之路】LeetCode 232. 用栈实现队列 一、题目描述二、解题1、图解主要思路2、先实现栈3、实现各个接口3.1、初始化接口3.2、入队接口3.3、出队接口3.4、取队头接口3.5、判空接口3.6、释放接口 一、题目描述 原题连接&#xff1a; 232. 用栈实现队列 题目描述&#xff1a;…

网站测试的主要方法

网站测试的主要方法 网站测试是保证网站质量的重要手段&#xff0c;通过对网站进行测试可以及时发现问题并修复&#xff0c;提高用户体验和网站的可靠性。本文将介绍网站测试的主要方法。 1.功能测试&#xff1a;测试网站的所有功能是否正常。通过模拟用户的操作&#xff0c;确…

在外包干了三年,我废了……不吹不黑!

没错&#xff0c;我也干过外包&#xff0c;一干就是三年&#xff0c;三年后&#xff0c;我废了…… 虽说废的不是很彻底&#xff0c;但那三年我几乎是出差了三年、玩了三年、荒废了三年&#xff0c;那三年&#xff0c;我的技术能力几乎是零成长的。 说起这段三年的外包经历&a…

文档管理-gitlab+markdown网页插件

特点 使用git进行版本管理&#xff0c;本地编辑使用Typora。使用gitlab进行权限管理可以在线阅读通过Markdown在线阅读插件实现&#xff0c;可显示目录显示与链接跳转&#xff0c;界面优于自带的wiki。 与其他方式对比 gitlab的wiki&#xff1a;显示界面效果不好&#xff0c…

【数据结构】栈及其实现

目录 &#x1f920;前言 什么是栈&#xff1f; 栈的定义及初始化 栈的定义 栈的初始化 栈的判空 栈顶压栈 栈顶出栈 栈的数据个数 栈的销毁 完整代码 总结 &#x1f920;前言 学了相当长一段时间的链表&#xff0c;总算是跨过了一个阶段。从今天开始我们将进入栈和…

[IOT物联网]Python快速上手开发物联网上位机程序——前言

一、什么是Python Python是一种简单易学、高级、通用的编程语言。它是一种解释型语言&#xff0c;不需要编译即可运行&#xff0c;因此可以快速地进行开发和测试。Python具有简洁优美的语法&#xff0c;使用它可以提高生产力和代码可读性。Python拥有强大的标准库和第三方库&am…

Linux Shell 实现一键部署virtualbox

VirtualBox 前言 VirtualBox 是一款开源虚拟机软件。VirtualBox 是由德国 Innotek 公司开发&#xff0c;由Sun Microsystems公司出品的软件&#xff0c;使用Qt编写&#xff0c;在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。Innotek 以 GNU General Public Licens…

孙鑫VC++第四章 1.简单绘图-MFC消息映射机制

1. MFC消息映射机制 接下来将剖析MFC消息映射机制&#xff0c;探讨发送给窗口的消息是如何被MFC框架通过窗口句柄映射表和消息映射表来用窗口类的处理函数进行响应的。另外&#xff0c;还将讲述“类向导”这一工具的运用&#xff0c;讨论设备描述表及其封装类CDC的使用&#x…

玩转ChatGPT:魔改文章成果格式

一、写在前面 首先&#xff0c;我让小Chat替我吐槽一下&#xff1a; 科研人员天天都在填各种表格&#xff0c;简直成了我们的“表格王子”和“表格公主”。从申请项目、提交论文到汇报成果&#xff0c;表格无处不在。我们填表格的时候总是期待着它能让我们的工作更高效、更顺…

遇到一个同事,喜欢查其他同事的BUG,然后截图发工作大群里,还喜欢甩锅,该怎么办?...

职场上都有哪些奇葩同事&#xff1f; 一位网友吐槽&#xff1a; 遇到一个同事&#xff0c;喜欢查同级别同事的bug&#xff0c;截图发工作群&#xff0c;甚至发大群里&#xff0c;还喜欢甩锅&#xff0c;该怎么办&#xff1f; 职场工贼&#xff0c;人人喊打&#xff0c;网友们纷…

asm 加盘 udev 重启 导致网络异常

Network interface going down when dynamically adding disks to storage using udev in RHEL 6 (Doc ID 1569028.1)正在上传…重新上传取消To Bottom In this Document APPLIES TO: Oracle Database - Enterprise Edition - Version 11.2.0.3 and later Oracle Net Servi…

UART驱动情景分析-read

一、源码框架回顾 shell读数据&#xff0c;一开始的时候没有就休眠。数据从串口发送到驱动&#xff0c;驱动接收到中断&#xff0c;驱动读取串口数据&#xff0c;这个数据会传给行规程。 行规程获取到数据后&#xff0c;会回显。按下删除就删除一个字符&#xff0c;按下回车&am…

【Linux升级之路】3_Linux进程概念

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux升级之路】 ✒️✒️本篇内容&#xff1a;认识冯诺依曼系统&#xff0c;操作系统概念与定位&#xff0c;深入理解进程概念&#xff08;了解PCB&…

【#ifndef, #define, 和 #endif】

前言 学习AFNetWoring源码的时候&#xff0c;在AFN的h借接口文件又看到了这几个宏定义&#xff0c;学习记录一下。 作用 #ifndef, #define, 和 #endif是C/CPP的预处理指令&#xff0c;常常用来条件编译和防止头文件重复包含。 简介 #ifndef 它是if not define的简写&…

Cy5.5-PEG-SH近红外荧光PEG试剂 Cyanine5.5-PEG-SH,Thiol-PEG-Cy5.5可用于活体成像

Cy5.5-PEG-SH &#xff0c;Cy5.5聚乙二醇巯基 英文名称&#xff1a;Cy5.5-PEG-SH 中文名称&#xff1a;Cy5.5聚乙二醇巯基 性状: 深蓝色固体或粘性液体&#xff0c;取决于分子量 溶剂&#xff1a;溶于水、 DMSO等常规性有机溶剂 激发/发射波长&#xff1a;684 nm/710 nm …

学习HCIP的day.06

十一、OSFP扩展知识点 1、关于OSPF状态机的问题 &#xff08;1&#xff09;在MA网络中&#xff08;要进行DR/BDR选举&#xff09;存在7种状态机&#xff0c;init是路由器A收到邻居B的hello包&#xff0c;但该hello包中没有A的RID&#xff1b; &#xff08;2&#xff09;在点到…
最新文章