zoukankan      html  css  js  c++  java
  • 运维笔记--给正在运行的Docker容器动态绑定卷组(挂载指定目录)

    场景描述:

    操作系统: ubuntu16.04, docker版本: Docker version 19.03.1

    系统运行一段时间后,该服务器上有一个运行中docker容器,需要在容器里边挂载本地服务器目录,从而实现某个文件在宿主机和容器内部都可以访问的效果。

    一般情况下,容器在启动的时候,我们通过挂载指定相应的目录就可以;例:

    docker run -p 8080:8080 -it --name test -v /home/test/bak_data:/mnt/bak_data mysql:5.7 /bin/bash

    但是,正在运行中的容器,如何动态挂载目录呢?

    别着急,有办法!

    处理方式:

    参考这篇:https://github.com/pushiqiang/utils/tree/master/docker

    1. 首先在宿主机本地创建你需要挂载的路径,这里以/home/test/bak_data为例:

    mkdir -p /home/test/bak_data

    2. 创建脚本文件,并写入内容:

    touch dynamic_mount_docker_volume
    
    vi dynamic_mount_docker_volume
    #!/bin/bash
    #This script is dynamic mount docker volumens
    #Author Deng Lei
    if [ -z $1 ] || [ -z $2 ] || [ -z $3 ]; then
        echo "Usage: container_name physics_volumes container_volumes"
        echo "Example: I want mount physics /tmp/test to container /src in test"
        echo "The command is: bash `basename $0` test_container_id /tmp/test /src "
        exit 1
    fi
    which nsenter &>>/dev/null
    if [ $? -ne 0 ];then
        echo "plsease install nsenser,command is:yum install util-linux"
        exit 1
    fi
    set -e
    CONTAINER=$1
    HOSTPATH=$2
    CONTPATH=$3
    if [ ! -d $HOSTPATH ];then
        echo "physics $HOSTPATH is not exist!"
        exit 1
    fi
    REALPATH=$(readlink --canonicalize $HOSTPATH)
    FILESYS=$(df -P $REALPATH | tail -n 1 | awk '{print $6}')
    while read DEV MOUNT JUNK
        do
            [ $MOUNT = $FILESYS ] && [ $DEV != "rootfs" ] && break
        done </proc/mounts
    [ $MOUNT = $FILESYS ] # Sanity check!
    while read A B C SUBROOT MOUNT JUNK
        do [ $MOUNT = $FILESYS ] && break
        done < /proc/self/mountinfo
    [ $MOUNT = $FILESYS ] # Moar sanity check!
    SUBPATH=$(echo $REALPATH | sed s,^$FILESYS,,)
    DEVDEC=$(printf "%d %d" $(stat --format "0x%t 0x%T" $DEV))
    PID=$(docker inspect --format "{{.State.Pid}}" "$CONTAINER")
    run_command="nsenter --target $PID --mount --uts --ipc --net --pid -- sh -c"
    if  [ `$run_command "mount|grep $CONTPATH|wc -l"` -ne 0 ];then
        echo "container $CONTAINER mount dir $CONTPATH is mounting!"
        exit 1
    fi
    $run_command "[ -b $DEV ] ||mknod --mode 0600 $DEV b $DEVDEC"
    $run_command "mkdir /tmpmnt"
    $run_command "mount $DEV /tmpmnt"
    $run_command "mkdir -p $CONTPATH"
    $run_command "mount -o bind /tmpmnt/$SUBROOT/$SUBPATH $CONTPATH"
    $run_command "umount /tmpmnt"
    $run_command "rmdir /tmpmnt"
    check_result=`$run_command "mount|grep $CONTPATH|wc -l"`
    if [ $check_result -ne 0 ];then
        echo "dymainc mount physics $HOSTPATH on $CONTAINER $CONTPATH is success!"
    else
        echo "dymaninc mount physics $HOSTPATH on $CONTAINER $CONTPATH is fail!"
    fi

    给该脚本赋执行权限:

    chmod +x dynamic_mount_docker_volume

    3. 重点来了,运行神器:---注意:本地没有该镜像,系统如果可以访问互联网,会自动从远程下载!

    如果不能下载,参考:https://github.com/jpetazzo/nsenter

    说明:nsenter是一个允许根据容器名称进入容器的小工具

    docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter

    4. 上述nsenter启动完成后,运行dynamic_mount_docker_volume脚本,执行动态挂载操作

    ./dynamic_mount_docker_volume 955138b6c3ed /home/test/bak_data /mnt/bak_data
    
    说明:955138b6c3ed 是你的容器ID
    /home/test/bak_data 是你的宿主机服务器路径
    /mnt/bak_data 是你目标容器内的路径--这个不不要提前创建,脚本会自动创建

    5. 验证结果

    在宿主机目录下/home/test/bak_data 创建一个文件123.test,然后进入到目标容器的/mnt/bak_data目录下,看能否看到该文件。

    OK,搞定!

  • 相关阅读:
    手机抓包方法
    IBM appscan 9.0破解版分享
    C#打开新页面
    双城记
    卸载趋势
    测试环境搭建
    C#常用函数→ASP.NET篇
    C#常用函数--通用篇
    读>>>>白帽子讲Web安全<<<<摘要→我推荐的一本书→1
    TCP/IP网络编程技术基础
  • 原文地址:https://www.cnblogs.com/hellojesson/p/12054334.html
Copyright © 2011-2022 走看看