转自: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. Jmeter(三十一)Jmeter Question 之 乱码解读

    众所周知,编码的问题影响着众多开发者,当然见多不怪. 先扒了一个编码的原因,也就是为什么要编码: 计算机中存储信息的最小单元是一个字节即 8 个 bit,所以能表示的字符范围是 0~255 个 人类要 ...

  2. css段落(后盾)

  3. Centos 7 下, 安装odoo 10

    1. Centos在虚拟机中, 最小化安装, 网络连接选择的是 桥接模式, 安装完成后, 是不能直接上网的, 输入root 和密码, 登录进去, 然后执行: [root@localhost ~]# v ...

  4. BCGcontrolBar(三) 添加表格(Grid)组件

    表格组件和图表组件是BCG的亮点之一 如下图 BCG有众多的表格样式可供选择 下图是插入基本表格组件后的效果 首先在程序中添加 BasicGridCtrl.h BasicGridCtrl.cpp 因为 ...

  5. Hibernate JPA 关联关系

    Hibernate JPA 关联关系: 使用cascade做级联操作(只有在满足数据库约束时才会生效): CascadeType.PERSIST: 级联保存,只有调用persist()方法,才会级联保 ...

  6. (转)C#操作Word文档

    原文1地址:http://www.cnblogs.com/lantionzy/archive/2009/10/23/1588511.html 原文2地址: http://www.cnblogs.com ...

  7. windows下使用gethostbyname函数报错无法解析的外部符号

    #include <winsock.h> 使用gethostbyname的函数的时候,会显示无法解析的外部符号. 主要问题是因为没有引用WS2_32的lib库 在include上面引用就行 ...

  8. C#提取双引号中的字符串

    public static void Main(string[] args) { string strtmp = "123\"456\"qqq\"789\&qu ...

  9. Windows Server 2016 启用完整版任务管理器

    众所周知 Windows Server 2012以上的任务管理器是被阉割过的 那么如何启用呢?首先把你的任务管理器复制一份出来位置:系统盘\Windows\System32\Taskmgr.exe和系 ...

  10. git error: failed to push some refs to...

    在git环境下push代码时,报错如下: 用gitk查看提交的信息,发现没有生产changeID,主要原因是clone项目时没有把hook克隆下来,解决办法:将项目clone地址的&& ...