自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(52)
  • 收藏
  • 关注

转载 Docker最佳实践:5个方法精简镜像

本文记录了精简Docker镜像尺寸的必要性及好处精简Docker镜像大小的必要性Docker镜像由很多镜像层(Layers)组成(最多127层),镜像层依赖于一系列的底层技术,比如文件系统(filesystems)、写时复制(copy-on-write)、联合挂载(union mounts)等技术,你可以查看Docker社区文档以了解更多有关Docker存储驱动的内容,这里就不再赘述技术细节。总的来说,Dockerfile中的每条指令都会创建一个镜像层,继而会增加整体镜像的尺寸。下面是精简.

2020-11-30 22:31:00 400 2

原创 Kubernetes 初始化容器InitContainer

Init ContainerPod中会有这几种类型的容器: • Infrastructure Container:基础容器 ,维护整个Pod网络空间 • InitContainers:初始化容器,先于业务容器开始执行 • Containers:业务容器 Init 容器是一种特殊容器,在 Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。你可以在 Pod 的规约中与用来描述应用容器的containers数组平行的位置指定 Init 容..

2020-11-30 17:27:42 4092

转载 Nio2Endpoint组件:Tomcat如何实现异步I/O?

Java 提供了 BIO、NIO 和 NIO.2 这些 API 来实现这些 I/O 模型。BIO 是我们最熟悉的同步阻塞,NIO 是同步非阻塞,那 NIO.2 又是什么呢?NIO 已经足够好了,为什么还要 NIO.2 呢?NIO 和 NIO.2 最大的区别是,一个是同步一个是异步。我在上期提到过,异步最大的特点是,应用程序不需要自己去触发数据从内核空间到用户空间的拷贝。为什么是应用程序去“触发”数据的拷贝,而不是直接从内核拷贝数据呢?这是因为应用程序是不能访问内核空间的,因此数据拷贝肯定是由内核来做

2020-11-27 10:19:31 553

原创 Keepalived+Lvs 原来如此简单,so easy

前言在lvs架构中,当后端的rs宕掉时,调度器仍会把请求转发到宕掉的rs上,而使用keepalived就可以解决该问题。keepalived已经嵌入了lvs功能,无需使用ipvsadm & 无需编写lvs相关脚本。完整的keepalived+lvs需要两台调度器实现高可用,提供调度服务的只需要一台,另外一台作为备用。用了lvs加keepalived可以使用一个VIP,LVS和keepalived整合的话,哪我们不需要手工去配置VIP操作了[root@localhost ~]#...

2020-11-25 11:37:47 729 4

转载 Docker 的多阶段构建镜像

Docker的口号是Build,Ship,and Run Any App,Anywhere,在我们使用 Docker 的大部分时候,的确能感觉到其优越性,但是往往在我们 Build 一个应用的时候,是将我们的源代码也构建进去的,这对于类似于 golang 这样的编译型语言肯定是不行的,因为实际运行的时候我只需要把最终构建的二进制包给你就行,把源码也一起打包在镜像中,需要承担很多风险,即使是脚本语言,在构建的时候也可能需要使用到一些上线的工具,这样无疑也增大了我们的镜像体积。示例比如我们现在有..

2020-11-24 17:03:24 334 1

转载 核心定义:Kubernetes 是如何搞定“不可变基础设施”的?

本节课我们会学习 Kubernetes 中最重要、也最核心的对象——Pod。在了解 Pod 之前,我们先来看一下CNCF 官方是怎么定义云原生的。云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。有没有注意到,云原生的代表技术里面提到了一个概念

2020-11-24 16:43:26 1538 1

原创 Kubernetes Pod 资源共享实现机制

Pod基本概念Pod是Kubernetes创建和管理的最小单元,一个Pod由一个容器或多个容器组成,这些容器共享存储、网络。Pod特点• 一个Pod可以理解为是一个应用实例,提供服务• Pod中容器始终部署在一个Node上 • Pod中容器共享网络、存储资源• Kubernetes直接管理Pod,而不是容器Pod就是豌豆荚,里面的豆子可以理解为容器,一个pod可以理解为一个应用提供具体的某个服务。Pod主要用法:• 运行单个容器:最常见的用法,在这种情况下,可以将Pod.

2020-11-24 16:08:45 2512

转载 一文聊透负载均衡神器 LVS、Nginx、HAProxy的工作原理

当前大多数的互联网系统都使用了服务器集群技术,集群是将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是 Web 应用服务器集群,也可以是数据库服务器集群,还可以是分布式缓存服务器集群等等。在实际应用中,在 Web 服务器集群之前总会有一台负载均衡服务器,负载均衡设备的任务就是作为 Web 服务器流量的入口,挑选最合适的一台 Web 服务器,将客户端的请求转发给它处理,实现客户端到真实服务端的透明转发。最近几年很火的「云计算」以及分布式架构,本质上也是将后端服务器作为计算..

2020-11-24 12:02:07 357

转载 Dockerfile 多阶段构建简要说明

Dockerfile多阶段构建Docker 17.05版本以后,新增了Dockerfile多阶段构建。所谓多阶段构建,实际上是允许一个Dockerfile 中出现多个FROM指令。这样做有什么意义呢?老版本Docker中为什么不支持多个 FROM 指令在17.05版本之前的Docker,只允许Dockerfile中出现一个FROM指令,这得从镜像的本质说起。你可以简单理解Docker的镜像是一个压缩文件,其中包含了你需要的程序和一个文件系统。其实这样说是不严谨的,Docke...

2020-11-23 22:23:42 694 1

原创 Kubernetes kubeconfig配置文件详细解读

kubeconfig配置文件在node节点上可以执行kubectl命令吗?[root@k8s-node1 ~]# kubectl get nodeThe connection to the server localhost:8080 was refused - did you specify the right host or port?localhost:8080这个端口是k8s api(kube-apiserver非安全端口)的端口,在master上面可以执行成功其...

2020-11-23 16:59:01 22708 3

原创 Keepalived 双主模式

双机双主正常情况下nginx是一台提供服务,另外一条备份,互为主备要引入两个VIP,如mysql双主,nginx双主,这样要引入两个VIP,也就是还需要引入virtual_ipaddress { 192.168.179.199 192.1681.79.188}只是代表这个实例有两个VIP192.168.179.102[root@localhost ~]# cat /etc/keepalived/keepalived.conf global_defs {.

2020-11-21 19:22:01 747

原创 Kubernetes 系统管理员不得不掌握的 9 个 kubectl 命令

kubectl 是 Kubernetes 的一个命令行管理工具,可用于 Kubernetes 上的应用部署和日常管理。本文列举了 9 个常见的 kubectl 命令,并总结了一些使用技巧,希望可以帮助系统管理员简化管理工作。kubectl 查询,创建,编辑,删除资源查看master组件状态:kubectl get cs[root@k8s-master ~]# kubectl get csWarning: v1 ComponentStatus is deprecated in ...

2020-11-20 15:09:26 1702 1

转载 Kubernetes PV 动态供给

前面的例子中,我们提前创建了 PV,然后通过 PVC 申请 PV 并在 Pod 中使用,这种方式叫做静态供给(Static Provision)。与之对应的是动态供给(Dynamical Provision),即如果没有满足 PVC 条件的 PV,会动态创建 PV。相比静态供给,动态供给有明显的优势:不需要提前创建 PV,减少了管理员的工作量,效率高。动态供给是通过 StorageClass 实现的,StorageClass 定义了如何创建 PV,下面是两个例子。StorageClasssta.

2020-11-19 19:03:56 550

原创 Kubernetes calio,dashboard,Kuboard 部署

Calico网络两台Docker主机如何实现容器互通? Docker跨主机会分配相同的的IP,这样肯定是无法通信的,在本地ping 172.17.0.2肯定是找的该主机上面的172.0.02不会去找另外一台主机上面的容器Q:1、统一管理这些k8s node网段,保障每个容器分配不一样的ip2、要知道转发哪个docker主机?3、怎么实现这个转发(从docker主机1上容器发送到另一台docker主机上容器)A:1、给每个docker主机分配唯一的网段2、做好记录,每.

2020-11-19 15:26:18 1450

原创 Jenkins 多实例配置

Jenkins多实例配置单台Jenkins服务器可以满足企业测试环境及生产环境使用Jenkins自动部署+测试平台,如果每天更新发布多个WEB网站,Jenkins需要同时处理很多的任务。基于Jenkins分布式,也即多Slave方式可以缓解Jenkins服务器的压力,Jenkins多实例架构如图所示,可以在Windows、Linux、MAC等操作系统上执行Slave。Jenkins多Slave原理是将原本在Jenkins Master端的构建项目分配给Slave端去执行,Jenkins Mas.

2020-11-19 14:17:08 1193 1

原创 Keepalived 配置详解与主备模式

keepalived 的几个进程生产环境使用Keepalived正常运行,共启动3个进程,一个是父进程,负责监控其子进程,一个是VRRP子进程,另外一个是Checkers子进程。两个子进程都被系统Watchlog看管,两个子进程各自负责自己的事,Healthcheck子进程检查各自服务器的健康状况,如果Healthcheck进程检查到Master上服务不可用了,就会通知本机上的VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态。[root@localhost ~]# ps

2020-11-19 11:18:20 3364 2

原创 Kubernetes secret使用详解

Secret 存在意义K8s configmap可以注入pod之内成为环境变量或者是配置文件,这些都是以明文方式保存,如果碰到密码这种的以明文方式保存就不行了,Secret更加倾向于保存要加密的文件。Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec中。Secret 可以以 Volume 或者环境变量的方式使用。密码这种可以先存储到secret里面,然后挂载到Pod里面即可。Secret 有三种类型:Service Acc.

2020-11-18 17:22:28 1419

转载 NioEndpoint组件:Tomcat如何实现非阻塞I/O?

UNIX 系统下的 I/O 模型有 5 种:同步阻塞 I/O、同步非阻塞 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O。这些名词我们好像都似曾相识,但这些 I/O 通信模型有什么区别?同步和阻塞似乎是一回事,到底有什么不同?等一下,在这之前你是不是应该问自己一个终极问题:什么是 I/O?为什么需要这些 I/O 模型?所谓的 I/O 就是计算机内存与外部设备之间拷贝数据的过程。我们知道 CPU 访问内存的速度远远高于外部设备,因此 CPU 是先把外部设备的数据读到内存里,然后再进行处理。..

2020-11-18 11:53:32 770

转载 Docker 容器监控原理及 cAdvisor 的安装与使用

生产环境中监控容器的运行状况十分重要,通过监控我们可以随时掌握容器的运行状态,做到线上隐患和问题早发现,早解决。所以今天我就和你分享关于容器监控的知识(原理及工具 cAdvisor)。虽然传统的物理机和虚拟机监控已经有了比较成熟的监控方案,但是容器的监控面临着更大的挑战,因为容器的行为和本质与传统的虚拟机是不一样的,总的来说,容器具有以下特性:容器是短期存活的,并且可以动态调度 容器的本质是进程,而不是一个完整操作系统 由于容器非常轻量,容器的创建和销毁也会比传统虚拟机更加频繁Docker .

2020-11-17 21:37:57 6020 1

原创 Kubernetes 当中启用IPVS模式

kubernetes自1.8版本开始强推ipvs,之前版本默认使用iptables,这个iptables大家应该比较熟悉的,Linux默认防火墙嘛,它是比较古老的一种网络模式。kubernetes在版本v1.6中已经支持5000个节点,但使用iptables 的 kube-proxy 实际上是将集群扩展到5000个节点的瓶颈。在5000节点集群中使用 NodePort 服务,如果有2000个服务并且每个服务有10个 pod,这将在每个工作节点上至少产生20000个iptable 记录,

2020-11-17 19:57:43 5202 1

原创 Kubernetes kubeadm 快速部署集群

Kubernetes集群架构与组件生产环境部署K8s的2种方式kubeadmKubeadm是一个工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。部署地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/(可以快速部署k8s,为了简化二进制部署K8s集群)缺点是如果使用kubeadm搭建出来k8s集群,那么后期的维护会有点难度,因为搭建集群完全帮你.

2020-11-17 15:11:31 903

转载 网络分层的真实含义是什么?

长时间从事计算机网络相关的工作,我发现,计算机网络有一个显著的特点,就是这是一个不仅需要背诵,而且特别需要将原理烂熟于胸的学科。很多问题看起来懂了,但是就怕往细里问,一问就发现你懂得没有那么透彻。我们上一节列了之后要讲的网络协议。这些协议本来没什么稀奇,每一本教科书都会讲,并且都要求你背下来。因为考试会考,面试会问。可以这么说,毕业了去找工作还答不出这类题目的,那你的笔试基本上也就挂了。当你听到什么二层设备、三层设备、四层 LB 和七层 LB 中层的时候,是否有点一头雾水,不知道这些所谓的层,对..

2020-11-17 09:26:17 418

转载 Redis 数据同步:主从库如何实现数据一致?

前两节课,我们学习了 AOF 和 RDB,如果 Redis 发生了宕机,它们可以分别通过回放日志和重新读入 RDB 文件的方式恢复数据,从而保证尽量少丢失数据,提升可靠性。不过,即使用了这两种方法,也依然存在服务不可用的问题。比如说,我们在实际使用时只运行了一个 Redis 实例,那么,如果这个实例宕机了,它在恢复期间,是无法服务新来的数据存取请求的。那我们总说的 Redis 具有高可靠性,又是什么意思呢?其实,这里有两层含义:一是数据尽量少丢失,二是服务尽量少中断。AOF 和 RDB 保证了前者,

2020-11-16 21:28:43 728 3

原创 Docker Gitlab+Jenkins+Harbor构建持久化平台

CI/CD概述CI工作流程设计Git 代码版本管理系统 只能命令行去管理git Gitlab 基于git做了图形管理页面,企业使用gitlab做私有的代码管理仓库 Github 公共代码管理仓库搭建gitlab搭建gitlab先创建工作目录,因为有些数据需要持久化[root@www ~]# mkdir -p /gitlab[root@www ~]# cd /gitlab/docker run -d \ --name gitlab \ -p 844...

2020-11-16 12:00:24 1627 1

原创 Docker 为你的镜像仓库Harbor部署HTTPS

Harbor 部署HTTPS生成SSL证书配置https必须要有ssl证书,ssl证书可以是受信任的第三方CA签发的,大部分是花钱要买的,要域名证书公司帮你签发。这些都是受信任的,大概一个域名3000左右。当然你也可以使用自签证书,比如使用openssl生成证书,或者使用cfssl工具去生成证书。我这里使用自签证书,创建生成证书的目录ssl,并且下载配置cfssl工具[root@reg harbor]# mkdir /ssl[root@reg harbor]# cd /ssl/

2020-11-13 12:12:49 686

原创 Docker Harbor镜像管理仓库2.0搭建与使用详解

Harbor 概述Harbor是由VMWare公司开源的容器镜像仓库。事实上,Harbor是在Docker Registry上进行了相应的企业级扩展, 从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访问控制 ,AD/LDAP集成以及 审计日志等,足以满足基本企业需求。官方:https://goharbor.io/Github:https://github.com/goharbor/harborHarbor有两个版本,之前使用的是1版本,这里使用2.0版本...

2020-11-13 11:44:42 5628 1

转载 Linux 为什么要学习网络协议?

《圣经》中有一个通天塔的故事,大致是说,上帝为了阻止人类联合起来,就让人类说不同的语言。人类没法儿沟通,达不成“协议”,通天塔的计划就失败了。但是千年以后,有一种叫“程序猿”的物种,敲着一种这个群体通用的语言,连接着全世界所有的人,打造这互联网世界的通天塔。如今的世界,正是因为互联网,才连接在一起。当"Hello World!"从显示器打印出来的时候,还记得你激动的心情吗?public class HelloWorld { public static void main(String[..

2020-11-11 10:03:39 310

转载 Kubernetes 深入理解 Pod

为什么需要 Pod; Pod 的实现机制; 详解容器设计模式。一、为什么需要 Pod容器的基本概念现在来看第一个问题:为什么需要 Pod?我们知道 Pod 是 Kubernetes 项目里面一个非常重要的概念,也是非常重要的一个原子调度单位,但是为什么我们会需要这样一个概念呢?我们在使用容器 Docker 的时候,也没有这个说法。其实如果要理解 Pod,我们首先要理解容器,所以首先来回顾一下容器的概念:容器的本质实际上是一个进程,是一个视图被隔离,资源受限的进程。容器里面 PID.

2020-11-10 21:19:31 588

原创 Kubernetes 灰度/滚动发布 滚动更新速率控制解读 maxUnavailable,maxSurge

利用kubernetes的滚动更新时,可能经常遇到发布“太快不稳定”或“太慢体验差”的情况。本文将介绍kubernetes滚动更新控制速率的特性。含义服务在滚动更新时,deployment控制器的目的是:给旧版本(old_rs)副本数减少至0、给新版本(new_rs)副本数量增至期望值(replicas)。大家在使用时,通常容易忽视控制速率的特性,以下是kubernetes提供的两个参数:maxUnavailable:和期望ready的副本数比,不可用副本数最大比例(或最大值),这个....

2020-11-10 17:34:14 15426 4

原创 Dockerfile JAVA微服务镜像 构建Jar

跑java微服务只需要有JDK的环境就行了,直接执行java -jar就行了,就直接可以将java跑起来了这个是将微服务的jar包直接打进去(只需要有个jdk环境就行)java:8-jdk-alpine还需要测试,因为环境库可能和centos不一样[root@localhost java]# cat Dockerfile FROM java:8-jdk-alpineLABEL maintainer www.jar.comENV JAVA_OPTS="$JAVA_OPTS -Dfile.e

2020-11-10 17:20:54 2255 1

原创 Docker Dockefile制作nginx php镜像搭建Wordpress网站

前端项目镜像构建与部署:Nginx[root@localhost _data]# cd /nginx/[root@localhost _data]# cd /nginx/[root@localhost nginx]# lsDockerfile nginx-1.15.5.tar.gz nginx.conf php.conf#这里nginx.conf需要COPY拷贝到编译好的nginx替换掉其默认配置文件,php.conf文件是为了搭建wordpress博客网站使用的虚拟主机配置文件

2020-11-10 12:02:56 2439 1

原创 Jenkins插件下载慢的解决办法(使用nginx反向代理)

即使更换清华源的update-center.json,依然很卡,那是因为清华源也是指向了官方地址。最好的办法就是使用nginx代理updates.jenkins-ci.org步骤分为两步将updates.jenkins-ci.org映射到本地环回地址127.0.0.1 使用nginx代理updates.jenkins-ci.org的镜像网站到清华源第一步:将updates.jenkins.org映射到本地环回地址vim /etc/hosts127.0.0.1 updates.jen

2020-11-10 11:34:38 570

原创 jenkins修改源来加速插件的安装(jenkins插件安装慢的解决方法)

PHP项目构建可以看到和nginx的Dockerfile大致相同Make -j 4指定编译时候的线程数,如果是多核CPU可以将其值调大。这样编译速度会更加快一些这个指令是在前台运行的,就是不加任何参数在前台运行。也是使用CMD去启动就行。在写Dokcefile的时候大部分情况下使用CMD启动就行。Php里面其实有了两个,一个是PHP引擎,安装完php之后可以使用php去执行你的脚本。另外一个是PHP FPM,类似于一个动态的服务器。可以解析php相关脚本这些文件都是编译之后拷..

2020-11-10 10:39:51 664

原创 Kubernetes 定时执行任务CronJob 

CronJobLinux 中有 cron 程序定时执行任务,Kubernetes 的 CronJob 提供了类似的功能,可以定时执行 Job。CronJob 配置文件示例如下:spec.template格式同Pod RestartPolicy仅支持Never或OnFailure 单个Pod时,默认Pod成功运行后Job即结束 spec.completions标志Job结束需要成功运行的Pod个数,默认为1 spec.parallelism标志并行运行的Pod的个数,默认为1 spec...

2020-11-09 15:17:46 3042

转载 使用 Linux 的 strace 命令跟踪/调试程序的常用选项

strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。strace命令是一个集诊断、调试、统计与一体的工具,我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。当然strace与专..

2020-11-09 12:00:47 782

转载 Tomcat 的“高层们”都负责做什么?

使用过 Tomcat 的同学都知道,我们可以通过 Tomcat 的/bin目录下的脚本startup.sh来启动 Tomcat,那你是否知道我们执行了这个脚本后发生了什么呢?你可以通过下面这张流程图来了解一下。1.Tomcat 本质上是一个 Java 程序,因此startup.sh脚本会启动一个 JVM 来运行 Tomcat 的启动类 Bootstrap。2.Bootstrap 的主要任务是初始化 Tomcat 的类加载器,并且创建 Catalina。关于 Tomcat 为什么需要自己...

2020-11-09 09:45:13 240

转载 Docker 制作镜像Dockerfile和commit

构建镜像构建镜像主要有两种方式: 使用docker commit命令从运行中的容器提交为镜像; 使用docker build命令从 Dockerfile 构建镜像。 首先介绍下如何从运行中的容器提交为镜像。我依旧使用 busybox 镜像举例,使用以下命令创建一个名为 busybox 的容器并进入 busybox 容器。$ docker run --rm --name=busybox -it busybox sh执行完上面的命令后,当前窗口会启动一个 busybox 容器.

2020-11-06 17:31:40 649 1

原创 Kubernetes 运行一次性任务Job

容器按照持续运行的时间可分为两类:服务类容器和工作类容器。服务类容器通常持续提供服务,需要一直运行,比如 http server,daemon 等。 工作类容器则是一次性任务,比如批处理程序,完成后容器就退出。Kubernetes 的 Deployment、ReplicaSet 和 DaemonSet 都用于管理服务类容器,对于工作类容器,我们用 Job。Job执行成功先看一个简单的 Job 配置文件 myjob.yml:[root@k8s-master ~]# cat m....

2020-11-06 15:18:02 3561

原创 Docker MySQL 环境下运行

MySQL安装部署拉取镜像,访问 MySQL 镜像库地址:https://hub.docker.com/_/mysql?tab=tags# 下载镜像[root@localhost ~]# docker pull mysql:5.7.30[root@localhost ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEm

2020-11-05 21:42:00 138 2

转载 Kubernetes 是什么以及其架构

一、什么是KubernetesKubernetes,从官方网站上可以看到,它是一个工业级的容器编排平台。Kubernetes 这个单词是希腊语,它的中文翻译是“舵手”或者“飞行员”。在一些常见的资料中也会看到“ks”这个词,也就是“k8s”,它是通过将8个字母“ubernete ”替换为“8”而导致的一个缩写。Kubernetes 为什么要用“舵手”来命名呢?大家可以看一下这张图:这是一艘载着一堆集装箱的轮船,轮船在大海上运着集装箱奔波,把集装箱送到它们该去的地方。我们之前其实介绍过一个概.

2020-11-05 20:00:17 338 2

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除