如何确认docker 和 宿主机上 veth 设备的关系?

docker 和 宿主机上 veth 设备的关系没有命令可以直接查到。不过可以进入容器可以看到。如果有个脚本能看到就好太多,docker 后续应该在docker ps加入一个类似的功能。

传统方式:

1、docker exec 进入容器内部

2、宿主机上执行: ip a

自动化方式:

#!/bin/sh

NL=$


####################
# DEFINE FUNCTIONS #
####################

usage () {
    printf %s 
"dockerveth.sh - Show which docker containers are attached to which
`veth` interfaces.

Usage: dockerveth.sh [DOCKER PS OPTIONS] | [-h, --help]

Options:
    DOCKER PS OPTIONS   Pass any valid `docker ps` flags. Do not pass
                        a --format flag.
    -h, --help          Show this help and exit.

Output:
    If stdout is not a tty, column headers are omitted.
"
}

get_container_data () {
    # Get data about the running containers. Accepts arbitrary arguments, so you can pass
    # a filter to `docker ps` if desired.
    # Input: `docker ps` arguments (optional)
    # Output: A multi-line string where each line contains the container id, followed by
    # a space, and then any friendly names.
    docker ps --format {
         
  {.ID}} {
         
  {.Names}} "$@"
}

get_veth () {
    # Get the host veth interface attached to a container.
    # Input: docker container ID; also needs $dockerveth__addrs
    # Output: the veth name, like "veth6638cfa"
    c_if_index=$(get_container_if_index "$1")
    a="${dockerveth__addrs%%@if${c_if_index}:*}"
    b="${a##*${NL}}"
    printf "${b#* }"
}

get_container_if_index () {
    # Get the index number of a docker containers first veth interface (typically eth0)
    # Input: the container ID
    # Output: The index number, like "42"
    c_pid=$(get_pid "$1")
    ip_netns_export "$c_pid"
    ils=$(ip netns exec "ns-${c_pid}" ip link show type veth)
    printf "${ils%%:*}"
}

ip_netns_export () {
    # Make a docker containers networking info available to `ip netns`
    # Input: the containers PID
    # Output: None (besides return code), but performs the set-up so that `ip netns` commands
    # can access this containers namespace.
    if [ ! -d /var/run/netns ]; then
        mkdir -p /var/run/netns
    fi
    ln  -sf "/proc/${1}/ns/net" "/var/run/netns/ns-${1}"
}

get_pid () {
    # Get the PID of a docker container
    # Input: the container ID
    # Output: The PID, like "2499"
    docker inspect --format {
         
  {.State.Pid}} "$1"
}

make_row () {
    # Produce a table row for output
    # Input:
    #     1 - The container ID
    #     2 - The containers friendly name
    # Output: A row of data, like "1e8656e195ba	veth1ce04be	thirsty_meitner"
    id="${1}"
    name="${2}"
    veth=$(get_veth "$id")
    printf "${id}	${veth}	${name}"
}

make_table () {
    # Produce a table for output
    # Input: raw data rows, like `c26682fe4545 friendly-name`
    # Output: A multi-line string consisting of rows from `make_row`. Does not
    # contain table column headers.
    for i in $@; do
        id="${i%% *}"
        name="${i#* }"
        r=$(make_row "$id" "$name")
        printf "${r}
"
    done
}


######################
# PARSE COMMAND LINE #
######################

case "$1" in
    -h|--help)
    usage
    exit 0
    ;;
    *)
    ;;
esac


##################
# EXECUTE SCRIPT #
##################

set -e
container_data=$(get_container_data "$@")
dockerveth__addrs="$(ip address show)"
table=$(IFS="$NL"; make_table $container_data)
if [ -t 1 ]; then
    printf "CONTAINER ID	VETH       	NAMES
"
fi
printf "${table}
"
经验分享 程序员 微信小程序 职场和发展