Docker 新手上路(三)

这个系列一共分为5篇,是我初次接触 Docker 的总结。

这几篇是一个很粗略的新手入门。并不足以了解全貌,不过可以让你短时间内了解 Docker 为何物以及一些简单的操作,可以一看。 前几天新学习了 docker 的基本知识,包括安装、环境配置、获取和运行镜像等最基础的东西。今天看看一些简单的网络配置和相关的开源软件。更加深入的内容暂时就不研究了。毕竟作为新手上路已经足够了。

外部访问容器

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。

docker run --name web -d -p 1644:80 nginx
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
docker logs -f web

使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址

docker port web

使用 docker inspect xxx 可以获取特定容器内部网络和 ip 地址所有的变量,-p 标记可以多次使用来绑定多个端口

容器互联

(待续)

参考资料:


Docker 新手上路(二)——Dockerfile

这个系列一共分为5篇,是我初次接触 Docker 的总结。

这几篇是一个很粗略的新手入门。并不足以了解全貌,不过可以让你短时间内了解 Docker 为何物以及一些简单的操作,可以一看。

前几天新学习了 docker 的基本知识,包括安装、环境配置、获取和运行镜像等最基础的东西。今天学习一些 docker 的启动查看定制等操作。

镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。 用过 PHP Laravel 框架的应该马上就理解了(其他例如java kotlin等也是类似),这个就和 composer.json 脚本一样,用来保证环境一致性的配置文件。

定制镜像需要用到下面几个命令

  • FROM 指定基础镜像
  • RUN 执行命令
  • BUILD 构建镜像

Dockerfile 正确的写法应该是这样:

FROM xxx

RUN buildDeps='gcc libc6-dev make' \
    && apt-get update \
    && apt-get install -y $buildDeps \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
    && mkdir -p /usr/src/redis \
    && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    && make -C /usr/src/redis \
    && make -C /usr/src/redis install \
    && rm -rf /var/lib/apt/lists/* \
    && rm redis.tar.gz \
    && rm -r /usr/src/redis \
    && apt-get purge -y --auto-remove $buildDeps

然后在该目录执行

$ docker build -t nginx:v3 .

使用 docker build 命令进行镜像构建。其格式为:

docker build [选项] <上下文路径/URL/->

#build
      --no-cache=false Do not use cache when building the image
      -q, --quiet=false Suppress the verbose output generated by the containers
      --rm=true Remove intermediate containers after a successful build
      -t, --tag="" Repository name (and optionally a tag) to be applied to the resulting image in case of success
      
docker build -t image_name Dockerfile_path



在这里我们指定了最终镜像的名称 -t nginx:v3。 一般大家习惯性的会使用默认的文件名 Dockerfile,以及会将其置于镜像构建上下文目录中。

Docker Build 的用法

  • Dockerfile docker build -t nginx:v3 .
  • Git repo docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14
  • tar 压缩包 docker build http://server/context.tar.gz
  • 标准输入中读取 Dockerfile

      docker build - < Dockerfile
      cat Dockerfile | docker build -
    
  • 标准输入中读取上下文压缩包 docker build - < context.tar.gz

Dockerfile

Dockerfile是自动构建docker镜像的配置文件,Dockerfile中的命令非常类似linux shell下的命令,支持以 # 开头的注释行.一般,Dockerfile分为4部分

  • 基础镜像(父镜像)信息
  • 维护者信息
  • 镜像操作命令
  • 容器启动命令

下面是一个CentOS7的Dockerfile实例

FROM       daocloud.io/centos:7
MAINTAINER hanxt <hanxiaotongtong@163.com>

ENV TZ "Asia/Shanghai"
ENV TERM xterm

ADD aliyun-mirror.repo /etc/yum.repos.d/CentOS-Base.repo
ADD aliyun-epel.repo /etc/yum.repos.d/epel.repo

RUN yum install -y curl wget tar bzip2 unzip vim-enhanced passwd sudo yum-utils hostname net-tools rsync man && \
    yum install -y gcc gcc-c++ git make automake cmake patch logrotate python-devel libpng-devel libjpeg-devel && \
    yum install -y --enablerepo=epel pwgen python-pip && \
    yum clean all

RUN pip install supervisor
ADD supervisord.conf /etc/supervisord.conf

RUN mkdir -p /etc/supervisor.conf.d && \
    mkdir -p /var/log/supervisor

EXPOSE 22

ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]

详细解析

FROM daocloud.io/centos:7
# 基于父镜像构建其他docker镜像,父镜像:可以通过docker pull 命令获得,也可以自己制作

MAINTAINER hanxt <hanxiaotongtong@163.com>
# Dockerfile维护者

ENV TZ "Asia/Shanghai"
# ENV(environment)设置环境变量,一个Dockerfile中可以写多个。以上例子是:设置docker容器的时区为Shanghai

# Dockerfile中有2条指令可以拷贝文件

ADD aliyun-mirror.repo /etc/yum.repos.d/CentOS-Base.repo
# 拷贝本地文件到docker容器里,还可以拷贝URL链接地址下的文件,ADD还具有解压软件包的功能(支持gzip, bzip2 or xz)

COPY test /mydir
# 拷贝本地文件到docker容器


安装linux软件包 RUN yum install -y curl wget….

# RUN命令,非常类似linux下的shell命令 (the command is run in a shell – /bin/sh -c – shell form)
在Dockerfile中每执行一条指令(ENV、ADD、RUN等命令),都会生成一个docker image layer
RUN pip install supervisor

# 安装supervisor进程管理系统,推荐使用
ADD supervisord.conf /etc/supervisord.conf

# 添加supervisor的主配置文件,到docker容器里
RUN mkdir -p /etc/supervisor.conf.d

# 创建存放启动其他服务”supervisor.conf”的目录,此目录下的所有以.conf结尾的文件,在启动docker容器的时候会被加载
端口映射
EXPOSE 22

# 端口映射 EXPOSE <host_port>:<container_port>
# 推荐使用docker run -p <host_port>:<container_port>来固化端口
# 容器启动时执行的命令 ENTRYPOINT [“/usr/bin/supervisord”, “-n”, “-c”, “/etc/supervisord.conf”]
# 一个Dockerfile中只有最后一条ENTRYPOINT生效,并且每次启动docker容器,都会执行ENTRYPOINT

参考资料:


PHP 获取类名、调用者类名方法名

先记一个案例。今天在写一个虚基类 AbstractUuidModel,因为要从 request 里批量将数据通过 Eloquent 保存至 model。而此时有很多 model 都需要这样一个操作,每个 model 都有20个以上的属性,一个一个赋值,真的是能把人写死。

为了提高效率,遂在虚基类中添加一个抽象度比较高的方法。

由 updateByConsole() 这个方法开始进入逻辑:

public function updateByConsole()
{
    $request = request();
    $flag = true;
    foreach ($request->all() as $key => $value) {
    	if(!$flag)continue;
        if(!$request->has($key))continue;
        if(is_string($value))$value = trim($value);
        $flag = $flag && $this->updateProperty($key,$value);
    }
    if($flag) $this->save();

    return $flag;
}

将每一个 input 交给 updateProperty() 这个方法。于是接下来是核心代码:

protected function updateProperty($key,$value){
    if(in_array($key,$this->keyExcept))return true;

    if($this->{$key} == $value) return true;

    $className = get_class($this);
    if(in_array($key,$this->keyUnion)){
        $count = $className::where($key,$value)->count();
        if($count>0)return false;
    }

    if(in_array($key,$this->keySpecific)){
        $this->specific($key,$value);
    }else{
        $this->{$key} = $value;
    }

    return true;
}

可以看出核心逻辑是这样的:

  • 是否有不需要存入的属性,有的话继续循环到一个属性
  • 前后值是否相等,相等则继续循环到一个属性
  • 该属性是否唯一,唯一则判断数据表中是否已有值,有的话继续循环到一个属性(通过 flag 变量做判断,最终的结果是跳过所有循环直到结束,然后上一个 updateByConsole() 方法不保存结果。
  • 该属性是否是特殊属性,是的话子类自己实现 specific() 方法;否则赋值给 this, 然后下一个循环,直到遍历所有的 request。

类方法获取类名

在写上边案例时候印象比较深的就是 php 的这个 get_class() 方法。这个方法可以获得这个类的名字,一般写在 trait 或者 require 里用到。

类静态方法获取类名

虽然 get_class 好用,毕竟是类成员方法才可行。如果是静态方法,有两个办法:

  • CLASS;
  • get_called_class();

获取堆栈信息

以下是我在项目实战中的代码,用来打印方法调用关系。

主要是 stack_trace() + stack_msg_assemble 方法,获得堆栈信息 + 堆栈偏移。

function debug($message = null, array $context = [])
{
    $stack = stack_trace(0);

    if (is_null($message)) {
        $message = '';
    }

    if (is_string($message)) {
        $message = stack_msg_assemble($stack) . "() " . $message;
    }
    return app('log')->debug($message, $context);
}

参考资料:


laravel 下正确添加扩展包

我们经常要往现有的项目中添加扩展包,有时候因为编码人员还不了解 Laravel,在一些不良开发文档的引导下,如下图来自 七牛云

又或者像这样:

前者,不经由 Laravel,使用原生 Composer, 舍弃了包的管理,显然有问题。后者,在现在的逻辑中,可能会对项目造成巨大的伤害——这个是一次性把所有扩展包更新到最新版本(避免这个问题可以针对单独一个包进行 update,或者在 composer.json 中指定版本号)。

所以今天好好看了下 composer 在 laravel 项目下的一些配置。

composer 命令

先简单解释下 composer 命令。

  • composer install - 如有 composer.lock 文件,直接安装,否则从 composer.json 安装最新扩展包和依赖;
  • composer update - 从 composer.json 安装最新扩展包和依赖;
  • composer update vendor/package - 从 composer.json 或者对应包的配置,并更新到最新;
  • composer require new/package - 添加安装 new/package, 可以指定版本,如: composer require new/package ~2.5.

更多详情可以查看 Composer官方网站,或对应的中文网站

流程

新项目:

  • composer install,安装扩展包并生成 composer.lock;

协作项目:

  • composer install

添加新扩展包:

  • composer require vendor/package 添加扩展包

需要加版本的话 composer require "foo/bar:1.0.0"

关于 composer.lock

composer.lock 文件里保存着对每一个代码依赖的版本记录,配合 composer install 使用,保证了团队所有协作者开发环境、线上生产环境中运行的代码版本的一致性。

关于 composer.json

相关文档在 Composer 的官方文档scripts里有详细讲解。

其实从命名里也能看出端倪了。

这是我们项目中的配置

{
    "name": "xxx/webapp",
    "type": "project",
    "repositories": [
        {
            "type": "vcs",
            "url": "https://git.oschina.net/xxx/xxx.git"
        }
    ],
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.1.*",
        "ramsey/uuid": "3.0.*",
        "rmccue/requests": "1.6.*",
        "doctrine/dbal": "2.5.*",
        "sinergi/browser-detector": "5.1.*",
        "intervention/image": "2.3.*",
        "apkj/webframework": "dev-dev",
        "ignited/laravel-omnipay": "2.*",
        "lokielse/omnipay-alipay": "dev-master",
        "predis/predis": "1.0.*",
        "qiniu/php-sdk": "v7.0.8"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~4.0",
        "phpspec/phpspec": "~2.1"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "classmap": [
            "tests/TestCase.php"
        ]
    },
    "scripts": {
        "post-install-cmd": [
            "php artisan clear-compiled",
            "php artisan optimize"
        ],
        "pre-update-cmd": [
            "php artisan clear-compiled"
        ],
        "post-update-cmd": [
            "php artisan clear-compiled",
            "php artisan optimize"
        ],
        "post-root-package-install": [
            "php -r \"copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "secure-http": false
    }
}

特别说明的一点是 "secure-http": false,因为某些包的 https 下载速度实在是太慢了。。。。。 特别说明的一点是 "secure-http": false,因为某些包的 https 下载速度实在是太慢了。。。。。

错误定位

今天 composer update 时发生了这样一个错误:

PHP Fatal error:  Class Illuminate\Cache\FileStore contains 2 abstract methods and must therefore 
be declared abstract or implement the remaining methods (Illuminate\Contracts\Cache\Store::many, 
Illuminate\Contracts\Cache\Store::putMany) in 

其实不是今天了,很久前就出现这个问题了。因为平时都是针对单个包update,所以并不会产生什么影响,也没去解决,一直拖到了现在。

但是事实上在项目的早期是没有这个问题的,于是慢慢回溯查看。终于找到了罪魁祸首!

现在已经不记得当时为什么要如此更改了。总之目前将划线的内容改为了

    "post-install-cmd": [
        "php artisan clear-compiled",
        "php artisan optimize"
    ],
    "pre-update-cmd": [
        "php artisan clear-compiled"
    ],
    "post-update-cmd": [
        "php artisan clear-compiled",
        "php artisan optimize"
    ],

参考资料

参考资料


Docker 新手上路(一)

新学习了 docker。记录一下。这个系列一共分为5篇,是我初次接触 Docker 的总结。

这几篇是一个很粗略的新手入门。并不足以了解全貌,不过可以让你短时间内了解 Docker 为何物以及一些简单的操作,可以一看。

Docker 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的运行效率,降低了云计算资源供应的成本! 使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松!

无论是应用开发者、运维人员、还是其他信息技术从业人员,都有必要认识和掌握 Docker,以在有限的时间内做更多有意义的事。

为什么要使用 Docker?

作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。

更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。

持续交付和部署

对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署 系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

安装

先查看服务器的版本。lsb_release -a

Distributor ID:	Debian
Description:	Debian GNU/Linux 8.7 (jessie)
Release:	8.7
Codename:	jessie

添加源

按照教程的说法,Debian 8 的内核默认为 3.16,仅仅满足基本的 Docker 运行条件。如果打算使用 overlay2 存储层驱动,或某些功能不够稳定希望升级到较新版本的内核,可以添加 backports 源,升级到新版本的内核。 执行下面的命令添加 backports 源:

$ echo "deb http://http.debian.net/debian jessie-backports main" | sudo tee /etc/apt/sources.list.d/backports.list

升级到 backports 内核:

$ sudo apt-get update
$ sudo apt-get -t jessie-backports install linux-image-amd64

配置存储驱动

升级到 backports 的内核之后,会因为 AUFS 内核模块不可用,而使用默认的 devicemapper 驱动,并且配置为 loop-lvm,这是不推荐的。因此,不要忘记安装 Docker 后,配置 overlay2 存储层驱动。(这一步我跳过了,待熟悉以后再看看存储驱动选择的问题).

安装 Docker

在一切准备就绪后,就可以安装最新版本的 Docker 了,软件包名称为 docker-engine。将当前用户加入 docker 组,然后启动引擎。

$ sudo apt-get install docker-engine
// 如果没有这个包的话,源码安装 $ curl -sSL https://get.docker.com/ | sh
$ sudo usermod -aG docker $USER
$ sudo systemctl enable docker
$ sudo systemctl start docker

查看 docker 信息

# 查看docker版本
$docker version
	Client:
	 Version:      17.10.0-ce-rc2
	 API version:  1.33
	 Go version:   go1.8.3
	 Git commit:   af94197
	 Built:        Thu Oct 12 00:47:13 2017
	 OS/Arch:      linux/amd64
	
	Server:
	 Version:      17.10.0-ce-rc2
	 API version:  1.33 (minimum version 1.12)
	 Go version:   go1.8.3
	 Git commit:   af94197
	 Built:        Thu Oct 12 00:48:46 2017
	 OS/Arch:      linux/amd64
	 Experimental: false

# 显示docker系统的信息
$docker info
	Containers: 20
	 Running: 0
	 Paused: 0
	 Stopped: 20
	Images: 18
	Server Version: 17.10.0-ce-rc2
	Storage Driver: overlay
	 Backing Filesystem: xfs
	 Supports d_type: true
	Logging Driver: json-file
	Cgroup Driver: cgroupfs
	Plugins:
	 Volume: local
	 Network: bridge host macvlan null overlay
	 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
	Swarm: inactive
	Runtimes: runc
	Default Runtime: runc
	Init Binary: docker-init
	containerd version: 06b9cb35161009dcb7123345749fef02f7cea8e0
	runc version: 0351df1c5a66838d0c392b4ac4cf9450de844e2d
	init version: 949e6fa
	Security Options:
	 seccomp
	  Profile: default
	Kernel Version: 3.10.0-693.2.2.el7.x86_64
	Operating System: CentOS Linux 7 (Core)
	OSType: linux
	Architecture: x86_64
	CPUs: 8
	Total Memory: 15.54GiB
	Name: adsl-172-10-1-100.dsl.sndg02.sbcglobal.net
	ID: L4KV:FTZP:42FI:DVUS:3RJD:4ATZ:UMJ7:6UHH:I5ZW:3WYV:6OMI:XNZ3
	Docker Root Dir: /var/lib/docker
	Debug Mode (client): false
	Debug Mode (server): false
	Registry: https://index.docker.io/v1/
	Experimental: false
	Insecure Registries:
	 127.0.0.0/8
	Live Restore Enabled: false

获取镜像

Docker Hub 上有大量的高质量的镜像可以用。有可以直接拿来使用的服务类的镜像,如 nginx、redis、mongo、mysql、httpd、php、tomcat 等; 也有一些方便开发、构建、运行各种语言应用的镜像,如 node、openjdk、python、ruby、golang 等。 可以在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。 如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,如 ubuntu、debian、centos、fedora、alpine 等,这些操作系统的软件库为我们提供了更广阔的扩展空间。

Docker Hub提供API和云服务来发布基于Docker的应用程序。

获取镜像命令:

docker pull [选项] [Docker Registry地址]<仓库名>:<标签>

# 检索image
$docker search image_name

# 下载image
$docker pull image_name

# 列出镜像列表; -a, --all=false Show all images; --no-trunc=false Don't truncate output; -q, --quiet=false Only show numeric IDs
$docker images

# 显示一个镜像的历史; --no-trunc=false Don't truncate output; -q, --quiet=false Only show numeric IDs
$docker history image_name

例如docker pull debian,安装完成后显示镜像列表docker images,如下

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
debian              latest              19134a8202e7        4 weeks ago         123 MB

运行镜像

有了镜像后,我们就可以以这个镜像为基础启动一个容器来运行。

$ docker run -it --rm debian bash
$ docker run --name webserver -d -p 1644:80 nginx

-it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
--rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。
debian:这是指用 debian 镜像为基础来启动容器。
bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。 
最后 exit 退出容器。

新建/启动/唤醒/进入/终止/删除

docker run ubuntu:14.04 /bin/echo 'Hello world' -d # 后台运行
docker run -t -i ubuntu:14.04 /bin/bash  # -t分配一个伪终端, -i 标准输入保持打开。
docker start ubuntu:14.04
docker stop pid
docker restart pid
docker ps         # 命令来查看运行中的容器信息
docker ps -a      # 包括终止的容器
docker ps -l       # 最近一次启动的container
docker attach pid    # 交互命令下 exit 命令退出 或 Ctrl+d进入后台运行
docker rm xxx/pid
docker rm $(docker ps -a -q) 清除所有终止状态的容器

也可以使用 nsenter 命令更方便地 attach docker 的界面。命令在debian 8中自带。下载 .bashrc_docker,并放到 .bashrc 或者 .zshrc 中。

wget -P ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker;
cd ~
cat .bashrc_docker >> .bashrc
source .bashrc

docker ps
docker-enter pid

保存和加载

当需要把一台机器上的镜像迁移到另一台机器的时候,需要保存镜像与加载镜像。

docker save image_name -o file_path # 保存镜像到一个tar包; -o, --output="" Write to an file
docker load -i file_path # 加载一个tar包格式的镜像; -i, --input="" Read from a tar archive file

$docker save image_name > /home/save.tar # 机器a

# 使用scp将save.tar拷到机器b上,然后:
$docker load < /home/save.tar


docker login # 登陆registry server; -e, --email="" Email; -p, --password="" Password; -u, --username="" Username

docker push new_image_name # 发布docker镜像

Docker 命令行

功能划分 命令 用法
环境信息相关    
  info 本地的配置信息
  version 显示Docker,API,Git commit,Docker,Go的版本号。
系统运维相关    
  attach 挂载正在后台运行的容器
  build 从源码构建新Image的命令
  commit 把有修改的container提交成新的Image,官方不建议使用
  cp 把容器內的文件复制到Host主机上
  diff 列出3种容器内文件状态变化(A - Add, D - Delete, C - Change )的列表清单。
  export 把容器系统文件打包并导出来,方便分发给其他场景使用
  images  
  import / save / load  
  inspect  
  kill  
  port  
  pause / unpause  
  ps  
  rm  
  rmi  
  run  
  start / stop / restart  
  tag  
  top  
  wait  
日志信息相关    
  events  
  history  
  logs  
Docker Hub服务相关    
  login  
  pull / push  
  search  
     

这篇就到这里。下一篇再写其他方面的。

参考资料: