Calico

了解 DC/OS Calico 集成

DC/OS Calico 组件

DC/OS Calico 组件通过提供用于 Mesos 通用容器运行时的 Calico CNI 插件和用于 Docker 引擎的 Calico libnetwork 插件,将 Calico 网络连接 集成到 DC/OS 中。此外,calico 控制面板还提供为 DC/OS 工作负载配置网络策略的功能。

DC/OS Calico 将 Calico 集成到 DC/OS 中,用于管理容器网络连接和网络安全,并引入了三种服务:

  • :BGP 客户端,可以在主机之间为 Calico 交换路由信息。
  • dcos-calico-confd.service:confd 模板引擎可以动态监控 etcd 数据存储,并动态地生成和重新加载 bird 配置。(来源)
  • dcos-calico-felix.service:Calico 网络连接的控制面板,用于为容器计划路由和 ACL。
  • dcos-calico-libntwork-plugin.service:Docker 的网络插件,为 Docker 引擎提供 Calico 网络连接。(来源)

DC/OS Calico CLI

DC/OS 命令行包括允许从群集外部运行 calicoctl 命令的 calico 插件。要运行任何 calicoctl 命令,则应将其作为 dcos calico 运行,如 dcos calico get nodes

Calico 网络连接(通用容器运行时)

要使用 Calico 网络连接容器,您只需要将网络名称指定为 calico

以下 Marathon 应用定义示例将使用 Mesos UCR engine 启动容器,并将其插入 calico 网络:

  1. {
  2. "id": "/calico-ucr",
  3. "instances": 1,
  4. "container": {
  5. "type": "MESOS",
  6. "volumes": [],
  7. "docker": {
  8. "image": "mesosphere/id-server:2.1.0"
  9. },
  10. "portMappings": []
  11. },
  12. "cpus": 0.1,
  13. "mem": 128,
  14. "requirePorts": false,
  15. "networks": [
  16. {
  17. "mode": "container",
  18. "name": "calico"
  19. }
  20. ],
  21. "healthChecks": [],
  22. "fetch": [],
  23. "constraints": []
  24. }

与之前的示例相似,以下 Marathon 应用定义示例将使用 Docker Engine 启动容器,并将其插入 calico 网络:

  1. {
  2. "id": "/calico-docker",
  3. "instances": 1,
  4. "container": {
  5. "type": "DOCKER",
  6. "volumes": [],
  7. "docker": {
  8. "image": "mesosphere/id-server:2.1.0"
  9. },
  10. "portMappings": []
  11. },
  12. "cpus": 0.1,
  13. "mem": 128,
  14. "requirePorts": false,
  15. "networks": [
  16. {
  17. "mode": "container",
  18. "name": "calico"
  19. }
  20. ],
  21. "healthChecks": [],
  22. "fetch": [],
  23. "constraints": []
  24. }

管理主题

网络策略

网络策略提供了根据标签选择器指定的应用于端点的有序规则集来控制网络流量的功能,请参阅 ,以了解有关策略规则定义和标签选择器语法的详细说明。

在 DC/OS 中,Calico 网络策略直接向操作人员公开,以便操作人员能够根据不同的情境来管理其流量控制。

DC/OS 中的网络策略限制:

  • Calico 网络策略是一个命名空间资源,但现在,我们仅支持 DC/OS 中的 default 命名空间,并且所有命名空间 Calico 资源应该在 default 命名空间下进行定义。
  • Calico 网络策略仅在 Calico 网络连接容器上生效,这意味着,在非 Calico 网络连接容器(例如,hostnetworkdcosbridge)上设置的标签不会计入 Calico 网络策略。
  • 要让网络策略标签生效,则必须将其设置在 Mesos 上的 NetworkInfo.Labels 中,对于 Marathon 而言,标签应设置在 networks.[].labels 中,例如:
  1. {
  2. "id": "/client",
  3. "instances": 1,
  4. ...
  5. "networks": [
  6. {
  7. "mode": "container",
  8. "name": "calico",
  9. "labels": {
  10. "role": "client"
  11. }
  12. }
  13. ],
  14. }

默认配置文件

Calico 配置文件对继承配置文件中所定义的标签的端点进行分组,例如,每个命名空间都有一个相应的配置文件,以将标签授予该命名空间中的 Pod。Calico 配置文件支持流量控制的策略规则,但不建议使用,我们更侧向于灵活的 NetworkPolicy 和 GlobalNetworkPolicy 资源。

就我们而言,calico 默认情况下,所有 Calico 网络连接容器都会被分配与 CNI 网络的名称相同的默认配置文件,此配置文件允许从一个 Calico 容器网络到另一个 Calico 容器网络的请求,这意味着 L4LB 和 L7 代理请求(其中源 IP 地址被转换到 Calico 所生成的隧道接口的地址(NATed))最后会被丢弃。该配置文件可以在以下 YAML 定义中找到。

  1. apiVersion: projectcalico.org/v3
  2. kind: Profile
  3. metadata:
  4. creationTimestamp: 2019-12-23T04:16:55Z
  5. name: calico
  6. resourceVersion: "75"
  7. uid: 0e105ecb-253b-11ea-9e52-065b6833052c
  8. spec:
  9. egress:
  10. - action: Allow
  11. source: {}
  12. ingress:
  13. - action: Allow
  14. destination: {}
  15. source:
  16. selector: has(calico)
  17. labelsToApply:
  18. calico: ""

在以下业务隔离示例中,我们有三个应用程序定义,如下所示,bookstore-frontend 和 bookstore-server 都被标记为 "biz_type": "bookstore",而 fruitstore-frontend 被标记为 "biz_type": "fruitstore"。在此,我们将创建一个网络策略,以拒绝从 fruitstore-frontend 到 bookstore-server 的请求,而允许从 bookstore-frontend 到 bookstore-server 的请求。

  1. +----------------------+ +------------------------+
  2. | | | |
  3. | bookstore-frontend | | fruitstore-frontend |
  4. | | | |
  5. +-----------------+----+ +----+-------------------+
  6. | |
  7. | |
  8. | x
  9. | |
  10. +----v----------------v--+
  11. | |
  12. | bookstore-server |
  13. | |
  14. +------------------------+

5.3.1. 启动 Marathon 应用程序

bookstore-frontend 的 Marathon 应用程序定义(带有策略标签 "biz_type": "bookstore"):

  1. {
  2. "id": "/bookstore-frontend",
  3. "instances": 1,
  4. "container": {
  5. "type": "MESOS",
  6. "volumes": [],
  7. "docker": {
  8. "image": "mesosphere/id-server:2.1.0"
  9. },
  10. "portMappings": []
  11. },
  12. "cpus": 0.1,
  13. "mem": 128,
  14. "requirePorts": false,
  15. "networks": [
  16. {
  17. "mode": "container",
  18. "name": "calico",
  19. "labels": {
  20. "biz_type": "bookstore"
  21. }
  22. }
  23. ],
  24. "healthChecks": [],
  25. "fetch": [],
  26. "constraints": []
  27. }

bookstore-server 的 Marathon 应用程序定义(带有策略标签 "biz_type": "bookstore""role": "server"),在端口 80 上可用:

fruitstore-frontend 的 Marathon 应用程序定义(带有策略标签 "biz_type": "fruitstore"):

  1. {
  2. "id": "/fruitstore-frontend",
  3. "instances": 1,
  4. "container": {
  5. "type": "MESOS",
  6. "volumes": [],
  7. "docker": {
  8. "image": "mesosphere/id-server:2.1.0"
  9. },
  10. "portMappings": []
  11. },
  12. "cpus": 0.1,
  13. "mem": 128,
  14. "requirePorts": false,
  15. "networks": [
  16. {
  17. "mode": "container",
  18. "name": "calico",
  19. "labels": {
  20. "biz_type": "fruitstore"
  21. }
  22. }
  23. ],
  24. "healthChecks": [],
  25. "fetch": [],
  26. "constraints": []
  27. }

通过执行 dcos marathon app add ${app_definition_yaml_file} 来启动以上三个 Marathon 应用程序,然后我们会获得三个运行中的 Marathon 应用程序,如下所示:

  1. NAME HOST USER STATE ID AGENT ID REGION ZONE
  2. fruitstore-frontend 172.16.2.233 root TASK_RUNNING fruitstore-frontend.instance-8a3ed6db-2a47-11ea-91b3-66db602e14f5._app.1 0a1399a2-fe1f-4613-a618-f45159e12f2a-S0 N/A N/A
  3. bookstore-server 172.16.29.45 root TASK_RUNNING bookstore-server.instance-825bcbda-2a47-11ea-91b3-66db602e14f5._app.1 0a1399a2-fe1f-4613-a618-f45159e12f2a-S1 N/A N/A
  4. bookstore-frontend 172.16.2.233 root TASK_RUNNING bookstore-frontend.instance-79853919-2a47-11ea-91b3-66db602e14f5._app.1 0a1399a2-fe1f-4613-a618-f45159e12f2a-S0 N/A N/A

前端和服务器连接测试

在应用网络策略之前,从 bookstore-frontend 和 fruitstore-frontend 到 bookstore-server 的请求已成功,我们期待 FQDN bookstore-server.marathon.containerip.dcos.thisdcos.directory 返回 bookstore-server 容器 IP 地址:

  1. dcos task exec fruitstore-frontend wget -qO- bookstore-server.marathon.containerip.dcos.thisdcos.directory:80/id
  2. hubfeu2yculh%
  3. dcos task exec bookstore-frontend wget -qO- bookstore-server.marathon.containerip.dcos.thisdcos.directory:80/id
  4. hubfeu2yculh%

应用网络策略

该网络策略在 bookstore-server 上生效,并允许来自标签 biz_type 设置为 bookstore 应用程序的请求,而拒绝来自标签 biz_type 设置为 fruitstore 的应用程序的请求:

  1. apiVersion: projectcalico.org/v3
  2. kind: NetworkPolicy
  3. metadata:
  4. name: allow-bookstore-cliient-to-server
  5. spec:
  6. selector: biz_type == 'bookstore' && role == 'server'
  7. types:
  8. - Ingress
  9. ingress:
  10. - action: Allow
  11. protocol: TCP
  12. source:
  13. selector: biz_type == 'bookstore'
  14. destination:
  15. ports:
  16. - 80
  17. - action: Deny
  18. protocol: TCP
  19. source:
  20. selector: biz_type == 'fruitstore'
  21. destination:
  22. ports:
  23. - 80

我们可以临时登录到 DC/OS 节点,并通过执行 dcos calico apply -f ${network_policy_yaml_file} 来应用网络策略。

来自 bookstore-frontend 的请求如期成功:

  1. dcos task exec bookstore-frontend wget -qO- bookstore-server.marathon.containerip.dcos.thisdcos.directory:80/id
  2. hubfeu2yculh%

来自 fruitstore-frontend 的请求超时,因为数据包丢失。

  1. dcos task exec fruitstore-frontend wget -qO- --timeout=5 bookstore-server.marathon.containerip.dcos.thisdcos.directory:80/id
  2. wget: can't connect to remote host (192.168.219.133): Connection timed out

添加网络配置文件

在大多数用例中,单个 Calico 配置文件已经足够。但是,如果出于任何原因需要创建更多网络,则应注意一些特殊情况。

也就是说,要添加网络配置文件,您应该:

  1. 创建新的 IP 池。例如:

将上述 yaml 保存到 ip.yml,然后运行:

  1. dcos calico create -f ip.yml
  1. 创建新的 Calico 配置文件。例如:
  1. apiVersion: projectcalico.org/v3
  2. kind: Profile
  3. metadata:
  4. name: <profile-name>
  5. spec:
  6. egress:
  7. - action: Allow
  8. destination: {}
  9. source: {}
  10. ingress:
  11. - action: Allow
  12. destination: {}
  13. source: {}
  14. labelsToApply:
  15. calico: ""

将上述 yaml 保存到 profile.yml,然后运行:

  1. dcos calico create -f profile.yml
  1. 每个代理 上,创建一个新的 docker 网络,并使用新的配置文件。您可以使用以下命令,确保子网与池中的 cidr 匹配:
  1. docker network create \
  2. --opt org.projectcalico.profile=<profile-name> \
  3. --driver calico \
  4. --ipam-driver calico-ipam \
  5. --subnet=10.1.0.0/16 \
  6. <network-name>

无法自动迁移 DC/OS 群集中现有的所有服务。可以通过各种 Apache Mesos 框架启动服务,包括经生产验证的平台 Marathon、构建于 [dcos-common](. This includes existing, stateful services such as Cassandra 和 之上的服务以及从您的环境中托管的服务。

Marathon 应用程序(aka DC/OS 服务)

至少有两种方法让 Marathon 应用程序的变更生效:

  • DC/OS CLI 更新应用程序定义,以将网络名称从 dcos 变更为 calicodcos app update calico_network_app.json

对于此方法,相应的文件 calico_network_app.json 包含不同于 DC/OS 网络应用程序的 Calico 网络应用程序的定义,如下所示:

  1. {
  2. "networks": [
  3. {
  4. "mode": "container",
  5. - "name": "dcos"
  6. + "name": "calico"
  7. }
  8. ]
  9. }
  • DC/OS GUI

导航至服务的“网络连接”选项卡,并将网络类型从 Virtual Network: dcos 变更为 Virtual Network: calico

通常,DC/OS 服务中有两个组件:

  • 调度器 - 执行一个计划以启动 Pod 的 Marathon 应用程序
  • Pod - 履行服务职责的工人应用程序。

由于调度器和 Pod 被定义为发布包,并且为了在调度器和 Pod 使用虚拟网络的情况下进行永久性更改,我们必须在执行以下更改后生成新版本的 DC/OS 服务:

  • 对于调度器 调度器的 Marathon 应用程序定义在包定义中被定义为模板 marathon.json.mustache,并由操作人员根据 config.json 中定义的变量来填写。启用虚拟网络时,操作员应确保 VIRTUAL_NETWORK_NAMEcalico

  • 对于 Pod dcos-common 允许 Pod 加入虚拟网络,并且默认情况下可使用 dcos 虚拟网络。将应用程序从 dcos 迁移至 calico,需要进行如下更改:

  1. pods:
  2. pod-on-virtual-network:
  3. count:
  4. networks:
  5. - dcos:
  6. + calico:
  7. tasks:
  8. ...
  9. pod-on-host:
  10. count:
  11. tasks:

故障排除