運維筆記--給正在運行的Docker容器動態綁定卷組(掛載指定目錄) volumes


場景描述:

操作系統: 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,搞定!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM