docker 中进行strace的三种方式

拉取nginx镜像启动容器

root@php56:/home/tb# docker pull nginx:alpine
root@php56:/home/tb# docker run -t -d --privileged -h nginxtest --name nginx-test -p 8080:80 nginx:alpine
045a04431e9982ddab0c05331057b8571b73fc1b740f04c79f73501c901fa85b`
root@php56:/home/tb# curl http://localhost:8080

查看宿主机8080端口及docker内nginx进程

root@php56:/home/tb# netstat -anp|grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      13893/docker-proxy
root@php56:/home/tb# docker exec nginx-test ps -ef| grep nginx
    1 root      0:00 nginx: master process nginx -g daemon off;
    6 nginx     0:00 nginx: worker process
root@php56:/home/tb# 

方法1:容器内安装apk --update add strace

root@php56:/home/tb# docker exec -uroot -it nginx-test /bin/bash 
OCI runtime exec failed: exec failed: container_linux.go:345: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown
root@php56:/home/tb# docker exec -uroot -it nginx-test sh
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # apk --update add strace
fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz
(1/1) Installing strace (4.26-r0)
Executing busybox-1.30.1-r2.trigger
OK: 29 MiB in 38 packages
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 nginx: master process nginx -g daemon off;
    6 nginx     0:00 nginx: worker process
   17 root      0:00 sh
   43 root      0:00 ps
/ # strace -p 6
strace: Process 6 attached
epoll_pwait(8, 

这时候可以curl 8080端口,即可strace到下面数据(顺便说下strace的-T -e -C选项~)

/ # strace -cp 6
strace: Process 6 attached
^Cstrace: Process 6 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         8           write
  0.00    0.000000           0         8           open
  0.00    0.000000           0        16           close
  0.00    0.000000           0         8           stat
  0.00    0.000000           0         8           fstat
  0.00    0.000000           0         8           writev
  0.00    0.000000           0         8           sendfile
  0.00    0.000000           0        16           recvfrom
  0.00    0.000000           0         8           setsockopt
  0.00    0.000000           0         8           epoll_ctl
  0.00    0.000000           0        24           epoll_pwait
  0.00    0.000000           0         8           accept4
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                   128           total

/ # strace -e writev -p 6
strace: Process 6 attached
writev(3, [{iov_base="HTTP/1.1 200 OK\r\nServer: nginx/1"..., iov_len=238}], 1) = 238

方法2:在宿主机内strace

# 为了看着简洁,我们把本机的nginx先停掉
root@php56:/home/tb# service nginx stop
root@php56:/home/tb# ps -aux |grep nginx
root     13916  0.0  0.3   5940  3508 pts/0    Ss+  11:19   0:00 nginx: master process nginx -g daemon off;
systemd+ 13960  0.0  0.1   6380  1844 pts/0    S+   11:19   0:00 nginx: worker process
root     14074  0.0  4.8 270912 49592 pts/0    Sl+  11:29   0:00 docker exec -uroot -it nginx-test sh
root     15135  0.0  0.0  12948   968 pts/1    S+   16:26   0:00 grep --color=auto nginx
# 保持和方法一的命令一样,此结果需要另外开一个命令行窗口执行`curl http://localhost:8080`
root@php56:/home/tb# strace  -e writev -p 13960
strace: Process 13960 attached
writev(3, [{"HTTP/1.1 200 OK\r\nServer: nginx/1"..., 238}], 1) = 238

方法3:用一个额外容器单独strace

  1. 先自己构建一个简单的Dockerfile,然后build一个基于alpine的strace命令的镜像。这里为了描述简单,只是将命令固定写为CMD ["strace","-p","6"](因为我们要strace的另一个容器的pid就是为6),后期可以利用compose 将参数动态的传入到cmd命令中。

    root@php56:/home/tb# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    nginx               alpine              a624d888d69f        5 weeks ago         21.5MB
    hyperf/hyperf       7.2-alpine-cli      10763d2393ce        5 months ago        72.7MB
    root@php56:/home/tb# cat > Dockerfile << EOF
    > FROM alpine
    > RUN apk update && apk add strace
    > CMD ["strace","-p","6"]
    > EOF
    root@php56:/home/tb# docker build -t strace .
    Sending build context to Docker daemon  161.6MB
    Step 1/3 : FROM alpine
    latest: Pulling from library/alpine
    e6b0cf9c0882: Pull complete 
    Digest: sha256:2171658620155679240babee0a7714f6509fae66898db422ad803b951257db78
    Status: Downloaded newer image for alpine:latest
    ---> cc0abc535e36
    Step 2/3 : RUN apk update && apk add strace
    ---> Running in 0c8ab5da7a28
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
    v3.11.2-11-gd5cdcefa20 [http://dl-cdn.alpinelinux.org/alpine/v3.11/main]
    v3.11.2-13-gf1c4a19ed9 [http://dl-cdn.alpinelinux.org/alpine/v3.11/community]
    OK: 11261 distinct packages available
    (1/1) Installing strace (5.3-r1)
    Executing busybox-1.31.1-r8.trigger
    OK: 7 MiB in 15 packages
    Removing intermediate container 0c8ab5da7a28
    ---> 6de4ef1b4157
    Step 3/3 : CMD ["strace","-p","6"]
    ---> Running in b2446e191f9e
    Removing intermediate container b2446e191f9e
    ---> 60691d8a2571
    Successfully built 60691d8a2571
    Successfully tagged strace:latest
    root@php56:/home/tb# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    strace              latest              60691d8a2571        14 seconds ago      8.51MB
    alpine              latest              cc0abc535e36        2 days ago          5.59MB
    nginx               alpine              a624d888d69f        5 weeks ago         21.5MB
    hyperf/hyperf       7.2-alpine-cli      10763d2393ce        5 months ago        72.7MB
  2. 启动基于strace镜像的容器,并同时配置一些权限(否则会报Permission denied)

    
    root@php56:/home/tb# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    84f853fa7d36        strace              "strace -p 6"            4 minutes ago       Up 4 minutes                               strace-test
    045a04431e99        nginx:alpine        "nginx -g 'daemon of…"   7 hours ago         Up 7 hours          0.0.0.0:8080->80/tcp   nginx-test
    root@php56:/home/tb# docker run -it   --name strace-test --pid=container:nginx-test --net=container:nginx-test --cap-add sys_admin --cap-add SYS_PTRACE  --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined strace
    strace: Process 6 attached
    epoll_pwait(8, 

todo:在3的方法上动态构建

  1. 改写dockerfile

    root@php56:/home/tb# cat Dockerfile 
    FROM alpine
    RUN apk update && apk add strace
    ARG envType=dev
    ARG pect=-p
    ARG pid=6
    ENV envType ${envType}
    ENV pect ${pect}
    ENV pid ${pid}
    # CMD ["strace","-p","6"] 数组方式的cmd,是用来运行命令,不支持参数替换
    CMD strace ${pect} ${pid}
    # 为了测试输出
    RUN file= "strace ${pect} ${pid}" && echo $file
    
  2. build,strace -cp 13960为动态传入参数

    root@php56:/home/tb# docker build --build-arg envType=pro --build-arg pect="-cp" --build-arg pid=13960  -t strace_dynamic .
    Sending build context to Docker daemon  216.6MB
    Step 1/10 : FROM alpine
     ---> cc0abc535e36
    Step 2/10 : RUN apk update && apk add strace
     ---> Using cache
     ---> 6de4ef1b4157
    Step 3/10 : ARG envType=dev
     ---> Using cache
     ---> d7b1410dfdbc
    Step 4/10 : ARG pect=-p
     ---> Using cache
     ---> 8ef9ba050011
    Step 5/10 : ARG pid=6
     ---> Using cache
     ---> 1bcf37e6e7c7
    Step 6/10 : ENV envType ${envType}
     ---> Using cache
     ---> c448b51323b7
    Step 7/10 : ENV pect ${pect}
     ---> Using cache
     ---> d25052bc5741
    Step 8/10 : ENV pid ${pid}
     ---> Running in f756fb16acdb
    Removing intermediate container f756fb16acdb
     ---> f0bfef6f4afd
    Step 9/10 : CMD strace ${pect} ${pid}
     ---> Running in 4c81a6d743ef
    Removing intermediate container 4c81a6d743ef
     ---> 93484d2bcbcd
    Step 10/10 : RUN file= "strace ${pect} ${pid}" && echo $file
     ---> Running in 561514dda683
    /bin/sh: strace -cp 13960: not found
    The command '/bin/sh -c file= "strace ${pect} ${pid}" && echo $file' returned a non-zero code: 127
    
  3. tips删除none镜像

    docker rmi -f$(docker images | ``grep` `"none"` `| ``awk'{print $3}'``)
  4. 失败。怎么像类似方法3那样传呢

    root@php56:/home/tb# docker run -it  --name strace-test-dynamic --pid=container:nginx-test --net=container:nginx-test --cap-add sys_admin --cap-add SYS_PTRACE  --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined  strace_dynamic
    strace: must have PROG [ARGS] or -p PID
    Try 'strace -h' for more information.
    root@php56:/home/tb# docker run -it  --name strace-test-dynamic --pid=container:nginx-test --net=container:nginx-test --cap-add sys_admin --cap-add SYS_PTRACE  --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined  strace_dynamic
    docker: Error response from daemon: Conflict. The container name "/strace-test-dynamic" is already in use by container "c4656ef188a4d1b5ca92ab44981dfaf49e821ad7afa82a43738985d9b7b5ccbb". You have to remove (or rename) that container to be able to reuse that name.
    See 'docker run --help'.
    root@php56:/home/tb# 
    

翻译自

你可能感兴趣的:(docker,strace)