docker 容器网络接口映射

docker 默认 bridge

排查容器网络问题笔记

 

怎样根据容器名称找到接口

方法一:

ip addr | grep -A 1 "^$(docker exec <容器名称或ID> cat /sys/class/net/eth0/iflink):"

方案2

#!/bin/bash

get_veth_by_container() {
    cname="$1"
    if [ -z "$cname" ]; then
        echo "用法: $0 <容器名>"
        return 1
    fi

    # 获取容器 PID
    pid=$(docker inspect -f '{{.State.Pid}}' "$cname" 2>/dev/null)
    if [ -z "$pid" ]; then
        echo "容器 $cname 不存在或未运行"
        return 1
    fi

    # 从容器 eth0 找到宿主机 ifindex
    ifindex=$(nsenter -t $pid -n ip link show eth0 2>/dev/null | grep -o 'if[0-9]\+' | sed 's/if//')
    if [ -z "$ifindex" ]; then
        echo "无法找到容器 $cname 的 eth0"
        return 1
    fi

    # 从宿主机查对应 veth 名称
    veth=$(ip link | awk -v idx="$ifindex" -F: '$1 ~ idx {print $2}' | awk '{print $1}')
    if [ -n "$veth" ]; then
        echo "$veth"
    else
        echo "未找到对应的 veth 接口"
        return 1
    fi
}

# 示例:调用
# get_veth_by_container my-nps

 

 

方案3:

#!/bin/bash

# ---
# A script to find the host-side virtual ethernet (veth) interface
# for a given Docker container using the ethtool method.
# ---

# Set color for output
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# 1. Check for input argument (container name)
if [ -z "$1" ]; then
  echo -e "${RED}Error: Please provide a container name or ID.${NC}"
  echo "Usage: $0 <container_name_or_id>"
  exit 1
fi

CONTAINER_NAME="$1"

# 2. Check if ethtool is installed on the host
if ! command -v ethtool &> /dev/null; then
    echo -e "${RED}Error: 'ethtool' is not installed. Please install it to use this script.${NC}"
    echo "On Debian/Ubuntu: sudo apt-get update && sudo apt-get install ethtool"
    echo "On CentOS/RHEL: sudo yum install ethtool"
    exit 1
fi

# 3. Get the Container's PID
echo "Inspecting container '$CONTAINER_NAME'..."
PID=$(docker inspect -f '{{.State.Pid}}' "$CONTAINER_NAME" 2>/dev/null)

if [ -z "$PID" ] || [ "$PID" -eq 0 ]; then
  echo -e "${RED}Error: Could not find a running container with name or ID '$CONTAINER_NAME'.${NC}"
  exit 1
fi
echo "Found Container PID: $PID"

# 4. Use nsenter to run ethtool inside the container's network namespace
echo "Searching for peer_ifindex inside the container..."
PEER_INDEX_LINE=$(nsenter -t "$PID" -n ethtool -S eth0 2>/dev/null | grep 'peer_ifindex')

if [ -z "$PEER_INDEX_LINE" ]; then
    echo -e "${RED}Error: Could not determine peer_ifindex. The container might not have an 'eth0' interface or ethtool failed inside the namespace.${NC}"
    exit 1
fi

# 5. Extract the peer_ifindex number from the output line
PEER_INDEX=$(echo "$PEER_INDEX_LINE" | awk '{print $2}')
echo "Found peer_ifindex: $PEER_INDEX"

# 6. Find the interface on the host with that index
HOST_INTERFACE_LINE=$(ip -o link | grep "^${PEER_INDEX}:")

if [ -z "$HOST_INTERFACE_LINE" ]; then
    echo -e "${RED}Error: Could not find a host interface with index '$PEER_INDEX'.${NC}"
    exit 1
fi

# 7. Extract the interface name and print the result
# The name is the second field, and we remove anything after the '@' symbol.
HOST_INTERFACE=$(echo "$HOST_INTERFACE_LINE" | awk -F': ' '{print $2}' | sed 's/@.*//')

echo "--------------------------------------------------"
echo -e "✅ ${GREEN}Success!${NC}"
echo -e "Container '${GREEN}${CONTAINER_NAME}${NC}' is connected to host interface: ${GREEN}${HOST_INTERFACE}${NC}"
echo "--------------------------------------------------"

 

 

 

 

根据接口查找容器

#!/bin/bash

# 检查是否提供了veth接口名称
if [ -z "$1" ]; then
    echo "用法: $0 <veth接口名称>"
    exit 1
fi

VETH_HOST="$1"

# 获取对端接口索引 (peer_ifindex)
PEER_IFINDEX=$(ethtool -S "$VETH_HOST" 2>/dev/null | grep 'peer_ifindex' | awk '{print $2}')

if [ -z "$PEER_IFINDEX" ]; then
    echo "错误:无法获取 $VETH_HOST 的 peer_ifindex"
    exit 1
fi

# 遍历所有容器,检查网络命名空间中的接口索引
FOUND=0
while read -r CONTAINER_ID; do
    PID=$(docker inspect --format '{{.State.Pid}}' "$CONTAINER_ID" 2>/dev/null)
    if [ -z "$PID" ]; then
        continue
    fi

    # 获取容器内的接口索引
    CONTAINER_IFINDEX=$(nsenter -t "$PID" -n ip -o link 2>/dev/null | \
                        awk -F': ' -v idx="$PEER_IFINDEX" '$1 == idx {print $1}')

    if [ "$CONTAINER_IFINDEX" = "$PEER_IFINDEX" ]; then
        CONTAINER_NAME=$(docker inspect --format '{{.Name}}' "$CONTAINER_ID" | sed 's#^/##')
        echo "找到关联容器:"
        echo "容器名称: $CONTAINER_NAME"
        echo "容器ID  : $CONTAINER_ID"
        FOUND=1
    fi
done < <(docker ps -q)

if [ "$FOUND" -eq 0 ]; then
    echo "未找到与 $VETH_HOST 关联的容器"
fi

 

image

 

 

 

docker ps -q | xargs -n1 docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'

查找容器内部ip

image

 

 

 

image

 

docker-compose -p yunshu -f /home/xxx.yaml  up -d

 

posted @ 2024-04-20 14:34  codestacklinuxer  阅读(58)  评论(0)    收藏  举报