Docker快速入门

docker底层原理

1.简介

Docker是一个开源的容器引擎,它基于LXC容器技术,使用Go语言开发。
源代码托管在Github上,并遵从Apache2.0协议。
Docker采用C/S架构,其可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。
简单来说:Docker就是一种快速解决生产问题的一种技术手段。
Docker 官网
Github Docker 源码

2.应用场景

  • Web 应用的自动化打包和发布。
  • 自动化测试和持续集成、发布。
  • 在服务型环境中部署和调整数据库或其他的后台应用。
  • 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。

理念

  • 构建:
    龙珠里的胶囊,将你需要的场景构建好,装在一个小胶囊里
  • 运输:
    随身携带着房子、车子等,非常方便
  • 运行:
    只需要你轻轻按一下胶囊,找个合适的地方一放,就ok了

4.优缺点

优点

  • 多: 适用场景多
  • 快: 环境部署快、更新快
  • 好: 好多人在用,东西好
  • 省: 省钱省力省人工(123原则)

缺点

  • 太腻歪人: 依赖操作系统
  • 不善于沟通:依赖网络
  • 不善理财: 银行U盾等场景不能用

5.架构

5.1概念

  • Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
  • Docker 容器通过 Docker 镜像来创建。
  • 容器与镜像的关系类似于面向对象编程中的对象与类。

5.2图示原理


6.软件源配置

官网参考
基软件源
注意:如果网络使用不了阿里云,可以配置如下软件源

cd /etc/apt/

mv sources.list sources.list.bak

vim sources.list
# sohu shangdong

deb http://mirrors.sohu.com/ubuntu/ trusty main restricted universe multiverse

deb http://mirrors.sohu.com/ubuntu/ trusty-security main restricted universe multiverse

deb http://mirrors.sohu.com/ubuntu/ trusty-updates main restricted universe multiverse

deb http://mirrors.sohu.com/ubuntu/ trusty-proposed main restricted universe multiverse

deb http://mirrors.sohu.com/ubuntu/ trusty-backports main restricted universe multiverse

 

# 163 guangdong

deb http://mirrors.163.com/ubuntu/ trusty main restricted universe multiverse

deb http://mirrors.163.com/ubuntu/ trusty-security main restricted universe multiverse

deb http://mirrors.163.com/ubuntu/ trusty-updates main restricted universe multiverse

deb http://mirrors.163.com/ubuntu/ trusty-proposed main restricted universe multiverse

deb http://mirrors.163.com/ubuntu/ trusty-backports main restricted universe multiverse

 

# tsinghua.edu

deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse

deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse

deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse

deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse

 

# aliyun

deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse partner

deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse

 

# neu.edu

deb http://mirror.neu.edu.cn/ubuntu/ xenial main restricted universe multiverse partner

deb http://mirror.neu.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse

deb http://mirror.neu.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse

deb http://mirror.neu.edu.cn/ubuntu/ xenial-security main restricted universe multiverse

安装依赖软件

apt-get update

apt-get install apt-transport-https ca-certificates curl software-properties-common -y

使用官方推荐源

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

使用阿里云的源 -------------推荐1

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

使用清华的源---------------推荐2

curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

add-apt-repository "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

检查

apt-get update

docker软件安装

查看支持的docker版本

apt-cache madison docker-ce

安装docker

apt-get install docker-ce -y

注:
可以指定版本安装docker:
apt-get install docker-ce=<VERSION> -y

启动docker

systemctl start docker
systemctl status docker
注意:
    ubuntu安装完毕后,默认就开启服务了

测试docker

docker version

网卡区别:
安装前:只有ens33和lo网卡
安装后:docker启动后,多出来了docker0网卡,网卡地址172.17.0.1

docker服务命令格式:

systemctl [参数] docker
参数详解:
start 开启服务
stop 关闭
restart 重启
status 状态

删除docker命令:

yum remove docker-ce

rm -rf /var/lib/docker/

rm -rf /etc/docker

基本目录

docker基本目录简介
/etc/docker/ docker的认证目录
/var/lib/docker/ docker的应用目录

7.docker加速器

docker加速器简介

在国内使用docker的官方镜像源,会因为网络的原因,造成无法下载,或者一直处于超时。所以我们使用 daocloud 的方法进行加速配置。

加速器配置

修改daemon.json文件,增加绿色背景字体"insecure-registries": []内容
# cat /etc/docker/daemon.json
{"registry-mirrors": ["http://74f21445.m.daocloud.io"], "insecure-registries": []}
注意:
docker cloud加速器的默认内容是少了一条配置,所以我们要编辑文件在后面加上绿色背景的内容,然后再重启docker
重启docker
systemctl restart docker

8.镜像管理

8.1简介:

它是一个只读的文件,就类似于我们安装操作系统时候所需要的那个iso光盘镜像,通过运行这个镜像来完成各种应用的部署。
这里的镜像就是一个能被docker运行起来的一个程序。

8.2搜索、查看、获取、历史

搜索镜像

命令格式:
docker search [image_name]

命令演示:
docker search ubuntu

获取镜像

命令格式:
docker pull [image_name]

命令演示:
docker pull ubuntu
docker pull nginx

注释:
获取的镜像在哪里?
/var/lib/docker 目录下,具体详见docker仓库知识

查看镜像

命令格式:
docker images <image_name>
命令演示:
docker images
镜像的ID唯一标识了镜像,如果ID相同,说明是同一镜像。TAG信息来区分不同发行版本,如果不指定具体标记,默认使用latest标记信息
docker images -a 列出所有的本地的images(包括已删除的镜像记录)

查看镜像历史

查看镜像历史命令格式:
docker history [image_name]
我们获取到一个镜像,想知道他默认启动了哪些命令或者都封装了哪些系统层,那么我们可以使用docker history这条命令来获取我们想要的信息
8.3重命名、删除

镜像重命名

命令格式:
docker tag [old_image]:[old_version] [new_image]:[new_version]
命令演示:
docker tag nginx:latest sswang-nginx:v1.0

删除镜像

命令格式:
docker rmi [image_id/image_name:image_version]
命令演示:
docker rmi 3fa822599e10
注意:
如果一个image_id存在多个名称,那么应该使用name:tag的格式删除镜像
清除状态为dangling的镜像
docker image prune
移除所有未被使用的镜像
docker image prune -a
删除部分镜像
docker image prune -a --filter "until=24h"
8.4 导出、导入

导出镜像

将已经下载好的镜像,导出到本地,以备后用。
命令格式:
docker save -o [包文件] [镜像]
docker save [镜像1] ... [镜像n] > [包文件]
注意:
docker save 会保存镜像的所有历史记录和元数据信息
导出镜像
docker save -o nginx.tar sswang-nginx

导入镜像

为了更好的演示效果,我们先将nginx的镜像删除掉
docker rmi nginx:v1.0
docker rmi nginx
 导入镜像命令格式:
docker load < [image.tar_name]
docker load --input [image.tar_name]
注意:
docker load 不能指定镜像的名称
导入镜像文件
docker load < nginx.tar

9.容器管理

9.1简介

容器就类似于我们运行起来的一个操作系统,而且这个操作系统启动了某些服务。
这里的容器指的是运行起来的一个Docker镜像。

9.2查看、启动

查看容器

命令格式:docker ps
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
注意:
- 管理docker容器可以通过名称,也可以通过ID
- ps是显示正在运行的容器, -a是显示所有运行过的容器,包括已经不运行的容器

启动容器

守护进程方式启动容器
    命令格式:docker run <参数,可选> [docker_image] [执行的命令]
    让Docker容器在后台以守护形式运行。此时可以通过添加-d参数来实现
              docker run -d nginx
启动已终止的容器
    在生产过程中,常常会出现运行和不运行的容器,我们使用 start 命令开起一个已关闭的容器
    命令格式:docker start [container_id]
9.3关闭、删除

关闭容器

在生产中,我们会以为临时情况,要关闭某些容器,我们使用 stop 命令来关闭某个容器
     命令格式:docker stop [container_id]
关闭容器id
     docker stop 8005c40a1d16

删除容器

删除容器有两种方法:
      正常删除  --  删除已关闭的
      强制删除  --  删除正在运行的
正常删除容器
      命令格式:  docker rm [container_id]
                 docker container prune
      删除已关闭的容器
          docker rm 1a5f6a0c9443
强制删除运行容器
      命令格式:docker rm -f [container_id]
      删除正在运行的容器
          docker rm -f 8005c40a1d16
删除部分容器
      docker container prune --filter "until=24h"
拓展批量关闭容器
    命令格式:
        docker rm -f $(docker ps -a -q)
9.4进入、退出

创建并进入容器

命令格式:docker run --name [container_name] -it [docker_image] /bin/bash
~]# docker run -it --name sswang-nginx nginx /bin/bash
root@7c5a24a68f96:/# echo "hello world"
hello world
root@7c5a24a68f96:/# exit
exit        
docker 容器启动命令参数详解:
    --name:给容器定义一个名称
    -i:则让容器的标准输入保持打开。
    -t:让docker分配一个伪终端,并绑定到容器的标准输入上
    /bin/bash:执行一个命令

退出容器

  • 方法一:exit
  • 方法二:Ctrl + D

手工方式进入容器

命令格式:
    docker exec -it 容器id /bin/bash
效果演示:
    docker exec -it d74fff341687 /bin/bash
9.5基于容器创建镜像

提交方式

命令格式:
    docker commit -m '改动信息' -a "作者信息" [container_id] [new_image:tag]
命令演示:
    进入一个容器,创建文件后并退出
        ./docker_in.sh d74fff341687
        mkdir /sswang
        exit
     创建一个镜像
          docker commit -m 'mkdir /sswang' -a "sswang" d74fff341687 sswang-nginx:v0.2
      查看镜像
          docker images
      启动一个容器
          docker run -itd sswang-nginx:v0.2 /bin/bash
      进入容器进行查看
          ./docker_in.sh ae63ab299a84
          ls
9.6日志、信息

查看容器运行日志

命令格式:
    docker logs [容器id]
命令效果:
    docker logs 7c5a24a68f96

查看容器详细信息

命令格式:
    docker inspect [容器id]
命令效果:
    查看容器全部信息
        docker inspect 930f29ccdf8a
    查看容器网络信息
        docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 930f29ccdf8a

10.仓库管理

10.1仓库简介

仓库就类似于我们在网上搜索操作系统光盘的一个镜像站。
这里的仓库指的是Docker镜像存储的地方。

Docker仓库

  • 公有仓库:Docker hub、Docker cloud、等
  • 私有仓库:registry、harbor等
  • 本地仓库:在当前主机存储镜像的地方。

相关命令

docker login [仓库名称]
docker pull [镜像名称]
docker push [镜像名称]
docker search [镜像名称]
10.2私有仓库部署

创建仓库流程

1、根据registry镜像创建容器
2、配置仓库权限
3、提交镜像到私有仓库
4、测试

实施方案

下载registry镜像
    docker pull registry
启动仓库容器
    docker run -d -p 5000:5000 registry
检查容器效果
    curl 127.0.0.1:5000/v2/_catalog
配置容器权限
    vim /etc/docker/daemon.json
    {"registry-mirrors": ["http://74f21445.m.daocloud.io"], "insecure-registries": ["192.168.8.14:5000"]}
    注意:
        私有仓库的ip地址是宿主机的ip,而且ip两侧有双引号
重启docker服务
    systemctl restart docker
    systemctl status docker

效果查看

启动容器
    docker start 315b5422c699
标记镜像
    docker tag ubuntu-mini 192.168.8.14:5000/ubuntu-14.04-mini
提交镜像
    docker push 192.168.8.14:5000/ubuntu-14.04-mini
下载镜像
    docker pull 192.168.8.14:5000/ubuntu-14.04-mini

11.数据管理

docker的镜像是只读的,虽然依据镜像创建的容器可以进行操作,但是我们不能将数据保存到容器中,因为容器会随时关闭和开启,那么如何将数据保存下来呢?
答案就是:数据卷和数据卷容器

11.1数据卷简介

就是将宿主机的某个目录,映射到容器中,作为数据存储的目录,我们就可以在宿主机对数据进行存储

  • 缺点:太单一了

docker 数据卷命令详解

# docker run --help
-v, --volume list Bind mount a volume (default [])
挂载一个数据卷,默认为空

我们可以使用命令 docker run 用来创建容器,可以在使用docker run 命令时添加 -v 参数,就可以创建并挂
载一个到多个数据卷到当前运行的容器中。
-v 参数的作用是将宿主机的一个目录(绝对路径)作为容器的数据卷挂载到docker容器中,使宿主机和容器之间可
以共享一个目录,如果本地路径不存在,Docker也会自动创建。
-v 宿主机文件:容器文件

11.2数据卷实践

目录

命令格式:
    docker run -itd --name [容器名字] -v [宿主机目录]:[容器目录] [镜像名称] [命令(可选)]
命令演示:
    创建测试文件
        echo "file1" > /tmp/file1.txt
    启动一个容器,挂载数据卷
        docker run -itd --name test1 -v /tmp:/test1 nginx
    测试效果
        ~# docker exec -it a53c61c77 /bin/bash
        root@a53c61c77bde:/# cat /test1/file1.txt
        file1

文件

命令格式:
    docker run -itd --name [容器名字] -v [宿主机文件]:[容器文件] [镜像名称] [命令(可选)]
    注意:容器里面的文件虽然可以改名,但类型必须和宿主机文件一致
命令演示:
    创建测试文件
        echo "file1" > /tmp/file1.txt
    启动一个容器,挂载数据卷
        docker run -itd --name test2 -v /tmp/file1.txt:/nihao/nihao.sh nginx
    测试效果
        ~# docker exec -it 84c37743 /bin/bash
        root@84c37743d339:/# cat /nihao/nihao.sh
        file1

删除

docker volume rm
docker volume prune
11.3数据卷容器简介

将宿主机的某个目录,使用容器的方式来表示,然后其他的应用容器将数据保存在这个容器中,达到大批量应用数据同时存储的目的

docker 数据卷命令详解

# docker run --help
-v, --volumes-from value Mount volumes from the specified container(s) (default [])
从指定的容器挂载卷,默认为空

数据卷容器操作流程

如果使用数据卷容器,在多个容器间共享数据,并永久保存这些数据,需要有一个规范的流程才能做得到:
1、创建数据卷容器
2、其他容器挂载数据卷容器
注意:
数据卷容器不启动

11.4数据卷容器实践

创建一个数据卷容器

命令格式:
    docker create -v [容器数据卷目录] --name [容器名字] [镜像名称] [命令(可选)]
执行效果
    docker create -v /data --name v-test nginx

创建两个容器,同时挂载数据卷容器

命令格式:
    docker run --volumes-from [数据卷容器id/name] -tid --name [容器名字] [镜像名称] [命令(可选)]
执行效果:
创建 vc-test1 容器
    docker run --volumes-from 4693558c49e8 -tid --name vc-test1 nginx /bin/bash
创建 vc-test2 容器
    docker run --volumes-from 4693558c49e8 -tid --name vc-test2 nginx /bin/bash

确认卷容器共享

进入vc-test1,操作数据卷容器
    ~# docker exec -it vc-test1 /bin/bash
    root@c408f4f14786:/# ls /data/
    root@c408f4f14786:/# echo 'v-test1' > /data/v-test1.txt
    root@c408f4f14786:/# exit
进入vc-test2,确认数据卷
    ~# docker exec -it vc-test2 /bin/bash
    root@7448eee82ab0:/# ls /data/
    v-test1.txt
    root@7448eee82ab0:/# echo 'v-test2' >         /data/v-test2.txt
    root@7448eee82ab0:/# exit
回到vc-test1进行验证
    ~# docker exec -it vc-test1 /bin/bash
    root@c408f4f14786:/# ls /data/
    v-test1.txt  v-test2.txt
    root@c408f4f14786:/# cat /data/v-test2.txt
    v-test2
回到宿主机查看/data/目录
    ~# ls /data/
    ~#

结果证明:
容器间可以共享数据卷你容器,不过数据是保存在数据卷内,并没有保存到宿主机的文件目录中

12.网络管理

12.1端口映射详解

端口映射简介

默认情况下,容器和宿主机之间网络是隔离的,我们可以通过端口映射的方式,将容器中的端口,映射到宿主机的某个端口上。这样我们就可以通过 宿主机的ip+port的方式来访问容器里的内容

端口映射种类

1、随机映射 -P(大写)
2、指定映射 -p 宿主机端口:容器端口
注意:
生产场景一般不使用随机映射,但是随机映射的好处就是由docker分配,端口不会冲突,
不管哪种映射都会影响性能,因为涉及到映射

12.2随机映射实践

默认随机映射

命令格式:
docker run -d -P [镜像名称]
命令效果:
启动一个 nginx 镜像
docker run -d -P nginx

查看效果


注意:

  • 宿主机的32768被映射到容器的80端口
  • -P 自动绑定所有对外提供服务的容器端口,映射的端口将会从没有使用的端口池中自动随机选择,但是如果连
    续启动多个容器的话,则下一个容器的端口默认是当前容器占用端口号+1

在浏览器中访问 http://192.168.8.14:32768/,效果显示:


注意:
浏览器输入的格式是: docker容器宿主机的ip:容器映射的端口

指定主机随机映射

命令格式
    docker run -d -p [宿主机ip]::[容器端口] --name [容器名称] [镜像名称]
命令效果
    docker run -d -p 192.168.8.14::80 --name nginx-2 nginx

检查效果


12.3指定映射实践

指定端口映射

命令格式:
docker run -d -p [宿主机ip]:[宿主机端口]:[容器端口] --name [容器名字] [镜像名称]
注意:
如果不指定宿主机ip的话,默认使用 0.0.0.0,
容器端口必须清楚,而且必须写出来
命令实践:
现状我们在启动容器的时候,给容器指定一个访问的端口 1199
docker run -d -p 192.168.8.14:1199:80 --name nginx-1 nginx
查看新容器ip
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 0ad3acfbfb76

查看容器端口映射


查看宿主机开启端口

查看浏览器效果:

多端口映射方法

命令格式
    docker run -d -p [宿主机端口1]:[容器端口1]  -p [宿主机端口2]:[容器端口2] --name [容器名称] [镜像名称]
开起多端口映射实践
    docker run -d -p 520:443 -p 6666:80 --name nginx-3 nginx

查看容器进程


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • 一、概述 Docker is the world’s leading software container pla...
    凛_冬_将_至阅读 294评论 0 0
  • 《Docker从入门到实践》阅读笔记 原书地址: https://yeasy.gitbooks.io/docker...
    GuoYuebo阅读 11,379评论 1 39
  • Docker是什么 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器...
    beyound87阅读 311评论 0 1
  • 雪花的白 是纯洁无暇的白 是纯粹的白 雪花的冰 是冰洁清凉的冰 是温柔的冰 雪花的形 是规则无芒的形 是整齐的形 ...
    风晓默阅读 138评论 0 1
  • 1.感恩我的生物钟让我自然醒来;2.感恩美好的一天开始啦,所有的美好都为我而来;3.感恩清晨真我带给我的灵感;4....
    丰盛心灵阅读 258评论 0 0