docker 之centos7虚拟机

想用docker安装一个centos7虚拟机,类似传统虚拟机那种;但是遇到一个问题,systemctl 启动服务的时候报错如下:

centos7默认使用systemd,其实 /usr/sbin/init 软连接的就是systemd,如果不用这个初始化,则目录: /run/systemd/system/ 是没有的; 也就是说,对于centos7,如果要想当做传统虚拟机来用,则首先要运行systemd进行初始化,而且需要超级权限,如此一来,宿主机将会感觉很不安全,如: 虚拟机可以直接修改宿主机时间。当启动的时候不适用超级权限来执行/usr/sbin/init ,虽然也能执行,但是依然不能使用systemctl来启动服务

结论: 在搞定该问题之前,暂不提供centos7的docker虚拟机

docker 容器资源管理

缘起

想用docker容器来做传统虚拟机的事情,但是从docker的api接口来看,如果限制容器的资源使用情况,需要在创建容器时指定,如: 内存、cpu等;一旦创建,将无法修改。

但是,资源限制本身就是运行时的事情,何故必须在创建时指定而且无法修改呢?比如:我创建一个容器允许使用4G内存,但是过了一段时间,我想将内存限制调整到8G,难道真的不行吗?

docker api似乎真做不到。

我们知道资源限制是通过cgroup实现的,其实可以跳过docker,直接调整cgroup也应该是可以的; 可以通过mount来查看各子系统都mount到哪里了。

如:

修改内存限制:

注意: 1. 如果容器已经使用了4g内存,修改为2g时会失败,错误如下:

2. 把占用内存多的进程先杀掉,让内存使用回归到合理值后,再降低内存配额是可以的

不过,有些东西目前还没发现如何修改,如: hostname

 

docker容器不同于真正的虚拟机,直接使用top、free等命令看到的是整个宿主机的资源使用状况,而无法知道本容器的资源限制和使用情况,可以借助一些监控软件:

http://www.tuicool.com/articles/nuE7b2E

参考资料:

php 之 xhprof

参考资料:http://blog.aboutc.net/profiling/17/php-profiler-xhprof

这里不说别的,只记录一个小有意思的事情:

由于所谓的PHP内存泄漏,在程序跑上几分钟后就耗尽内存而退出,据说xhprof很是厉害,可以分析是哪个函数占用了太多内存;由于xhprof没有现成的环境,配置起来花费了一些功夫,最后发现,是pdo_mysql的execute占用了90%+的内存,天哪,用了N多年的东西突然有问题了?冥思苦想,夜不能寐。

突然间,想到一个其他的办法,就是在每段代码前后添加memory_get_usage()来检查是否内存使用有发生变化,如果没有变化,则这部分代码没有问题;如果有变化,则这部分代码有问题;(注意:如果这部分代码有函数调用,则函数调用不应该有大的返回值,如果有自己看着处理);就这样,通过二分法一步一步排查,终于发现,小朋友为了提高性能,使用类的静态变量数组cache了sql查询的结果,这个cache没有大小限制。

然后回到xhprof分析的结果,可以想象,之所以xhprof认为pdo_mysql的execute有问题,是因为这些内存都是该函数申请的,你说pdo_mysql 冤不冤?

javascript 之文件下载

一般来讲,浏览器中下载文件都是一个链接给浏览器,下载进度有浏览器来显示;比较先进一些的实现就是通过js不断地循环请求服务器端,来获取下载的百分比。

最近发现一个网站(https://mega.nz/#F!nJR3BTjJ!N5wZsncqDkdKyFQLELU1wQ )在下载文件时,并没有立即调出文件保存对话框,而是直接在网页中显示下载进度,直到下载完毕才弹出文件保存对话框,点击保存就完成了。觉得很新鲜,研究了一下,是通过blob实现的; 关于blob的学习:百度: js blob

文亮同学提到了: URL.createObjectURL  ,稍后再研究这个东西

关于VPN的纠结

需求

公司内网需要搭建一个VPN服务,这是一个非常常见的功能性需求;为了安全,要求VPN登录时使用动态口令,这是一个非常合理的非功能性需求。

探索

VPN服务比较多,如: L2TP/PPTP/OPENVPN/SSLVPN 等等; 但是支持动态口令的VPN就找不到了;不过,有些VPN支持pam,如:openvpn; 由于vpn代码比较多,编译也比较麻烦,未敢擅自修改;但是openldap的代码看了下不太复杂,于是,通过修改ldap中的验证逻辑,实现了openvpn + pam_ldap的动态口令验证功能。

突然有一天,发现xx宽带连接公司的vpn总是失败,电话询问xx客服,得知根据国家xxxx规定,xx宽带不允许使用vpn。后来发现,其实也不完全禁止,或许是具体实现封杀的技术问题,有时候还是可以使用openvpn的; 尽管如此,关于无法使用vpn的事情总会发生的,还得想其他办法。

据说shadowsocks很有名气,能否借助这个实现呢?尤其openvpn其实也是走某个指定端口的应用层面的服务;搜了一下,果然有: https://github.com/shadowsocks/shadowsocks/wiki/Connect-to-OpenVPN-over-Shadowsocks (点进去才发现,该项目已被我star多时了)

不过,这个有两个问题:

  1. 对于不懂技术的同事来讲,使用起来有点儿难度,需要配置shadowsocks客户端(如果能写个包装器,把shadowsocks和openvpn包装起来就方便多了)
  2. 如果要shadowsocks到公司内部,也必然要考虑到同样的验证问题,就是:shadowsocks需要支持动态口令; 还好这个修改起来应该不太复杂,应该比修改openldap要简单的多吧!

 

参考资料:

  1. http://hyspace.io/posts/2015/08/22/%E7%BA%AA%E5%BF%B5shadowsocks/
  2. https://ericfu.me/fight-with-greatwall-conclusion/

 

vpn自动安装脚本(配置过程太酸爽)

 

site-to-site vpn : http://ostolc.org/category/vpn.html

PHP 内存管理

 

测试脚本:

 

  1. php每次问系统要内存不是需要多少就要多少,而是最少申请 256KB,这样就有可能有一部分属于申请了,但是没使用;于是php函数memory_get_usage($real)的参数就能理解了; real = true,即:向系统确实申请了多少; real = false 即: php真正用到了多少。
  2. 每次申请系统内存的单位为 256KB,这个在 ./configure:#define SEG_SIZE (256*1024)    中有定义; 也可以通过环境变量ZEND_MM_SEG_SIZE 来设置;需要注意的是,该值必须为2的n次方,如:4096 可以,40960就不可以

安全领域工具

Nmap、Netcat、Hping3

 

在网络安全领域,Nmap、Netcat、Hping3都是安全工程师必备的工具。Nmap主要作为端口扫描器,侦查目标机的端口及服务状态;而Netcat则整合了网络中各种常用功能(如后门、文件传输、端口扫描、端口转发等等),能辅助完成丰富的操作;Hping3主要作为特定的TCPIP数据包产生与解析的工具,当然也可用于Ping操作。

 

参考资料:

  1. http://www.2cto.com/Article/201210/158961.html
  2. nmap使用: http://www.2cto.com/Article/201210/158960.html
  3. hping原理、安装、使用详解介绍: http://blog.itechol.com/space-33-do-blog-id-5772.html
  4. 利用hping3和伪造IP地址执行DOS攻击: http://sec.chinabyte.com/222/13522222.shtml
  5. hping3命令详解: http://man.linuxde.net/hping3

systemtap初体验

写在前面:

systemtap依赖的debuginfo可以从这里(http://debuginfo.centos.org/6/x86_64/)找到,如果幸运的话,你可以直接yum install kernel-debuginfo kernel-debuginfo-common来安装;

不过,正确的安装姿势应该是:

  1. yum update kernel-*      (没有这个将可能出现很多不必要的麻烦)
  2. reboot
  3. yum install systemstap
  4. stap-prep

话说systemtap是一个非常强悍的linux调试工具,但是似乎并不是特别的常用,今天尝试用了一下,确实有一些心得。

安装:

然后就有systap命令了,弄个脚本试试跑跑吧:

有错误了:

大致如上,可能版本号有所差异;好歹有提示,那就照做;不过,可能你确实已经安装了对应版本的kernel-devel; 你们不防rpm -ql kernel-devel 看看安装到哪里了,如果是 /usr/src/kernels/2.6.32-431.el6.x86_64 那么不妨执行:

 

其实可以这样:

该命令可以帮你安装需要的依赖,主要是kernel-devel 和 kernel-debuginfo; 关键是要安装指定的版本,版本错了不行,如果使用的是本地的yum源,可能找不到指定的版本号的包,这样可以修改为使用官方的yum源,这可能是一个比较慢的过程,因为kernel-debuginfo 大小可能超过1G;单从这个来看,该工具的使用成本还是不小的; 也很有可能你配置了debuginfo的yum源,但是没有enable,可以在yum时候临时enable一下,eg:

安装完后再次执行:

果然有hello world输出,再来一个 profile.stp:

使用场景

  1. 看看哪个进程在查询dns
    dns.stp:

参考资料:

关于限速

出于各种需要,经常需要限速

  1. 针对进程限速
  2. 针对ip、port限速
  3. 针对一组进程限速
  4. 模拟低速环境
  5. 程序上实现限速
  6. 针对下载限速
  7. 针对上传限速

真实需求:

调用第三方接口发邮件,经常会有很大的附件,当发送大量这类邮件时,就会将带宽占满。(第三方出口带宽还挺大)

 

限速工具:

  1. tc
    1. tc只能控制发送的速率,不能控制收包的速率(来了就收呗,干嘛要限速)
  2. iptables
  3. iptables + tc
  4. pv (pipe view)
  5. chrome开发者工具直接限速
  6. 程序自身支持限速 ,如:curl
  7. 通过特定编程语言实现
    1. PHP: https://github.com/bandwidth-throttle/bandwidth-throttle  (利用了stream_filter_append )
    2. PHP: https://packagist.org/search/?tags=rate%20limit
    3. Go: https://github.com/juju/ratelimit

通过nginx限速

nginx可以做http代理、tcp代理,而程序上设置代理也都比较方便,如果能在nginx上限速,会比较通用一些,目前发现有2个nginx限速模块:

  1. http://nginx.org/en/docs/http/ngx_http_limit_req_module.html   限制单个IP每秒最大请求数
  2. http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html   限制单个IP每秒最大并发

但是目前还没有一个限制流量的模块

(注:这些模块提供的时间段为‘秒’是不够灵活的,应该允许指定n秒,参考限速方面知识的其他参数)

通过apache限速

apache是一个老牌的web server,模块很多,果然有限速模块:

  1. http://bwmod.sourceforge.net/   这是是实现带宽限制的
  2. http://dembol.org/blog/mod_cband/   这个支持对单个虚拟主机限速,主要用于卖服务的
  3. http://www.zdziarski.com/blog/?page_id=442   这个类似于nginx的那两个模块
  4. http://dominia.org/djao/limitipconn.html 这个只是限制连接数的
  5. http://www.topology.org/src/bwshare/README.html

 

参考: http://serverfault.com/questions/540743/how-to-rate-limit-apache-server-on-ip-basis

注意: 一般来讲,这些模块都是针对下行进行限速,很少对上行也限速的;如果对上行也要限速,则未必好使。对于代理的情况呢?

通过haproxy限速

参考文章: http://blog.serverfault.com/2010/08/26/1016491873/

        haproxy 是代理,不是隧道,如果仅仅作为一个限速的隧道或许还不行

注意:有些限制策略是超过限制就加入黑名单,并且直接返回错误(或许这不是你想要的)

通过squid限速

参考: http://wiki.squid-cache.org/Features/DelayPools

squid.conf 中添加:

测试发现: 这个限速也是针对下行的限速,上行不限速

自定义proxy

goproxy( https://github.com/elazarl/goproxy ) 是一个开发proxy的golang库,在此基础上开发自定义功能的proxy是很方便的

关于iptables限速

  1. 至少两条规则
    1. 允许的速度
    2. 默认的丢弃
  2. 问题
    1. 如果发快了,则系统调用不是被阻塞,而是“Operation not permitted”, 这可能导致进程逻辑异常,尤其是tcp三次握手时候,可能会导致连接失败

其他:

关于phpmailer的发邮件限速:

php 的curl限速:

http://php.net/manual/en/function.curl-setopt.php

CURLOPT_MAX_RECV_SPEED_LARGE

CURLOPT_MAX_SEND_SPEED_LARGE

 

http://m.blog.csdn.net/tianyaleixiaowu/article/details/74942405