rpm -q命令,查看指定软件是否已安装
我们现在在一台没有安装过docker的机器上执行这些操作。
我们可以使用netns管理网络名称空间
r1,r2就是两个网络名称空间,如果我们没有单独指令创建网卡的话,那么它就只有一个lo
我们也可以使用ip命令直接创建虚拟网卡对,然后把一个人工分配到网络名称空间来。
而创建虚拟网卡对无非就是使用ip link命令。
现在我们就创建了一对虚拟网卡,而且他们是成对出现的,但是它们都没有被激活,现在我们使用ifconfig是看不到的。
现在我们就可以将其中的一个放在宿主机上,另一个放到网络名称空间。
接下来我们就将虚拟网卡,veth1.2挪到网络名称空间r1上。
我们甚至还可以对挪到网络名称空间r1的网卡veth1.2进行改名操作
现在我们就将两块网卡全部激活。
先激活宿主机上的网卡
现在我们用宿主机ping一下网络名称空间看能否ping通。
事实上我们也可以将宿主机上的网卡分配给网络名称空间r2
挪到r2之后,这个网卡默认是不被激活的,我们还需要重新激活
现在可以看到挪到r2上的网卡已经被激活了。
现在我们在r2中去ping r1的地址看能否连通
我们可以看到r1和r2也是能连通的。
实际上我们创建的这一对网卡,它们之间本来就有连接,这一对网卡各自在哪,它们就能互相通信。
1.封闭式容器,不设置任何网络设备
2.我们创建一个容器,给它设置一个虚拟网络设备,一半在容器上,另一半在docker连接桥上。
3.我们可以创建一个容器加入到另外一个容器,比如我们先有一个容器A,它有自己的网络名称空间,然后再创建一个容器B,它可以共享容器A的网络名称空间。(UTS及IPC名称空间),这个叫做联盟式容器。所以使得容器A和容器B可以使用lo进行本地通信。
4.第四种是第三种的延伸,它把容器创建之后,网络命名空间直接共享的是宿主机
接下来我们就来看一下效果:
首先是第一种:
正常情况下如果不指定任何网络的话,它就会默认是桥接网络。
运行完之后容器被删除
这样我们就实现了第一种,封闭式容器
我们都知道桥接式容器是用来对外通信的,虽然这个对外并不包含宿主机之外的其他位置。但至少包含宿主机上的其他容器。
大家都知道主机之间通信,很多时候都会使用主机名,那我们先看看当前容器的主机名:
这里看到的主机名其实就是容器id
如果我们想正常使用主机名该怎么办?
我们可以在启动时直接给它分配
现在我们再看的话,主机名就已经改变了
假如说这个容器还希望通过主机名的方式去访问其他主机或者其他容器,那无非就是两种方式。
1.这个容器能够通过DNS服务器进行主机名解析
2.通过自己本地的host文件
我们可以看到当前的域名解析如下图
如果我们不想使用当前的域名解析我们也可以在启动的时候指定。
如果希望在hosts文件中自动解析主机名该怎么办?
同样也可以在启动的时候设置,可以直接在外部注入hosts文件的解析记录
但是这样也有不好的地方,因为宿主机有很多,如果我们一条一条这样去加的话会很麻烦
所以我们就需要进行暴露出来,创建容器的时候使用-p选项可以进行暴露。
我们来暴露一下试试:
接下来看看myweb所使用的ip地址
docker inspect myweb
然后使用curl查看
但是我们这样查看只是内部通信,如果我们想通过外部访问怎么办?
我们先查看一下nat表的规则
iptables -t nat -vnL是什么命令?
用详细方式列出 nat 表所有链的所有规则,只显示 IP 地址和端口号
或者我们也可以通过docker port 容器名称查看
现在我们就可以看到成功从外部访问到了
我们启动两个容器来看看效果,我们启动这两个容器使用同一个镜像
先启动第一个容器
再启动第二个容器
我们可以看到正常启动的话两个容器的ip地址是不同的,说明这两个容器隔离。
所以我们重新启动第二个容器:
这样就构建了联盟式容器,但是这两个容器的文件系统还是隔离的(比如我在第一个容器中创建的目录并不会出现在第二个容器中),只有网络是共享的(比如我在第一台容器上发布的web服务,在第二台容器上可以直接访问,就相当于访问本机)。
这样实现的效果就像在同一个主机下的两个进程
构建web页面,发布web服务
从上图我们可以看出已经将web服务发布到80端口了。
这是将容器的web服务暴露给外部使用最简单的方法(直接与宿主机共享网络命名空间,构建联盟式容器),比我们上面使用的桥接法更简单。
以上就是docker的全部四种网络模型的讲解。
我们可以看到docker0的ip默认为172.17。。。
自定义docker桥的网络属性,需要修改/etc/docker/daemon.json文件。
bip:就是指明docker0桥的ip地址和它的掩码,系统会自动推算出这个桥所属的网络并把这个网络当作随后加入这个桥的所有容器。
default-gateway:默认网关。
dns:dns服务器地址
其中bip是最重要的,只要改了bip其他选项可以通过此地址自动计算得出。
现在我们查看有没有正在运行的docker进程,然后将docker服务停掉
然后编辑docker的daemon.json文件
接着我们重新启动,再次查看ip会发现已经变了
如果期望每个容器自动获得的dns服务器不是宿主机的dns服务器,我们可以修改dns属性,它的值是一个列表,最多只能有三个值。至少一个。
假如我们有两台机器marshal 和 marshal01我们期望通过marshal上的docker来操作marshal01上的docker
我们可以修改docker的daemon.json文件,在文件中添加hosts这就相当于把marshal01上的docker服务发布在2375端口
然后marshal可以通过指定- H参数 实现客户端访问marshal01上的docker并执行操作。
当我们修改完,重新启动的时候可能会报错如下:
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
这可能是docker的socket配置出现了冲突,我们需要修改docker的启动入口文件。
vi /lib/systemd/system/docker.service
修改内容如下:
修改完成之后需要
systemctl daemon-reload
如果直接启动,会有如下警告
重新启动之后,使用ss命令可以看到2375端口已经开放
我们在marshal上操作,默认是显示本机的,但是我们可以使用-H指定连接另一台docker上的docker