一、docker中php容器默认不会追写php的慢日志问题及Linux capabilities
在docker中部署的php容器默认是不能记录慢日志的,如下我们在PHP的配置文件中添加好了慢日志的配置slowlog的文件地址以及request_slowlog_timeout的阈值,运行PHP容器时也能生成www.log.slow慢日志文件,但你会发现这个文件大小一直是0,好像从来没有慢程序。但如果把阈值设为1秒,它仍不会有慢日志产生时,于是你就会开始怀疑这个docker下的php有问题吧?是的,真有问题。
; Note: slowlog is mandatory if request_slowlog_timeout is set
slowlog = /var/log/php/$pool.log.slow
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) Default Value: 0
request_slowlog_timeout = 5
在Linux系统中,PHP-FPM使用SYS_PTRACE跟踪worker进程,SYS_PTRACE是什么?这是Linux capabilities里的一种操作特权?Linux capabilities 是什么?linux从内核2.2开始,将传统上与超级用户root关联的特权划分为不同的单元,称为capabilites。Capabilites 作为线程(Linux 并不真正区分进程和线程)的属性存在,每个单元可以独立启用和禁用。如此一来,权限检查的过程就变成了:在执行特权操作时,如果进程的有效身份不是 root,就去检查是否具有该特权操作所对应的capabilites,并以此决定是否可以进行该特权操作。所以在docker容器中php写慢日志就得有CAP_KILL capability ,设置系统时间,就得具有 capability CAP_SYS_TIME。docker容器中默认是不启用这个功能的,因此导致了问题。
解决办法:在docker启动的时候加上选项--cap-add=SYS_PTRACE选项或者--privileged选项:
#docker run 添加选项示例
docker run .. --cap-add=SYS_PTRACE ..
docker run .. --privileged ..
#docker run --help 可以查看这些选项的意义
--cap-add list Add Linux capabilities
--privileged Give extended privileges to this container
#. Linux capabilities列表
capability 名称 描述
CAP_AUDIT_CONTROL 启用和禁用内核审计;改变审计过滤规则;检索审计状态和过滤规则
CAP_AUDIT_READ 允许通过 multicast netlink 套接字读取审计日志
CAP_AUDIT_WRITE 将记录写入内核审计日志
CAP_BLOCK_SUSPEND 使用可以阻止系统挂起的特性
CAP_CHOWN 修改文件所有者的权限
CAP_DAC_OVERRIDE 忽略文件的 DAC 访问限制
CAP_DAC_READ_SEARCH 忽略文件读及目录搜索的 DAC 访问限制
CAP_FOWNER 忽略文件属主 ID 必须和进程用户 ID 相匹配的限制
CAP_FSETID 允许设置文件的 setuid 位
CAP_IPC_LOCK 允许锁定共享内存片段
CAP_IPC_OWNER 忽略 IPC 所有权检查
CAP_KILL 允许对不属于自己的进程发送信号
CAP_LEASE 允许修改文件锁的 FL_LEASE 标志
CAP_LINUX_IMMUTABLE 允许修改文件的 IMMUTABLE 和 APPEND 属性标志
CAP_MAC_ADMIN 允许 MAC 配置或状态更改
CAP_MAC_OVERRIDE 覆盖 MAC(Mandatory Access Control)
CAP_MKNOD 允许使用 mknod() 系统调用
CAP_NET_ADMIN 允许执行网络管理任务
CAP_NET_BIND_SERVICE 允许绑定到小于 1024 的端口
CAP_NET_BROADCAST 允许网络广播和多播访问
CAP_NET_RAW 允许使用原始套接字
CAP_SETGID 允许改变进程的 GID
CAP_SETFCAP 允许为文件设置任意的 capabilities
CAP_SETPCAP 参考 capabilities man page
CAP_SETUID 允许改变进程的 UID
CAP_SYS_ADMIN 允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等
CAP_SYS_BOOT 允许重新启动系统
CAP_SYS_CHROOT 允许使用 chroot() 系统调用
CAP_SYS_MODULE 允许插入和删除内核模块
CAP_SYS_NICE 允许提升优先级及设置其他进程的优先级
CAP_SYS_PACCT 允许执行进程的 BSD 式审计
CAP_SYS_PTRACE 允许跟踪任何进程
CAP_SYS_RAWIO 允许直接访问 /devport、/dev/mem、/dev/kmem 及原始块设备
CAP_SYS_RESOURCE 忽略资源限制
CAP_SYS_TIME 允许改变系统时钟
CAP_SYS_TTY_CONFIG 允许配置 TTY 设备
CAP_SYSLOG 允许使用 syslog() 系统调用
CAP_WAKE_ALARM 允许触发一些能唤醒系统的东西(比如 CLOCK_BOOTTIME_ALARM 计时器)
二、docker中添加PHP配置项php_value, php_flag, php_admin_value, php_admin_flag的区别
docker中添加PHP配置项的方法有不少,php_value、php_flag、php_admin_value、php_admin_flag,如下是一个加载的php配置文件示例。
php_flag[display_errors] = off
php_admin_value[memory_limit] = 512M
php_admin_flag[log_errors] = on
那这些方法有什么区别呢?官方文档的解释如下:
php_value name value
Sets the value of the specified directive. Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives. To clear a previously set value use none as the value. Note: Don’t use php_value to set boolean values. php_flag (see below) should be used instead.
设置指定的值. 只适合于 PHP_INI_ALL 和 PHP_INI_PERDIR 类型指令. 清除之前设置的值使用 none 标记. Note: 不要使用 php_value 设定布尔值和php_flag (见下文) .
php_flag name on|off
Used to set a boolean configuration directive. Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives.
用于设置一个布尔配置指令, 只适合于 PHP_INI_ALL 和 PHP_INI_PERDIR 类型指令(和上面的不同就是 php_value 用于设置值(如字符串),而这只能设置 on off)
php_admin_value name value
Sets the value of the specified directive. This can not be used in .htaccess files. Any directive type set with php_admin_value can not be overridden by .htaccess or virtualhost directives. To clear a previously set value use none as the value.
功能和php_value一样,但这个不能用在 .htaccess 文件里, 只能在conf(包括virtualhost)文件里引用.
php_admin_flag name on|off
Used to set a boolean configuration directive. This can not be used in .htaccess files. Any directive type set with php_admin_flag can not be overridden by .htaccess or virtualhost directives。
同上php_flag和php_value的区别。