docker启动服务时,输出PHP 慢日志 ERROR: failed to ptrace(ATTACH) child 24: Operation not permitted (1)

1.错误说明 

当使用docker-compose启动容器后,通过浏览器访问服务器,发现一直转圈,通过php-fpm slow慢日志查看,发现如下错误:

[31-May-2023 12:02:34] ERROR: failed to ptrace(ATTACH) child 12: Operation not permitted (1)
[31-May-2023 12:02:34] WARNING: [pool www] child 12, script '/www/index.php' (request: "GET /index.php") executing too slow (5.021099 sec), logging

2.错误原因 

这是因为Docker容器权限问题

在docker中部署的php容器默认是不能记录慢日志的;

        在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容器中默认是不启用这个功能的,因此导致了问题

3.解决办法

在容器启动时,加入参数--cap-add SYS_PTRACE即可

(1).通过–security-opt seccomp=unconfined命令

简单暴力(不推荐),直接关闭 seccomp 配置,用法:

docker run --security-opt seccomp:unconfined ...

(2).启动docker时加上 –cap-add=SYS_PTRACE

使用 --cap-add 明确添加指定功能:

docker run --cap-add=SYS_PTRACE ...

(3). 在Docker Compose中的解决方式

Docker Compose 自 version 1.1.0 (2015-02-25) 起支持 cap_add,官方文档:cap_add, cap_drop.在docker-compose.yml用法:

version: "3"

services:
    nginx:
        build: ./nginx/
        ports:
            - 80:80
        volumes:
            - "${PROJECT_ROOT}:/var/www"
            - "${VHOST_ROOT}:/etc/nginx/conf.d"
        networks:
            - server
        depends_on:
            - php
        cap_add:
          - SYS_PTRACE
    php:
        build: ./php-fpm/
        expose:
            - 9000
        volumes:
            - "${PROJECT_ROOT}:/var/www"
            - "/etc/crontab:/etc/crontab"
        links:
            - redis
#            - sphinx
            - mysql
            - mongo
        networks:
            - server
        cap_add:
          - SYS_PTRACE
#    sphinx:
#        build: ./sphinx/
#        ports:
#            - 9312:9312
#        networks:
#            - server

    redis:
        build: ./redis/
        ports:
            - 6379:6379
        networks:
            - server
    mysql:
        build: ./mysql
        ports:
            - 3306:3306
        volumes:
            - ./mysql/conf:/etc/mysql/conf.d
            - ./mysql/data:/var/lib/mysql
        restart: always
        networks:
            - server
        environment:
            MYSQL_ROOT_PASSWORD: 123456
            MYSQL_USER: user
            MYSQL_PASSWORD: 123456

    rabbitmq:
        hostname: rabbit01
        environment:
            RABBITMQ_DEFAULT_VHOST: "/"
            RABBITMQ_DEFAULT_USER: "user"
            RABBITMQ_DEFAULT_PASS: "123456"
            TZ: 'Asia/Shanghai'
            RABBITMQ_ERLANG_COOKIE: 'rabbitmqCookie'
        image: "rabbitmq:3.7.16-management"
        restart: always
        networks:
            - server
        volumes:
        - "./rabbitmq:/var/lib/rabbitmq"
        - "./rabbitmq/log:/var/log/rabbitmq/log"
        ports:
        - "15672:15672"
        - "4369:4369"
        - "5672:5672"
        - "25672:25672"

    mongo:
        build:
            context: ./mongo
        ports:
            - "27017:27017"
        #container_name: mongo
        environment:
            AUTH: "yes"
            MONGO_INITDB_ROOT_USERNAME: root
            MONGO_INITDB_ROOT_PASSWORD: 123456
        volumes: #数据卷映射
            - /mongo/mongod.conf:/etc/mongod.conf  #这里做配置文件的映射,想通过配置文件开启数据库的权限验证,但好像没有效果,后面在研究下
            - /mongo/data:/data/db
            - /mongo/logs/:/var/log/mongodb
        #command: mongodb
        restart: always
        privileged: true
        networks:
            - server

    #mongodb可视化工具:部署完后,需开放对应端口号
    mongo-express:
        image: mongo-express
        restart: always
        links:
            - mongo
        depends_on:
            - mongo
        ports:
            - "28017:8081"
        networks:
            - server
        environment:
            #注意: 冒号后面需要有对应的空格,不然docker-compose安装会报错,fuck!
            ME_CONFIG_MONGODB_ADMINUSERNAME: root
            ME_CONFIG_MONGODB_ADMINPASSWORD: 123456
            ME_CONFIG_BASICAUTH_USERNAME: root
            ME_CONFIG_BASICAUTH_PASSWORD: b123456
            ME_CONFIG_MONGODB_URL: mongodb://root:123456@mongo:27017/


networks:
    server:

好了,问题解决

但是在这里还需要注意一点:在 docker-compose.yml中加入cap_add配置时,注意空格的处理,不然启动docker-compose时会报下面错误:

ERROR: yaml.parser.ParserError: while parsing a block mapping   in "./docker-compose.yml", line 1, column 1 expected <block end>, but found '<block mapping start>'   in "./docker-compose.yml", line 31, column 7

错误原因:空格导致的未对齐(严格意义上的对齐)
解决方案:对应位置line 31, column 7添加或者删除空格,使得同一层的保持对齐,在这里建议先在编辑器中编辑docker-compose.yml后再传到服务器中

猜你喜欢

转载自blog.csdn.net/zhoupenghui168/article/details/132090741