有时候容器内没有ifconfig、route等命令,给网络调试带来了很大的困难。我们知道,容器有自已的网络命名空间,所以我们只需要进入到容器的网络命名空间,再利用主机上的命令进行调试就可以了。
接下来给一个例子
## **准备**
1、运行一个容器
```
$ docker run -itd --name nginx nginx:1.16.1
4ac2dc3735d6134112806667745cac916596132655c099499950d9307481166b
```
2、找到容器中PID为1的进程在root命名空间下的PID
```
$ docker inspect -f {{.State.Pid}} nginx
18809
```
我们可以在root命名空间下(即在主机的shell下),查看这个进程的相关信息
```
$ ps -ef | grep 18809
root 18809 18781 0 17:49 pts/0 00:00:00 nginx: master process nginx -g daemon off;
101 18854 18809 0 17:49 pts/0 00:00:00 nginx: worker process
```
3、nsenter命令如下
```
$ nsenter --help
Usage:
nsenter [options] <program> [<argument>...]
Run a program with namespaces of other processes.
Options:
-t, --target <pid> target process to get namespaces from
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
-U, --user[=<file>] enter user namespace
-S, --setuid <uid> set uid in entered namespace
-G, --setgid <gid> set gid in entered namespace
--preserve-credentials do not touch uids or gids
-r, --root[=<dir>] set the root directory
-w, --wd[=<dir>] set the working directory
-F, --no-fork do not fork before exec'ing <program>
-Z, --follow-context set SELinux context according to --target PID
```
## **进入网络命名空间**
进入到PID为18809这个进程的网络命名空间
```
$ nsenter -t 18809 -n
```
然后,查看网络命名空间下的相关资源:网卡应该是容器内看到的网卡
```
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 28 bytes 2152 (2.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
```
## **进入PID命名空间**
先执行exit命令从上面的网络命名空间退出来,然后执行以下命令进行到PID命令空间
```
$ nsenter -t 18809 -p
```
我们查看PID命名空间下的相关资源,这里看到的进程应该只有容器内的进程
```
$ ps
PID TTY TIME CMD
14377 pts/0 00:00:01 bash
18809 pts/0 00:00:00 nginx
52630 pts/0 00:00:00 nsenter
52631 pts/0 00:00:00 bash
52646 pts/0 00:00:00 ps
```
上面有点奇怪的是,PID没有显示为1,而且执行`ps -ef`的话,会看到很多主机上很多其他的进程,暂时未明白原因
## **进入mount命名空间**
先执行exit命令从上面的PID命名空间退出来,然后执行以下命令进行到mount命令空间
```
$ nsenter -t 18809 -m
```
然后我们ls发现,看到是的容器里面的文件,查看`/etc/hostname`就是容器ID的前几位(就是docker ps看到的容器ID)
```
$ cat /etc/hostname
4ac2dc3735d6
```
- 安装
- 在线安装
- 离线安装
- 下载镜像
- 下载DockerHub镜像
- 下载Google镜像
- 阿里云镜像中心
- 下载ARM镜像
- 容器命名空间
- Linux命名空间概述
- 根据PID快速定位到容器
- 进入到容器的命名空间
- Dockerfile
- 基本语法
- 前台运行
- 镜像存储
- 本地存储
- Registry中的存储
- 如何判断两个镜像是否是同一个
- Registry
- Notification
- Auth
- 基本原理
- Token认证的设计
- API
- Pull镜像
- Push镜像
- Docker设置代理
- 日志
- 磁盘占用与清理
- Docker选项与K8S的Yaml
- 运维总结
- 常用命令
- DockerCompose
- 构建ARM版本
- 跨架构
- x86架构下构建arm64镜像
- Containerd
- ctr-crictl-nerdctl
- ctr
- Insecure-Registry
- Kata
- 构建OS镜像
- 进入到kata虚机