## Swarm 過濾器
swarm 的調度器(scheduler)在選擇節點運行容器的時候支持幾種過濾器 (filter):Constraint,Affinity,Port,Dependency,Health
可以在執行 `swarm manage` 命令的時候通過 `--filter` 選項來設置。
###Constraint Filter
constraint 是一個跟具體節點相關聯的鍵值對,可以看做是每個節點的標簽,這個標簽可以在啟動docker daemon的時候指定,比如
```sh
sudo docker -d --label label_name=label01
```
也可以寫在docker的配置文件里面(在ubuntu上面是 `/etc/default/docker`)。
在本次試驗中,給083添加標簽--label label_name=083,084添加標簽--label label_name=084,124添加標簽--label label_name=084,
以083為例,打開/etc/default/docker文件,修改DOCKER_OPTS:
```sh
DOCKER_OPTS="-H 0.0.0.0:2375 -H unix:///var/run/docker.sock --label label_name=083"
```
在使用docker run命令啟動容器的時候使用 `-e constarint:key=value` 的形式,可以指定container運行的節點。
比如我們想在84上面啟動一個 redis 容器。
```sh
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_1 -d -e constraint:label_name==084 redis
fee1b7b9dde13d64690344c1f1a4c3f5556835be46b41b969e4090a083a6382d
```
注意,是**兩個**等號,不是一個等號,這一點會經常被忽略。
接下來再在084這臺機器上啟動一個redis 容器。
```sh
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_2 -d -e constraint:label_name==084 redis 4968d617d9cd122fc2e17b3bad2f2c3b5812c0f6f51898024a96c4839fa000e1
```
然后再在083這臺機器上啟動另外一個 redis 容器。
```sh
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_3 -d -e constraint:label_name==083 redis 7786300b8d2232c2335ac6161c715de23f9179d30eb5c7e9c4f920a4f1d39570
```
現在來看下執行情況:
```sh
rio@085:~$ sudo docker -H 192.168.1.83:2376 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7786300b8d22 redis:latest "/entrypoint.sh redi 15 minutes ago Up 53 seconds 6379/tcp 083/redis_3
4968d617d9cd redis:latest "/entrypoint.sh redi 16 minutes ago Up 2 minutes 6379/tcp 084/redis_2
fee1b7b9dde1 redis:latest "/entrypoint.sh redi 19 minutes ago Up 5 minutes 6379/tcp 084/redis_1
```
可以看到,執行結果跟預期的一樣。
但是如果指定一個不存在的標簽的話來運行容器會報錯。
```sh
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_0 -d -e constraint:label_name==0 redis
FATA[0000] Error response from daemon: unable to find a node that satisfies label_name==0
```
###Affinity Filter
通過使用 Affinity Filter,可以讓一個容器緊挨著另一個容器啟動,也就是說讓兩個容器在同一個節點上面啟動。
現在其中一臺機器上面啟動一個 redis 容器。
```sh
rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis redis
ea13eddf667992c5d8296557d3c282dd8484bd262c81e2b5af061cdd6c82158d
rio@085:~$ sudo docker -H 192.168.1.83:2376 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea13eddf6679 redis:latest /entrypoint.sh redis 24 minutes ago Up Less than a second 6379/tcp 083/redis
```
然后再次啟動兩個 redis 容器。
```sh
rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis_1 -e affinity:container==redis redis
bac50c2e955211047a745008fd1086eaa16d7ae4f33c192f50412e8dcd0a14cd
rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis_1 -e affinity:container==redis redis
bac50c2e955211047a745008fd1086eaa16d7ae4f33c192f50412e8dcd0a14cd
```
現在來查看下運行結果,可以看到三個容器都是在一臺機器上運行
```sh
rio@085:~$ sudo docker -H 192.168.1.83:2376 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
449ed25ad239 redis:latest /entrypoint.sh redis 24 minutes ago Up Less than a second 6379/tcp 083/redis_2
bac50c2e9552 redis:latest /entrypoint.sh redis 25 minutes ago Up 10 seconds 6379/tcp 083/redis_1
ea13eddf6679 redis:latest /entrypoint.sh redis 28 minutes ago Up 3 minutes 6379/tcp 083/redis
```
通過 `-e affinity:image=image_name` 命令可以指定只有已經下載了`image_name`鏡像的機器才運行容器
```sh
sudo docker –H 192.168.1.83:2376 run –name redis1 –d –e affinity:image==redis redis
```
redis1 這個容器只會在已經下載了 redis 鏡像的節點上運行。
```sh
sudo docker -H 192.168.1.83:2376 run -d --name redis -e affinity:image==~redis redis
```
這條命令達到的效果是:在有 redis 鏡像的節點上面啟動一個名字叫做 redis 的容器,如果每個節點上面都沒有 redis 容器,就按照默認的策略啟動 redis 容器。
###Port Filter
Port 也會被認為是一個唯一的資源
```sh
sudo docker -H 192.168.1.83:2376 run -d -p 80:80 nginx
```
執行完這條命令,之后任何使用 80 端口的容器都是啟動失敗。
- 前言
- Docker 簡介
- 什么是 Docker
- 為什么要用 Docker
- 基本概念
- 鏡像
- 容器
- 倉庫
- 安裝
- Ubuntu
- CentOS
- 鏡像
- 獲取鏡像
- 列出
- 創建
- 存出和載入
- 移除
- 實現原理
- 容器
- 啟動
- 守護態運行
- 終止
- 進入容器
- 導出和導入
- 刪除
- 倉庫
- Docker Hub
- 私有倉庫
- 配置文件
- 數據管理
- 數據卷
- 數據卷容器
- 備份、恢復、遷移數據卷
- 使用網絡
- 外部訪問容器
- 容器互聯
- 高級網絡配置
- 快速配置指南
- 配置 DNS
- 容器訪問控制
- 端口映射實現
- 配置 docker0 網橋
- 自定義網橋
- 工具和示例
- 編輯網絡配置文件
- 實例:創建一個點到點連接
- 實戰案例
- 使用 Supervisor 來管理進程
- 創建 tomcat/weblogic 集群
- 多臺物理主機之間的容器互聯
- 標準化開發測試和生產環境
- 安全
- 內核名字空間
- 控制組
- 服務端防護
- 內核能力機制
- 其它安全特性
- 總結
- Dockerfile
- 基本結構
- 指令
- 創建鏡像
- 底層實現
- 基本架構
- 名字空間
- 控制組
- 聯合文件系統
- 容器格式
- 網絡
- Docker Compose 項目
- 簡介
- 安裝
- 使用
- 命令說明
- YAML 模板文件
- Docker Machine 項目
- 簡介
- 安裝
- 使用
- Docker Swarm 項目
- 簡介
- 安裝
- 使用
- 調度器
- 過濾器
- Etcd 項目
- 簡介
- 安裝
- 使用 etcdctl
- Fig 項目
- 簡介
- 安裝
- 命令參考
- fig.yml參考
- 環境變量參考
- 實戰 Django
- 實戰 Rails
- 實戰 wordpress
- CoreOS 項目
- 簡介
- 工具
- 快速搭建CoreOS集群
- Kubernetes 項目
- 簡介
- 快速上手
- 基本概念
- kubectl 使用
- 架構設計
- Mesos 項目
- 簡介
- 安裝與使用
- 原理與架構
- 配置項解析
- 常見框架
- 附錄一:命令查詢
- 附錄二:常見倉庫介紹
- Ubuntu
- CentOS
- MySQL
- MongoDB
- Redis
- Nginx
- WordPress
- Node.js
- 附錄三:有用的資源