从0开始学Docker(下)

引言

这一篇文章,理论和实践各占一半,有需要的可以先安装配置好两台虚拟机和Docker。
觉得写的可以不妨点个赞吧,收藏比赞高N倍,枯了​😂~

文章导读

  • Docker的C/S架构​​
  • Docker容器的网络连接​
  • Docker容器的数据管理

一、Docker的C/S模式

Docker的C/S架构中,最重要的就是Docker Client和Docker Daemon。

1.1 Docker的C/S模式

Docker守护进程会在Docker启动后,在宿主机后台运行,负责处理docker的各种命令功能。用户并不是直接和守护进程交互,而是和Docker客户端交互。意思是我们输入的命令,通过命令行接口(/bin/bash这样二进制的程序),再传递给守护进程,守护进程再将命令执行后返回结果给客户端,显示于命令行接口。

图片来源于网络

docker客户端除了以命令的方式和守护进程通信,还可通过Remote API。

图片来源于网络

客户端与守护进程的连接方式

从整体上来看,用户通过命令行接口或应用程序(程序是对Remote API的封装)来对Docker Client进行访问,而这个客户端是以Socket的方式来对守护进程访问的。

Docker是以Socket的方式连接,有三种模式:

  • unix://var/run/docker.sock(默认)
  • tcp://host:port
  • fd://socketfd
图片来源于网络

1.2 Docker守护进程的配置和操作

使用service命令管理

  • service docker start
  • service docker stop
  • service docker restart

Docker的启动选项

docker -d [OPTIONS]

  • 运行相关 
    -D,--debug:是否开启debug
    -e, 运行时使用的驱动模式
    -g ,指定docker写入文件的地址
    --icc :指定容器之间是否可以互相连接
    -l,--log-level:设置日志界别 
    -p,pidfile默认为"/var/run/docker.pid"
  • 服务器连接相关 
    -G,指定用户组,默认是"docker" 
    -H,按照上一节所讲的Socket连接模式来写
    --tls=false 安全性相关选项
    ... ...
  • RemoteAPI相关
    --api-enable-cors 是否使用RemoteAPI
  • 存储相关
    -s:storage driver,设置驱动 
    --selinux-enable:是否开启selinux 
    ... ...
  • Registry相关
    --registry-mirror:配置镜像连接
  • 网络设置相关(下一章会讲) 
    -ip 
    -ip-forward:决定是否会转发流量
    --iptables :允许容器与iptables设置的ip之间的访问
    ... ...

具体配置可以参考官网: 详细配置说明

除了通过设置启动时的参数,也可以通过配置docker启动时的配置文件,/etc/default/docker设置详细的配置项。

二、Docker容器的网络连接

Docker的网络连接部分主要包括:

  • Docker容器的网络基础
  • Docker容器的互联
  • Docker容器与外部网络的连接
  • Docker容器的跨主机访问

2.1 Docker容器的网络基础

Docker守护进程启动后,在宿主机中查看网卡信息,会发现多了一个网卡(Docker0)。Docker0其实就是一个Linux虚拟网桥。

提到这里,先回顾一下什么是网桥? 
网桥工作于数据链路层,通过网络设备的物理地址(MAC地址)对网络进行划分,在不同网络之间传递数据。

Linux虚拟网桥的特点是可以设置IP地址,相当于拥有一个隐藏的虚拟网卡。

docker0来说,他的IP地址为172.17.0.1,属于B类IP。子网掩码为255.255.0.0。可以计算出总共可划分65534个地址。

docker0的工作过程

Docker对网络连接的管理,是在容器启动时就初始化两端。一端是容器中的网络设备,另一端在守护进程的主机中(docker0的Host端)开放veth开头的接口,用于网桥与容器网卡的网络通信。

简单感受下网桥是怎么工作的:

  1. 首先安装网桥管理程序
    yum install bridge-utils
  2. 查看网桥设备 
    brctl show

3. 创建一个容器

  • docker run -it --name container1 centos:centos7 /bin/bash
  • ctrl+P;ctrl+Q(让容器后台运行)

此时可以看到,网桥有了对应的网络。

我们也可以自定义docker0的ip网段,使用ifconfig指令:
ifconfig docker0 192.168.200.1 netmask 255.255.255.0

自定义虚拟网桥

  1. 添加虚拟网桥 
    brctl addbr newbridge 
    ifconfig newbridge 192.168.100.1 netmask 255.255.255.0
  2. 更改docker守护进程的启动配置 
    vim /etc/default/docker 
    添加DOCKER_OPS="-b=newbridge"

2.2 Docker容器的互联

Docker容器的互联可分为:

  • 允许所有容器互联
  • 拒绝容器间互联
  • 允许特定容器间的连接

前提

FROM centos:centos7
RUN yum install -y ping
RUN yum install -y nginx
RUN yum install -y curl
EXPOSE 80
CMD /bin/bash

构建镜像 docker build -t image1 .

2.2.1 允许容器间的互联

容器之间默认是可以互联的,具体可由docker守护进程的启动选项:--icc=true|false指定。

  1. 构建容器 
    docker run -it --name container1 image1
  2. 启动服务 
    nginx
  3. 让容器后台运行后,再启动一个容器 docker run -it --name container2 image1
  4. 进入各自容器,互相ping一下,发现是可行的

配置容器间的动态连接

docker容器重启后,IP会发生变化,如果服务与服务之间将IP写死调用,势必会调用失败,此时就需要link参数: 
docker run --link=[CONTAINER]:[ALIAS] [IMAGE] [COMMAND] 

给某个想要连接的容器取别名,这样在容器重启时,对应的host文件中的映射也会变化

2.2.2 拒绝容器间的互联

首先要修改守护进程的启动选项,就要修改docker默认的配置文件。

  • vim /etc/default/docker
  • 在DOCKER_OPS中添加--icc=false

执行service dockers restart后,创建的所有容器都不能互联,如果需要指定容器互联就需要下一节的操作。

2.2.3 允许特定容器间的连接

  1. Docekr守护进程的启动选项:
    --icc=false
    --iptables=true
  2. 重启一下docker,创建容器时用--link指定
    service docker restart 
    docker run -it --name container3 --link=container1:c1 image1
  3. 测试是否能连通
    curl c1

2.3 Docker容器与外部网络连接

ip-forward是linux系统中的变量,决定是否会转发流量。 对应了Linux的这个系统变量:
sysctl net.ipv4.conf.all.forwarding

docekr守护进程配置的ip-forword默认为true。iptables是与Linux内核集成的包过滤防火墙系统,几乎所有的Linux发行版本都包括iptables的功能。

阻止特定ip对特定容器的访问

指令格式:
iptables -I DOCKER -s 源地址 -d 目标地址 -p TCP --dport 目的端口 -j 执行操作 
注:执行操作包括DROP,ACCEPT等等。

可以通过iptables -L -n 来查看系统中的一些包过滤规则。

通过一个例子感受下:
阻止192.168.29.100访问容器ip为192.168.29.111的80端口
iptables -l DOCKER -s 192.168.29.100 -d 192.168.29.111 -p TCP --dport 80 -j DROP

如果是允许的化,也同理,讲DROP改为ACCEPT。

2.4 Docker容器的跨主机访问

目前搜集的至少有3中方式可以实现:

  • 使用网桥实现跨主机容器连接。
  • 使用Open vSwitch实现跨主机容器连接。
  • 使用weave实现跨主机容器连接。

这里由于配置简单,就讲解第一种,使用网桥的方式。

主要思路:
如果将连接容器的网桥桥接到docker宿主机提供的网卡上,并将网桥分配的ip地址与docker宿主机的ip地址设置到同一网段,就能够实现容器与容器之间跨主机的通信。简单来说就是在一个宿主机中,大家都用一个网桥

图片来源于网络

操作步骤

  1. 需要两台虚拟机
    IP地址:Host1(192.168.29.3),Host2(192.168.29.4)
  2. 修改两台虚拟机中网桥的连接
    vim /etc/network/interfaces 
    配置如下:
auto bridge
#分配网桥的方式
iface bridge inet static
address 192.168.29.3
netmask 255.255.255.0
#默认网关
gateway 192.168.29.1
#将本地的物理网卡连接到新建的网桥上
bridge_ports eth0

在另一台虚拟机中也进行类似操作。

3. 修改docker默认的网络配置
IP的划分将改成192.168.29.65~192.168.29.126和192.168.29.129~192.168.29.190
Host1中:
vim /etc/default/docker 
DOCKER_OPTS=" -b=bridge --fixed-cidr='192.168.29.64/26' "

Host2中:
DOCKER_OPTS=" -b=bridge --fixed-cidr='192.168.29.128/26' "

4. 启动一个容器,执行ping另一台宿主机的ip或者另一台宿主机中的容器,发现能够连通则配置成功。

三、Docker容器的数据管理

有时候,我们需要容器与宿主机磁盘中的数据共享,对此,Docker提供的解决方案是数据卷技术。以容器挂载数据卷的方式来实现数据的互通。

本小节主要分为:

  • Docekr容器的数据卷
  • Docker的数据卷容器
  • Docker数据卷的备份和还原

3.1 Docker容器的数据卷

什么是数据卷? 
数据卷是经过特殊设计的目录,可以绕过联合文件系统(UFS),为一个或多个容器提供访问。对数据卷应该有如下的感觉:

数据卷设计的目的在于持久化,它完全独立于容器的生存周期,因此,Docker不会在容器删除时,删除其挂载的数据卷,也不会存在类似的垃圾收集机制,对容器的数据卷进行处理。

数据卷的特点

  • 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会拷贝到新初始化的数据卷中。
  • 数据卷可以在容器之间共享和重用。
  • 可以对数据卷里的内容直接进行修改。
  • 数据卷的变化不会影响镜像的更新。
  • 卷会一直存在,即使挂载数据卷的容器已经被删除。

为容器添加数据卷

docker run -v ~/container_data:/data -it centos:centos7 /bin/bash

为数据卷添加访问权限

docker run -v 宿主机目录:容器目录:ro IMAGE COMMAND -d 
注:"ro"的意思是read only。

使用Dockerfile构建数据卷

VOLUME["/data"]

这里是不需要写明映射关系的,因为通过这个镜像创建的不同容器的数据卷是不一样的。具体映射关系可以通过docker inspect CONTAINER 查看。

3.2 Docker的数据卷容器

数据卷提供了容器与宿主机的共享数据,如果容器与容器之间要共享,该怎么办呢?这就需要挂载包含数据卷的容器来实现。

什么是数据卷容器? 
命名的容器挂载数据卷,其他容器通过挂载这个容器实现数据共享,挂载数据卷的容器叫数据卷容器。

文字看着又绕又枯燥,一张图梳理一下:

图中可以看出:

  1. 数据卷容器挂载了一个本地目录。
  2. 其他容器通过连接这个数据卷容器实现数据的共享。

挂载数据卷容器的方法 
docekr run --volumes-from [CONTAINER] 
注:CONTAINER是挂载数据卷的容器。

下面通过一个例子来实现container1与container2的数据共享。

前提

image2.dockerfile如下:

FROM centos:centos7
VOLUME["/datavolume"]
CMD /bin/bash

构建镜像后的步骤

下面步骤中container1是数据卷容器,container2和container3要实现数据共享。

  1. 启动container1
    docker run -it --name container1 image2
  2. 在container1中创建文件
    touch /datavolume/c1
  3. exit
  4. 启动container2,并挂载到container1
    docker run -it --name container2 --volumes-from container1 IMAGE /bin/bash
  5. 在container2中创建文件
    touceh /datavolume/c2
  6. exit
  7. 同理启动container3
    docker run -it --name container3 --volumes-from container1 IMAGE /bin/bash
  8. exit
  9. docker inspect --format="{{.Volumes}}" container2
  10. docker inspect --format="{{.Volumes}}" container3

最后,我们可以惊奇地发现两个挂载了数据卷容器的容器返回结果一样

此时将container1容器删除,会发现,container2和container3还是共享了一个数据卷容器,因此可以得出这样的结论:数据卷容器仅仅承载配置信息的传递

3.3 Docker数据卷的备份和还原

数据备份方法

docker run --volumes-from CONTAINER -v 期望备份存放的路径(宿主机路径):映射到备份命令容器中的目录:权限(一般为wr,即读写权限) IMAGE tar cvf 压缩至某个路径下的某个文件名(宿主机路径) 数据卷在容器中的路径

文字描述比较绕,通过例子展示一下:

docker run --volumes-from container1 -v ~/backup:/backup --name container2 IMAGE tar cvf /backup/c1.tar /datavolume1

具体过程:

备份过程其实就是对数据容器挂载的数据卷中的数据的转移,相当于执行备份命令的容器既挂载了数据容器的数据卷,又挂载了备份数据存放的数据卷。

同样地,数据还原方法就是对备份的解压缩:
docker run --volumes-from container1 -v ~/backup:/backup IMAGE tar xvf /backup/backup.tar /datavolume1

总结

Docker的学习暂时告一段落,在这个过程中,最终要的还是在虚拟机中多多实践。真实运行中可能会碰到许多问题,解决问题的过程中经验才能一步一步的积累~

感觉写得还可不妨点个赞哈~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值