Docker容器——网络模式和Cgroup资源限制

一、Docker网络

(1)Docker网络实现原理

Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP直接通信。

Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过Container-IP访问到容器。如果容器希望外部网络能够访问到,可以通过映射容器端口到宿主主机(端口映射),

即docker run创建容器时候通过-p或-P参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

docker run -d --name cwk -P nginx:latest				#随机映射端口(从32768开始)
docker run -d --name zzr -p 1314:80(宿主机端口:容器端口) nginx:latest		#指定映射端口(将容器的80端口映射为宿主机的1314端口)
docker ps -a

-P随机生出映射端口 

浏览器输入:192.168.10.21:32769 即可访问页面

-p指定映射端口

浏览器输入:192.168.10.21:1314/即可访问页面

用iptables命令可以查看映射转化

查看容器的输出和日志信息

docker logs 容器的ID/名称

二、Docker 的网络模式

  • Host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口范围(不能使用相同的端口)。
  • Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围(不能使用相同的端口)。
  • None:该模式关闭了容器的网络功能。
  • Bridge:默认为该模式,此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及iptables nat 表配置与宿主机通信。
  • 自定义网络

安装Docker时,它会自动创建三个网络:bridge(创建容器默认连接到此网络)、 none 、host

查看docker列表的网络模式

docker network ls	
docker network list			

使用docker run创建Docker容器时,可以用- -net或- -network选项指定容器的网络模式

(1)网络模式详解

1)host模式

相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。 但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。

语法格式:docker run -d --network=host 镜像名:标签
<
### 如何查看或获取 Docker 容器的 ID #### 方法一:通过 `docker ps` `docker ps -a` 命令 可以通过执行 `docker ps` 或者 `docker ps -a` 来查看容器的相关信息,其中包括容器的 ID。 - 使用 `docker ps` 可以仅列出当前正在运行的容器及其详细信息,包括容器 ID、镜像名称、启动命令、创建时间状态等[^2]。 - 如果希望查看所有容器(无论是运行中还是已停止),则可以使用 `docker ps -a` 命令。 以下是示例输出: ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES abcdef123456 nginx:latest "nginx -g 'daemon ..." 5 minutes ago Up 5 minutes 80/tcp my-nginx-container 123456abcdef mysql:latest "docker-entrypoint..." 2 hours ago Up 2 hours 3306/tcp my-mysql-container ``` 在该输出中,“CONTAINER ID” 列即为容器的唯一标识符。 --- #### 方法二:通过 Python 获取容器 ID 如果希望通过编程方式获取容器 ID,可以利用 Python 的 `subprocess` 模块来调用 Linux Shell 命令并解析返回的结果。以下是一个具体的实现方法: ```python import subprocess def get_container_ids(): """ 获取所有 Docker 容器的 ID(包括运行中已停止的) :return: list[str], 所有容器的 ID 列表 """ result = subprocess.run(["docker", "ps", "-aq"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) if result.returncode != 0: raise RuntimeError(f"Error occurred while fetching container IDs: {result.stderr}") ids = result.stdout.strip().split("\n") return ids if __name__ == "__main__": container_ids = get_container_ids() print("Container IDs:", container_ids) ``` 此脚本的核心逻辑如下: - 使用 `subprocess.run` 调用 `docker ps -aq` 命令,其中 `-q` 参数表示只返回容器 ID[^3]。 - 解析标准输出并将结果按行分割成列表形式。 --- #### 方法三:从容器内部获取宿主机分配给它的 ID 当进入某个容器后,也可以通过读取 `/proc/self/cgroup` 文件的内容提取容器 ID。这种方法适用于需要从容器内部动态获取其自身的 ID 场景。 具体实现代码如下所示: ```python import subprocess def get_current_container_id_inside(): """ 在容器内部运行时,获取当前容器的 ID :return: str, 当前容器的 ID """ command = "cat /proc/self/cgroup | grep '/docker/' | head -n 1 | awk -F'/' '{print $NF}'" process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = process.communicate() if process.returncode != 0 or not output.strip(): raise ValueError(f"Failed to retrieve the current container's ID. Error: {error.decode('utf-8').strip()}") return output.decode('utf-8').strip() # 测试函数 try: cid = get_current_container_id_inside() print(f"The current container ID is: {cid}") except Exception as e: print(e) ``` 上述代码片段解释了如何通过分析 cgroups 配置文件定位到容器对应的 UUID[^3]。 --- ### 总结 以上介绍了三种不同的途径来查询或者捕获 Docker 容器的唯一识别码——ID。每种方案都有各自的适用场景以及优缺点,在实际应用过程中可以根据需求灵活选用合适的工具技术手段完成任务目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值