Docker容器学习梳理--容器登陆方法梳理(attach、exec、nsenter)

对于运行在后台的Docker容器,我们运维人员时常是有登陆进去的需求。登陆Docker容器的方式:

1)使用ssh登陆容器。这种方法需要在容器中启动sshd,存在开销和攻击面增大的问题。同时也违反了Docker所倡导的一个容器一个进程的原则。 参考Docker容器学习梳理--SSH方式登陆容器

2)使用自带命令docker attach登陆容器。命令格式:docker attach container_id。不过docker attach存在的问题是:当多个窗口同时attach到同一个容器时,所有的窗口都会同步的显示,假如其中的一个窗口发生阻塞时,其它的窗口也会阻塞,docker attach命令可以说是最不方便的进入后台docker容器的方法。

3)使用自带命令docker exec登陆容器。命令格式:docker exec -ti container_id /bin/bash。docker exec和docker attach是Docker的原生方法,大多数情况下就使用这两种命令登陆容器。docker exec命令是在docker1.3之后出现的,比docker attach命令更加方便!两者之间的区别:

1.Docker attach必须是登陆到一个已经运行的容器里。需要注意的是如果从这个容器中exit退出的话,就会导致容器停止!!这是极其不方便的!
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"              4 days ago          Up About an hour    0.0.0.0:8888->8080/tcp          tomcat
[[email protected] ~]# docker attach tomcat
[[email protected] /]# exit          //按住ctrl+d退出当前窗口
[[email protected] ~]# docker ps        //发现该容器也停止了!!
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                           NAMES
 
2.docker exec登陆容器,注意有两个参数:-t和-i,这两个参数很重要!
 
1)如果只用-i时,由于没有分配伪终端,看起来像pipe执行一样。但是执行结果、命令返回值都可以正确获取。
这种方式可以理解为:在运行的容器上执行新进程!即在宿主机上执行容器里的命令并查看到命令结果!这很方便的~但是仅仅使用-i参数无法直接登陆到容器内!
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"              4 days ago          Up About a minute   0.0.0.0:8888->8080/tcp          tomcat
 
[[email protected] ~]# docker exec -i tomcat date
Sat Apr  1 06:53:46 UTC 2017
[[email protected] ~]# docker exec -i tomcat uptime
 06:54:44 up 163 days, 23:28,  0 users,  load average: 0.00, 0.01, 0.05
[[email protected] ~]# docker exec -i tomcat /usr/local/tomcat7/bin/startup.sh
Tomcat started.
 
2)如果只使用-t参数,则可以看到一个console窗口,可以在宿主机上执行容器里的命令并查看到命令结果,但是这种方式登陆到容器内执行的命令是没有结果信息输出的!
[[email protected] ~]# docker exec -t tomcat uptime
 07:02:38 up 163 days, 23:36,  0 users,  load average: 0.00, 0.02, 0.05
[[email protected] ~]# docker exec -t tomcat pwd
/
[[email protected] ~]# docker exec -t tomcat /bin/bash   //注意,使用-t参数登陆容器,退出当前窗口用的是ctrl+c而不是ctrl+d;而下面使用-ti参数,退出当前窗口使用ctrl+d
[[email protected] /]# uptime      //仅仅使用-t参数登陆容器内,发现执行命令后,没有结果输出!
 
3)使用-it时,则和我们平常操作console界面类似,而且不会像attach方式因为退出而导致 整个容器退出。 这种方式可以替代ssh或者nsenter方式,在容器内进行操作。
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"              4 days ago          Up About a minute   0.0.0.0:8888->8080/tcp          tomcat
 
[[email protected] ~]# docker exec -t tomcat /bin/bash
[[email protected] /]# exit          //按住ctrl+d退出当前窗口
[[email protected] ~]# docker ps       //发现容器还在,并没有因为上面的窗口退出而停止容器!
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"              4 days ago          Up About a minute   0.0.0.0:8888->8080/tcp          tomcat
 
在使用docker exec登陆容器或执行容器中的命令时,最好都带上-t和-i参数
[[email protected] ~]# docker exec -ti  tomcat yum install -y net-tools
[[email protected] ~]# docker exec -t -i  tomcat ifconfig
 
----------------------------------------------
除此之外,docker exec还可以使用-d参数,表示在后台执行一个进程。如果一个命令需要长时间进程,使用-d参数会很快返回,程序在后台运行。
这一般用于容器中的命令长时间执行的情况下。
[[email protected] ~]# docker exec -d tomcat yum install -y mysql

4)对于一个已关闭的容器的登陆,可以使用"docker start -ai container"登陆。这种其实就是先启动容器,然后再进入容器内。

[[email protected] ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"              4 days ago          Up 9 minutes        0.0.0.0:8888->8080/tcp          tomcat
 
[[email protected] ~]# docker stop tomcat
tomcat
[[email protected] ~]# docker start -i tomcat        //参数用-i或-a -i两个参数都可以
[[email protected] /]# exit       //不过这种方式,在退出当前窗口后,也会导致容器停止!
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                           NAMES

5)使用外部工具nsenter登陆容器,该工具和docker exec命令的效果差不多。使用nsenter或docker exec,都可以在容器的上下文(严格地说,是命名空间)中运行任意命令!

1.安装nsenter
nsenter 工具在util-linux包2.23版本后包含。如果系统中 util-linux 包没有该命令,可以按照下面的方法从源码安装。
[[email protected] ~]# cd /usr/local/src/
[[email protected] src]# curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-; cd util-linux-2.24;
[[email protected] util-linux-2.24]# ./configure  --without-ncurses
[[email protected] util-linux-2.24]# make nsenter && cp nsenter /usr/local/bin
   
2.nsenter使用
在使用nsenter命令之前需要获取到docker容器的进程,然后再使用nsenter工具进去到docker容器中,具体的使用方法如下:
# docker inspect -f {{.State.Pid}} 容器名或者容器id   //每一个容器都有.State.Pid,所以这个命令除了容器的id需要我们根据docker ps -a去查找,其他的全部为固定的格式
# nsenter --target 上面查到的进程id --mount --uts --ipc --net --pid    // 输入该命令便进入到容器中
   
解释nsenter指令中进程id之后的参数的含义:
--mount参数是进去到mount namespace中
--uts参数是进入到uts namespace中
--ipc参数是进入到System V IPC namaspace中
--net参数是进入到network namespace中
--pid参数是进入到pid namespace中
--user参数是进入到user namespace中
   
在Linux中,最爱简单的查看指定命令参数含义的办法是在终端中输入:
# nsenter --help  #会回显所有与该命令有关的参数
# man nsenter  #能查到更加详细的使用示例和参数说明
 
[[email protected] ~]# nsenter --help
 
Usage:
 nsenter [options] <program> [args...]
 
Options:
 -t, --target <pid>     target process to get namespaces from
 -m, --mount [=<file>]  enter mount namespace
 -u, --uts   [=<file>]  enter UTS namespace (hostname etc)
 -i, --ipc   [=<file>]  enter System V IPC namespace
 -n, --net   [=<file>]  enter network namespace
 -p, --pid   [=<file>]  enter pid namespace
 -U, --user  [=<file>]  enter user namespace
 -S, --setuid <uid>     set uid in user namespace
 -G, --setgid <gid>     set gid in user namespace
 -r, --root  [=<dir>]   set the root directory
 -w, --wd    [=<dir>]   set the working directory
 -F, --no-fork          do not fork before exec'ing <program>
 
 -h, --help     display this help and exit
 -V, --version  output version information and exit
   
实例如下:
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND             CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"         4 days ago          Up 23 minutes       0.0.0.0:8888->8080/tcp          tomcat
  
[[email protected] ~]# docker inspect -f {{.State.Pid}} tomcat
31356
[[email protected] ~]# nsenter --target 31356 --mount --uts --ipc --net --pid
[[email protected] /]# exit     //退出当前窗口,容器不会停止。
logout
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND             CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"         4 days ago          Up 27 minutes       0.0.0.0:8888->8080/tcp          tomcat
 
或者:
[[email protected] ~]# nsenter -m -u -n -i -p -t 31356 bash
[[email protected] /]#
 
[[email protected] ~]# nsenter -m -u -n -i -p -t 31356 uptime
 10:17:08 up 164 days,  2:50,  0 users,  load average: 0.00, 0.01, 0.05
[[email protected] ~]# nsenter -m -u -n -i -p -t 31356 free -m
              total        used        free      shared  buff/cache   available
Mem:       65759080      591904    58142584      419724     7024592    64301784
Swap:       2097148           0     2097148

6)更简单的是,强烈推荐下载.bashrc_docker,并将内容放到.bashrc中。这个文件中定义了很多方便使用Docker的命令,比如docker-pid可以获取某个容器的 PID;而 docker-enter 可以进入容器或直接在容器内执行命令!

[[email protected] ~]# wget -P ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker
[[email protected] ~]# echo "[ -f ~/.bashrc_docker ] && . ~/.bashrc_docker" >> ~/.bashrc; source ~/.bashrc
  
举例:
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND             CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"         4 days ago          Up 37 minutes       0.0.0.0:8888->8080/tcp          tomcat
  
1)直接使用docker-enter命令进入容器,非常方便!
[[email protected] ~]# docker-enter tomcat   
Last login: Sat Apr  1 10:07:21 UTC 2017
[[email protected] ~]# exit
logout
[[email protected] ~]# docker ps       //退出登陆窗口后,容器还在!
CONTAINER ID        IMAGE                       COMMAND             CREATED             STATUS              PORTS                           NAMES
2faf24118766        192.168.1.23:5000/tomcat7   "/bin/bash"         4 days ago          Up 39 minutes       0.0.0.0:8888->8080/tcp          tomcat
  
以在容器的上下文中运行任意命令!即在宿主机上执行容器里的命令
[[email protected] ~]# docker-enter tomcat uptime 
 10:11:05 up 164 days,  2:44,  0 users,  load average: 0.05, 0.03, 0.05
 
-----------------
注意:在宿主机上使用docker-enter命令执行容器中的命令时,最好后面加上--符号,这样容器里的所有存在的命令都可以正常执行。
[[email protected] ~]# docker-enter tomcat -- uptime
 10:49:08 up 164 days,  3:22,  0 users,  load average: 0.02, 0.02, 0.05
 
[[email protected] ~]# docker-enter tomcat -- df -h        //这条命令如果去掉--符号,就不会顺利执行容器中的df -h命令了
Filesystem                                                                                           Size  Used Avail Use% Mounted on
/dev/mapper/docker-253:0-268868570-9ae66abb2dc10d8d1c4327a41bab376c3684f1c49af91cf6ca2b3a3d58a1d07f   10G  584M  9.5G   6% /
tmpfs                                                                                                 32G     0   32G   0% /dev
tmpfs                                                                                                 32G     0   32G   0% /sys/fs/cgroup
/dev/mapper/centos-root                                                                              150G  6.4G  144G   5% /etc/hosts
shm       
 
[[email protected] ~]# docker-enter tomcat -- cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
  
2)使用docker-pid获取容器PID
[[email protected] ~]# echo $(docker-pid tomcat)
31356
[[email protected] ~]# nsenter --target 31356 --mount --uts --ipc --net --pid
[[email protected] /]#

原文地址:http://blog.51cto.com/dengaosky/2067229

时间: 2024-09-27 19:15:47

Docker容器学习梳理--容器登陆方法梳理(attach、exec、nsenter)的相关文章

Docker入门学习2 ——容器基本操作

摘要:介绍Docker容器相关的操作命令. 知识点: run ps start attach exec top stop kill inspect rm logs images rmi pull push commit build 注:可以使用docker COMMAND --help来查看COMMAND的详细用法,本文只介绍常用的子集. 一.启动容器 启动之前未启动过的容器: docker run [-d] [-i] [-t] IMAGE [Command] [Arguments] · -d:

Docker容器学习梳理--容器间网络通信设置(Pipework和Open vSwitch)

自从Docker容器出现以来,容器的网络通信就一直是被关注的焦点,也是生产环境的迫切需求.容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信.下面将分别针对这两方面,对容器的通信原理进行简单的分析,帮助大家更好地使用docker.前面已经在Docker容器学习梳理--基础知识(2)这一篇中详细介绍了Docker的网络配置以及pipework工具. docker单主机容器通信 基于对net namespace的控制,docker可以为在容器创建隔离的网络环境,在隔离的

Docker容器学习梳理--小知识点补充

之前已经梳理了Docker的相关使用事项,这里再补充一些,以便加深掌握程度.1)docker run指令 [[email protected] ~]# docker run --help : docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Run a command in a new container -a, --attach=[] Attach to STDIN, STDOUT or STDERR --add-host=[] Add a custo

Docker容器学习梳理-Dockerfile构建镜像

在Docker的运用中,从下载镜像,启动容器,在容器中输入命令来运行程序,这些命令都是手工一条条往里输入的,无法重复利用,而且效率很低.所以就需要一 种文件或脚本,我们把想执行的操作以命令的方式写入其中,然后让docker读取并分析.执行,那么重复构建.更新将变得很方便,所以Dockerfile就此诞生了.Docker提供了Dockerfile作为构建Docker镜像脚本,避免人们一行一行的输入,真是善莫大焉.Dockerfile脚本可以做到随时维护修改,即可以分享,更有利于在模板化,更不用说传

Docker容器学习--1

Docker是PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源.Docker是通过内核虚拟化技术(namespace以及cgroups等)来提供容器的资源隔离与安全保障.由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机( VM)额外的操作系统开销,提高资源利用率. 特点 1.更高效的利用系统资源 2.更快速的启动时间 3.一致的运行环境 4.更轻

Docker容器学习

Docker学习 docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何接口. 优点:1.提高效率,方便快捷(容器系统资源开销低) 2.沙箱机制,互不干扰 3.集群部署,负载均衡 Client docker CLI(命令行界面工具的客户端)-->REST API-->docker daemon(服务器,守护进程) swarm:docker容器的集群和调

Docker容器学习整理

一.使用Docker镜像1.1 docker常用命令1.2 创建镜像1.3 存出和载入镜像1.4 上传镜像 二.操作docker容器2.1 创建容器2.2 终止容器2.3 进入容器2.4 删除容器2.5 导入和导出容器 三.访问Docker仓库 一.docker基本管理1.1 docker常用命令1.1.1 docker images # 列出本机已有镜像1.1.2 tag命令添加镜像标签1.1.3 docker inspect 查看镜像详细信息1.1.4 history 查看镜像历史1.1.5

关于在docker中配置elasticsearch容器的方法

一.关于docker的安装,注意几点 1.如果系统是Win10家庭版,是没有Hyper-V的,所以无法安装docker(运行docker安装包会报错),为此docker官网提供的解决方法是安装docker toolbox(一种结合docker,git,virtualBox的管理工具),而docker toolbox安装之后下面的导航栏是没有docker图标的. 2.第二种解决方法就是创建一个Hyper-V骗过扫描,网上很多方法可以去查看. 二.docker安装成功之后打开toolbox(我是安装

docker 修改镜像和容器的存放路径(最新自己实践了第三种方法)

原文:docker 修改镜像和容器的存放路径(最新自己实践了第三种方法) docker info :查看docker的存储等相关信息. 将路径修改至挂载磁盘中 前提:磁盘已挂载成功 方法一: 1.停止docker 服务 service docker stop 2.备份数据到新的存放路径 cp -r /var/lib/docker/* /mnt/docker 3.备份 /var/lib/docker 路径 mv /var/lib/docker /var/lib/dockerbak} 4.创建软连接