转自:https://www.cnblogs.com/jsonhc/p/7760144.html

运行一个container的本身就是开启一个具有独立namespace的进程
  进程有自己的网络,文件系统等
docker通过run命令来启动一个container
运行一个container必须要指定一个image作为初始化的文件系统
 
对于不存在的image,docker会自动去registry里面下载对应的image,然后再运行container
 
command标志的是在container中实际运行的首进程
  操作系统的0号进程
  在centos7系统上是0号进程systemd

  在容器中是/bin/bash进程,也就是本机host上面的一个普通进程
如果image里面包含了CMD的命令,那么在启动container的时候,不需要指定command,否则会使用指定的command来覆盖image中的CMD

  也就是这里显示的COMMAND
  容器的状态会随着command的命令执行而改变
 
前台运行和后台运行:
  默认的container是在前台运行的,会绑定command进程的STDIN、STDOUT、STDERR到console上(在console上展现标准输入、输出和标准错误输出)
    可以通过-d的选项让container运行在后台
  如果是在前台运行,也可以通过-a {STDIN,STDOUT,STDERR}选择需要绑定的IO
    只选择某一个标准展示在console上面
[root@docker ~]# docker run -t -a stdin centos sh -c "while true;do echo hello world;sleep 2;done"
b7930a6c5c4cdf2b73e24e26f2a8fd801e9eb11a1e28b0a376d180d3fd2e4d4a
-a stdin:表示只执行了stdin(虽然在前台运行,但是没有指定stdout和stderr所以并没有显示输出)可以通过logs来查看该容器的stdout
[root@docker ~]# docker logs b7930a6c5c4c
hello world
hello world
通过attach命令可以重新attach一个后台运行的container
  attach可以将后台运行的切换到前台

在后台运行的情况下,RUN命令会返回一个容器的uuid,唯一标识container
可以通过docker ps来查看container的uuid和运行信息
可以通过指定--name的方式来指定container的名字,name必须唯一
 
inspect:可以查看container的更多信息
  通过docker inspect {container_id}来获取container的更多的信息,包括网络,volume,实际在host上的进程id等信息
 
log:
  通过logs命令可以看到container中command所指向进程的STDOUT,STDERR数据
  可以进程排错(-d后台运行没有输出到console时,查看)
# docker run -dt --name mycentos centos sh -c "while true;do echo hello world;sleep 2;done" 

环境变量:
  通过-e参数,可以在运行container的时候添加系统环境变量
 
网络设置:
  docker使用bridge桥接的方式来实现container之间以及和外部的通信

查看本机host的网络信息:
[root@docker ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:efff:fe2d:d653 prefixlen 64 scopeid 0x20<link>
ether 02:42:ef:2d:d6:53 txqueuelen 0 (Ethernet)
RX packets 1 bytes 76 (76.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3 bytes 258 (258.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.101.14 netmask 255.255.255.0 broadcast 192.168.101.255
inet6 fe80::9b70:a5ba:c2d6:d665 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:07:65:c0 txqueuelen 1000 (Ethernet)
RX packets 375314 bytes 497786475 (474.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 134729 bytes 10091671 (9.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 280 bytes 22624 (22.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 280 bytes 22624 (22.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 veth9bd4211: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::5045:f6ff:fef6:da10 prefixlen 64 scopeid 0x20<link>
ether 52:45:f6:f6:da:10 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethe1ab8ab: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::e0e5:e5ff:fe58:ddec prefixlen 64 scopeid 0x20<link>
ether e2:e5:e5:58:dd:ec txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
上述中veth对应几个container网络
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7930a6c5c4c centos "sh -c 'while true..." 5 minutes ago Up 5 minutes stoic_shirley
8179b8e95e31 centos "sh -c 'while true..." 15 minutes ago Up 15 minutes mycentos
两张veth网卡对应两个container容器(正在运行的)
veth网络都桥接在docker0上(被分配)
 
network架构:
  在host主机上的一个veth{id}的虚拟网卡和一个container里面的eth0网卡一一映射
  host上的bridge负责把数据流在不同的veth间转发,实现网络的IO
  bridge(docker0)使用RFC1918私有网络,给每一个container分配ip
 
网络设置
  通过--net参数来修改container的网络设置,默认是bridge的方式
  none表示关闭container的网路连接
  host表示使用主机的网络栈,这个时候host主机不会创建veth虚拟网卡映射到container
    container的网络和主机host的网络在同一网段
# docker run -t --net host saltstack/ubuntu-14.04 sh -c "while true;do ifconfig;sleep 2;done"
container:{name|id},使用另外一个container的网络栈
创建一个容器内的服务,采用本机host的网络ip:
[root@docker ~]# docker run -d --net host saltstack/ubuntu-14.04 python -m SimpleHTTPServer
cd07720586501b298c90067e33fb3c099e6e14d91b9de4327026cc2f06321e08
  -d:创建在后台运行
  --net host:创建在本机host网络上
  python -m SimpleHTTPServer:在容器内执行的命令(命令进程不终止,容器状态也不会停止)

可以看出python的进程已经监听在8000端口上了

  如果不将容器的网络挂在本机host上,那么如何进行访问容器的服务呢?
  将本机host的端口同容器内的端口进行映射,详情看下面端口映射
 
DNS:
  默认使用host的dns设置
  可以通过--dns的参数来指定container自己的dns配置
 
端口映射:
  docker通过采用端口映射的方式,允许把内部container的服务端口暴露到外包
  使用-p参数可以指定需要暴露的container的内部端口,在不指定特定的host的对应端口的情况下,docker会自动分配(49000-49900)在一个host上的端口与其映射
  使用-P参数,表示暴露所有在image中通过EXPOSE指定的端口
[root@docker ~]# docker run -dt -p 8000 saltstack/ubuntu-14.04 python -m SimpleHTTPServer
f7d04a31f5a2d6220a70c8dd7d78a5819bd722b3baab9e743c6c098533bd96ec
-p 8000:表示将容器内的8000端口暴露了出来,由于这里没有明确指定用本机host的哪个端口与之映射,所以这里采用了随机端口
-p 8000:80 -p 443:443:映射容器中的多个端口(前面本机host端口,后面container端口)

通过查看container可以看见随机端口与之做了映射,然后访问主机host的这个端口

下面直接启动一个指定了本机host端口与容器服务端口进行映射:
[root@docker ~]# docker run -dt -p 80:8000 saltstack/ubuntu-14.04 python -m SimpleHTTPServer
a9c3d1c7b6f4319ee34fe726eb5989b7f20bdf4e75e26ef4d5e734665c7efa75

  python -m SimpleHTTPServer:这个服务开启的默认端口为8000

使用inspect查看整个container信息:

如果想映射多个端口时:

  -p 8000:80 -p 443:443:映射容器中的多个端口,只需要在后面连接映射本机host端口对应container端口就行
或者直接-P暴露掉container中的所有端口对应host本机的随机端口
 
volume绑定:
  通过-v参数,可以把host上的一个目录绑定到container中,允许container对其进行读写
[root@docker ~]# mkdir test/wadeson -p
[root@docker ~]# docker run -t -v /root/test:/wadeson saltstack/ubuntu-14.04 sh -c "ls -al /wadeson"
total 0
drwxr-xr-x. 3 root root 21 Oct 27 22:09 .
drwxr-xr-x. 22 root root 257 Oct 27 22:10 ..
drwxr-xr-x. 2 root root 6 Oct 27 22:09 wadeson
  -v /root/test:/wadeson:将本机host下面的test目录映射到container中下面的wadeson目录

  由于命令执行完成后,container也就消亡了停止了
docker 数据卷
  -v, --volume list Bind mount a volume
    为container绑定一个数据卷
[root@docker ~]# docker run -it -v /data -h wadeson saltstack/ubuntu-14.04
root@wadeson:/# ls
bin boot data dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
  -i:交互模式,直接进入到container容器中
  -t:tty,伪终端
  -h wadeson:指定为container设置hostname
  -v /data:container内的/data为挂载点
查看data目录:
root@wadeson:/# ls /data/
root@wadeson:/#
容器中的data目录实际也对应这本机host的某一处目录,使用inspect查看:
  "Mounts": [
{
"Type": "volume",
"Name": "71025e4f8325fce175e21861a1fe0d089b9a08760778a8c9c517d6391c0dbceb",
"Source": "/var/lib/docker/volumes/71025e4f8325fce175e21861a1fe0d089b9a08760778a8c9c517d6391c0dbceb/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}

[root@docker _data]# pwd
/var/lib/docker/volumes/71025e4f8325fce175e21861a1fe0d089b9a08760778a8c9c517d6391c0dbceb/_data
[root@docker _data]# ll
total 0
这里就是本机host的目录映射到container中的/data目录
现在在本机host上创建文件,看看容器中的data目录是否存在创建的文件?
[root@docker _data]# touch wadeson.sh
[root@docker _data]# ll
total 0
-rw-r--r--. 1 root root 0 Oct 26 21:46 wadeson.sh
返回容器查看:
root@wadeson:/# ls /data/
wadeson.sh
于是验证成功,本机host将某个目录映射到容器中,当不指定host的源目录,那么默认在这里
 
现在创建一个指定host上一个目录挂载到容器中:
[root@docker ~]# docker run -it -v /root:/root -h wadeson saltstack/ubuntu-14.04
  将本机host的/root目录挂载到容器中的/root目录
root@wadeson:/# ls /root/
anaconda-ks.cfg docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm
  在容器中已经成功有了本机host下/root目录的数据
而默认的挂载点并没有:
[root@docker volumes]# ll
total 24
drwxr-xr-x. 3 root root 19 Oct 26 21:46 71025e4f8325fce175e21861a1fe0d089b9a08760778a8c9c517d6391c0dbceb
-rw-------. 1 root root 32768 Oct 26 21:39 metadata.db
如果需要将目录挂载在container中只读:
docker run -it -v /root:/root:ro -h wadeson saltstack/ubuntu-14.04
--volumes-from list Mount volumes from the specified container(s)
  从一个指定的容器选择挂载点

现在有两个容器,都是exited状态,现在启动一个容器,将启动的容器的挂载点选择上面图中的任何一个:
[root@docker ~]# docker run -it --volumes-from b8c05a805280 -h wadeson saltstack/ubuntu-14.04
root@wadeson:/# ls /data/
root@wadeson:/#
  --volumes-from b8c05a805280:后面接容器名称或者容器id
  相当于两个container共同使用本机host的挂载点
[root@docker volumes]# ll
total 24
drwxr-xr-x. 3 root root 19 Oct 26 21:46 71025e4f8325fce175e21861a1fe0d089b9a08760778a8c9c517d6391c0dbceb
drwxr-xr-x. 3 root root 19 Oct 26 22:11 f808fc539538ba743c08a852b4b8c4e52c61a33df4c8e52032596385a39b963b
-rw-------. 1 root root 32768 Oct 26 22:11 metadata.db
[root@docker volumes]# cd f808fc539538ba743c08a852b4b8c4e52c61a33df4c8e52032596385a39b963b/_data/
[root@docker _data]# ll
total 0
  上面就是刚刚新建的(两个container共同使用的挂载点)
 
容器间通信:
  通过link参数,把container的端口信息暴露到另一个container中,实现container之间的通信
[root@docker ~]# docker run --name redis -dt redis
7014723aea605fa4baedb83be8e5f6d528b2fc009aa4379a1694f3131b72b041
  启动一个名为redis的实例,后台运行

  因为有默认的CMD命令,所以创建之后容器在处于运行状态
[root@docker ~]# docker run --link redis:db -t saltstack/ubuntu-14.04 sh -c "export"
export DB_ENV_GOSU_VERSION='1.10'
export DB_ENV_REDIS_DOWNLOAD_SHA='b1a0915dbc91b979d06df1977fe594c3fa9b189f1f3d38743a2948c9f7634813'
export DB_ENV_REDIS_DOWNLOAD_URL='http://download.redis.io/releases/redis-4.0.2.tar.gz'
export DB_ENV_REDIS_VERSION='4.0.2'
export DB_NAME='/wizardly_keller/db'
export DB_PORT='tcp://172.17.0.2:6379'
export DB_PORT_6379_TCP='tcp://172.17.0.2:6379'
export DB_PORT_6379_TCP_ADDR='172.17.0.2'
export DB_PORT_6379_TCP_PORT='6379'
export DB_PORT_6379_TCP_PROTO='tcp'
export HOME='/root'
export HOSTNAME='192208a0c626'
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
export PWD='/'
export TERM='xterm'
  该命令创建了将redis的容器的redis服务暴露在另一个container中,利用db这个别名将redis的服务信息暴露给后面这个container的环境变量中,这样后面的container就可以利用变量来连接redis容器的redis服务了
 

docker之container的更多相关文章

  1. 如何获取 docker 容器(container)的 ip 地址

    1. 进入容器内部后 cat /etc/hosts 会显示自己以及(– link)软连接的容器IP 2.使用命令 docker inspect --format '{{ .NetworkSetting ...

  2. 如何获取 docker 容器(container)的 ip 地址(转)

    1. 进入容器内部后 cat /etc/hosts 会显示自己以及(– link)软连接的容器IP 2.使用命令 docker inspect --format '{{ .NetworkSetting ...

  3. Failed to start Docker Application Container

    [root@localhost ~]# systemctl status docker.service ● docker.service - Docker Application Container ...

  4. [问题] docker: Failed to start Docker Application Container Engine.

    docker无法启动: # systemctl restart docker Job for docker.service failed because the control process exi ...

  5. Failed to start Docker Application Container Engine.

    [root@dockertest ~]# systemctl status docker.service● docker.service - Docker Application Container ...

  6. 014-docker-终端获取 docker 容器(container)的 ip 地址

    1. 进入容器内部后 cat /etc/hosts 会显示自己以及(– link)软连接的容器IP 2.使用命令 docker inspect --format '{{ .NetworkSetting ...

  7. Docker 容器(container)及资源限制

    Container: 既然container是由image运行起来的,那么是否可以理解为container和image有某种关系?先来看张图: 其实可以理解为container只是基于image之后的 ...

  8. 启动docker报Failed to start Docker Application Container Engine.解决

    [root@docker ~]# systemctl status docker.service● docker.service - Docker Application Container Engi ...

  9. docker起不来报错:Failed to start Docker Application Container Engine.

    报错信息如下: [root@localhost localdisk]# systemctl restart docker Job for docker.service failed because t ...

  10. docker开启remote-api 2375端口后,Failed to start Docker Application Container Engine,重启docker失败的问题解决

    1.  按照网上的教程修改了 /usr/lib/systemd/system/docerk.service配置后,重启失败.修改/etc/docker/daemon.json 增加hosts后重启也是 ...

随机推荐

  1. MFC 控件使用教程

    combo box控件用法: 下拉选择控件,首先将控件拖动到你需要使用控件的地方,用ClassWizard为它关联一个变量,我们注意到变量类型是CString型的.右击属性,General中可以设置一 ...

  2. [UE4]小技巧:自动添加函数返回值

    将一个变量拖放到返回节点上面会自动创建响应类型的返回值 同样的,函数参数也可以这样来做:

  3. vi/vim 光标移动命令(转载)

    转载至:https://www.cnblogs.com/Jacklovely/p/6015037.html vi/vim 光标移动命令 移动光标上:k nk:向上移动n行 9999k或gg可以移到第一 ...

  4. SCCM2012 R2实战系列之四:初始化配置

    在之前的文章中,我们已经完成了SCCM 2012 R2 独立主站点的部署.为了客户端代理软件的顺利安装和OSD操作系统的分发,我们需要配置组策略及DHCP服务.在本系列的第四部分,跟大家一起分享下如何 ...

  5. linux system()函数详解

    system(3) - Linux man page Name system - execute a shell command Synopsis #include <stdlib.h> ...

  6. Ren'Py视觉小说安装,玩一下吧,上班很闲的话

    ---------------------------------------------------------------------------------------------------- ...

  7. Linux性能优化 第六章 性能工具:磁盘I/O

    6.1 磁盘I/O介绍 一般来说,Linux磁盘的每个分区要么包含一个文件系统,要么包含一个交换分区.这些分区被挂载到Linux根文件系统,该系统由/etc/fstab指定.这些被挂载的文件系统包含了 ...

  8. elasticsearch无故关闭,Log无报错

    可以看到图中的关闭log之前没有任务报错,这也让博主非常抓狂,这看着就像是人为关闭的,于是博主在群里问是不是有人动过该服务,确认没人关闭后,百度无果,社区上也没找到有关信息,最后灵光一闪,猜测是不是因 ...

  9. Linux下卸载安装jdk

    1.检查一下系统中的jdk版本 [root@localhost software]# java -version 显示: openjdk version "1.8.0_102" O ...

  10. val和var和Java

    object Hello { def main(args :Array[String]) { val k = i } } jvm代码 public final class Hello$ { publi ...