Edited at
DockerDay 21

コンテナから他サーバをいじってみる

More than 1 year has passed since last update.

この記事は、Docker Advent Calendar 2017 21日目の記事です。


概要

Dockerのサーバでは許可されていないけど、Dockerが動いてないサーバで許可されているものを使いたい場合が時々ありますよね?

※人によります。僕にはそんな場合がありました。

そんな場合がいつ起こるかわからないのでsshfsを使うことで他サーバのファイルをいじってみる。


検証内容

sshfs-fromサーバ上のコンテナからsshfs-toサーバのファイルをいじる


環境


  • OS : CentOS 7.4.1708(Core)

[root@docker-test centos]# cat /etc/centos-release

CentOS Linux release 7.4.1708 (Core)


  • Docker : 17.09.1-ce

[root@docker-test centos]# docker info

Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 17.09.1-ce
Storage Driver: overlay
Backing Filesystem: extfs
Supports d_type: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 06b9cb35161009dcb7123345749fef02f7cea8e0
runc version: 3f2f8b84a77f73d38244dd690525642a72156c64
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-693.11.1.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.702GiB
Name: docker-test
ID: QDXG:Z7GS:Y5GW:CJCW:RDEY:KCHQ:5ENQ:5CVC:FBLZ:3IZI:MRZA:ZSC6
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Http Proxy: XXXX
Https Proxy: XXXX
No Proxy: localhost,127.0.0.1
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false


サーバ情報


  • sshfs-to

    マウントされる側のサーバ。

    sshfs-fromからノンパスでsshが実行できる。


  • sshfs-from

    マウントする側のサーバ。

    sshfs-toへノンパスでsshが実行できる。



ディレクトリ


  • sshfs-to

[root@sshfs-to sshfs]# tree /tmp/sshfs

/tmp/sshfs
└── sshfs-to.txt

0 directories, 1 file
[root@sshfs-to sshfs]# cat /tmp/sshfs/sshfs-to.txt
sshfs-to


  • sshfs-from

[root@sshfs-from Docker]# tree /Docker

/Docker/
├── Dockerfile
├── rsa
│   ├── id_rsa
│   └── known_hosts
└── src
└── wrapper.sh

2 directories, 4 files


Dockefile

FROM alpine:latest

MAINTAINER hihihiroro@gmail.com

RUN set -x \
&& http_proxy=XXXX https_proxy=XXXX apk update \
&& http_proxy=XXXX https_proxy=XXXX apk upgrade \
&& http_proxy=XXXX https_proxy=XXXX apk add --no-cache sshfs

ADD rsa/id_rsa /root/.ssh/id_rsa
ADD rsa/known_hosts /root/.ssh/known_hosts

RUN chmod 700 /root/.ssh \
&& chmod 600 /root/.ssh/id_rsa \
&& chmod 644 /root/.ssh/known_hosts \
&& mkdir /sshfs-dir

ADD src/wrapper.sh /usr/local/bin/wrapper.sh
RUN chmod a+x /usr/local/bin/wrapper.sh
CMD ["/usr/local/bin/wrapper.sh"]


wrapper.sh

[root@sshfs-from Docker]# cat src/wrapper.sh

#!/usr/bin/env sh
# Fail on unset variables and command errors
set -ue -o pipefail

# Prevent commands misbehaving due to locale differences
export LC_ALL=C

echo "## sshfs前確認 : ls -l /sshfs-dir"
ls -l /sshfs-dir

echo "## sshfs : sshfs sshfs-to:/tmp/sshfs /sshfs-dir"
sshfs sshfs-to:/tmp/sshfs /sshfs-dir

echo "## sshfs後確認 : ls -l /sshfs-dir"
ls -l /sshfs-dir

echo "## 書き込み前確認 : ssh sshfs-to ls -l /tmp/sshfs"
ssh sshfs-to ls -l /tmp/sshfs

echo "## 書き込み : touch /sshfs-dir/from_sshfs-from.txt"
touch /sshfs-dir/from_sshfs-from.txt
ls -l /sshfs-dir

echo "## 書き込み後確認 : ssh sshfs-to ls -l /tmp/sshfs"
ssh sshfs-to ls -l /tmp/sshfs


docker image作成

[root@sshfs-from Docker]# docker build -t sshfs-image .

Sending build context to Docker daemon 8.192kB
Step 1/9 : FROM alpine:latest
---> e21c333399e0
Step 2/9 : MAINTAINER hihihiroro@gmail.com
---> Running in 07d8189705ab
---> e5f8e6074942
Removing intermediate container 07d8189705ab
Step 3/9 : RUN set -x && http_proxy=XXXX https_proxy=XXXX apk update && http_proxy=XXXX https_proxy=XXXX apk upgrade && http_proxy=XXXX https_proxy=XXXX apk add --no-cache sshfs
---> Running in b987259de3ef
+ http_proxy=XXXX https_proxy=XXXX apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
v3.7.0-35-g1f6e64f5d4 [http://dl-cdn.alpinelinux.org/alpine/v3.7/main]
v3.7.0-34-g4caa398901 [http://dl-cdn.alpinelinux.org/alpine/v3.7/community]
OK: 9046 distinct packages available
+ http_proxy=XXXX https_proxy=XXXX apk upgrade
Upgrading critical system libraries and apk-tools:
(1/1) Upgrading apk-tools (2.8.1-r1 -> 2.8.1-r2)
Executing busybox-1.27.2-r6.trigger
Continuing the upgrade transaction with new apk-tools:
(1/1) Upgrading busybox (1.27.2-r6 -> 1.27.2-r7)
Executing busybox-1.27.2-r7.post-upgrade
Executing busybox-1.27.2-r7.trigger
OK: 4 MiB in 11 packages
+ http_proxy=XXXX https_proxy=XXXX apk add --no-cache sshfs
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/11) Installing openssh-keygen (7.5_p1-r8)
(2/11) Installing openssh-client (7.5_p1-r8)
(3/11) Installing fuse (2.9.7-r0)
(4/11) Installing libffi (3.2.1-r4)
(5/11) Installing libintl (0.19.8.1-r1)
(6/11) Installing libuuid (2.31-r0)
(7/11) Installing libblkid (2.31-r0)
(8/11) Installing libmount (2.31-r0)
(9/11) Installing pcre (8.41-r1)
(10/11) Installing glib (2.54.2-r0)
(11/11) Installing sshfs (2.10-r2)
Executing busybox-1.27.2-r7.trigger
Executing glib-2.54.2-r0.trigger
OK: 11 MiB in 22 packages
---> d65f1420e231
Removing intermediate container b987259de3ef
Step 4/9 : ADD rsa/id_rsa /root/.ssh/id_rsa
---> ac2f15cc05f7
Step 5/9 : ADD rsa/known_hosts /root/.ssh/known_hosts
---> fb14539d6a09
Step 6/9 : RUN chmod 700 /root/.ssh && chmod 600 /root/.ssh/id_rsa && chmod 644 /root/.ssh/known_hosts && mkdir /sshfs-dir
---> Running in ba0cad24c993
---> 1fbff8497e17
Removing intermediate container ba0cad24c993
Step 7/9 : ADD src/wrapper.sh /usr/local/bin/wrapper.sh
---> c372519234c4
Step 8/9 : RUN chmod a+x /usr/local/bin/wrapper.sh
---> Running in feb975f5ab43
---> f1dbfcd868cd
Removing intermediate container feb975f5ab43
Step 9/9 : CMD /usr/local/bin/wrapper.sh
---> Running in fd4debbcc9ae
---> 70a89ed38a86
Removing intermediate container fd4debbcc9ae
Successfully built 70a89ed38a86
Successfully tagged sshfs-image:latest


docker run

[root@sshfs-from Docker]# docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse -v /etc/hosts:/etc/hosts:ro sshfs-image

## sshfs前確認 : ls -l /sshfs-dir
total 0
## sshfs : sshfs sshfs-to:/tmp/sshfs /sshfs-dir
## sshfs後確認 : ls -l /sshfs-dir
total 4
-rw-r--r-- 1 root root 0 Dec 21 14:29 from_sshfs-from.txt
-rw-r--r-- 1 root root 9 Dec 21 13:18 sshfs-to.txt
## 書き込み前確認 : ssh sshfs-to ls -l /tmp/sshfs
total 4
-rw-r--r-- 1 root root 0 Dec 21 23:29 from_sshfs-from.txt
-rw-r--r-- 1 root root 9 Dec 21 22:18 sshfs-to.txt
## 書き込み : touch /sshfs-dir/from_sshfs-from.txt
total 4
-rw-r--r-- 1 root root 0 Dec 21 14:32 from_sshfs-from.txt
-rw-r--r-- 1 root root 9 Dec 21 13:18 sshfs-to.txt
## 書き込み後確認 : ssh sshfs-to ls -l /tmp/sshfs
total 4
-rw-r--r-- 1 root root 0 Dec 21 23:32 from_sshfs-from.txt
-rw-r--r-- 1 root root 9 Dec 21 22:18 sshfs-to.txt

sshfs-fromサーバ上のコンテナから、sshfs-toサーバのディレクトリをマウントしファイルの読み書きができている。

※コンテナからsshfsコマンドを実行する際にdockerコマンドを実行する際にprivilegedなコンテナにしています。

詳しくはこちらを参照して下さい。


まとめ

sshfsコマンドを使うことでコンテナから他サーバのディレクトリをマウントし、ファイルをいじることができた。


参考

Docker privileged オプションについて