Docker Swarm
最后更新于:2022-04-01 21:34:15
# Docker 三剑客之 Docker Swarm
Docker Swarm 是 Docker 官方三剑客项目之一,提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。
使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。
注意:Docker 1.12.0+ [Swarm mode](https://docs.docker.com/engine/swarm/) 已经内嵌入 Docker 引擎,成为了 docker 子命令 `docker swarm`,绝大多数用户已经开始使用 `Swarm mode`,Docker 引擎 API 已经删除 Docker Swarm。为避免大家混淆旧的 `Docker Swarm` 与新的 `Swarm mode`,旧的 `Docker Swarm` 内容已经删除,请查看 `Swarm mode` 一节。
';
使用
最后更新于:2022-04-01 21:34:12
## 使用
Docker Machine 支持多种后端驱动,包括虚拟机、本地主机和云平台等。
### 创建本地主机实例
#### Virtualbox 驱动
使用 `virtualbox` 类型的驱动,创建一台 Docker 主机,命名为 test。
```bash
$ docker-machine create -d virtualbox test
```
你也可以在创建时加上如下参数,来配置主机或者主机上的 Docker。
`--engine-opt dns=114.114.114.114` 配置 Docker 的默认 DNS
`--engine-registry-mirror https://hub-mirror.c.163.com` 配置 Docker 的仓库镜像
`--virtualbox-memory 2048` 配置主机内存
`--virtualbox-cpu-count 2` 配置主机 CPU
更多参数请使用 `docker-machine create --driver virtualbox --help` 命令查看。
#### macOS xhyve 驱动
`xhyve` 驱动 GitHub: https://github.com/zchee/docker-machine-driver-xhyve
[`xhyve`](https://github.com/mist64/xhyve) 是 macOS 上轻量化的虚拟引擎,使用其创建的 Docker Machine 较 `VirtualBox` 驱动创建的运行效率要高。
```bash
$ brew install docker-machine-driver-xhyve
$ docker-machine create \
-d xhyve \
# --xhyve-boot2docker-url ~/.docker/machine/cache/boot2docker.iso \
--engine-opt dns=114.114.114.114 \
--engine-registry-mirror https://hub-mirror.c.163.com \
--xhyve-memory-size 2048 \
--xhyve-rawdisk \
--xhyve-cpu-count 2 \
xhyve
```
>注意:非首次创建时建议加上 `--xhyve-boot2docker-url ~/.docker/machine/cache/boot2docker.iso` 参数,避免每次创建时都从 GitHub 下载 ISO 镜像。
更多参数请使用 `docker-machine create --driver xhyve --help` 命令查看。
#### Windows 10
Windows 10 安装 Docker Desktop for Windows 之后不能再安装 VirtualBox,也就不能使用 `virtualbox` 驱动来创建 Docker Machine,我们可以选择使用 `hyperv` 驱动。
> 注意,必须事先在 `Hyper-V` 管理器中新建一个 **外部虚拟交换机** 执行下面的命令时,使用 `--hyperv-virtual-switch=MY_SWITCH` 指定虚拟交换机名称
```bash
$ docker-machine create --driver hyperv --hyperv-virtual-switch=MY_SWITCH vm
```
更多参数请使用 `docker-machine create --driver hyperv --help` 命令查看。
### 使用介绍
创建好主机之后,查看主机
```bash
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
test - virtualbox Running tcp://192.168.99.187:2376 v17.10.0-ce
```
创建主机成功后,可以通过 `env` 命令来让后续操作对象都是目标主机。
```bash
$ docker-machine env test
```
后续根据提示在命令行输入命令之后就可以操作 test 主机。
也可以通过 `SSH` 登录到主机。
```bash
$ docker-machine ssh test
docker@test:~$ docker --version
Docker version 17.10.0-ce, build f4ffd25
```
连接到主机之后你就可以在其上使用 Docker 了。
### 官方支持驱动
通过 `-d` 选项可以选择支持的驱动类型。
* amazonec2
* azure
* digitalocean
* exoscale
* generic
* google
* hyperv
* none
* openstack
* rackspace
* softlayer
* virtualbox
* vmwarevcloudair
* vmwarefusion
* vmwarevsphere
### 第三方驱动
请到 [第三方驱动列表](https://github.com/docker/docker.github.io/blob/master/machine/AVAILABLE_DRIVER_PLUGINS.md) 查看
### 操作命令
* `active` 查看活跃的 Docker 主机
* `config` 输出连接的配置信息
* `create` 创建一个 Docker 主机
* `env` 显示连接到某个主机需要的环境变量
* `inspect` 输出主机更多信息
* `ip` 获取主机地址
* `kill` 停止某个主机
* `ls` 列出所有管理的主机
* `provision` 重新设置一个已存在的主机
* `regenerate-certs` 为某个主机重新生成 TLS 认证信息
* `restart` 重启主机
* `rm` 删除某台主机
* `ssh` SSH 到主机上执行命令
* `scp` 在主机之间复制文件
* `mount` 挂载主机目录到本地
* `start` 启动一个主机
* `status` 查看主机状态
* `stop` 停止一个主机
* `upgrade` 更新主机 Docker 版本为最新
* `url` 获取主机的 URL
* `version` 输出 docker-machine 版本信息
* `help` 输出帮助信息
每个命令,又带有不同的参数,可以通过
```bash
$ docker-machine COMMAND --help
```
来查看具体的用法。
';
安装
最后更新于:2022-04-01 21:34:10
## 安装
Docker Machine 可以在多种操作系统平台上安装,包括 Linux、macOS,以及 Windows。
### macOS、Windows
`Docker Desktop for Mac/Windows` 自带 `docker-machine` 二进制包,安装之后即可使用。
查看版本信息。
```bash
$ docker-machine -v
docker-machine version 0.16.1, build cce350d7
```
### Linux
在 Linux 上的也安装十分简单,从 [官方 GitHub Release](https://github.com/docker/machine/releases) 处直接下载编译好的二进制文件即可。
例如,在 Linux 64 位系统上直接下载对应的二进制包。
```bash
$ sudo curl -L https://github.com/docker/machine/releases/download/v0.16.1/docker-machine-`uname -s`-`uname -m` > /usr/local/bin/docker-machine
$ sudo chmod +x /usr/local/bin/docker-machine
```
完成后,查看版本信息。
```bash
$ docker-machine -v
docker-machine version 0.16.1, build cce350d7
```
';
Docker Machine
最后更新于:2022-04-01 21:34:08
# Docker Machine 项目
![](https://docs.docker.com/machine/img/machine.png)
Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境。
Docker Machine 项目基于 Go 语言实现,目前在 [Github](https://github.com/docker/machine) 上进行维护。
本章将介绍 Docker Machine 的安装及使用。
';
本章小结
最后更新于:2022-04-01 21:34:05
## 本章小结
本章讲解了 Mesos 的安装使用、基本原理和架构,以及支持 Mesos 的重要应用框架。Mesos 最初设计为资源调度器,然而其灵活的设计和对上层框架的优秀支持,使得它可以很好的支持大规模的分布式应用场景。结合 Docker,Mesos 可以很容易部署一套私有的容器云。
除了核心功能之外,Mesos 在设计上有许多值得借鉴之处,比如它清晰的定位、简洁的架构、细致的参数、高度容错的可靠,还有对限速、监控等的支持等。
Mesos 作为一套成熟的开源项目,可以很好的被应用和集成到生产环境中。但它的定位集中在资源调度,往往需要结合应用框架或二次开发。
';
常见应用框架
最后更新于:2022-04-01 21:34:03
## 常见应用框架
应用框架是实际干活的,可以理解为 Mesos 之上跑的 `应用`。应用框架注册到 Mesos master 服务上即可使用。
用户大部分时候,只需要跟应用框架打交道。因此,选择合适的应用框架十分关键。
Mesos 目前支持的应用框架分为四大类:长期运行任务(以及 PaaS)、大数据处理、批量调度、数据存储。
随着 Mesos 自身的发展,越来越多的框架开始支持 Mesos,下面总结了目前常用的一些框架。
### 长期运行的服务
#### [Aurora](http://aurora.incubator.apache.org)
利用 Mesos 调度安排的任务,保证任务一直在运行。
提供 REST 接口,客户端和 webUI(8081 端口)
#### [Marathon](https://github.com/mesosphere/marathon)
一个私有 PaaS 平台,保证运行的应用不被中断。
如果任务停止了,会自动重启一个新的相同任务。
支持任务为任意 bash 命令,以及容器。
提供 REST 接口,客户端和 webUI(8080 端口)
#### [Singularity](https://github.com/HubSpot/Singularity)
一个私有 PaaS 平台。
调度器,运行长期的任务和一次性任务。
提供 REST 接口,客户端和 webUI(7099、8080 端口),支持容器。
### 大数据处理
#### [Cray Chapel](https://github.com/nqn/mesos-chapel)
支持 Chapel 并行编程语言的运行框架。
#### [Dpark](https://github.com/douban/dpark)
Spark 的 Python 实现。
#### [Hadoop](https://github.com/mesos/hadoop)
经典的 map-reduce 模型的实现。
#### [Spark](http://spark.apache.org)
跟 Hadoop 类似,但处理迭代类型任务会更好的使用内存做中间状态缓存,速度要快一些。
#### [Storm](https://github.com/mesos/storm)
分布式流计算,可以实时处理数据流。
### 批量调度
#### [Chronos](https://github.com/airbnb/chronos)
Cron 的分布式实现,负责任务调度,支持容错。
#### [Jenkins](https://github.com/jenkinsci/mesos-plugin)
大名鼎鼎的 CI 引擎。使用 mesos-jenkins 插件,可以将 jenkins 的任务被 Mesos 集群来动态调度执行。
#### [JobServer](http://www.grandlogic.com/content/html_docs/jobserver.html)
基于 Java 的调度任务和数据处理引擎。
#### [GoDocker](https://bitbucket.org/osallou/go-docker)
基于 Docker 容器的集群维护工具。提供用户接口,除了支持 Mesos,还支持 Kubernetes、Swarm 等。
### 数据存储
#### [ElasticSearch](https://github.com/mesos/elasticsearch)
功能十分强大的分布式数据搜索引擎。
一方面通过分布式集群实现可靠的数据库,一方面提供灵活的 API,对数据进行整合和分析。ElasticSearch + LogStash + Kibana 目前合成为 ELK 工具栈。
#### [Hypertable](https://code.google.com/p/hypertable)
高性能的分布式数据库,支持结构化或者非结构化的数据存储。
#### [Tachyon](http://tachyon-project.org/)
内存为中心的分布式存储系统,利用内存访问的高速提供高性能。
';
日志与监控
最后更新于:2022-04-01 21:34:01
## 日志与监控
Mesos 自身提供了强大的日志和监控功能,某些应用框架也提供了针对框架中任务的监控能力。通过这些接口,用户可以实时获知集群的各种状态。
### 日志配置
日志文件默认在 `/var/log/mesos` 目录下,根据日志等级带有不同后缀。
用户可以通过日志来调试使用中碰到的问题。
一般的,推荐使用 `--log_dir` 选项来指定日志存放路径,并通过日志分析引擎来进行监控。
### 监控
Mesos 提供了方便的监控接口,供用户查看集群中各个节点的状态。
#### 主节点
通过 `http://MASTER_NODE:5050/metrics/snapshot` 地址可以获取到 Mesos 主节点的各种状态统计信息,包括资源(CPU、硬盘、内存)使用、系统状态、从节点、应用框架、任务状态等。
例如查看主节点 `10.0.0.2` 的状态信息,并用 jq 来解析返回的 json 对象。
```sh
$ curl -s http://10.0.0.2:5050/metrics/snapshot |jq .
{
"system/mem_total_bytes": 4144713728,
"system/mem_free_bytes": 153071616,
"system/load_5min": 0.37,
"system/load_1min": 0.6,
"system/load_15min": 0.29,
"system/cpus_total": 4,
"registrar/state_store_ms/p9999": 45.4096616192,
"registrar/state_store_ms/p999": 45.399272192,
"registrar/state_store_ms/p99": 45.29537792,
"registrar/state_store_ms/p95": 44.8336256,
"registrar/state_store_ms/p90": 44.2564352,
"registrar/state_store_ms/p50": 34.362368,
...
"master/recovery_slave_removals": 1,
"master/slave_registrations": 0,
"master/slave_removals": 0,
"master/slave_removals/reason_registered": 0,
"master/slave_removals/reason_unhealthy": 0,
"master/slave_removals/reason_unregistered": 0,
"master/slave_reregistrations": 2,
"master/slave_shutdowns_canceled": 0,
"master/slave_shutdowns_completed": 1,
"master/slave_shutdowns_scheduled": 1
}
```
#### 从节点
通过 `http://SLAVE_NODE:5051/metrics/snapshot` 地址可以获取到 Mesos 从节点的各种状态统计信息,包括资源、系统状态、各种消息状态等。
例如查看从节点 `10.0.0.10` 的状态信息。
```sh
$ curl -s http://10.0.0.10:5051/metrics/snapshot |jq .
{
"system/mem_total_bytes": 16827785216,
"system/mem_free_bytes": 3377315840,
"system/load_5min": 0.11,
"system/load_1min": 0.16,
"system/load_15min": 0.13,
"system/cpus_total": 8,
"slave/valid_status_updates": 11,
"slave/valid_framework_messages": 0,
"slave/uptime_secs": 954125.458927872,
"slave/tasks_starting": 0,
"slave/tasks_staging": 0,
"slave/tasks_running": 1,
"slave/tasks_lost": 0,
"slave/tasks_killed": 2,
"slave/tasks_finished": 0,
"slave/executors_preempted": 0,
"slave/executor_directory_max_allowed_age_secs": 403050.709525191,
"slave/disk_used": 0,
"slave/disk_total": 88929,
"slave/disk_revocable_used": 0,
"slave/disk_revocable_total": 0,
"slave/disk_revocable_percent": 0,
"slave/disk_percent": 0,
"containerizer/mesos/container_destroy_errors": 0,
"slave/container_launch_errors": 6,
"slave/cpus_percent": 0.025,
"slave/cpus_revocable_percent": 0,
"slave/cpus_revocable_total": 0,
"slave/cpus_revocable_used": 0,
"slave/cpus_total": 8,
"slave/cpus_used": 0.2,
"slave/executors_registering": 0,
"slave/executors_running": 1,
"slave/executors_terminated": 8,
"slave/executors_terminating": 0,
"slave/frameworks_active": 1,
"slave/invalid_framework_messages": 0,
"slave/invalid_status_updates": 0,
"slave/mem_percent": 0.00279552715654952,
"slave/mem_revocable_percent": 0,
"slave/mem_revocable_total": 0,
"slave/mem_revocable_used": 0,
"slave/mem_total": 15024,
"slave/mem_used": 42,
"slave/recovery_errors": 0,
"slave/registered": 1,
"slave/tasks_failed": 6
}
```
另外,通过 `http://MASTER_NODE:5050/monitor/statistics.json` 地址可以看到该从节点上容器网络相关的统计数据,包括进出流量、丢包数、队列情况等。获取方法同上,在此不再演示。
';
Mesos 配置项解析
最后更新于:2022-04-01 21:33:59
## Mesos 配置项解析
Mesos 支持在运行时通过命令行参数形式提供的配置项。如果是通过系统服务方式启动,也支持以配置文件或环境变量方式给出。当然,实际上最终是提取为命令行参数传递给启动命令。
Mesos 的配置项分为三种类型:通用项(master 和 slave 都支持),只有 master 支持的,以及只有 slave 支持的。
Mesos 配置项比较多,下面对一些重点配置进行描述。少数为必备项,意味着必须给出配置值;另外一些是可选配置,自己带有默认值。
### 通用项
通用项数量不多,主要涉及到服务绑定地址和日志信息等,包括:
* `--advertise_ip=VALUE` 可以通过该地址访问到服务,比如应用框架访问到 master 节点;
* `--advertise_port=VALUE` 可以通过该端口访问到服务;
* `--external_log_file=VALUE` 指定存储日志的外部文件,可通过 Web 界面查看;
* `--firewall_rules=VALUE` endpoint 防火墙规则,`VALUE` 可以是 JSON 格式或者存有 JSON 格式的文件路径;
* `--ip=VALUE` 服务绑定到的IP 地址,用来监听外面过来的请求;
* `--log_dir=VALUE` 日志文件路径,如果为空(默认值)则不存储日志到本地;
* `--logbufsecs=VALUE` buffer 多少秒的日志,然后写入本地;
* `--logging_level=VALUE` 日志记录的最低级别;
* `--port=VALUE` 绑定监听的端口,master 默认是 5050,slave 默认是 5051。
### master 专属配置项
这些配置项是针对主节点上的 Mesos master 服务的,围绕高可用、注册信息、对应用框架的资源管理等。用户应该根据本地主节点资源情况来合理的配置这些选项。
用户可以通过 `mesos-master --help` 命令来获取所有支持的配置项信息。
必须指定的配置项有三个:
* `--quorum=VALUE` 必备项,使用基于 replicated-Log 的注册表(即利用 ZooKeeper 实现 HA)时,参与投票时的最少节点个数;
* `--work_dir=VALUE` 必备项,注册表持久化信息存储位置;
* `--zk=VALUE` 如果主节点为 HA 模式,此为必备项,指定 ZooKeepr 的服务地址,支持多个地址,之间用逗号隔离,例如 `zk://username:password@host1:port1,host2:port2,.../path`。还可以为存有路径信息的文件路径。
可选的配置项有:
* `--acls=VALUE` ACL 规则或所在文件;
* `--allocation_interval=VALUE` 执行 allocation 的间隔,默认为 1sec;
* `--allocator=VALUE` 分配机制,默认为 HierarchicalDRF;
* `--[no-]authenticate` 是否允许非认证过的 framework 注册;
* `--[no-]authenticate_slaves` 是否允许非认证过的 slaves 注册;
* `--authenticators=VALUE` 对 framework 或 salves 进行认证时的实现机制;
* `--cluster=VALUE` 集群别名,显示在 Web 界面上供用户识别的;
* `--credentials=VALUE` 存储加密后凭证的文件的路径;
* `--external_log_file=VALUE` 采用外部的日志文件;
* `--framework_sorter=VALUE` 给定 framework 之间的资源分配策略;
* `--hooks=VALUE` master 中安装的 hook 模块;
* `--hostname=VALUE` master 节点使用的主机名,不配置则从系统中获取;
* `--[no-]log_auto_initialize` 是否自动初始化注册表需要的 replicated 日志;
* `--modules=VALUE` 要加载的模块,支持文件路径或者 JSON;
* `--offer_timeout=VALUE` offer 撤销的超时;
* `--rate_limits=VALUE` framework 的速率限制,即 query per second (qps);
* `--recovery_slave_removal_limit=VALUE` 限制注册表恢复后可以移除或停止的 slave 数目,超出后 master 会失败,默认是 100%;
* `--slave_removal_rate_limit=VALUE slave` 没有完成健康度检查时候被移除的速率上限,例如 1/10mins 代表每十分钟最多有一个;
* `--registry=VALUE` 注册表信息的持久化策略,默认为 `replicated_log` 存放本地,还可以为 `in_memory` 放在内存中;
* `--registry_fetch_timeout=VALUE` 访问注册表失败超时;
* `--registry_store_timeout=VALUE` 存储注册表失败超时;
* `--[no-]registry_strict` 是否按照注册表中持久化信息执行操作,默认为 false;
* `--roles=VALUE` 集群中 framework 可以所属的分配角色;
* `--[no-]root_submissions` root 是否可以提交 framework,默认为 true;
* `--slave_reregister_timeout=VALUE` 新的 lead master 节点选举出来后,多久之内所有的 slave 需要注册,超时的 salve 将被移除并关闭,默认为 10mins;
* `--user_sorter=VALUE` 在用户之间分配资源的策略,默认为 drf;
* `--webui_dir=VALUE` webui 实现的文件目录所在,默认为 `/usr/local/share/mesos/webui`;
* `--weights=VALUE` 各个角色的权重;
* `--whitelist=VALUE` 文件路径,包括发送 offer 的 slave 名单,默认为 None;
* `--zk_session_timeout=VALUE` session 超时,默认为 10secs;
* `--max_executors_per_slave=VALUE` 配置了 `--with-network-isolator` 时可用,限制每个 slave 同时执行任务个数。
下面给出一个由三个节点组成的 master 集群典型配置,工作目录指定为 `/tmp/mesos`,集群名称为 `mesos_cluster`。
```sh
mesos-master \
--zk=zk://10.0.0.2:2181,10.0.0.3:2181,10.0.0.4:2181/mesos \
--quorum=2 \
--work_dir=/tmp/mesos \
--cluster=mesos_cluster
```
### slave 专属配置项
slave 节点支持的配置项是最多的,因为它所完成的事情也最复杂。这些配置项既包括跟主节点打交道的一些参数,也包括对本地资源的配置,包括隔离机制、本地任务的资源限制等。
用户可以通过 `mesos-slave --help` 命令来获取所有支持的配置项信息。
必备项就一个:
* `--master=VALUE` 必备项,master 所在地址,或对应 ZooKeeper 服务地址,或文件路径,可以是列表。
以下为可选配置项:
* `--attributes=VALUE` 机器属性;
* `--authenticatee=VALUE` 跟 master 进行认证时候的认证机制;
* `--[no-]cgroups_enable_cfs` 采用 CFS 进行带宽限制时候对 CPU 资源进行限制,默认为 false;
* `--cgroups_hierarchy=VALUE` cgroups 的目录根位置,默认为 `/sys/fs/cgroup`;
* `--[no-]cgroups_limit_swap` 限制内存和 swap,默认为 false,只限制内存;
* `--cgroups_root=VALUE` 根 cgroups 的名称,默认为 mesos;
* `--container_disk_watch_interval=VALUE` 为容器进行硬盘配额查询的时间间隔;
* `--containerizer_path=VALUE` 采用外部隔离机制(`--isolation=external`)时候,外部容器机制执行文件路径;
* `--containerizers=VALUE` 可用的容器实现机制,包括 mesos、external、docker;
* `--credential=VALUE` 加密后凭证,或者所在文件路径;
* `--default_container_image=VALUE` 采用外部容器机制时,任务缺省使用的镜像;
* `--default_container_info=VALUE` 容器信息的缺省值;
* `--default_role=VALUE` 资源缺省分配的角色;
* `--disk_watch_interval=VALUE` 硬盘使用情况的周期性检查间隔,默认为 1mins;
* `--docker=VALUE` docker 执行文件的路径;
* `--docker_remove_delay=VALUE` 删除容器之前的等待时间,默认为 6hrs;
* `--[no-]docker_kill_orphans` 清除孤儿容器,默认为 true;
* `--docker_sock=VALUE` docker sock 地址,默认为 `/var/run/docker.sock`;
* `--docker_mesos_image=VALUE` 运行 slave 的 docker 镜像,如果被配置,docker 会假定 slave 运行在一个 docker 容器里;
* `--docker_sandbox_directory=VALUE` sandbox 映射到容器里的哪个路径;
* `--docker_stop_timeout=VALUE` 停止实例后等待多久执行 kill 操作,默认为 0secs;
* `--[no-]enforce_container_disk_quota` 是否启用容器配额限制,默认为 false;
* `--executor_registration_timeout=VALUE` 执行应用最多可以等多久再注册到 slave,否则停止它,默认为 1mins;
* `--executor_shutdown_grace_period=VALUE` 执行应用停止后,等待多久,默认为 5secs;
* `--external_log_file=VALUE` 外部日志文件;
* `--fetcher_cache_size=VALUE` fetcher 的 cache 大小,默认为 2 GB;
* `--fetcher_cache_dir=VALUE` fetcher cache 文件存放目录,默认为 /tmp/mesos/fetch;
* `--frameworks_home=VALUE` 执行应用前添加的相对路径,默认为空;
* `--gc_delay=VALUE` 多久清理一次执行应用目录,默认为 1weeks;
* `--gc_disk_headroom=VALUE` 调整计算最大执行应用目录年龄的硬盘留空量,默认为 0.1;
* `--hadoop_home=VALUE` hadoop 安装目录,默认为空,会自动查找 HADOOP_HOME 或者从系统路径中查找;
* `--hooks=VALUE` 安装在 master 中的 hook 模块列表;
* `--hostname=VALUE` slave 节点使用的主机名;
* `--isolation=VALUE` 隔离机制,例如 `posix/cpu,posix/mem`(默认)或者 `cgroups/cpu,cgroups/mem`、`external` 等;
* `--launcher_dir=VALUE` mesos 可执行文件的路径,默认为 `/usr/local/lib/mesos`;
* `--image_providers=VALUE` 支持的容器镜像机制,例如 'APPC,DOCKER';
* `--oversubscribed_resources_interval=VALUE` slave 节点定期汇报超配资源状态的周期;
* `--modules=VALUE` 要加载的模块,支持文件路径或者 JSON;
* `--perf_duration=VALUE` perf 采样时长,必须小于 perf_interval,默认为 10secs;
* `--perf_events=VALUE` perf 采样的事件;
* `--perf_interval=VALUE` perf 采样的时间间隔;
* `--qos_controller=VALUE` 超配机制中保障 QoS 的控制器名;
* `--qos_correction_interval_min=VALUE` Qos 控制器纠正超配资源的最小间隔,默认为 0secs;
* `--recover=VALUE` 回复后是否重连旧的执行应用,reconnect(默认值)是重连,cleanup 清除旧的执行器并退出;
* `--recovery_timeout=VALUE` slave 恢复时的超时,太久则所有相关的执行应用将自行退出,默认为 15mins;
* `--registration_backoff_factor=VALUE` 跟 master 进行注册时候的重试时间间隔算法的因子,默认为 1secs,采用随机指数算法,最长 1mins;
* `--resource_monitoring_interval=VALUE` 周期性监测执行应用资源使用情况的间隔,默认为 1secs;
* `--resources=VALUE` 每个 slave 可用的资源,比如主机端口默认为 [31000, 32000];
* `--[no-]revocable_cpu_low_priority` 运行在可撤销 CPU 上容器将拥有较低优先级,默认为 true。
* `--slave_subsystems=VALUE` slave 运行在哪些 cgroup 子系统中,包括 memory,cpuacct 等,缺省为空;
* `--[no-]strict` 是否认为所有错误都不可忽略,默认为 true;
* `--[no-]switch_user` 用提交任务的用户身份来运行,默认为 true;
* `--work_dir=VALUE` framework 的工作目录,默认为 /tmp/mesos。
下面这些选项需要配置 `--with-network-isolator` 一起使用(编译时需要启用 ` --with-network-isolator` 参数)。
* `--ephemeral_ports_per_container=VALUE` 分配给一个容器的临时端口的最大数目,需要为 2 的整数幂(默认为 1024);
* `--eth0_name=VALUE` public 网络的接口名称,如果不指定,根据主机路由进行猜测;
* `--lo_name=VALUE` loopback 网卡名称;
* `--egress_rate_limit_per_container=VALUE` 每个容器的输出流量限制速率限制(采用 fq_codel 算法来限速),单位是字节每秒;
* `--[no-]-egress_unique_flow_per_container` 是否把不同容器的流量当作彼此不同的流,避免彼此影响(默认为 false);
* `--[no-]network_enable_socket_statistics` 是否采集每个容器的 socket 统计信息,默认为 false。
下面给出一个典型的 slave 配置,容器为 Docker,监听在 `10.0.0.10` 地址;节点上限制 16 个 CPU、64 GB 内存,容器的非临时端口范围指定为 [31000-32000],临时端口范围指定为 [32768-57344];每个容器临时端口最多为 512 个,并且外出流量限速为 50 MB/s。
```sh
mesos-slave \
--master=zk://10.0.0.2:2181,10.0.0.3:2181,10.0.0.4:2181/mesos \
--containerizers=docker \
--ip=10.0.0.10 \
--isolation=cgroups/cpu,cgroups/mem,network/port_mapping \
--resources=cpus:16;mem:64000;ports:[31000-32000];ephemeral_ports:[32768-57344] \
--ephemeral_ports_per_container=512 \
--egress_rate_limit_per_container=50000KB \
--egress_unique_flow_per_container
```
为了避免主机分配的临时端口跟我们指定的临时端口范围冲突,需要在主机节点上进行配置。
```sh
$ echo "57345 61000" > /proc/sys/net/ipv4/ip_local_port_range
```
*注:非临时端口是 Mesos 分配给框架,绑定到任务使用的,端口号往往有明确意义;临时端口是系统分配的,往往不太关心具体端口号。*
';
原理与架构
最后更新于:2022-04-01 21:33:56
## 原理与架构
首先,再次需要强调 Mesos 自身只是一个资源调度框架,并非一整套完整的应用管理平台,所以只有 Mesos 自己是不能干活的。但是基于 Mesos,可以比较容易地为各种应用管理框架或者中间件平台(作为 Mesos 的应用)提供分布式运行能力;同时多个框架也可以同时运行在一个 Mesos 集群中,提高整体的资源使用效率。
Mesos 对自己定位范围的划分,使得它要完成的任务很明确,其它任务框架也可以很容易的与它进行整合。
### 架构
下面这张基本架构图来自 Mesos 官方。
![mesos 的基本架构](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-12-16_5671229ca589e.png)
可以看出,Mesos 采用了经典的主-从(master-slave)架构,其中主节点(管理节点)可以使用 zookeeper 来做 HA。
Mesos master 服务将运行在主节点上,Mesos slave 服务则需要运行在各个计算任务节点上。
负责完成具体任务的应用框架们,跟 Mesos master 进行交互,来申请资源。
### 基本单元
Mesos 中有三个基本的组件:管理服务(master)、任务服务(slave)以及应用框架(framework)。
#### 管理服务 - master
跟大部分分布式系统中类似,主节点起到管理作用,将看到全局的信息,负责不同应用框架之间的资源调度和逻辑控制。应用框架需要注册到管理服务上才能被使用。
用户和应用需要通过主节点提供的 API 来获取集群状态和操作集群资源。
#### 任务服务 - slave
负责汇报本从节点上的资源状态(空闲资源、运行状态等等)给主节点,并负责隔离本地资源来执行主节点分配的具体任务。
隔离机制目前包括各种容器机制,包括 LXC、Docker 等。
#### 应用框架 - framework
应用框架是实际干活的,包括两个主要组件:
* 调度器(scheduler):注册到主节点,等待分配资源;
* 执行器(executor):在从节点上执行框架指定的任务(框架也可以使用 Mesos 自带的执行器,包括 shell 脚本执行器和 Docker 执行器)。
应用框架可以分两种:一种是对资源的需求是会扩展的(比如 Hadoop、Spark 等),申请后还可能调整;一种是对资源需求大小是固定的(MPI 等),一次申请即可。
### 调度
对于一个资源调度框架来说,最核心的就是调度机制,怎么能快速高效地完成对某个应用框架资源的分配,是核心竞争力所在。最理想情况下(大部分时候都无法实现),最好是能猜到应用们的实际需求,实现最大化的资源使用率。
Mesos 为了实现尽量优化的调度,采取了两层(two-layer)的调度算法。
#### 算法基本过程
调度的基本思路很简单,master 先全局调度一大块资源给某个 framework,framework 自己再实现内部的细粒度调度,决定哪个任务用多少资源。两层调度简化了 Mesos master 自身的调度过程,通过将复杂的细粒度调度交由 framework 实现,避免了 Mesos master 成为性能瓶颈。
调度机制支持插件机制来实现不同的策略。默认是 Dominant Resource Fairness(DRF)。
*注:DRF 算法细节可以参考论文《Dominant Resource Fairness: Fair Allocation of Multiple Resource Types》。其核心思想是对不同类型资源的多个请求,计算请求的主资源类型,然后根据主资源进行公平分配。*
#### 调度过程
调度通过 offer 发送的方式进行交互。一个 offer 是一组资源,例如 `<1 CPU, 2 GB Mem>`。
基本调度过程如下:
* 首先,slave 节点会周期性汇报自己可用的资源给 master;
* 某个时候,master 收到应用框架发来的资源请求,根据调度策略,计算出来一个资源 offer 给 framework;
* framework 收到 offer 后可以决定要不要,如果接受的话,返回一个描述,说明自己希望如何使用和分配这些资源来运行某些任务(可以说明只希望使用部分资源,则多出来的会被 master 收回);
* 最后,master 则根据 framework 答复的具体分配情况发送给 slave,以使用 framework 的 executor 来按照分配的资源策略执行任务。
具体给出一个例子,某从节点向主节点汇报自己有 `<4 CPU, 8 GB Mem>` 的空闲资源,同时,主节点看到某个应用框架请求 `<3 CPU, 6 GB Mem>`,就创建一个 offer `` 把满足的资源发给应用框架。应用框架(的调度器)收到 offer 后觉得可以接受,就回复主节点,并告诉主节点希望运行两个任务:一个占用 `<1 CPU, 2 GB Mem>`,一个占用 一个占用 `<2 CPU, 4 GB Mem>`。主节点收到任务信息后分配任务到从节点上进行运行(实际上是应用框架的执行器来负责执行任务)。任务运行结束后资源可以被释放出来。
剩余的资源还可以继续分配给其他应用框架或任务。
应用框架在收到 offer 后,如果 offer 不满足自己的偏好(例如希望继续使用上次的 slave 节点),则可以选择拒绝 offer,等待 master 发送新的 offer 过来。另外,可以通过过滤器机制来加快资源的分配过程。
#### 过滤器
framework 可以通过过滤器机制告诉 master 它的资源偏好,比如希望分配过来的 offer 有哪个资源,或者至少有多少资源等。
过滤器可以避免某些应用资源长期分配不到所需要的资源的情况,加速整个资源分配的交互过程。
#### 回收机制
为了避免某些任务长期占用集群中资源,Mesos 也支持回收机制。
主节点可以定期回收计算节点上的任务所占用的资源,可以动态调整长期任务和短期任务的分布。
### HA
从架构上看,最为核心的节点是 master 节点。除了使用 ZooKeeper 来解决单点失效问题之外,Mesos 的 master 节点自身还提供了很高的鲁棒性。
Mesos master 节点在重启后,可以动态通过 slave 和 framework 发来的消息重建内部状态,虽然可能导致一定的时延,但这避免了传统控制节点对数据库的依赖。
当然,为了减少 master 节点的负载过大,在集群中 slave 节点数目较多的时候,要避免把各种通知的周期配置的过短。实践中,可以通过部署多个 Mesos 集群来保持单个集群的规模不要过大。
';
安装与使用
最后更新于:2022-04-01 21:33:54
## Mesos 安装与使用
以 Mesos 结合 Marathon 应用框架为例,来看下如何快速搭建一套 Mesos 平台。
Marathon 是可以跟 Mesos 一起协作的一个 framework,基于 Scala 实现,可以实现保持应用的持续运行。
另外,Mesos 默认利用 ZooKeeper 来进行多个主节点之间的选举,以及从节点发现主节点的过程。一般在生产环境中,需要启动多个 Mesos master 服务(推荐 3 或 5 个),并且推荐使用 supervisord 等进程管理器来自动保持服务的运行。
ZooKeeper 是一个分布式集群中信息同步的工具,通过自动在多个节点中选举 `leader`,保障多个节点之间的某些信息保持一致性。
### 安装
安装主要需要 mesos、zookeeper 和 marathon 三个软件包。
Mesos 也采用了经典的主-从结构,一般包括若干主节点和大量从节点。其中,mesos master 服务和 zookeeper 需要部署到所有的主节点,mesos slave 服务需要部署到所有从节点。marathon 可以部署到主节点。
安装可以通过源码编译、软件源或者 Docker 镜像方式进行,下面分别进行介绍。
#### 源码编译
源码编译方式可以保障获取到最新版本,但编译过程比较费时间。
首先,从 apache.org 开源网站下载最新的源码。
```sh
$ git clone https://git-wip-us.apache.org/repos/asf/mesos.git
```
其中,主要代码在 `src` 目录下,应用框架代码在 `frameworks` 目录下,文档在 `docs` 目录下,`include ` 中包括了跟 Mesos 打交道使用的一些 API 定义头文件。
安装依赖,主要包括 Java 运行环境、Linux 上的自动编译环境等。
```sh
$ sudo apt-get update
$ sudo apt-get install -y openjdk-8-jdk autoconf libtool \
build-essential python-dev python-boto libcurl4-nss-dev \
libsasl2-dev maven libapr1-dev libsvn-dev
```
后面就是常规 C++ 项目的方法,configure 之后利用 Makefile 进行编译和安装。
```sh
$ cd mesos
$ ./bootstrap
$ mkdir build
$ cd build && ../configure --with-network-isolator
$ make
$ make check && sudo make install
```
#### 软件源安装
通过软件源方式进行安装相对会省时间,但往往不是最新版本。
这里以 Ubuntu 系统为例,首先添加软件源地址。
```sh
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E56151BF
$ DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
$ CODENAME=$(lsb_release -cs)
$ echo "deb http://repos.mesosphere.io/${DISTRO} ${CODENAME} main" | \
sudo tee /etc/apt/sources.list.d/mesosphere.list
```
刷新本地软件仓库信息并安装 zookeeper、mesos、marathon 三个软件包。
```sh
$ sudo apt-get -y update && sudo apt-get -y install zookeeper mesos marathon
```
注意,Marathon 最新版本需要 jdk 1.8+ 的支持。如果系统中有多个 Java 版本,需要检查配置默认的 JDK 版本符合要求。
```sh
$ sudo update-alternatives --config java
```
安装 Mesos 成功后,会在 `/usr/sbin/` 下面发现 `mesos-master` 和 `mesos-slave` 两个二进制文件,分别对应主节点上需要运行的管理服务和从节点上需要运行的任务服务。
用户可以手动运行二进制文件启动服务,也可以通过 `service` 命令来方便进行管理。
例如,在主节点上重启 Mesos 管理服务:
```sh
$ sudo service mesos-master restart
```
通过 `service` 命令来管理,实际上是通过调用 `/usr/bin/mesos-init-wrapper` 脚本文件进行处理。
#### [基于 Docker](https://github.com/sekka1/mesosphere-docker)
需要如下三个镜像。
* ZooKeeper:https://registry.hub.docker.com/u/garland/zookeeper/
* Mesos:https://registry.hub.docker.com/u/garland/mesosphere-docker-mesos-master/
* Marathon:https://registry.hub.docker.com/u/garland/mesosphere-docker-marathon/
其中 mesos-master 镜像在后面将分别作为 master 和 slave 角色进行使用。
首先,拉取三个镜像。
```sh
$ docker pull garland/zookeeper
$ docker pull garland/mesosphere-docker-mesos-master
$ docker pull garland/mesosphere-docker-marathon
```
导出主节点机器的地址到环境变量。
```sh
$ HOST_IP=10.0.0.2
```
在主节点上启动 Zookeepr 容器。
```sh
docker run -d \
-p 2181:2181 \
-p 2888:2888 \
-p 3888:3888 \
garland/zookeeper
```
在主节点上启动 Mesos Master 服务容器。
```sh
docker run --net="host" \
-p 5050:5050 \
-e "MESOS_HOSTNAME=${HOST_IP}" \
-e "MESOS_IP=${HOST_IP}" \
-e "MESOS_ZK=zk://${HOST_IP}:2181/mesos" \
-e "MESOS_PORT=5050" \
-e "MESOS_LOG_DIR=/var/log/mesos" \
-e "MESOS_QUORUM=1" \
-e "MESOS_REGISTRY=in_memory" \
-e "MESOS_WORK_DIR=/var/lib/mesos" \
-d \
garland/mesosphere-docker-mesos-master
```
在主节点上启动 Marathon。
```sh
docker run \
-d \
-p 8080:8080 \
garland/mesosphere-docker-marathon --master zk://${HOST_IP}:2181/mesos --zk zk://${HOST_IP}:2181/marathon
```
在从节点上启动 Mesos slave 容器。
```sh
docker run -d \
--name mesos_slave_1 \
--entrypoint="mesos-slave" \
-e "MESOS_MASTER=zk://${HOST_IP}:2181/mesos" \
-e "MESOS_LOG_DIR=/var/log/mesos" \
-e "MESOS_LOGGING_LEVEL=INFO" \
garland/mesosphere-docker-mesos-master:latest
```
接下来,可以通过访问本地 8080 端口来使用 Marathon 启动任务了。
### 配置说明
下面以本地通过软件源方式安装为例,解释如何修改各个配置文件。
#### ZooKeepr
ZooKeepr 是一个分布式应用的协调工具,用来管理多个主节点的选举和冗余,监听在 2181 端口。推荐至少布置三个主节点来被 ZooKeeper 维护。
配置文件默认都在 `/etc/zookeeper/conf/` 目录下。比较关键的配置文件有两个:`myid` 和 `zoo.cfg`。
myid 文件会记录加入 ZooKeeper 集群的节点的序号(1-255之间)。`/var/lib/zookeeper/myid` 文件其实也是软连接到了该文件。
比如配置某节点序号为 1,则需要在该节点上执行:
```sh
$ echo 1 | sudo dd of=/etc/zookeeper/conf/myid
```
节点序号在 ZooKeeper 集群中必须唯一,不能出现多个拥有相同序号的节点。
另外,需要修改 zoo.cfg 文件,该文件是主配置文件,主要需要添加上加入 ZooKeeper 集群的机器的序号和对应监听地址。
例如,现在 ZooKeeper 集群中有三个节点,地址分别为 `10.0.0.2`、`10.0.0.3`、`10.0.0.4`,序号分别配置为 `2`、`3`、`4`。
则配置如下的三行:
```sh
server.2=10.0.0.2:2888:3888
server.3=10.0.0.3:2888:3888
server.4=10.0.0.4:2888:3888
```
其中第一个端口 2888 负责从节点连接到主节点的;第二个端口 3888 则负责主节点进行选举时候通信。
也可以用主机名形式,则需要各个节点 `/etc/hosts` 文件中都记录地址到主机名对应的映射关系。
完成配置后,启动 ZooKeeper 服务。
```sh
$ sudo service zookeeper start
```
#### Mesos
Mesos 的默认配置目录有三个:
* /etc/mesos/:主节点和从节点都会读取的配置文件,最关键的是 zk 文件存放主节点的信息;
* /etc/mesos-master/:只有主节点会读取的配置,等价于启动 mesos-master 命令时候的默认选项;
* /etc/mesos-slave/:只有从节点会读取的配置,等价于启动 mesos-master 命令时候的默认选项。
最关键的是需要在所有节点上修改 `/etc/mesos/zk`,写入主节点集群的 ZooKeeper 地址列表,例如:
```sh
zk://10.0.0.2:2181,10.0.0.3:2181,10.0.0.4:2181/mesos
```
此外,`/etc/default/mesos`、`/etc/default/mesos-master`、`/etc/default/mesos-slave` 这三个文件中可以存放一些环境变量定义,Mesos 服务启动之前,会将这些环境变量导入进来作为启动参数。格式为 `MESOS_OPTION_NAME`。
下面分别说明在主节点和从节点上的配置。
##### 主节点
一般只需要关注 `/etc/mesos-master/` 目录下的文件。默认情况下目录下为空。
该目录下文件命名和内容需要跟 mesos-master 支持的命令行选项一一对应。可以通过 `mesos-master --help` 命令查看支持的选项。
例如某个文件 `key` 中内容为 `value`,则在 mesos-master 服务启动的时候,会自动添加参数 `--key=value` 给二进制命令。
例如,mesos-master 服务默认监听在 loopback 端口,即 `127.0.0.1:5050`,我们需要修改主节点监听的地址,则可以创建 /etc/mesos-master/ip 文件,在其中写入主节点监听的外部地址。
为了正常启动 mesos-master 服务,还需要指定 `work_dir` 参数(表示应用框架的工作目录)的值,可以通过创建 /etc/mesos-master/work_dir 文件,在其中写入目录,例如 ` /var/lib/mesos`。工作目录下会生成一个 `replicated_log` 目录,会存有各种同步状态的持久化信息。
以及指定 quorum 参数的值,该参数用来表示 ZooKeeper 集群中要求最少参加表决的节点数目。一般设置为比 ZooKeeper 集群中节点个数的半数多一些(比如三个节点的话,可以配置为 `2`)。
此外,要修改 Mesos 集群的名称,可以创建 `/etc/mesos-master/cluster` 文件,在其中写入集群的别名,例如 `MesosCluster`。
总结下,建议在 `/etc/mesos-master` 目录下,配置至少四个参数文件:`ip`、`quorum`、`work_dir`、`cluster`。
修改配置之后,需要启动服务即可生效。
```sh
$ sudo service mesos-master start
```
更多选项可以参考后面的配置项解析章节。
主节点服务启动后,则可以在从节点上启动 mesos-slave 服务来加入主节点的管理。
##### 从节点
一般只需要关注 `/etc/mesos-slave/` 目录下的文件。默认情况下目录下为空。
文件命名和内容也是跟主节点类似,对应二进制文件支持的命令行参数。
建议在从节点上,创建 `/etc/mesos-slave/ip` 文件,在其中写入跟主节点通信的地址。
修改配置之后,也需要重新启动服务。
```sh
$ sudo service mesos-slave start
```
更多选项可以参考后面的配置项解析章节。
#### Marathon
Marathon 作为 Mesos 的一个应用框架,配置要更为简单,必需的配置项有 `--master` 和 `--zk`。
安装完成后,会在 /usr/bin 下多一个 marathon shell 脚本,为启动 marathon 时候执行的命令。
配置目录为 `/etc/marathon/conf`(需要手动创建),此外默认配置文件在 `/etc/default/marathon`。
我们手动创建配置目录,并添加配置项(文件命名和内容跟 Mesos 风格一致),让 Marathon 能连接到已创建的 Mesos 集群中。
```sh
$ sudo mkdir -p /etc/marathon/conf
$ sudo cp /etc/mesos/zk /etc/marathon/conf/master
```
同时,让 Marathon 也将自身的状态信息保存到 ZooKeeper 中。创建 `/etc/marathon/conf/zk` 文件,添加 ZooKeeper 地址和路径。
```sh
zk://10.0.0.2:2181,10.0.0.2:2181,10.0.0.2:2181/marathon
```
启动 marathon 服务。
```sh
$ sudo service marathon start
```
### 访问 Mesos 图形界面
Mesos 自带了 Web 图形界面,可以方便用户查看集群状态。
用户在 Mesos 主节点服务和从节点服务都启动后,可以通过浏览器访问主节点 5050 端口,看到类似如下界面,已经有两个 slave 节点加入了。
![mesos 界面查看加入的 slave 节点](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-12-16_5671229c33c21.png)
通过 Slaves 标签页能看到加入集群的从节点的信息。
如果没有启动 Marathon 服务,在 Frameworks 标签页下将看不到任何内容。
### 访问 Marathon 图形界面
Marathon 服务启动成功后,在 Mesos 的 web 界面的 Frameworks 标签页下面将能看到名称为 marathon 的框架出现。
同时可以通过浏览器访问 8080 端口,看到 Marathon 自己的管理界面。
![marathon 图形管理界面](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-12-16_5671229c442d4.png)
此时,可以通过界面或者 REST API 来创建一个应用,Marathon 会保持该应用的持续运行。
![marathon 查看任务支持的参数](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/b799fabed0b3e1e3fe2bceec3ee464a2_739x599.png)
通过界面方式可以看到各任务支持的参数(包括资源、命令、环境变量、健康检查等),同时可以很容易地修改任务运行实例数进行扩展,非常适合进行测试。
如果要更自动化地使用 Marathon,则需要通过它的 REST API 进行操作。
一般的,启动新任务需要先创建一个定义模板(JSON 格式),然后发到指定的 API。
例如,示例任务 basic-0 的定义模板为:
```json
{
"id": "basic-0",
"cmd": "while [ true ] ; do echo 'Hello Marathon' ; sleep 5 ; done",
"cpus": 0.1,
"mem": 10.0,
"instances": 1
}
```
该任务申请资源为 0.1 个单核 CPU 资源和 10 MB 的内存资源,具体命令为每隔五秒钟用 shell 打印一句 `Hello Marathon`。
可以通过如下命令发出 basic-0 任务到 Marathon 框架,框架会分配任务到某个满足条件的从节点上,成功会返回一个 json 对象,描述任务的详细信息。
```sh
$ curl -X POST http://marathon_host:8080/v2/apps -d @basic-0.json -H "Content-type: application/json"
{"id":"/basic-0","cmd":"while [ true ] ; do echo 'Hello Marathon' ; sleep 5 ; done","args":null,"user":null,"env":{},"instances":1,"cpus":0.1,"mem":10,"disk":0,"executor":"","constraints":[],"uris":[],"storeUrls":[],"ports":[0],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":null,"healthChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1,"maximumOverCapacity":1},"labels":{},"acceptedResourceRoles":null,"version":"2015-12-28T05:33:05.805Z","tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"3ec3fbd5-11e4-479f-bd17-813d33e43e0c"}],"tasks":[]}%
```
Marathon 的更多 REST API 可以参考本地自带的文档:`http://marathon_host:8080/api-console/index.html`。
此时,如果运行任务的从节点出现故障,任务会自动在其它可用的从节点上启动。
此外,目前也已经支持基于 Docker 容器的任务。需要先在 Mesos slave 节点上为 slave 服务配置 `--containerizers=docker,mesos` 参数。
例如如下面的示例任务:
```json
{
"id": "basic-3",
"cmd": "python3 -m http.server 8080",
"cpus": 0.5,
"mem": 32.0,
"container": {
"type": "DOCKER",
"volumes": [],
"docker": {
"image": "python:3",
"network": "BRIDGE",
"portMappings": [
{
"containerPort": 8080,
"hostPort": 31000,
"servicePort": 0,
"protocol": "tcp"
}
],
"privileged": false,
"parameters": [],
"forcePullImage": true
}
}
}
```
该任务启动一个 `python:3` 容器,执行 `python3 -m http.server 8080` 命令,作为一个简单的 web 服务,实际端口会映射到宿主机的 31000 端口。
注意区分 hostPort 和 servicePort,前者代表任务映射到的本地可用端口(可用范围由 Mesos slave 汇报,默认为 31000 ~ 32000);后者作为服务管理的端口,可以被用作一些服务发行机制使用进行转发,在整个 Marathon 集群中是唯一的。
任务执行后,也可以在对应 slave 节点上通过 Docker 命令查看容器运行情况,容器将以 `mesos-SLAVE_ID` 开头。
```sh
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1226b4ec8d7d python:3 "/bin/sh -c 'python3 " 3 days ago Up 3 days 0.0.0.0:10000->8080/tcp mesos-06db0fba-49dc-4d28-ad87-6c2d5a020866-S10.b581149e-2c43-46a2-b652-1a0bc10204b3
```
';
Mesos 简介
最后更新于:2022-04-01 21:33:52
## 简介
Mesos 最初由 UC Berkeley 的 AMP 实验室于 2009 年发起,遵循 Apache 协议,目前已经成立了 Mesosphere 公司进行运营。Mesos 可以将整个数据中心的资源(包括 CPU、内存、存储、网络等)进行抽象和调度,使得多个应用同时运行在集群中分享资源,并无需关心资源的物理分布情况。
如果把数据中心中的集群资源看做一台服务器,那么 Mesos 要做的事情,其实就是今天操作系统内核的职责:抽象资源 + 调度任务。Mesos 项目是 Mesosphere 公司 Datacenter Operating System (DCOS) 产品的核心部件。
Mesos 项目主要由 C++ 语言编写,项目官方地址为 [https://mesos.apache.org](https://mesos.apache.org),代码仍在快速演化中,已经发布了正式版 1.0.0 版本。
Mesos 拥有许多引人注目的特性,包括:
* 支持数万个节点的大规模场景(Apple、Twitter、eBay 等公司实践);
* 支持多种应用框架,包括 Marathon、Singularity、Aurora 等;
* 支持 HA(基于 ZooKeeper 实现);
* 支持 Docker、LXC 等容器机制进行任务隔离;
* 提供了多个流行语言的 API,包括 Python、Java、C++ 等;
* 自带了简洁易用的 WebUI,方便用户直接进行操作。
值得注意的是,Mesos 自身只是一个资源抽象的平台,要使用它往往需要结合运行其上的分布式应用(在 Mesos 中被称作框架,framework),比如 Hadoop、Spark 等可以进行分布式计算的大数据处理应用;比如 Marathon 可以实现 PaaS,快速部署应用并自动保持运行;比如 ElasticSearch 可以索引海量数据,提供灵活的整合和查询能力……
大部分时候,用户只需要跟这些框架打交道即可,完全无需关心底下的资源调度情况,因为 Mesos 已经自动帮你实现了。这大大方便了上层应用的开发和运维。
当然,用户也可以基于 Mesos 打造自己的分布式应用框架。
';
Mesos – 优秀的集群资源调度平台
最后更新于:2022-04-01 21:33:49
# Mesos - 优秀的集群资源调度平台
Mesos 项目是源自 UC Berkeley 的对集群资源进行抽象和管理的开源项目,类似于操作系统内核,用户可以使用它很容易地实现分布式应用的自动化调度。
同时,Mesos 自身也很好地结合和主持了 Docker 等相关容器技术,基于 Mesos 已有的大量应用框架,可以实现用户应用的快速上线。
本章将介绍 Mesos 项目的安装、使用、配置以及核心的原理知识。
';
归档
最后更新于:2022-04-01 21:33:47
# 归档项目
以下项目不被官方支持或内容陈旧,将在下一版本中删除。
* Docker Machine
* Mesos
* Docker Swarm
';
附录六:资源链接
最后更新于:2022-04-01 21:33:45
# 资源链接
## 官方网站
* Docker 官方主页:https://www.docker.com
* Docker 官方博客:https://www.docker.com/blog/
* Docker 官方文档:https://docs.docker.com/
* Docker Hub:https://hub.docker.com
* Docker 的源代码仓库:https://github.com/moby/moby
* Docker 路线图 https://github.com/docker/roadmap/projects
* Docker 发布版本历史:https://docs.docker.com/release-notes/
* Docker 常见问题:https://docs.docker.com/engine/faq/
* Docker 远端应用 API:https://docs.docker.com/develop/sdk/
## 实践参考
* Dockerfile 参考:https://docs.docker.com/engine/reference/builder/
* Dockerfile 最佳实践:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/
## 技术交流
* Docker 邮件列表: https://groups.google.com/forum/#!forum/docker-user
* Docker 的 IRC 频道:https://chat.freenode.net#docker
* Docker 的 Twitter 主页:https://twitter.com/docker
## 其它
* Docker 的 StackOverflow 问答主页:https://stackoverflow.com/search?q=docker
';
附录五:如何调试 Docker
最后更新于:2022-04-01 21:33:43
# 如何调试 Docker
## 开启 Debug 模式
在 dockerd 配置文件 daemon.json(默认位于 /etc/docker/)中添加
```json
{
"debug": true
}
```
重启守护进程。
```bash
$ sudo kill -SIGHUP $(pidof dockerd)
```
此时 dockerd 会在日志中输入更多信息供分析。
## 检查内核日志
```bash
$ sudo dmesag |grep dockerd
$ sudo dmesag |grep runc
```
## Docker 不响应时处理
可以杀死 dockerd 进程查看其堆栈调用情况。
```bash
$ sudo kill -SIGUSR1 $(pidof dockerd)
```
## 重置 Docker 本地数据
*注意,本操作会移除所有的 Docker 本地数据,包括镜像和容器等。*
```bash
$ sudo rm -rf /var/lib/docker
```
';
附录四:Dockerfile 最佳实践
最后更新于:2022-04-01 21:33:40
# Dockerfile 最佳实践
本附录是笔者对 Docker 官方文档中 [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) 的理解与翻译。
## 一般性的指南和建议
### 容器应该是短暂的
通过 `Dockerfile` 构建的镜像所启动的容器应该尽可能短暂(生命周期短)。「短暂」意味着可以停止和销毁容器,并且创建一个新容器并部署好所需的设置和配置工作量应该是极小的。
### 使用 `.dockerignore` 文件
使用 `Dockerfile` 构建镜像时最好是将 `Dockerfile` 放置在一个新建的空目录下。然后将构建镜像所需要的文件添加到该目录中。为了提高构建镜像的效率,你可以在目录下新建一个 `.dockerignore` 文件来指定要忽略的文件和目录。`.dockerignore` 文件的排除模式语法和 Git 的 `.gitignore` 文件相似。
### 使用多阶段构建
在 `Docker 17.05` 以上版本中,你可以使用 [多阶段构建](../image/multistage-builds.md) 来减少所构建镜像的大小。
### 避免安装不必要的包
为了降低复杂性、减少依赖、减小文件大小、节约构建时间,你应该避免安装任何不必要的包。例如,不要在数据库镜像中包含一个文本编辑器。
### 一个容器只运行一个进程
应该保证在一个容器中只运行一个进程。将多个应用解耦到不同容器中,保证了容器的横向扩展和复用。例如 web 应用应该包含三个容器:web应用、数据库、缓存。
如果容器互相依赖,你可以使用 [Docker 自定义网络](../network/linking.md) 来把这些容器连接起来。
### 镜像层数尽可能少
你需要在 `Dockerfile` 可读性(也包括长期的可维护性)和减少层数之间做一个平衡。
### 将多行参数排序
将多行参数按字母顺序排序(比如要安装多个包时)。这可以帮助你避免重复包含同一个包,更新包列表时也更容易。也便于 `PRs` 阅读和审查。建议在反斜杠符号 `\` 之前添加一个空格,以增加可读性。
下面是来自 `buildpack-deps` 镜像的例子:
```docker
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
```
### 构建缓存
在镜像的构建过程中,Docker 会遍历 `Dockerfile` 文件中的指令,然后按顺序执行。在执行每条指令之前,Docker 都会在缓存中查找是否已经存在可重用的镜像,如果有就使用现存的镜像,不再重复创建。如果你不想在构建过程中使用缓存,你可以在 `docker build` 命令中使用 `--no-cache=true` 选项。
但是,如果你想在构建的过程中使用缓存,你得明白什么时候会,什么时候不会找到匹配的镜像,遵循的基本规则如下:
* 从一个基础镜像开始(`FROM` 指令指定),下一条指令将和该基础镜像的所有子镜像进行匹配,检查这些子镜像被创建时使用的指令是否和被检查的指令完全一样。如果不是,则缓存失效。
* 在大多数情况下,只需要简单地对比 `Dockerfile` 中的指令和子镜像。然而,有些指令需要更多的检查和解释。
* 对于 `ADD` 和 `COPY` 指令,镜像中对应文件的内容也会被检查,每个文件都会计算出一个校验和。文件的最后修改时间和最后访问时间不会纳入校验。在缓存的查找过程中,会将这些校验和和已存在镜像中的文件校验和进行对比。如果文件有任何改变,比如内容和元数据,则缓存失效。
* 除了 `ADD` 和 `COPY` 指令,缓存匹配过程不会查看临时容器中的文件来决定缓存是否匹配。例如,当执行完 `RUN apt-get -y update` 指令后,容器中一些文件被更新,但 Docker 不会检查这些文件。这种情况下,只有指令字符串本身被用来匹配缓存。
一旦缓存失效,所有后续的 `Dockerfile` 指令都将产生新的镜像,缓存不会被使用。
## Dockerfile 指令
下面针对 `Dockerfile` 中各种指令的最佳编写方式给出建议。
### FROM
尽可能使用当前官方仓库作为你构建镜像的基础。推荐使用 [Alpine](https://hub.docker.com/_/alpine/) 镜像,因为它被严格控制并保持最小尺寸(目前小于 5 MB),但它仍然是一个完整的发行版。
### LABEL
你可以给镜像添加标签来帮助组织镜像、记录许可信息、辅助自动化构建等。每个标签一行,由 `LABEL` 开头加上一个或多个标签对。下面的示例展示了各种不同的可能格式。`#` 开头的行是注释内容。
>注意:如果你的字符串中包含空格,必须将字符串放入引号中或者对空格使用转义。如果字符串内容本身就包含引号,必须对引号使用转义。
```docker
# Set one or more individual labels
LABEL com.example.version="0.0.1-beta"
LABEL vendor="ACME Incorporated"
LABEL com.example.release-date="2015-02-12"
LABEL com.example.version.is-production=""
```
一个镜像可以包含多个标签,但建议将多个标签放入到一个 `LABEL` 指令中。
```docker
# Set multiple labels at once, using line-continuation characters to break long lines
LABEL vendor=ACME\ Incorporated \
com.example.is-beta= \
com.example.is-production="" \
com.example.version="0.0.1-beta" \
com.example.release-date="2015-02-12"
```
关于标签可以接受的键值对,参考 [Understanding object labels](https://docs.docker.com/config/labels-custom-metadata/)。关于查询标签信息,参考 [Managing labels on objects](https://docs.docker.com/config/labels-custom-metadata/)。
### RUN
为了保持 `Dockerfile` 文件的可读性,可理解性,以及可维护性,建议将长的或复杂的 `RUN` 指令用反斜杠 `\` 分割成多行。
#### apt-get
`RUN` 指令最常见的用法是安装包用的 `apt-get`。因为 `RUN apt-get` 指令会安装包,所以有几个问题需要注意。
不要使用 `RUN apt-get upgrade` 或 `dist-upgrade`,因为许多基础镜像中的「必须」包不会在一个非特权容器中升级。如果基础镜像中的某个包过时了,你应该联系它的维护者。如果你确定某个特定的包,比如 `foo`,需要升级,使用 `apt-get install -y foo` 就行,该指令会自动升级 `foo` 包。
永远将 `RUN apt-get update` 和 `apt-get install` 组合成一条 `RUN` 声明,例如:
```docker
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
package-foo
```
将 `apt-get update` 放在一条单独的 `RUN` 声明中会导致缓存问题以及后续的 `apt-get install` 失败。比如,假设你有一个 `Dockerfile` 文件:
```docker
FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install -y curl
```
构建镜像后,所有的层都在 Docker 的缓存中。假设你后来又修改了其中的 `apt-get install` 添加了一个包:
```docker
FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install -y curl nginx
```
Docker 发现修改后的 `RUN apt-get update` 指令和之前的完全一样。所以,`apt-get update` 不会执行,而是使用之前的缓存镜像。因为 `apt-get update` 没有运行,后面的 `apt-get install` 可能安装的是过时的 `curl` 和 `nginx` 版本。
使用 `RUN apt-get update && apt-get install -y` 可以确保你的 Dockerfiles 每次安装的都是包的最新的版本,而且这个过程不需要进一步的编码或额外干预。这项技术叫作 `cache busting`。你也可以显示指定一个包的版本号来达到 `cache-busting`,这就是所谓的固定版本,例如:
```docker
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
package-foo=1.3.*
```
固定版本会迫使构建过程检索特定的版本,而不管缓存中有什么。这项技术也可以减少因所需包中未预料到的变化而导致的失败。
下面是一个 `RUN` 指令的示例模板,展示了所有关于 `apt-get` 的建议。
```docker
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& rm -rf /var/lib/apt/lists/*
```
其中 `s3cmd` 指令指定了一个版本号 `1.1.*`。如果之前的镜像使用的是更旧的版本,指定新的版本会导致 `apt-get udpate` 缓存失效并确保安装的是新版本。
另外,清理掉 apt 缓存 `var/lib/apt/lists` 可以减小镜像大小。因为 `RUN` 指令的开头为 `apt-get udpate`,包缓存总是会在 `apt-get install` 之前刷新。
> 注意:官方的 Debian 和 Ubuntu 镜像会自动运行 apt-get clean,所以不需要显式的调用 apt-get clean。
### CMD
`CMD` 指令用于执行目标镜像中包含的软件,可以包含参数。`CMD` 大多数情况下都应该以 `CMD ["executable", "param1", "param2"...]` 的形式使用。因此,如果创建镜像的目的是为了部署某个服务(比如 `Apache`),你可能会执行类似于 `CMD ["apache2", "-DFOREGROUND"]` 形式的命令。我们建议任何服务镜像都使用这种形式的命令。
多数情况下,`CMD` 都需要一个交互式的 `shell` (bash, Python, perl 等),例如 `CMD ["perl", "-de0"]`,或者 `CMD ["PHP", "-a"]`。使用这种形式意味着,当你执行类似 `docker run -it python` 时,你会进入一个准备好的 `shell` 中。`CMD` 应该在极少的情况下才能以 `CMD ["param", "param"]` 的形式与 `ENTRYPOINT` 协同使用,除非你和你的镜像使用者都对 `ENTRYPOINT` 的工作方式十分熟悉。
### EXPOSE
`EXPOSE` 指令用于指定容器将要监听的端口。因此,你应该为你的应用程序使用常见的端口。例如,提供 `Apache` web 服务的镜像应该使用 `EXPOSE 80`,而提供 `MongoDB` 服务的镜像使用 `EXPOSE 27017`。
对于外部访问,用户可以在执行 `docker run` 时使用一个标志来指示如何将指定的端口映射到所选择的端口。
### ENV
为了方便新程序运行,你可以使用 `ENV` 来为容器中安装的程序更新 `PATH` 环境变量。例如使用 `ENV PATH /usr/local/nginx/bin:$PATH` 来确保 `CMD ["nginx"]` 能正确运行。
`ENV` 指令也可用于为你想要容器化的服务提供必要的环境变量,比如 Postgres 需要的 `PGDATA`。
最后,`ENV` 也能用于设置常见的版本号,比如下面的示例:
```docker
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
```
类似于程序中的常量,这种方法可以让你只需改变 `ENV` 指令来自动的改变容器中的软件版本。
### ADD 和 COPY
虽然 `ADD` 和 `COPY` 功能类似,但一般优先使用 `COPY`。因为它比 `ADD` 更透明。`COPY` 只支持简单将本地文件拷贝到容器中,而 `ADD` 有一些并不明显的功能(比如本地 tar 提取和远程 URL 支持)。因此,`ADD` 的最佳用例是将本地 tar 文件自动提取到镜像中,例如 `ADD rootfs.tar.xz`。
如果你的 `Dockerfile` 有多个步骤需要使用上下文中不同的文件。单独 `COPY` 每个文件,而不是一次性的 `COPY` 所有文件,这将保证每个步骤的构建缓存只在特定的文件变化时失效。例如:
```docker
COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/
```
如果将 `COPY . /tmp/` 放置在 `RUN` 指令之前,只要 `.` 目录中任何一个文件变化,都会导致后续指令的缓存失效。
为了让镜像尽量小,最好不要使用 `ADD` 指令从远程 URL 获取包,而是使用 `curl` 和 `wget`。这样你可以在文件提取完之后删掉不再需要的文件来避免在镜像中额外添加一层。比如尽量避免下面的用法:
```docker
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
```
而是应该使用下面这种方法:
```docker
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
```
上面使用的管道操作,所以没有中间文件需要删除。
对于其他不需要 `ADD` 的自动提取功能的文件或目录,你应该使用 `COPY`。
### ENTRYPOINT
`ENTRYPOINT` 的最佳用处是设置镜像的主命令,允许将镜像当成命令本身来运行(用 `CMD` 提供默认选项)。
例如,下面的示例镜像提供了命令行工具 `s3cmd`:
```docker
ENTRYPOINT ["s3cmd"]
CMD ["--help"]
```
现在直接运行该镜像创建的容器会显示命令帮助:
```bash
$ docker run s3cmd
```
或者提供正确的参数来执行某个命令:
```bash
$ docker run s3cmd ls s3://mybucket
```
这样镜像名可以当成命令行的参考。
`ENTRYPOINT` 指令也可以结合一个辅助脚本使用,和前面命令行风格类似,即使启动工具需要不止一个步骤。
例如,`Postgres` 官方镜像使用下面的脚本作为 `ENTRYPOINT`:
```bash
#!/bin/bash
set -e
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec "$@"
```
>注意:该脚本使用了 Bash 的内置命令 exec,所以最后运行的进程就是容器的 PID 为 1 的进程。这样,进程就可以接收到任何发送给容器的 Unix 信号了。
该辅助脚本被拷贝到容器,并在容器启动时通过 `ENTRYPOINT` 执行:
```docker
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
```
该脚本可以让用户用几种不同的方式和 `Postgres` 交互。
你可以很简单地启动 `Postgres`:
```bash
$ docker run postgres
```
也可以执行 `Postgres` 并传递参数:
```bash
$ docker run postgres postgres --help
```
最后,你还可以启动另外一个完全不同的工具,比如 `Bash`:
```bash
$ docker run --rm -it postgres bash
```
### VOLUME
`VOLUME` 指令用于暴露任何数据库存储文件,配置文件,或容器创建的文件和目录。强烈建议使用 `VOLUME` 来管理镜像中的可变部分和用户可以改变的部分。
### USER
如果某个服务不需要特权执行,建议使用 `USER` 指令切换到非 root 用户。先在 `Dockerfile` 中使用类似 `RUN groupadd -r postgres && useradd -r -g postgres postgres` 的指令创建用户和用户组。
>注意:在镜像中,用户和用户组每次被分配的 UID/GID 都是不确定的,下次重新构建镜像时被分配到的 UID/GID 可能会不一样。如果要依赖确定的 UID/GID,你应该显示的指定一个 UID/GID。
你应该避免使用 `sudo`,因为它不可预期的 TTY 和信号转发行为可能造成的问题比它能解决的问题还多。如果你真的需要和 `sudo` 类似的功能(例如,以 root 权限初始化某个守护进程,以非 root 权限执行它),你可以使用 [gosu](https://github.com/tianon/gosu)。
最后,为了减少层数和复杂度,避免频繁地使用 `USER` 来回切换用户。
### WORKDIR
为了清晰性和可靠性,你应该总是在 `WORKDIR` 中使用绝对路径。另外,你应该使用 `WORKDIR` 来替代类似于 `RUN cd ... && do-something` 的指令,后者难以阅读、排错和维护。
## 官方镜像示例
这些官方镜像的 Dockerfile 都是参考典范:https://github.com/docker-library/docs
';
服务端命令 – dockerd
最后更新于:2022-04-01 21:33:38
# 服务端命令(dockerd)
## dockerd 命令选项
* `--api-cors-header=""`:CORS 头部域,默认不允许 CORS,要允许任意的跨域访问,可以指定为 "*";
* `--authorization-plugin=""`:载入认证的插件;
* `-b=""`:将容器挂载到一个已存在的网桥上。指定为 `none` 时则禁用容器的网络,与 `--bip` 选项互斥;
* `--bip=""`:让动态创建的 `docker0` 网桥采用给定的 CIDR 地址; 与 `-b` 选项互斥;
* `--cgroup-parent=""`:指定 cgroup 的父组,默认 fs cgroup 驱动为 `/docker`,systemd cgroup 驱动为 `system.slice`;
* `--cluster-store=""`:构成集群(如 `Swarm`)时,集群键值数据库服务地址;
* `--cluster-advertise=""`:构成集群时,自身的被访问地址,可以为 `host:port` 或 `interface:port`;
* `--cluster-store-opt=""`:构成集群时,键值数据库的配置选项;
* `--config-file="/etc/docker/daemon.json"`:daemon 配置文件路径;
* `--containerd=""`:containerd 文件的路径;
* `-D, --debug=true|false`:是否使用 Debug 模式。缺省为 false;
* `--default-gateway=""`:容器的 IPv4 网关地址,必须在网桥的子网段内;
* `--default-gateway-v6=""`:容器的 IPv6 网关地址;
* `--default-ulimit=[]`:默认的 ulimit 值;
* `--disable-legacy-registry=true|false`:是否允许访问旧版本的镜像仓库服务器;
* `--dns=""`:指定容器使用的 DNS 服务器地址;
* `--dns-opt=""`:DNS 选项;
* `--dns-search=[]`:DNS 搜索域;
* `--exec-opt=[]`:运行时的执行选项;
* `--exec-root=""`:容器执行状态文件的根路径,默认为 `/var/run/docker`;
* `--fixed-cidr=""`:限定分配 IPv4 地址范围;
* `--fixed-cidr-v6=""`:限定分配 IPv6 地址范围;
* `-G, --group=""`:分配给 unix 套接字的组,默认为 `docker`;
* `-g, --graph=""`:Docker 运行时的根路径,默认为 `/var/lib/docker`;
* `-H, --host=[]`:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`;
* `--icc=true|false`:是否启用容器间以及跟 daemon 所在主机的通信。默认为 true。
* `--insecure-registry=[]`:允许访问给定的非安全仓库服务;
* `--ip=""`:绑定容器端口时候的默认 IP 地址。缺省为 `0.0.0.0`;
* `--ip-forward=true|false`:是否检查启动在 Docker 主机上的启用 IP 转发服务,默认开启。注意关闭该选项将不对系统转发能力进行任何检查修改;
* `--ip-masq=true|false`:是否进行地址伪装,用于容器访问外部网络,默认开启;
* `--iptables=true|false`:是否允许 Docker 添加 iptables 规则。缺省为 true;
* `--ipv6=true|false`:是否启用 IPv6 支持,默认关闭;
* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别;
* `--label="[]"`:添加指定的键值对标注;
* `--log-driver="json-file|syslog|journald|gelf|fluentd|awslogs|splunk|etwlogs|gcplogs|none"`:指定日志后端驱动,默认为 `json-file`;
* `--log-opt=[]`:日志后端的选项;
* `--mtu=VALUE`:指定容器网络的 `mtu`;
* `-p=""`:指定 daemon 的 PID 文件路径。缺省为 `/var/run/docker.pid`;
* `--raw-logs`:输出原始,未加色彩的日志信息;
* `--registry-mirror=://`:指定 `docker pull` 时使用的注册服务器镜像地址;
* `-s, --storage-driver=""`:指定使用给定的存储后端;
* `--selinux-enabled=true|false`:是否启用 SELinux 支持。缺省值为 false。SELinux 目前尚不支持 overlay 存储驱动;
* `--storage-opt=[]`:驱动后端选项;
* `--tls=true|false`:是否对 Docker daemon 启用 TLS 安全机制,默认为否;
* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径;
* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径;
* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径;
* `--tlsverify=true|false`:启用 TLS 校验,默认为否;
* `--userland-proxy=true|false`:是否使用用户态代理来实现容器间和出容器的回环通信,默认为 true;
* `--userns-remap=default|uid:gid|user:group|user|uid`:指定容器的用户命名空间,默认是创建新的 UID 和 GID 映射到容器内进程。
## 参考
* [官方文档](https://docs.docker.com/engine/reference/commandline/dockerd/)
';
客户端命令 – docker
最后更新于:2022-04-01 21:33:36
# 客户端命令(docker)
## 客户端命令选项
* `--config=""`:指定客户端配置文件,默认为 `~/.docker`;
* `-D=true|false`:是否使用 debug 模式。默认不开启;
* `-H, --host=[]`:指定命令对应 Docker 守护进程的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`;
* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别;
* `--tls=true|false`:是否对 Docker 守护进程启用 TLS 安全机制,默认为否;
* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径;
* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径;
* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径;
* `--tlsverify=true|false`:启用 TLS 校验,默认为否。
## 客户端命令
可以通过 `docker COMMAND --help` 来查看这些命令的具体用法。
* `attach`:依附到一个正在运行的容器中;
* `build`:从一个 Dockerfile 创建一个镜像;
* `commit`:从一个容器的修改中创建一个新的镜像;
* `cp`:在容器和本地宿主系统之间复制文件中;
* `create`:创建一个新容器,但并不运行它;
* `diff`:检查一个容器内文件系统的修改,包括修改和增加;
* `events`:从服务端获取实时的事件;
* `exec`:在运行的容器内执行命令;
* `export`:导出容器内容为一个 `tar` 包;
* `history`:显示一个镜像的历史信息;
* `images`:列出存在的镜像;
* `import`:导入一个文件(典型为 `tar` 包)路径或目录来创建一个本地镜像;
* `info`:显示一些相关的系统信息;
* `inspect`:显示一个容器的具体配置信息;
* `kill`:关闭一个运行中的容器 (包括进程和所有相关资源);
* `load`:从一个 tar 包中加载一个镜像;
* `login`:注册或登录到一个 Docker 的仓库服务器;
* `logout`:从 Docker 的仓库服务器登出;
* `logs`:获取容器的 log 信息;
* `network`:管理 Docker 的网络,包括查看、创建、删除、挂载、卸载等;
* `node`:管理 swarm 集群中的节点,包括查看、更新、删除、提升/取消管理节点等;
* `pause`:暂停一个容器中的所有进程;
* `port`:查找一个 nat 到一个私有网口的公共口;
* `ps`:列出主机上的容器;
* `pull`:从一个Docker的仓库服务器下拉一个镜像或仓库;
* `push`:将一个镜像或者仓库推送到一个 Docker 的注册服务器;
* `rename`:重命名一个容器;
* `restart`:重启一个运行中的容器;
* `rm`:删除给定的若干个容器;
* `rmi`:删除给定的若干个镜像;
* `run`:创建一个新容器,并在其中运行给定命令;
* `save`:保存一个镜像为 tar 包文件;
* `search`:在 Docker index 中搜索一个镜像;
* `service`:管理 Docker 所启动的应用服务,包括创建、更新、删除等;
* `start`:启动一个容器;
* `stats`:输出(一个或多个)容器的资源使用统计信息;
* `stop`:终止一个运行中的容器;
* `swarm`:管理 Docker swarm 集群,包括创建、加入、退出、更新等;
* `tag`:为一个镜像打标签;
* `top`:查看一个容器中的正在运行的进程信息;
* `unpause`:将一个容器内所有的进程从暂停状态中恢复;
* `update`:更新指定的若干容器的配置信息;
* `version`:输出 Docker 的版本信息;
* `volume`:管理 Docker volume,包括查看、创建、删除等;
* `wait`:阻塞直到一个容器终止,然后输出它的退出符。
## 一张图总结 Docker 的命令
![Docker 命令总结](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/5970ea4d5acd2a3510154741f83920dc_1600x1520.png)
## 参考
* [官方文档](https://docs.docker.com/engine/reference/commandline/cli/)
';
附录三:Docker 命令查询
最后更新于:2022-04-01 21:33:33
# Docker 命令查询
## 基本语法
Docker 命令有两大类,客户端命令和服务端命令。前者是主要的操作接口,后者用来启动 Docker Daemon。
* 客户端命令:基本命令格式为 `docker [OPTIONS] COMMAND [arg...]`;
* 服务端命令:基本命令格式为 `dockerd [OPTIONS]`。
可以通过 `man docker` 或 `docker help` 来查看这些命令。
接下来的小节对这两个命令进行介绍。
';
Minio
最后更新于:2022-04-01 21:33:31
# minio
[TOC]
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。
[官方文档](https://docs.min.io/)
## 简单使用
测试、开发环境下不考虑数据存储的情况下可以使用下面的命令快速开启服务。
```bash
docker pull minio/minio
docker run -p 9000:9000 minio/minio server /data
```
## 离线部署
许多生产环境是一般是没有公网资源的,这就需要从有公网资源的服务器上把镜像导出,然后导入到需要运行镜像的内网服务器。
### 导出镜像
在有公网资源的服务器上下载好`minio/minio`镜像
```bash
docker save -o minio.tar minio/minio:latest
```
### 导入镜像
把压缩文件复制到内网服务器上,使用下面的命令导入镜像
```bash
docker load minio.tar
```
### 运行 minio
- 把/mnt/data 改成要替换的数据目录
- 替换 MINIO_ACCESS_KEY
- 替换 MINIO_SECRET_KEY
- 替换 name,minio1(可选)
- 如果9000端口冲突,替换端口前面的如:9009:9000
```bash
sudo docker run -d -p 9000:9000 --name minio1 \
-e "MINIO_ACCESS_KEY=改成自己需要的" \
-e "MINIO_SECRET_KEY=改成自己需要的" \
-v /mnt/data:/data \
--restart=always \
minio/minio server /data
```
### 访问 web 管理页面
http://x.x.x.x:9000/minio/
';