Docker v17.04.0-ce-rc1 发布,应用容器引擎
![不指定 不指定](images/weather/blank.gif)
Docker v17.04.0-ce-rc1 发布了,并将于 2017-04-05 发布 17.04.0-ce 版本。本次更新内容如下:
Client
Suppressing image digest in docker ps #30848
Hide command options that are related to Windows #30788
Fix docker plugin install prompt to accept "enter" for the "N" default #30769
Add truncate function for Go templates #30484
Support expanded syntax of ports in stack deploy #30476
Support expanded syntax of mounts in stack deploy #30597 #31795
Add --add-host for docker build #30383
Add .CreatedAt placeholder for docker network ls --format #29900
Add --filter enabled=true for docker plugin ls #28627
Add --format to docker service ls #28199
Add publish and expose filter for docker ps --filter #27557
Support multiple service IDs on docker service ps #25234
Allow swarm join with --availability=drain #24993
Removal of the email from docker login #26868
Networking
Check parameter --ip, --ip6 and --link-local-ip in docker network connect #30807
Added support for dns-search #30117
Added --verbose option for docker network inspect to show task details from all swarm nodes #31710
Clear stale datapath encryption states when joining the cluster docker/libnetwork#1354
Ensure iptables initialization only happens once docker/libnetwork#1676
Fix bad order of iptables filter rules docker/libnetwork#961
Add anonymous container alias to service record on attachable network docker/libnetwork#1651
Support for com.docker.network.container_interface_prefix driver label docker/libnetwork#1667
Runtime
Handle paused container when restoring without live-restore set #31704
Do not allow sub second in healthcheck options in Dockerfile #31177
Support name and id prefix in secret update #30856
Use binary frame for websocket attach endpoint #30460
Fix linux mount calls not applying propagation type changes #30416
Fix ExecIds leak on failed exec -i #30340
Prune named but untagged images if danglingOnly=true #30330
Add daemon flag to set no_new_priv as default for unprivileged containers #29984
Add daemon option --default-shm-size #29692
Support registry mirror config reload #29650
Ignore the daemon log config when building images #29552
Move secret name or ID prefix resolving from client to daemon #29218
Implement optional ring buffer for container logs #28762
Allow adding rules to cgroup devices.allow on container create/run #22563
Swarm Mode
Topology-aware scheduling #30725
Automatic service rollback on failure #31108
Worker and manager on the same node are now connected through a UNIX socket docker/swarmkit#1828, docker/swarmkit#1850, docker/swarmkit#1851
Improve raft transport package docker/swarmkit#1748
No automatic manager shutdown on demotion/removal docker/swarmkit#1829
Use TransferLeadership to make leader demotion safer docker/swarmkit#1939
Decrease default monitoring period docker/swarmkit#1967
Add Service logs formatting #31672
Fix service logs API to be able to specify stream #31313
Add --stop-signal for service create and service update #30754
Add --read-only for service create and service update #30162
Renew the context after communicating with the registry #31586
Windows
Wait for OOBE to prevent crashing during host update #31054
Block pulling Windows images on non-Windows daemons #29001
下载
deb/rpm install: curl -fsSL https://test.docker.com/ | sh
Linux 64bits tgz: https://test.docker.com/builds/Linux/x86_64/docker-17.04.0-ce-rc1.tgz
Darwin/OSX 64bits client tgz: https://test.docker.com/builds/Darwin/x86_64/docker-17.04.0-ce-rc1.tgz
Linux 32bits arm tgz: https://test.docker.com/builds/Linux/armel/docker-17.04.0-ce-rc1.tgz
Windows 64bits zip: https://test.docker.com/builds/Windows/x86_64/docker-17.04.0-ce-rc1.zip
Windows 32bits client zip: https://test.docker.com/builds/Windows/i386/docker-17.04.0-ce-rc1.zip
What does el5, el6, and el7 mean?
EL is short for Red Hat Enterprise Linux (EL).
EL6 is the download for Red Hat 6.x, CentOS 6.x, and CloudLinux 6.x.
EL5 is the download for Red Hat 5.x, CentOS 5.x, CloudLinux 5.x.
EL7 is the download for Red Hat 7.x, CentOS 7.x, and CloudLinux 7.x.
The UNIXy Varnish Plugins run on all the above platforms.
RC ?
RC=Release Candidate,含义是”发布候选版”,它不是最终的版本,而是最终版(RTM=Release To Manufacture)之前的最后一个版本。广义上对测试有三个传统的称呼:alpha、beta、gamma,用来标识测试的阶段和范围。alpha 是指内测,即现在说的CB,指开发团队内部测试的版本或者有限用户体验测试版本。beta 是指公测,即针对所有用户公开的测试版本。然后做过一些修改,成为正式发布的候选版本时叫做gamma,现在叫做RC(Release Candidate)。
官网tar.gz下载:https://download.docker.com/linux/static/stable/x86_64/
官网安装教程:https://docs.docker.com/engine/installation/linux/centos/#install-from-a-package
下载
Docker重大更新,2017-03-02版本升至17.03,包名仓库全换
![不指定 不指定](images/weather/blank.gif)
3月2日,Docker 官方发布了一篇 blog ,宣布企业版到来。版本也从1.13.x一跃到17.03。
之后,Docker 会每月发布一个 edge 版本(17.03, 17.04, 17.05...),每三个月发布一个 stable 版本(17.03, 17.06, 17.09...),企业版(EE) 和 stable 版本号保持一致,但每个版本提供一年维护。
Docker 的 Linux 发行版的软件仓库也从以前的https://apt.dockerproject.org / https://yum.dockerproject.org 变更为目前的 https://download.docker.com/。软件包名变更为 docker-ce(社区版) 和 docker-ee(企业版)。
旧的仓库和包名(docker-engine)依旧可以使用,但不确定什么时候会被废弃,docker-engine 的版本号也变成了17.03.0~ce-0这种的版本号。
Docker v17.03.0-ce 版本更新内容和下载地址请查看发行日志。
Docker的网络模式和跨主机通信(Docker的四种网络模式Bridge模式)
当Docker进程启动时,会在主机上创建一个名为docker0...
Docker的四种网络模式
1. Bridge模式
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
bridge模式如下图所示:
- #docker run -tid --net=bridge --name docker_bri1 ubuntu-base:v3
- #docker run -tid --net=bridge --name docker_bri2 ubuntu-base:v3
- #brctl show
- #docker exec -ti docker_bri1 /bin/bash
- #docker exec -ti docker_bri1 /bin/bash
- #ifconfig –a
- #route –n
2. Host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
Host模式如下图所示:
演示:
- #docker run -tid --net=host --name docker_host1 ubuntu-base:v3
- #docker run -tid --net=host --name docker_host2 ubuntu-base:v3
- #docker exec -ti docker_host1 /bin/bash
- #docker exec -ti docker_host1 /bin/bash
- #ifconfig –a
- #route –n
3. Container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
Container模式示意图:
演示:
- #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
- #ifconfig –a
- #route -n
4. None模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
Node模式示意图:
演示:
- #docker run -tid --net=none --name docker_non1 ubuntu-base:v3
- #docker exec -ti docker_non1 /bin/bash
- #ifconfig –a
- #route -n
跨主机通信
Docker默认的网络环境下,单台主机上的Docker容器可以通过docker0网桥直接通信,而不同主机上的Docker容器之间只能通过在主机上做端口映射进行通信。这种端口映射方式对很多集群应用来说极不方便。如果能让Docker容器之间直接使用自己的IP地址进行通信,会解决很多问题。按实现原理可分别直接路由方式、桥接方式(如pipework)、Overlay隧道方式(如flannel、ovs+gre)等。
直接路由
通过在Docker主机上添加静态路由实现跨宿主机通信:
Pipework
Pipework是一个简单易用的Docker容器网络配置工具。由200多行shell脚本实现。通过使用ip、brctl、ovs-vsctl等命令来为Docker容器配置自定义的网桥、网卡、路由等。
使用新建的bri0网桥代替缺省的docker0网桥
bri0网桥与缺省的docker0网桥的区别:bri0和主机eth0之间是veth pair
Webbench MAC下安装
![不指定 不指定](images/weather/blank.gif)
Webbench是有名的网站压力测试工具,它是由 Lionbridge公司开发。
Webbech能测试处在相同硬件上,不同服务的性能以及不同硬件上同一个服务的运行状况。webBech的标准测试可以向我们展示服务器的两项内容:每秒钟相应请求数和每秒钟传输数据量。webbench不但能具有便准静态页面的测试能力,还能对动态页面(ASP,PHP,Java,CGI)进 行测试的能力。还有就是他支持对含有SSL的安全网站例如电子商务网站进行静态或动态的性能测试。
安装: Make install 需 sudo 权限, 需要写入 /usr/local/bin
- brew install ctags # 依赖安装
- curl -o webbench.tar.gz http://blog.zyan.cc/soft/linux/webbench/webbench-1.5.tar.gz
- tar -zxvf webbench-1.5.tar.gz
- cd webbench-1.5/
- mkdir -pv /usr/local/man/man1 # 关键
- sudo make && sudo make install # sudo 权限因为需要创建文件夹
Mac下自带apache压力测试:
- localhost:webbench-1.5 jesse$ webbench -c 500 -t 120 http://localhost/
- Webbench - Simple Web Benchmark 1.5
- Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
- Benchmarking: GET http://localhost/
- 500 clients, running 120 sec.
- Speed=33001 pages/min, 696314 bytes/sec.
- Requests: 64078 susceed, 1924 failed.
- localhost:webbench-1.5 jesse$
实例化php类的时候如何传参
![不指定 不指定](images/weather/blank.gif)
当我们实例化一个php类的时候,要怎么传递参数呢?这取决于该类的构造方法。
例:
person.class.php
class person{
var $name;
var $color;
var $sex;
var $age;
function __construct($name,$age='',$sex='boy'){
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
$this->color = 'yello';
}
function eat(){
echo $this->name.'要吃饭';
}
function xinxi(){
echo $this->name.' is '.$this->sex.' and age is '.$this->age.' fuse is '.$this->color;
}
}
?>
son.php
include('person.class.php');
$son = new person('cuihua',25,'girl');//此处的参数传递要和类的构造方法里面的参数顺序对应
//$son->xinxi();//cuihua is girl and age is 25 fuse is yello
$son->name = '田妞';
$son->eat();//田妞要吃饭
?>
搞定 koa 之generator 与 co
![不指定 不指定](images/weather/blank.gif)
koa 是由 tj大神利用 generator 开发的 web 框架。要理解 koa,首先要先了解 generator 与 co。作为搞定 koa 的第一篇,我们便谈谈这个。文章首发在boke.io
generator介绍
function* Gene(){
yield 1;
yield 2;
}
var gene = Gene();
console.log(gene.next());//{ value: 1, done: false }
console.log(gene.next());//{ value: 2, done: false }
console.log(gene.next());//{ value: undefined, done: true }
console.log(gene.next());//Error: Generator has already finished 经@Ralph-Wang提醒从 v0.11.13 开始不抛错了,返回{ value: undefined, done: true }
从上面我们可以看到
generator 的定义和函数类似,只是在 function 后面多了一个*
调用generator 和调用函数一样,只是不像函数立即执行,而是会生成一个对象
generator 生成的对象存在一个 next 函数,调用 next 会返回 yield运算的结果对象,并停止。再次调用会在下一个 yield 处停止。
当所有的 yield 被执行完,调用 next 函数会返回{ value: undefined, done: true }。再次调用会报错
generator 与异步
看完 generator 的介绍,你心里回想这跟异步有毛关系?不着急听我接着说
串行请求两个网页的代码
var request = require('request');
var a = {};
var b = {};
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
a.response = response;
a.body = body;
request('http://www.yahoo.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
b.response = response;
b.body = body;
}
});
}
});
我们再看看最终我们是如何利用 generator请求网页的
co(function *(){
var a = yield request('http://google.com');
var b = yield request('http://yahoo.com');
console.log(a[0].statusCode);
console.log(b[0].statusCode);
})()
上面的代码可以看到,co 里面传入了一个 generator,里面用 yield 调用异步函数。从逻辑上看,里面的异步被变成了同步。
co 到底有什么魔法?可以把我们从异步中解救出来?
想想 generator 的特性,当我们执行第一个 next 的时候,会调用第一个 request,此时我们去调用 request 的逻辑,然后把 generator 的实例穿进去。当第一个 request 逻辑完成时,在调用这个 generator 的 next,这样就到了第二个 yield 的逻辑了。当然这需要一些逻辑的封装,也就是 co 了。
根据上面的分析,我们大概可以写出下面的代码
function co(Gene){
//先实例化一下
var gene = Gene();
//如果存在 next 函数
if(gene.next){
var fun = gene.next();//把异步函数返回过来,好继续封装
//fun 处理完,再调用 gene.next()
//...
}
}
从上面的代码可以看出
yield 后面的内容需要返回一个异步函数,这样我们才可进一步封装异步处理的逻辑。
fun 需要可以传入参数,这样才可以处理多个异步
需要一个递归调用,这样才可以持续调用 next,同时根据 next 返回对象中的done属性停止逻辑
需要考虑错误处理
今天就到这里,下一篇详细讲一下 co 的源码
co最简版实现,学习generator & co
![不指定 不指定](images/weather/blank.gif)
看了co的源码 比较难懂 了解了其原理后实现了一个最简版本https://github.com/yucong/simple-co 希望对想学习的tx有帮助~ yeild后面只支持thunk,co本身也是一个thunk
核心代码:
function co(generator) {
return function(fn) {
var gen = generator();
function next(err, result) {
if(err){
return fn(err);
}
var step = gen.next(result);
if (!step.done) {
step.value(next);
} else {
fn(null, step.value);
}
}
next();
}
}
用法:
var co = require('./co');
// wrap the function to thunk
function readFile(filename) {
return function(callback) {
require('fs').readFile(filename, 'utf8', callback);
};
}
co(function * () {
var file1 = yield readFile('./file/a.txt');
var file2 = yield readFile('./file/b.txt');
console.log(file1);
console.log(file2);
return 'done';
})(function(err, result) {
console.log(result)
});
会打印出:
content in a.txt
content in b.txt
done
================================
generator_co: http://liuxinxiu.com/generator_co/
js 判断各种数据类型
![不指定 不指定](images/weather/blank.gif)
了解js的都知道, 有个typeof 用来判断各种数据类型,有两种写法:typeof xxx ,typeof(xxx)
如下实例:
typeof 2 输出 number
typeof null 输出 object
typeof {} 输出 object
typeof [] 输出 object
typeof (function(){}) 输出 function
typeof undefined 输出 undefined
typeof '222' 输出 string
typeof true 输出 boolean
这里面包含了js里面的五种数据类型 number string boolean undefined object和函数类型 function
看到这里你肯定会问了:我怎么去区分对象,数组和null呢?
接下来我们就用到另外一个利器:Object.prototype.toString.call
这是对象的一个原生原型扩展函数,用来更精确的区分数据类型。
我们来试试这个玩儿意儿:
var gettype=Object.prototype.toString
gettype.call('aaaa') 输出 [object String]
gettype.call(2222) 输出 [object Number]
gettype.call(true) 输出 [object Boolean]
gettype.call(undefined) 输出 [object Undefined]
gettype.call(null) 输出 [object Null]
gettype.call({}) 输出 [object Object]
gettype.call([]) 输出 [object Array]
gettype.call(function(){}) 输出 [object Function]
看到这里,刚才的问题我们解决了。
其实js 里面还有好多类型判断 [object HTMLDivElement] div 对象 , [object HTMLBodyElement] body 对象 ,[object Document](IE)或者 [object HTMLDocument](firefox,google) ......各种dom节点的判断,这些东西在我们写插件的时候都会用到。
可以封装的方法如下 :
var gettype=Object.prototype.toString
var utility={
isObj:function(o){
return gettype.call(o)=="[object Object]";
},
isArray:function(o){
return gettype.call(o)=="[object Array]";
},
isNULL:function(o){
return gettype.call(o)=="[object Null]";
},
isDocument:function(){
return gettype.call(o)=="[object Document]"|| [object HTMLDocument];
}
........
}
Redis 未授权访问缺陷可轻易导致系统被黑
![不指定 不指定](images/weather/blank.gif)
注:近日曝出大规模利用 Redis 漏洞进行入侵的事件,会给用户的 Redis 运行环境以及 Linux 主机造成安全风险。若用户的Linux服务器中安装了Redis并对公网开放了Redis端口,则可能导致Redis数据丢失,服务器则存在被植入公钥用于SSH远程登录的风险。
关于Redis
Redis是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类keyvalue存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。
容易遭受入侵的环境
用户自建的运行了 Redis 服务的 Linux 主机,依root身份运行Redis服务,并在公网上开放了 6379 的 Redis 端口。
入侵现象
1)Redis 可能被执行过 flushall 命令
2)Redis 内建了名为 crackit 的 key
3)Redis 的 dir 参数指向了 /root/.ssh
4)/root/.ssh/authorized_keys 被覆盖或者包含 Redis 相关的内容
修复办法
5)以非 root 权限启动 Redis
6)增加 Redis 密码验证
7)禁止公网开放 Redis 端口, 例如可以在青云防火墙上禁用 6379 Redis 的端口
8)检查 authorized_keys 是否非法
详细内容请看下文:
漏洞概要
Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将Redis服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。
漏洞描述
Redis 安全模型的观念是: “请不要将Redis暴露在公开网络中, 因为让不受信任的客户接触到Redis是非常危险的” 。
Redis 作者之所以放弃解决未授权访问导致的不安全性是因为, 99.99%使用Redis的场景都是在沙盒化的环境中, 为了0.01%的可能性增加安全规则的同时也增加了复杂性, 虽然这个问题的并不是不能解决的, 但是这在他的设计哲学中仍是不划算的。
因为其他受信任用户需要使用Redis或者因为运维人员的疏忽等原因,部分Redis 绑定在0.0.0.0:6379,并且没有开启认证(这是Redis的默认配置),如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源ip访问等,将会导致Redis服务直接暴露在公网上,导致其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。
利用Redis自身的相关方法,可以进行写文件操作,攻击者可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。
漏洞影响
Redis 暴露在公网(即绑定在0.0.0.0:6379,目标IP公网可访问),并且没有开启相关认证和添加相关安全策略情况下可受影响而导致被利用。
通过ZoomEye 的搜索结果显示,有97700在公网可以直接访问的Redis服务。
根据 ZoomEye 最新于2015年11月12日0点探测结果显示:
总的存在无验证可直接利用 Redis 服务的目标全球有49099,其中中国有16477。其中被明着写入crackit的,也就是已经被黑的比例分别是全球65%(3.1万),中国67.5%(1.1万)。
1.1. 漏洞分析与利用
首先在本地生产公私钥文件:
- ? 1 $ssh-keygen –t rsa
然后将公钥写入foo.txt文件
- ? 1 $ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo.txt
再连接Redis写入文件
这样就可以成功的将自己的公钥写入/root/.ssh文件夹的authotrized_keys文件里,然后攻击者直接执行:
- ? 1 $ ssh –i id_rsa root@192.168.1.11
即可远程利用自己的私钥登录该服务器。
当然,写入的目录不限于/root/.ssh 下的authorized_keys,也可以写入用户目录,不过Redis很多以root权限运行,所以写入root目录下,可以跳过猜用户的步骤。
Redis 未授权的其他危害与利用
数据库数据泄露
Redis 作为数据库,保存着各种各样的数据,如果存在未授权访问的情况,将会导致数据的泄露,其中包含保存的用户信息等
代码执行
Redis可以嵌套Lua脚本的特性将会导致代码执行, 危害同其他服务器端的代码执行, 样例如下
一旦攻击者能够在服务器端执行任意代码, 攻击方式将会变得多且复杂, 这是非常危险的.
通过Lua代码攻击者可以调用 redis.sha1hex() 函数,恶意利用 Redis 服务器进行 SHA-1 的破解。
敏感信息泄露
通过 Redis 的 INFO 命令, 可以查看服务器相关的参数和敏感信息, 为攻击者的后续渗透做铺垫
可以看到泄露了很多 Redis 服务器的信息, 有当前 Redis 版本, 内存运行状态, 服务端个数等等敏感信息。
全球无验证可直接利用 Redis 分布情况
Linux-以指定用户运行redis
![不指定 不指定](images/weather/blank.gif)
redis中无配置启动用户信息,需要添加redis用户,后以其启动(1):
useradd -s /bash/false -M redis sudo -u redis /xxx/redis-server /xxx/etc/redis.conf >/dev/null 2>&1 &
以Linux下指定sun用户在linux开机时执行/home/sun/startrun.sh为例:
/bin/false和/sbin/nologin的区别
![不指定 不指定](images/weather/blank.gif)
不会有任何提示,用户切换不过去