在docker容器中调用和执行宿主机的docker操作

首先这个帖子,献给docker新手。当然如果你是一个老手,文中分割线后的操作方法也是一种思路。

首先说一下,如何在docker中执行宿主机的docker操作,我们管它叫docker in docker。

至于为什么要在docker中操作宿主机的docker,优点不言而喻,你既可以将你的具体需求容器化部署,又不用直接在宿主机上安装(假设我们没有办法在docker中操作宿主机的docker,那么我们只能将这样的软件程序直接安装到宿主机上,这样显然是不利于管理和维护的)。

实现这种需求,其实非常简单,你只需要将docker宿主机的docker文件和docker.sock文件挂载到容器中即可,具体为:

-v /var/run/docker.sock:/var/run/docker.sock

-v /usr/bin/docker:/usr/bin/docker

你要先找到你宿主机的docker和docker.sock位置,别挂载错了,标准的Linux正常来说就是上面的位置。

你在启动docker容器的时候,将上述两个文件正常挂载后,就可以在docker中执行诸如 docker images 等等这样的命令了。

如果出现问题 permission denied

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

…………………………………………………………

dial unix /var/run/docker.sock: connect: permission denied

解决方法

在容器所在的宿主机上直接给 docker.sock 777权限,命令 chmod 777 docker.sock

华丽丽的分割线

下面是针对群辉系统,你不用太关心这个系统是什么,总之就是这个系统在docker方面有一些特有的问题,导致你不能这么随心所欲,所以我采用了一种变通的方法来处理(一种思路,抛砖引玉)先叙述一下现状:

该系统提供了docker的UI管理工具,我们在这个工具上可以进行常规的挂载操作,但是如果我们想挂载上面的docker和docker.sock文件,就不行了,先看一下截图:

说一下图上UI操作的局限性!

群辉官方进行了限制,你可以选择的文件,是不可能选择到 /usr/ /va/ 等这样系统层面的文件的,也就是我们无法直接挂载docker和docker.sock文件。

做 ln -s 软连接是否可行?

经尝试,先通过ssh命令行在jenkins文件夹中创建2个软连接(将docker和docker.sock进行软连接),然后回到群辉的UI界面,依然不能选择(因为群辉直接屏蔽了软连接文件,你是看不到的)

那么如何解决呢?

我的方法是(软连接的方法变通一下):

1、在图上的jenkins目录下随便创建2个文件 docker 和 docker.sock 文件(命名正确即可)

2、然后在docker点击“添加文件”按钮,正常选择这2个文件,进行挂载,你完全可以正常挂载并且完成其他配置,配置完毕后,暂时不要启动docker容器。

3、登录ssh进入群辉,将jenkins目录中刚刚创建的2个文件删除掉,然后把docker和docker.sock源文件创建软连接到jenkins中。

root@test:cd /volume1/docker/jenkins/
root@test:rm -rf docker docker.sock
root@test:ln -s /run/docker.sock /volume1/docker/jenkins/docker.sock
root@test:ln -s /usr/local/bin/docker /volume1/docker/jenkins/docker
root@test:/volume1/docker/jenkins# ll
total 8
drwxrwxrwx+ 1 Nuggets users 96 Jun 6 11:22 .
drwxr-xr-x+ 1 root root 188 May 30 19:29 ..
lrwxrwxrwx 1 root root 21 Jun 6 11:22 docker -> /usr/local/bin/docker
lrwxrwxrwx 1 root root 16 Jun 6 11:21 docker.sock -> /run/docker.sock
drwxrwxrwx+ 1 shanhongyu users 24 Jun 1 11:07 java_home
drwxrwxrwx+ 1 Nuggets users 4476 Jun 6 11:00 jenkins_home
drwxrwxrwx+ 1 shanhongyu users 82 Jun 1 11:12 maven_home

4、然后回到群辉UI,启动容器,这样就完美了。

(群辉不让你选软连接,但是linux和docker本质上是可以直接挂载软连接的)

补充知识:使用docker在镜像中运行宿主机程序

docker run命令用于在新容器中运行命令。docker run命令首先在指定的映像上创建一个可写容器层,然后使用指定的命令启动它。

也就是说,docker run相当于API /containers/create 和 /containers/(id)/start。

可以使用docker start重新启动停止的容器,并使用其所有先前的更改完整。 请参阅docker ps -a查看所有容器的列表。

用法

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Shell

例子

分配名称并分配伪TTY(-name,-it)

$ docker run --name test -it debian

root@d6c0fe130dba:/# exit 13
$ echo $?
13
$ docker ps -a | grep test
d6c0fe130dba  debian:7   "/bin/bash"   26 seconds ago  Exited (13) 17 seconds ago       test

Shell

此示例使用debian:latest映像运行一个名为test的容器。 -it 指示Docker分配连接到容器的stdin的伪TTY; 在容器中创建一个交互式的bash shell。 在该示例中,bash shell通过输入exit 13退出。该退出代码传递给docker run的调用者,并记录在测试容器的元数据中。

捕获容器ID(-cidfile)

$ docker run --cidfile /tmp/docker_test.cid ubuntu echo "test"

Shell

这将创建一个容器并打印测试到控制台。--cidfile标志使Docker尝试创建一个新文件,并将容器ID写入它。如果文件已经存在,Docker将返回一个错误。 Docker运行退出时,Docker将关闭此文件。

完整的容器功能(-privileged)

$ docker run -t -i --rm ubuntu bash
root@bc338942ef20:/# mount -t tmpfs none /mnt
mount: permission denied

Shell

这将不起作用,因为默认情况下,大多数潜在的危险内核功能被丢弃; 包括cap_sys_admin(这是挂载文件系统所需的)。 但是,--privileged标志将允许它运行:

$ docker run -t -i --privileged ubuntu bash
root@50e3f57e16e6:/# mount -t tmpfs none /mnt
root@50e3f57e16e6:/# df -h
Filesystem  Size Used Avail Use% Mounted on
none   1.9G  0 1.9G 0% /mnt

Shell

设置工作目录[-w]

$ docker run -w /path/to/dir/ -i -t ubuntu pwd

Shell

-w允许在目录中执行命令,这里是/path/to/dir/。 如果路径不存在,则在容器内创建。

为每个容器设置存储驱动程序选项

$ docker run -it --storage-opt size=120G fedora /bin/bash

Shell

挂载tmpfs(-tmpfs)

$ docker run -d --tmpfs /run:rw,noexec,nosuid,size=65536k my_image

Shell

--tmpfs标志使用rw,noexec,nosuid,size = 65536k选项将一个空tmpfs装载到容器中。

挂载卷(-v,-read-only)

$ docker run -v `pwd`:`pwd` -w `pwd` -i -t ubuntu pwd

Shell

-v标志将当前工作目录装载到容器中。 -w允许在当前工作目录中执行命令,将目录更改为pwd返回的值。所以这个组合使用容器执行命令,但在当前工作目录中。

$ docker run -v /doesnt/exist:/foo -w /foo -i -t ubuntu bash

Shell

当绑定卷的主机目录不存在时,Docker将自动在主机上创建此目录。 在上面的示例中,Docker将在启动容器之前创建/doesnt/exists文件夹。

$ docker run --read-only -v /icanwrite busybox touch /icanwrite/here

Shell

卷可以与--read-only组合使用,以控制容器写入文件的位置。 --read-only标志将容器的根文件系统挂载为只读禁止写入容器的指定卷以外的位置。

以上这篇在docker容器中调用和执行宿主机的docker操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 在docker容器中使用非root用户执行脚本操作

    应用容器化之后,在docker容器启动时,默认使用的是root用户执行命令,因此容器中的应用默认都是使用root用户来运行的,存在很高的安全风险,那么如何能够使用非root的业务用户来运行应用呢, 下面我将举一个简单的例子来说明. 该例子是在容器中使用自建的用户来运行一个简单的shell脚本,并将脚本输出日志持久到容器外部.接下来让我们来看从制作镜像到容器运行的全过程吧. 1.构建镜像: 我将会使用dockerfile的方式来构建镜像,基础镜像使用ubuntu 14.04(需要先拉取该镜像,do

  • Docker容器和本机之间的文件传输方法

    主机和容器之间传输文件的话需要用到容器的ID全称. 获取方法如下: 1.先拿到容器的短ID或者指定的name. 2.然后根据这两项的任意一项拿到ID全称. 有了这个长长的ID的话,本机和容器之间的文件传输就简单了. docker cp 本地文件路径 ID全称:容器路径 进入容器之后就能够看到刚才上传进来的文件了. 如果是容器传输文件到本地的话,反过来就好了: docker cp ID全称:容器文件路径 本地路径 进行挂载的话可以参考这篇:利用Volume在主机和Docker容器文件传输. 以上就

  • Docker容器访问宿主机网络的方法

    最近部署一套系统,使用nginx作反向代理,其中nginx是使用docker方式运行: $ docker run -d --name nginx $PWD:/etc/nginx -p 80:80 -p 443:443 nginx:1.15 需要代理的API服务运行在宿主机的 1234 端口, nginx.conf 相关配置如下: server { ... location /api { proxy_pass http://localhost:1234 } ... } 结果访问的时候发现老是报 5

  • WIN10系统和Docker内部容器IP互通方式

    1.安装了Window版本的Docker之后,我们启动 Docker Quickstart Terminal ,我们会得到一个IP,我的为: 192.168.99.100 2.启动一个mysql镜像,并获取这个镜像的IP: 在开始的时候,从本机直接到172.17.0.2是网络不通的,但是我们本机能到 192.168.99.100,172.17.0.2到192.168.99.100也是通的,我们可以在本机配置一个到172.17.0.2通过192.168.99.100的路由: route add -

  • 在docker容器中调用和执行宿主机的docker操作

    首先这个帖子,献给docker新手.当然如果你是一个老手,文中分割线后的操作方法也是一种思路. 首先说一下,如何在docker中执行宿主机的docker操作,我们管它叫docker in docker. 至于为什么要在docker中操作宿主机的docker,优点不言而喻,你既可以将你的具体需求容器化部署,又不用直接在宿主机上安装(假设我们没有办法在docker中操作宿主机的docker,那么我们只能将这样的软件程序直接安装到宿主机上,这样显然是不利于管理和维护的). 实现这种需求,其实非常简单,

  • docker容器中无法获取宿主机hostname的解决方案

    在nodejs环境中测试通过,其它语言同理,只需要使用获取环境变量的方法即可. 思路: docker容器和宿主机环境是隔离的,但是可以在启动docker容器时将宿主机的主机名以环境变量的形式传入,代码在容器中获取该值即可. 操作: docker run -d -p 3000:3000 --name myTest -e HOST_Q=$(hostname) mytest:v1 # 使用-e 参数传入环境变量,值为主机名 如果使用yml文件启动: version: '3' services: mys

  • windows宿主机和docker容器设置挂载共享文件夹的步骤

    docker容器内的程序经常需要访问.调用宿主机目录中的数据,每次都要导入导出非常麻烦费力. 接下来,一步步实现将宿主机的指定文件夹挂载到docker容器中. 1. 打开Oracle VM VitualBox: 2. 点击[设置]->点击左侧的[共享文件夹] 3. 双击默认的[c/Users \\?\c:\Users],进行编辑,这里设置D盘下的data为挂载共享目录,名称可修改,此处设为"data". 点击确定 4. 重启virtualbox虚拟机,中间有等待时间: 5. 创建

  • 在Docker容器中不需要运行sshd的原因浅析

    当开始使用Docker时,人们经常问:"我该如何进入容器?",其他人会说"在你的容器里运行一个SSH服务器".但是,从这篇博文中你将会了解到你根本不需要运行SSHd守护进程来进入你的容器.当然,除非你的容器就是一个SSH服务器. 运行SSH服务器是很想当然的,因为它提供了进入容器的简便方式.在我们公司基本上每个人都最少使用过一次SSH.我们中有很大一部分人每天都会使用它,并且他们很熟悉公钥与私钥,无密码登录,密钥代理,甚至有时会使用端口转发和其他不常用的功能.正因如

  • docker容器中crontab无法正常运行解决方案

    相信很多人看完docker容器, 需要加crontab, 加完却发现不能执行,心塞.....接着便开始各种折腾... 首先当然是看日志了, 发现/var/log 下面没有任何信息, 那是因为你没有打开rsyslog. # /etc/init.d/rsyslog start 继续看日志 # tail /var/log/crond Dec 29 16:39:01 web01-50794 crond[2839]: (root) FAILED to open PAM security session (

  • 如何隔离docker容器中的用户的方法

    笔者在前文<理解 docker 容器中的 uid 和 gid>介绍了 docker 容器中的用户与宿主机上用户的关系,得出的结论是:docker 默认没有隔离宿主机用户和容器中的用户.如果你已经了解了 Linux 的 user namespace 技术(参考<Linux Namespace : User>),那么自然会问:docker 为什么不利用 Linux user namespace 实现用户的隔离呢?事实上,docker 已经实现了相关的功能,只是默认没有启用而已.笔者将在

  • docker容器访问宿主机的MySQL操作

    背景: 有一个flask项目提供接口,使用docker容器构建并且运行,MySQL在宿主机运行,需要在容器中可以让flask连接上宿主机的mysql 使用ifconfig命令可以看到,有一个docker0和eth0,在docker容器中可以通过eth0的IP地址加上端口号(3306)这样就可以连接上宿主机的MySQL了:另外,nginx可以通过docker0的IP地址加上构建容器时指定的端口号进行访问容器. 补充:docker的mysql容器运行正常,但是宿主机却连不上数据库,解决方法来啦 do

  • 详解如何在 docker 容器中捕获信号

    我们可能都使用过 docker stop 命令来停止正在运行的容器,有时可能会使用 docker kill 命令强行关闭容器或者把某个信号传递给容器中的进程.这些操作的本质都是通过从主机向容器发送信号实现主机与容器中程序的交互.比如我们可以向容器中的应用发送一个重新加载信号,容器中的应用程序在接到信号后执行相应的处理程序完成重新加载配置文件的任务.本文将介绍在 docker 容器中捕获信号的基本知识. 信号(linux) 信号是一种进程间通信的形式.一个信号就是内核发送给进程的一个消息,告诉进程

  • 在Docker容器中使用iptables时的最小权限的开启方法

    在Docker容器中使用iptables时的最小权限的开启方法 Dcoker容器在使用的过程中,有的时候是需要使用在容器中使用iptables进行启动的,默认的docker run时都是以普通方式启动的,没有使用iptables的权限,那么怎样才能在容器中使用iptables呢?要如何开启权限呢? 那么在docker进行run的时候如何将此容器的权限进行配置呢?主要是使用--privileged或--cap-add.--cap-drop来对容器本身的能力的开放或限制.以下将举例来进行说明: 例如

随机推荐