网络服务
Rancher实现了一个CNI框架,用户可以在Rancher中选择不同的网络驱动。为了支持CNI框架,每个Rancher环境中都需要部署网络服务,默认情况下,每个环境模版都会启用网络服务。除了网络服务这个基础设施服务之外,您还需要选择相关的CNI驱动。在默认的环境模版中,IPSec驱动是默认启用的,它是一种简单且有足够安全性的隧道网络模型。当您一个网络驱动在环境中运行时,它会自动创建一个默认网络,任何使用托管网络的服务其实就是在使用这个默认网络。
与先前版本的区别
当使用1.2版本之前的IPsec网络时,容器使用托管网络将会被分配两个IP,分别是Docker网桥IP(172.17.0.0/16)和Rancher托管IP(10.42.0.0/16)。之后的版本中,则集成了CNI网络框架的标准,容器只会被分配Rancher托管IP(10.42.0.0/16)。
使用CNI的影响
Rancher托管IP不会显示在Docker元数据中,这意味着通过docker inspect
无法查到IP。因为Rancher使用IPtables来管理端口映射, 任何端口映射也无法通过docker ps
显示出来。
容器间连通性
默认情况下,同一环境下的托管网络之间的容器是可达的。如果您想要控制这个行为,您可以部署网络策略服务。如果您在跨主机容器通信中碰到问题,可以移步常见的故障排查与修复方法。
网络类型
在UI上创建服务时,切换到“网络”页签上可以选择网络类型,但是UI上默认不提供“Container”网络类型,如果要使用“Container”类型,则需要通过Rancher CLI/Rancher Compose/Docker CLI来创建。
托管网络
默认情况下,通过UI创建容器会使用托管网络,在容器中使用ip addr或者ifconfig可以看到eth0和lo设备,eth0的IP从属于Rancher托管子网中,默认的子网是10.42.0.0/16,当然您也可以修改这个子网。注意:如果在基础设施服务中删除了网络驱动服务,那么容器的网络设置将会失效。
通过Docker CLI创建容器
任何通过Docker CLI创建的容器,只要添加–label io.rancher.container.network=true的标签,那么将会自动使用托管网络。不用这个标签,大部分情况下使用的是bridge网络。如果容器只想使用托管网络,您需要使用–net=none和–label io.rancher.container.network=true。
None
当容器使用none网络类型,基本上等同于Docker中的—net=none。在容器中也不会看到任何网络设备除了lo设备。
Host
当容器使用host网络类型,基本上等同于Docker中的—net=host。在容器中能够看到主机的网络设备。
Bridge
当容器使用bridge网络类型,基本上等同于Docker中的—net=bridge。默认情况下,容器中可以看到172.17.0.0/16的网段IP。
Container
当容器使用container网络类型,基本上等同于Docker中—net=container:。在容器中可以看到指定容器的网络配置。
Rancher IPSEC使用例子
通过编写YAML文件,利用CNI框架来驱动,就可以构建Rancher的网络基础服务。下面是IPSEC网络驱动的YAML文件样例:
ipsec:
network_driver:
name: Rancher IPsec
default_network:
name: ipsec
host_ports: true
subnets:
- network_address: $SUBNET
dns:
- 169.254.169.250
dns_search:
- rancher.internal
cni_config:
'10-rancher.conf':
name: rancher-cni-network
type: rancher-bridge
bridge: $DOCKER_BRIDGE
bridgeSubnet: $SUBNET
logToFile: /var/log/rancher-cni.log
isDebugLevel: ${RANCHER_DEBUG}
isDefaultGateway: true
hostNat: true
hairpinMode: true
mtu: ${MTU}
linkMTUOverhead: 98
ipam:
type: rancher-cni-ipam
logToFile: /var/log/rancher-cni.log
isDebugLevel: ${RANCHER_DEBUG}
routes:
- dst: 169.254.169.250/32
Name
网络驱动的名字
Default Network
默认网络定义的是当前环境的网络配置
Host Ports
默认情况下,可以在主机上开放端口,当然您可以选择不开放
Subnets
您可以给Overlay网络定义一个子网
DNS && DNS Search
这两个配置Rancher会自动放到容器的DNS配置中
CNI 配置
您可以将CNI的具体配置放在cni_config
下面,具体的配置将会依赖您选择的CNI插件
bridge
Rancher IPSEC实际上利用了CNI的bridge插件,所以您会看到这个设置,默认是docker0
bridgeSubnet
这个配置可以理解为主机上容器的子网,对于Rancher IPSEC就是10.42.0.0/16
mtu
不同的云厂商在网络中配置了不同的MTU值。这个选项可以根据您的需要进行修改。这个选项也是Rancher需要的选项。需要明确的是MTU的配置需要在每一个网络组件上进行设置;在主机上,在Docker Deamon上,在IPsec或者VXLAN的基础服务里都要进行设置。同时同一个环境中的全部主机都需要有相同的设置。如果同一个环境中的全部主机,有着不同的MTU值,那么将会有随机的网络错误发生。
Rancher的IPsec Overlay网络有一个98字节的开销
容器网络接口的MTU = 网络的MTU - 98
例如,您有一个云厂商的MTU值为1200字节,那么如果您在容器中输入
ip addr
或者ifconfig
时,您将会看到1102 (= 1200 - 98)字节的MTU值。
修改MTU
MTU的配置需要在每一个网络组件上进行设置;在主机上,在Docker Deamon上,在IPsec或者VXLAN的基础服务里都要进行设置(需要创建一个新的环境模版)。同时同一个环境中的全部主机都需要有相同的设置。您可以按照下面的步骤来修改MTU。
- 修改主机的MTU
- 我们应该在主机的网络接口上修改这个值,请参考您使用的Linux发行版的文档,来了解如何修改MTU。
- 修改Docker网桥的MTU
- 在大多数情况下,这将会是docker0。如下列,您可以通过在
/etc/docker/daemon.json
中设置MTU。更多详情,请参考Docker的官方文档自定义网桥docker0
{
"mtu": 1450
}
- 创建一个新的环境模版来设置IPsec或者VXLAN基础设施服务所需的MTU值。
- 使用这个新建的环境模版来创建一个新的环境。
MTU只能在环境模版中进行配置。不建议在已有的环境中配置一个不同的MTU值,因为这个值仅会在新创建的容器中生效。
网络策略
Rancher允许用户在环境中配置网络策略。网络策略允许您在一个环境中定义特定的网络规则。所有的容器默认可以互相通信,但是有时您可能需要对的容器间通信做一些限制。
启动Network Policy Manager
当配置环境模版时,您可以启动 Network Policy Manage 组件。
如果您已经有一个启动的Rancher环境,您可以从Rancher应用商店中启动 Network Policy Manager
注意: Network Policy Manager现在只能在使用Cattle编排引擎的时候使用。环境模版基于编排引擎确定哪些组件可用,Rancher支持几乎所有的编排引擎。
通过UI管理网络策略规则
网络策略规则可以在每个环境设置页面中配置。点击左上角下拉列表中的环境管理,然后在需要配置的环境右侧点击编辑按钮
在界面上有四个选择,允许
允许网络通信,禁止
限制网络通信
- 链接服务之间:这个选项用来控制两个服务中链接的容器
- 服务内部: 这个选项用来控制服务内的容器
- 应用内部: 这个选项用来控制相同应用中不同服务
- 其他: 这个选项用来控制上面不包含的情况一个通常的配置是在其他选择
禁止
,其他的都选择允许
。
注意: 规则生效的顺序为从左至右
通过API管理网络策略规则
对于网络资源,defaultPolicyAction
和policy
字段定义了容器间通信的工作规则。policy
字段是内容为网络策略规则的有序数组。通过Rancher的API,可以配置环境的网络策略
获取网络的API地址
要配置网络策略,需要找到相应的网络资源。网络是环境的一部分,找到网络的URL为:
http://<RANCHER_SERVER_IP>/v2-beta/projects/<PROJECT_ID>/networks/<NETWORK_ID>`
怎么查找需要配置的网络的URL:
- 点击API打开高级选项。在 环境API Keys,点击 Endpoint (v2-beta).> 注意:: 在UI上是
环境
,在API是project
。 - 在环境的links属性中查找networks,点击链接。
- 查询您环境中启动的网络驱动的名字。例如:可能为
ipsec
。点击该网络驱动的self - 在右边的Operations中,点击Edit,在
defaultPolicyAction
中,您可以修改默认的网络策略,同时在policy
字段,您可以管理您的网络策略规则。
默认策略
默认所有容器间可以互相通信,在API中,您可以看到defaultPolicyAction
被设置成allow
。
可以通过修改defaultPolicyAction
为deny
来限制所有容器间的通信
网络策略规则
网络策略规则配置容器可以和一系列特定的容器通信
链接服务之间的容器
假设: 服务A链接服务B。
开启服务A和服务B之间的通信:
{
"within": "linked",
"action": "allow"
}
注意: 服务B的容器不会初始化一个链接到服务A。
关闭服务A和服务B之间的通信:
{
"within": "linked",
"action": "deny"
}
在环境内任一链接服务之间的网络策略规则适用于所有有链接的服务
同一服务中的容器
开通同一服务内容器的通信:
{
"within": "service",
"action": "allow"
}
关闭同一服务内容器的通信:
{
"within": "service",
"action": "deny"
}
同一应用中的容器
开通同一应用内容器的通信:
{
"within": "stack",
"action": "allow"
}
关闭同一应用内容器的通信:
{
"within": "stack",
"action": "deny"
}
基于标签的容器通信策略
通过标签开通容器间的通信:
{
"between": {
"groupBy": "<KEY_OF_LABEL>"
},
"action": "allow"
}
通过标签关闭容器间的通信:
{
"between": {
"groupBy": "<KEY_OF_LABEL>"
},
"action": "deny"
}
例子
容器隔离
环境内的容器都无法和彼此通信
- 设置
defaultActionPolicy
为deny
.
应用隔离
同一个应用中的容器可以彼此通信,但是不能和其他应用中的容器通信
- 设置
defaultActionPolicy
为deny
. policy
中添加如下规则:
{
"within": "stack",
"action": "allow"
}
标签隔离
包含匹配的标签的容器之间可以通信,这个规则通过标签去划分可以相互通信的容器
假设在环境中,我们有如下一系列的应用
stack_one:
service_one:
label: com.rancher.department = qa
service_two:
label: com.rancher.department = engineering
service_three:
label: com.rancher.location = cupertino
stack_two:
service_one:
label: com.rancher.department = qa
service_two:
label: com.rancher.location = cupertino
stack_three:
service_one:
label: com.rancher.department = engineering
service_two:
label: com.rancher.location = phoenix
包含com.rancher.department
标签的容器可以相互通信
- 设置
defaultActionPolicy
为deny
. - 在
policy
中添加如下规则:
{
"between": {
"groupBy": "com.rancher.department"
},
"action": "allow"
}
上面有两个不同的标签键值对(例如 com.rancher.department
)。
- 容器包含
com.rancher.department = engineering
彼此间可以通信,但是和其他的容器不能通信。在上面例子中,任何stack_one.service_two
中的容器和stack_three.service_one
中的容器可以彼此通信,但是其他的不能。 - 容器包含
com.rancher.department = qa
彼此间可以通信,但是和其他的不能。在上面的例子中,任何stack_one.service_two
中的容器可以和任何stack_two.service_two
中的容器通信,但是其他的不能。 - 容器不包含key
com.rancher.department
不能和其他容器通信。