docker快速熟悉

一、简介

1.docker的意义

  • 容器是标准化的软件单元,Docker 将应用程序与该程序的依赖,打包在一个image文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。
  • Docker容器映像是一个轻量级,独立的可执行软件包,包含运行应用程序所需的一切:代码,运行时,系统工具,系统库和设置。
  • 容器映像在Docker Engine上运行时成为容器,Docker Engine使容器化应用程序能够在任何基础架构上一致地运行。

2.容器和虚拟机的区别

  • 容器是应用层的抽象,它将代码和依赖关系打包在一起。多个容器可以在同一台机器上运行,并与其他容器共享操作系统内核,每个容器在用户空间中作为独立进程运行。容器占用的空间比VM少(容器映像的大小通常为几十MB),可以处理更多的应用程序,并且需要更少的VM和操作系统。

  • 虚拟机(VM)是物理硬件的抽象,将一台服务器转变为多台服务器。管理程序允许多台VM在单台机器上运行。每个VM都包含操作系统的完整副本,应用程序,必要的二进制文件和库 - 占用数十GB。虚拟机也可能很慢启动。

3.基本概念

  • 镜像(Image):一个只读模板,带有创建 Docker 容器的说明。
  • 容器(container):容器就是镜像的运行实例,负责应用程序的运行,包括操作系统、用户添加的文件以及元数据。它可以被启动、开始、停止、删除。容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。。
  • Docker Registry:用来存储 Docker 镜像的仓库,Docker Hub 是 Docker 官方提供的一个公共仓库,而且 Docker 默认也是从 Docker Hub 上查找镜像的。
  • Docker客户端(Docker client):命令行工具,用于与Docker后台交互。
  • Docker后台(Docker daemon):dockerd,用来监听 Docker API 的请求和管理 Docker 对象,比如镜像、容器、网络和 Volume。
  • 底层技术支持:Namespaces(做隔离)、CGroups(做资源限制)、UnionFS(镜像和容器的分层)

二、ubuntu 安装docker社区版

1.先决条件

Support oparation

64-bit version of one of these Ubuntu versions:

  • Disco 19.04
  • Cosmic 18.10
  • Bionic 18.04 (LTS)
  • Xenial 16.04 (LTS)
Uninstall old versions
$ sudo apt-get remove docker docker-engine docker.io containerd runc
Supported storage drivers
  • Docker Engine - Community on Ubuntu supports overlay2, aufs and btrfs storage drivers.
    • Docker Engine - Community uses the overlay2 storage driver by default.

2.安装docker engine - community

有三种安装方法

  • 使用软件源docker repository安装,适合于有网状态
  • 使用deb 包安装,适合于无网状态
  • 通过脚本安装,适合于测试和开发环境,有风险
1)Install using the repository

配置仓库

# 更新软件源
$ sudo apt-get update

# Install packages to allow apt to use a repository over HTTPS
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

# add Docker’s official GPG key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# 验证系统拥有指纹数据9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
$ sudo apt-key fingerprint 0EBFCD88

# 添加远程仓库到软件源,稳定版、测试版或轻量版 x86_64/amd64:[arch=amd64], arm64:[arch=arm64],armhf:[arch=armhf]
$ sudo add-apt-repository \
   "deb [arch=arm64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

安装docker engine

# 更新软件源 (必须)
$ sudo apt-get update

$ sudo apt-get install docker-ce docker-ce-cli containerd.io

# 安装特定版本docker
    #列出可用版本
    $ apt-cache madison docker-ce
    # 安装特定版本,比如<VERSION_STRING>可以为 5:18.09.1~3-0~ubuntu-xenial
    $ sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
    
# 验证docker是否安装成功
$ docker --version
$ sudo docker run hello-world
2)Install from a package

下载所需版本的docker https://download.docker.com/linux/ubuntu/dists/

# 安装deb包
$ sudo dpkg -i /path/to/package.deb
# 测试docker
$ docker --version
$ sudo docker run hello-world

3.卸载docker engine - community

$ sudo apt-get purge docker-ce

$ sudo rm -rf /var/lib/docker

三、镜像的操作

1.获取镜像

Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker 会从镜像仓库下载(默认是 Docker Hub 公共注册服务器中的仓库)。

  • docker search 命令来查找官方仓库中的镜像

    sudo docker search ubuntu
    
  • docker pull 命令来从仓库获取所需要的镜像到本地镜像库

    # 从注册服务器仓库中下载
    $ sudo docker pull ubuntu:12.04
    # 相当于 $ sudo docker pull registry.hub.docker.com/ubuntu:12.04 命令,即从注册服务器 registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。
    
    # 从其它仓库下载
    $ sudo docker pull dl.dockerpool.com:5000/ubuntu:12.04
    
    # 列出本地镜像
    $ sudo docker images
    

2.导出导入镜像

# 从本地镜像库导出到本地文件
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              14.04               c4ff7513909d        5 weeks ago         225.4 MB
...
$ sudo docker save -o ubuntu_14.04.tar ubuntu:14.04
# 或
$ sudo docker save ubuntu:14.04 > ubuntu_14.04.tar
# 或
$ sudo docker save ubuntu:14.04 | gzip > ubuntu_14.04.tar.gz

# 导入本地文件到本地镜像库
$ sudo docker load --input ubuntu_14.04.tar  #或ubuntu_14.04.tar.gz
# 或
$ sudo docker load -i ubuntu_14.04.tar #或ubuntu_14.04.tar.gz
# 或
$ sudo docker load < ubuntu_14.04.tar #或ubuntu_14.04.tar.gz

3.移除本地镜像

# docker rm 命令是移除容器
$ docker rm [imageName]

# docker rmi 或 docker image rm 命令移除本地的镜像
$ sudo docker rmi training/sinatra
Untagged: training/sinatra:latest
Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d
Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f
Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0

注意:在删除镜像之前要先用 docker rm 删掉依赖于这个镜像的所有容器。

四、容器的操作

容器是独立运行的一个或一组应用,以及它们的运行态环境。因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。

1.创建并启动容器

# docker run运行image文件,每执行一次就会新建一个容器实例
$ sudo docker run ubuntu:14.04 /bin/echo 'Hello world'
Hello world

# 交互模式下启动容器,用户可以通过所创建的终端来输入命令
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#
    # -t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。

# 守护态运行(后台运行)容器,通过添加 -d 参数来实现
$ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147
    # 获取容器的输出信息
    $ sudo docker logs insane_babbage
    hello world
    hello world
    ...

$ sudo docker ps #查看所有正在运行的容器
$ sudo docker ps -a #查看创建的所有容器
$ sudo docker ps -l #查看最近创建的一个容器

容器启动流程

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个 ip 地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止

2.启动已创建并终止的容器

# 启动已经生成且已停止运行的容器文件
$ docker start [containerID]

# 交互模式下启动容器
$ docker start -it [containerID] /bin/bash

# 后台启动容器
$ docker start -d [containerID]

# 重启容器
$ docker restart [containID]

3.终止容器

# 停止终止容器实例的运行,向容器里面的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号。应用程序可以自行进行收尾清理工作
$ docker stop [containerID]

# 强制终止容器实例的运行,直接发出 SIGKILL 信号,有些容器会自动终止
$ docker kill [containID]

4.进入容器

# 进入一个已经启动的容器
$ docker exec -it [containerID] /bin/bash

# 退出容器
exit

5.导入导出容器

# 导出容器到本地容器快照
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS               NAMES
7691a814370e        ubuntu:14.04        "/bin/bash"         36 hours ago        Exited (0) 21 hours ago                       test
$ sudo docker export 7691a814370e > ubuntu.tar

# 导入本地容器快照到本地镜像库
$ cat ubuntu.tar | sudo docker import - test/ubuntu:v1.0

注意:用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。

6.移除容器

# docker rm 命令移除容器
$ docker rm [imageName]

五、Docker 的网络模式

1.Bridge模式【默认】

  • 当 Docker 启动时,会自动在主机上创建一个 docker0 虚拟网桥,实际上是 Linux 的一个 bridge。Docker 随机分配一个本地未占用的私有网段(在 RFC1918 中定义)中的一个地址给 docker0 接口。此后启动的容器内的网口也会自动分配一个同一网段的地址,并设置 docker0 的 IP 地址为容器的默认网关

  • 当创建一个 Docker 容器的时候,同时会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。

image
$ docker run -tid --net=bridge --name docker_bri1 ubuntu-base:v3
$ docker exec -ti docker_bri1

2.Host 模式

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

image
$ docker run -tid --net=host --name docker_host1 ubuntu-base:v3
$ docker exec -ti docker_host1 /bin/bash

3.Container 模式

新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

$ docker run -tid --net=container:docker_bri1 --name docker_con1 ubuntu-base:v3
$ docker exec -ti docker_con1 /bin/bash
$ docker exec -ti docker_bri1 /bin/bash

4.None模式

使用none模式,Docker 容器拥有自己的 Network Namespace,但是,并不为Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。

image
$ docker run -tid --net=none --name docker_non1 ubuntu-base:v3
$ docker exec -ti docker_non1 /bin/bash

六、数据共享与持久化

为了能保存容器运行过程中产生的数据,我们使用数据卷来实现持久化。 数据卷可以docker创建,也可以使用主机目录。

数据卷

1)特点

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响镜像
  • 数据卷默认会一直存在,即使容器被删除

2)操作

# 创建一个数据卷volume
$ docker volume create my-vol

# 查看所有的数据卷volume
$ docker volume ls
DRIVER              VOLUME NAME
local               1c3caf57674bd2e7e85511ed41932cc065a2f6c8a00c9f94cb9a70467206fcb4
local               2b7eb2cc385fff0cd8b36abb09a1f4975f3c0c90a9cd0f55e88f09657ce7436a
......
local               compose-files_consul-config
......
local               my-vol

# 查看指定 数据卷 的信息
$ docker volume inspect my-vol
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]

# 运行image,给容器添加数据卷,并进入容器
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名  /bin/bash
    # 例如 docker run -it -v /src/app:/opt/app centos /bin/bash
    # 或docker run -it -v my-vol:/opt/app centos /bin/bash

# 设置只读数据卷
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
    # 只可以在宿主机创建文件,然后共享给容器,但是容器内不允许修改文件

# 删除指定volume
docker volume rm [volume name]

3)数据共享测试

  • 容器和宿主机之间数据共享
    • 通过在宿主机的环境和容器的环境下,分别操作文件,观察数据是否可以同步
  • 容器停止退出后,主机修改后数据是否同步

4)数据卷容器

给容器挂载了数据卷,然后其它容器也可以通过挂载这个容器(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器

docker run -it --name childDoc --volumes-from 77c79cca0420 centos

七、docker常用命令汇总

# 查看docker版本或信息
$ docker version
# 或者
$ docker info

# 查看docker占用磁盘空间
$ docker system df

# 显示容器使用的系统资源
$ docker stats

# 列出本机的所有 image 文件。
$ docker image ls

# 删除 image 文件
$ docker image rm [imageName]

# 运行image文件,每执行一次就会新建一个容器实例
$ docker container run [imageName]
# 运行image文件,并进入容器
$ docker container run -it [imageName] /bin/bash

# 查看所有运行的容器实例
$ docker container ls --all
$ docker ps #查看所有正在运行的容器
$ docker ps -a #查看创建的所有容器
$ docker ps -l #查看最近创建的一个容器

# 启动已经生成且已停止运行的容器文件
$ docker start [containerID]

# 停止终止容器实例的运行,向容器里面的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号。应用程序可以自行进行收尾清理工作
$ docker stop [containerID]

# 强制终止容器实例的运行,直接发出 SIGKILL 信号,有些容器会自动终止
$ docker kill [containID]

# 进入一个正在运行的容器实例,一旦进入了容器,就可以在容器的 Shell 执行命令
$ docker exec -it [containerID] /bin/bash

# 从正在运行的 Docker 容器里面,将文件拷贝到本机
$ docker cp [containID]:[/path/to/file] .

八、验证linux内核的容器兼容性

如果在自定义系统下安装或运行docker运行出错,则需要确定当前linux的内核配置是否满足docker的要求。

# 例如运行hello-world engine报错
$ docker run hello-world
docker: Error response from daemon: failed to create endpoint focused_kepler on network bridge: failed to add the host (veth801a7b4) <=> sandbox (veth0fbfd2e) pair interfaces: operation not supported.
ERRO[0000] error waiting for container: context canceled 

使用check-config.sh脚本检验linux内核的配置项是否满足要求

$ wget https://github.com/moby/moby/raw/master/contrib/check-config.sh
$ chmod +x check-config.sh

$ ./check-config.sh
admin@edgenode:~$ ./check-config.sh 
info: reading kernel config from /proc/config.gz ...

Generally Necessary:
- cgroup hierarchy: properly mounted [/sys/fs/cgroup]
- CONFIG_NAMESPACES: enabled
- CONFIG_NET_NS: enabled
- CONFIG_PID_NS: enabled
- CONFIG_IPC_NS: enabled
- CONFIG_UTS_NS: enabled
- CONFIG_CGROUPS: enabled
- CONFIG_CGROUP_CPUACCT: enabled
- CONFIG_CGROUP_DEVICE: enabled
- CONFIG_CGROUP_FREEZER: enabled
- CONFIG_CGROUP_SCHED: missing
- CONFIG_CPUSETS: enabled
- CONFIG_MEMCG: enabled
- CONFIG_KEYS: enabled
- CONFIG_VETH: missing
- CONFIG_BRIDGE: enabled
- CONFIG_BRIDGE_NETFILTER: enabled (as module)
- CONFIG_NF_NAT_IPV4: enabled
- CONFIG_IP_NF_FILTER: enabled
- CONFIG_IP_NF_TARGET_MASQUERADE: enabled
- CONFIG_NETFILTER_XT_MATCH_ADDRTYPE: enabled
- CONFIG_NETFILTER_XT_MATCH_CONNTRACK: enabled
- CONFIG_NETFILTER_XT_MATCH_IPVS: enabled
- CONFIG_IP_NF_NAT: enabled
- CONFIG_NF_NAT: enabled
- CONFIG_NF_NAT_NEEDED: enabled
- CONFIG_POSIX_MQUEUE: enabled
- CONFIG_DEVPTS_MULTIPLE_INSTANCES: missing

Optional Features:
- CONFIG_USER_NS: enabled
- CONFIG_SECCOMP: enabled
- CONFIG_CGROUP_PIDS: enabled
- CONFIG_MEMCG_SWAP: enabled
- CONFIG_MEMCG_SWAP_ENABLED: enabled
    (cgroup swap accounting is currently enabled)
- CONFIG_MEMCG_KMEM: enabled
- CONFIG_BLK_CGROUP: enabled
- CONFIG_BLK_DEV_THROTTLING: enabled
- CONFIG_IOSCHED_CFQ: enabled
- CONFIG_CFQ_GROUP_IOSCHED: enabled
- CONFIG_CGROUP_PERF: enabled
- CONFIG_CGROUP_HUGETLB: missing
- CONFIG_NET_CLS_CGROUP: enabled
- CONFIG_CGROUP_NET_PRIO: enabled
- CONFIG_CFS_BANDWIDTH: enabled
- CONFIG_FAIR_GROUP_SCHED: enabled
- CONFIG_RT_GROUP_SCHED: enabled
- CONFIG_IP_NF_TARGET_REDIRECT: enabled
- CONFIG_IP_VS: enabled
- CONFIG_IP_VS_NFCT: enabled
- CONFIG_IP_VS_PROTO_TCP: enabled
- CONFIG_IP_VS_PROTO_UDP: enabled
- CONFIG_IP_VS_RR: enabled
- CONFIG_EXT4_FS: enabled
- CONFIG_EXT4_FS_POSIX_ACL: enabled
- CONFIG_EXT4_FS_SECURITY: enabled
- Network Drivers:
  - "overlay":
    - CONFIG_VXLAN: enabled
    - CONFIG_BRIDGE_VLAN_FILTERING: enabled
      Optional (for encrypted networks):
      - CONFIG_CRYPTO: enabled
      - CONFIG_CRYPTO_AEAD: enabled
      - CONFIG_CRYPTO_GCM: enabled
      - CONFIG_CRYPTO_SEQIV: enabled
      - CONFIG_CRYPTO_GHASH: enabled
      - CONFIG_XFRM: enabled
      - CONFIG_XFRM_USER: missing
      - CONFIG_XFRM_ALGO: enabled
      - CONFIG_INET_ESP: missing
      - CONFIG_INET_XFRM_MODE_TRANSPORT: missing
  - "ipvlan":
    - CONFIG_IPVLAN: enabled
  - "macvlan":
    - CONFIG_MACVLAN: enabled
    - CONFIG_DUMMY: enabled
  - "ftp,tftp client in container":
    - CONFIG_NF_NAT_FTP: missing
    - CONFIG_NF_CONNTRACK_FTP: missing
    - CONFIG_NF_NAT_TFTP: missing
    - CONFIG_NF_CONNTRACK_TFTP: missing
- Storage Drivers:
  - "aufs":
    - CONFIG_AUFS_FS: missing
  - "btrfs":
    - CONFIG_BTRFS_FS: enabled
    - CONFIG_BTRFS_FS_POSIX_ACL: enabled
  - "devicemapper":
    - CONFIG_BLK_DEV_DM: enabled
    - CONFIG_DM_THIN_PROVISIONING: enabled
  - "overlay":
    - CONFIG_OVERLAY_FS: enabled
  - "zfs":
    - /dev/zfs: missing
    - zfs command: missing
    - zpool command: missing

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

推荐阅读更多精彩内容

  • 《Docker从入门到实践》阅读笔记 原书地址: https://yeasy.gitbooks.io/docker...
    GuoYuebo阅读 11,364评论 1 39
  • 一、Docker 简介 Docker 两个主要部件:Docker: 开源的容器虚拟化平台Docker Hub: 用...
    R_X阅读 4,383评论 0 27
  • 统筹方法就是对所做事务的优先级安排,对时间的精准把控,对平行时间任务的重新安排。我们无法忍受简单重复,自然思考对工...
    凉凉小茶馆阅读 1,908评论 0 1
  • 上一章JVM系列02-垃圾回收算法中我们聊了垃圾回收的具体算法,本章我们一起来聊聊垃圾回收算法的具体应用实现垃圾回...
    Bryant0024阅读 197评论 0 0
  • 每次看到404错误总是很无奈;这里总结一下相关的网页显示错误 在myeclipse下部署web工程时,经常会出现T...
    灰羽_阅读 487评论 0 1