Magnum 用户指南

本指南面向使用 Magnum 部署和管理容器编排引擎主机集群的用户。它描述了 Magnum 创建的基础设施以及如何使用它们。

第 1-3 部分描述了 Magnum 本身,包括概述、CLI 和 Horizon 界面。第 4-9 部分描述了支持的容器编排引擎 (COE),以及如何选择最符合您需求的引擎以及如何为新的 COE 开发驱动程序。第 10-15 部分描述了 Magnum 创建和管理的底层 OpenStack 基础设施,以支持 COE。

警告

此处描述的 heat 驱动程序已被弃用,推荐使用 k8s_capi_helm 或 k8s_cluster_api 驱动程序,并且将在未来的 Magnum 版本中删除。

  1. 概述

  2. Python 客户端

  3. Horizon 界面

  4. 集群驱动程序

  5. Heat 堆栈模板

  6. 选择 COE

  7. 原生客户端

  8. Kubernetes

  9. 传输层安全

  10. 网络

  11. 高可用性

  12. 伸缩

  13. Storage

  14. 镜像管理

  15. 通知

  16. 容器监控

  17. Kubernetes 安装后清单

  18. Kubernetes 外部负载均衡器

  19. Kubernetes 的 Keystone 身份验证和授权

  20. 节点组

  21. Kubernetes 健康监控

概述

Magnum 是由 OpenStack Containers Team 开发的 OpenStack API 服务,它使像 Kubernetes 这样的容器编排引擎作为 OpenStack 中的一流资源可用。

Magnum 使用 Heat 来编排包含 Docker 和 COE 的 OS 镜像,并在虚拟机或裸机集群配置中运行该镜像。

Magnum 提供 OpenStack 环境中 COE 的完整生命周期管理,并与 OpenStack 的其他服务集成,为希望在 OpenStack 环境中运行容器的 OpenStack 用户提供无缝体验。

以下是 Magnum 的一些主要特性

  • 基于标准 API 的容器集群完整生命周期管理

  • 容器集群的多租户支持

  • COE 的选择:Kubernetes

  • 容器集群部署模型的选择:VM 或裸机

  • 基于 Keystone 的多租户安全和身份验证管理

  • 基于 Neutron 的多租户网络控制和隔离

  • 基于 Cinder 的容器卷服务

  • 与 OpenStack 集成:云用户的 SSO 体验

  • 安全的容器集群访问(启用 TLS)

ClusterTemplate

ClusterTemplate(以前称为 BayModel)是一组描述如何构建集群的参数。一些参数与集群的基础设施相关,而另一些参数则与特定的 COE 相关。在典型的流程中,用户会创建一个 ClusterTemplate,然后使用该 ClusterTemplate 创建一个或多个集群。云提供商还可以定义一些 ClusterTemplate 并将其提供给用户。如果使用此 ClusterTemplate 的集群仍然存在,则无法更新或删除 ClusterTemplate。

ClusterTemplate 的参数定义和使用如下。它们大致分为:必需、基础设施、COE 特定。

<name>

要创建的 ClusterTemplate 的名称。名称不必唯一。如果多个 ClusterTemplate 具有相同的名称,则需要在创建集群或更新、删除 ClusterTemplate 时使用 UUID 来选择 ClusterTemplate。如果未指定名称,将使用字符串和数字生成随机名称,例如“pi-13-model”。

–coe <coe>

指定要使用的容器编排引擎。支持的 COE 是“kubernetes”。如果您的环境安装了其他集群驱动程序,请参阅集群驱动程序文档以获取新的 COE 名称。这是一个必需的参数,没有默认值。

–image <image>

在 Glance 中启动集群服务器的基础镜像的名称或 UUID。镜像必须定义 ‘os_distro’ 属性,该属性适合集群驱动程序。对于当前支持的镜像,os_distro 名称是

COE

os_distro

Kubernetes

fedora-coreos

这是一个必需的参数,没有默认值。请注意,os_distro 属性区分大小写。

–keypair <keypair>

要在集群服务器上配置的 SSH 密钥对的名称,用于 ssh 访问。您需要密钥才能 ssh 到集群中的服务器。登录名特定于集群驱动程序。如果在模板中未提供密钥对,则在创建集群时需要提供它。此值将覆盖在创建集群期间提供的任何密钥对值。

–external-network <external-network>

Neutron 网络名称或网络 ID,用于为集群提供与外部互联网的连接。此网络必须是外部网络,即其属性 ‘router:external’ 必须为 ‘True’。集群中的服务器将连接到私有网络,Magnum 将在此私有网络和外部网络之间创建一个路由器。这将允许服务器下载镜像、访问发现服务等,并允许容器安装软件包等。反之,将从外部网络分配浮动 IP,以提供从外部互联网到服务器和集群中托管的容器服务的访问权限。这是一个必需的参数,没有默认值。

--public

对 ClusterTemplate 的访问通常仅限于管理员、所有者或与所有者在同一租户中的用户。设置此标志会使 ClusterTemplate 公开,并可供其他用户访问。默认情况下不公开。

–server-type <server-type>

集群中的服务器可以是 VM 或裸机。此参数选择为集群创建的服务器类型。默认值为 ‘vm’。可能的值是 ‘vm’、‘bm’。

–network-driver <network-driver>

用于为容器提供网络的网络驱动程序的名称。请注意,这与集群的 Neutron 网络不同。操作和网络模型特定于特定的驱动程序;请参阅 网络 部分以获取更多详细信息。支持的网络驱动程序和默认驱动程序是

COE

网络驱动程序

默认值

Kubernetes

flannel, calico

flannel

请注意,网络驱动程序名称区分大小写。

–volume-driver <volume-driver>

用于管理容器持久存储的卷驱动程序的名称。支持的功能特定于驱动程序。支持的卷驱动程序和默认驱动程序是

COE

卷驱动程序

默认值

Kubernetes

cinder

无驱动程序

请注意,卷驱动程序名称区分大小写。

–dns-nameserver <dns-nameserver>

集群中的服务器和容器要使用的 DNS 域名服务器。这在集群的私有 Neutron 网络中配置。默认值为 ‘8.8.8.8’。

–flavor <flavor>

用于启动节点服务器的 nova flavor id。默认值为 ‘m1.small’。此值可以在集群创建时覆盖。

–master-flavor <master-flavor>

用于启动主服务器或管理器服务器的 nova flavor id。默认值为 ‘m1.small’。此值可以在集群创建时覆盖。

–http-proxy <http-proxy>

服务器直接通过 http 访问外部网站被阻止时要使用的代理的 IP 地址。这可能发生在某些国家/地区或企业中,并且代理允许服务器和容器访问这些网站。格式是包含端口号的 URL。默认值为 ‘None’。

–https-proxy <https-proxy>

服务器直接通过 https 访问外部网站被阻止时要使用的代理的 IP 地址。这可能发生在某些国家/地区或企业中,并且代理允许服务器和容器访问这些网站。格式是包含端口号的 URL。默认值为 ‘None’。

–no-proxy <no-proxy>

当使用代理服务器时,某些网站不应通过代理,而应正常访问。在这种情况下,您可以将这些网站指定为逗号分隔的 IP 列表。默认值为 ‘None’。

–docker-volume-size <docker-volume-size>

如果指定,容器镜像将存储在指定大小(以 GB 为单位)的 cinder 卷中。每个集群节点将附加一个上述大小的卷。如果未指定,则镜像将存储在计算实例的本地磁盘中。对于 ‘devicemapper’ 存储驱动程序,必须指定卷,并且最小值为 3GB。对于 ‘overlay’ 和 ‘overlay2’ 存储驱动程序,最小值为 1GB 或 None(无卷)。此值可以在集群创建时覆盖。

–docker-storage-driver <docker-storage-driver>

用于管理镜像和容器可写层存储的驱动程序的名称。默认值为 ‘devicemapper’。

–labels <KEY1=VALUE1,KEY2=VALUE2;KEY3=VALUE3…>

任意标签,格式为 key=value 对。接受的键和有效值由驱动程序定义。它们用作传递特定于集群驱动程序的附加参数的一种方式。有关支持的键/值对及其用法的列表,请参阅标签子部分。

--tls-disabled

传输层安全 (TLS) 通常启用以保护集群。在某些情况下,用户可能希望在集群中禁用 TLS,例如在开发期间或排除某些问题的故障。指定此参数将禁用 TLS,以便用户无需证书即可访问 COE 端点。默认情况下启用 TLS。

--registry-enabled

Docker 镜像默认从公共 Docker 注册表拉取,但在某些情况下,用户可能希望使用私有注册表。此选项提供了一个基于 Registry V2 的替代注册表:Magnum 将在集群中创建一个本地注册表,该注册表由 swift 支持,以托管镜像。有关更多详细信息,请参阅 Docker Registry 2.0。默认情况下使用公共注册表。

--master-lb-enabled

由于集群中可能存在多个主节点,因此会创建一个负载均衡器来提供集群的 API 端点并将其请求定向到主节点。在某些情况下,例如当 LBaaS 服务不可用时,可以将此选项设置为 ‘false’ 以创建一个没有负载均衡器的集群。在这种情况下,一个主节点将充当 API 端点。默认值为 ‘true’,即为集群创建负载均衡器。

Labels

Labels 是一种指定与特定 COE 或与特定选项相关的补充参数的通用方法。它们的格式是键/值对,其含义由使用它们的驱动程序解释。驱动程序会验证键/值对。它们的使用在适当的部分中详细说明,但是,由于可能存在许多标签,以下表格提供了一个摘要,以帮助更清晰地了解情况。表格中的标签键链接到用户指南其他地方的更多详细信息。

标签键

标签值

default

flannel_network_cidr

IPv4 CIDR

10.100.0.0/16

flannel_backend

  • udp

  • vxlan

  • host-gw

vxlan

flannel_network_subnetlen

分配给节点的子网大小

24

heapster_enabled

  • true

  • false

false

metrics_server_chart_tag

见下文

见下文

metrics_server_enabled

  • true

  • false

true

monitoring_enabled

  • true

  • false

false

monitoring_retention_days

见下文

见下文

monitoring_retention_size

见下文

见下文

monitoring_storage_class_name

见下文

见下文

monitoring_interval_seconds

见下文

见下文

monitoring_ingress_enabled

  • true

  • false

false

cluster_basic_auth_secret

见下文

见下文

cluster_root_domain_name

见下文

见下文

prometheus_operator_chart_tag

见下文

见下文

prometheus_adapter_enabled

  • true

  • false

true

prometheus_adapter_chart_tag

见下文

见下文

prometheus_adapter_configmap

(rules CM 名称)

“”

traefik_ingress_controller_tag

见下文

见下文

admission_control_list

见下文

见下文

prometheus_monitoring (已弃用)

  • true

  • false

false

grafana_admin_passwd

(任何字符串)

“admin”

hyperkube_prefix

见下文

见下文

kube_tag

见下文

见下文

cloud_provider_tag

见下文

见下文

etcd_tag

见下文

见下文

coredns_tag

见下文

见下文

flannel_tag

见下文

见下文

flannel_cni_tag

见下文

见下文

heat_container_agent_tag

见下文

见下文

kube_dashboard_enabled

  • true

  • false

true

kube_dashboard_version

见下文

见下文

metrics_scraper_tag

见下文

见下文

influx_grafana_dashboard_enabled

  • true

  • false

false

docker_volume_type

见下文

见下文

boot_volume_size

见下文

见下文

boot_volume_type

见下文

见下文

etcd_volume_size

etcd 存储卷大小

0

etcd_volume_type

见下文

见下文

container_infra_prefix

见下文

“”

availability_zone

集群节点的 AZ

“”

cert_manager_api

见下文

false

ingress_controller

见下文

“”

ingress_controller_role

见下文

“ingress”

octavia_ingress_controller_tag

见下文

见下文

nginx_ingress_controller_tag

见下文

见下文

nginx_ingress_controller_chart_tag

见下文

见下文

kubelet_options

额外的 kubelet 参数

“”

kubeapi_options

额外的 kubeapi 参数

“”

kubescheduler_options

额外的 kubescheduler 参数

“”

kubecontroller_options

额外的 kubecontroller 参数

“”

kubeproxy_options

额外的 kubeproxy 参数

“”

cgroup_driver

  • systemd

  • cgroupfs

“cgroupfs”

cloud_provider_enabled

  • true

  • false

见下文

service_cluster_ip_range

k8s 服务门户的 IPv4 CIDR

10.254.0.0/16

keystone_auth_enabled

见下文

true

k8s_keystone_auth_tag

见下文

见下文

helm_client_url

见下文

见下文

helm_client_sha256

见下文

见下文

helm_client_tag

见下文

见下文

master_lb_floating_ip_enabled

  • true

  • false

见下文

master_lb_allowed_cidrs

见下文

“”

auto_healing_enabled

  • true

  • false

false

auto_healing_controller

见下文

“draino”

magnum_auto_healer_tag

见下文

见下文

auto_scaling_enabled

  • true

  • false

false

node_problem_detector_tag

见下文

见下文

draino_tag

见下文

见下文

autoscaler_tag

见下文

见下文

min_node_count

见下文

见下文

max_node_count

见下文

见下文

npd_enabled

  • true

  • false

true

use_podman

  • true

  • false

见下文

selinux_mode

  • enforcing

  • permissive

  • disabled

见下文

container_runtime

  • “”

  • containerd

“”

containerd_version

见下文

见下文

containerd_tarball_url

见下文

见下文

containerd_tarball_sha256

见下文

见下文

calico_tag

见下文

见下文

calico_ipv4pool

见下文

10.100.0.0/16

calico_ipv4pool_ipip

见下文

Off

fixed_subnet_cidr

见下文

“”

octavia_provider

见下文

amphora

octavia_lb_algorithm

见下文

ROUND_ROBIN

octavia_lb_healthcheck

见下文

true

Cluster

集群是 COE 的 ClusterTemplate 的实例。Magnum 通过引用特定 ClusterTemplate 中定义的属性以及集群的一些其他参数来部署集群。Magnum 部署集群驱动程序提供的编排模板,以创建和配置所有必要的基础设施。准备就绪后,集群是一个功能齐全的 COE,可以托管容器。

基础设施

集群的基础设施由各种 OpenStack 服务提供的资源组成。集群还可以使用现有的基础设施,包括 OpenStack 外部的基础设施,例如 DNS、公共网络、公共发现服务、Docker 注册表。实际创建的资源取决于 COE 类型和指定的选项;因此,您需要参考 COE 的集群驱动程序文档以获取具体详细信息。例如,ClusterTemplate 中的 ‘–master-lb-enabled’ 选项将导致创建一个负载均衡器池以及健康监控和浮动 IP。区分 IaaS 级别和 PaaS 级别的资源非常重要。例如,OpenStack IaaS 中的基础设施网络与 Kubernetes PaaS 中的容器网络不同且独立。

典型的基础设施包括以下内容。

服务器

服务器托管集群中的容器,这些服务器可以是虚拟机 (VM) 或裸机服务器。虚拟机由 Nova 提供。由于多个虚拟机托管在物理服务器上,因此虚拟机为在同一物理服务器上运行的不同租户之间的容器提供所需隔离。裸机服务器由 Ironic 提供,当需要峰值性能且几乎没有开销时使用。

身份

Keystone 提供用于管理集群基础设施的身份验证和授权。

网络

服务器之间的网络由 Neutron 提供。由于 COE 目前不是多租户的,因此网络级别的多租户隔离是通过为每个集群使用私有网络来实现的。因此,属于一个租户的容器将无法访问另一个租户的容器或服务器。还可以使用其他网络资源,例如负载均衡器和路由器。如果需要,Kuryr 可以提供容器之间的网络。

Storage

Cinder 提供块存储,可用于托管容器并作为容器的持久存储。

安全性

Barbican 提供用于存储密钥的存储,例如用于传输层安全 (TLS) 的证书。

生命周期

Magnum 提供的集群生命周期操作集是其关键价值之一,可以轻松地在 OpenStack 上管理集群。当前的操作是基本的 CRUD 操作,但更多高级操作正在社区中讨论中,并将根据需要实施。

注意 为集群创建的 OpenStack 资源完全可供集群所有者访问。在修改或重用这些资源时应小心,以免以意想不到的方式影响 Magnum 操作。例如,如果您在集群私有网络上启动自己的 Nova 实例,Magnum 将无法识别此实例。因此,cluster-delete 操作将失败,因为 Magnum 将无法删除额外的 Nova 实例,并且在 Nova 实例仍然连接时,无法删除私有 Neutron 网络。

注意 目前使用 Heat 嵌套模板创建资源;因此,如果发生错误,可以通过 Heat 进行故障排除。有关 Heat 堆栈故障排除的更多帮助,请参阅 Magnum 故障排除指南

创建

‘cluster-create’ 命令部署集群,例如

openstack coe cluster create mycluster \
                  --cluster-template mytemplate \
                  --node-count 8 \
                  --master-count 3

‘cluster-create’ 操作是异步的;因此,您可以在当前集群正在创建时启动另一个 ‘cluster-create’ 操作。如果集群创建失败,到目前为止创建的基础设施可能会保留或删除,具体取决于特定的编排引擎。作为常见做法,在开发期间保留失败的集群以进行故障排除,但在生产环境中会自动删除。当前的集群驱动程序使用 Heat 模板,并且失败的 ‘cluster-create’ 的资源将被保留。

‘cluster-create’ 的参数定义和用法如下

<name>

要创建的集群的名称。如果未指定名称,将使用字符串和数字生成随机名称,例如“gamma-7-cluster”。

–cluster-template <cluster-template>

要使用的 ClusterTemplate 的 ID 或名称。这是一个必需的参数。一旦 ClusterTemplate 被用于创建集群,在所有使用该 ClusterTemplate 的集群被删除之前,它就无法被删除或修改。

–keypair <keypair>

配置在集群服务器中的 SSH 密钥对的名称,用于 ssh 访问。您需要密钥才能 ssh 到集群中的服务器。登录名特定于集群驱动程序。如果未提供密钥对,它将尝试使用 ClusterTemplate 中的值。如果 ClusterTemplate 也缺少密钥对值,则将返回错误。此处提供的密钥对值将覆盖 ClusterTemplate 中的密钥对值。

–node-count <node-count>

将作为集群中节点的服务器数量。默认值为 1。

–master-count <master-count>

将作为集群主节点的服务器数量。默认值为 1。设置为多个主节点以启用高可用性。如果 ClusterTemplate 中指定了 ‘–master-lb-enabled’ 选项,则主服务器将放置在负载均衡器池中。

–discovery-url <discovery-url>

用于节点发现的自定义发现 URL。COE 使用它来发现创建以托管容器的服务器。实际的发现机制因 COE 而异。在某些情况下,Magnum 将服务器信息填充到发现服务中。在其他情况下,如果未指定 discovery-url,Magnum 将使用公共发现服务,地址为

https://discovery.etcd.io

在这种情况下,Magnum 将为每个集群生成一个唯一的 URL,并存储服务器的信息。

–timeout <timeout>

集群创建的超时时间,以分钟为单位。期望值为正整数,默认值为 60 分钟。如果在 cluster-create 期间达到超时时间,则操作将被中止,集群状态将被设置为 ‘CREATE_FAILED’。

--master-lb-enabled

指示创建的集群是否应为 master 节点具有负载均衡器。

列出

‘cluster-list’ 命令列出属于租户的所有集群,例如

openstack coe cluster list

显示

‘cluster-show’ 命令打印集群的所有详细信息,例如

openstack coe cluster show mycluster

属性包括用户未指定且已分配默认值以及为集群创建的新资源中的属性。

更新

可以使用 ‘cluster-update’ 命令修改集群,例如

openstack coe cluster update mycluster replace node_count=8

参数是位置参数,其定义和用法如下。

<cluster>

这是第一个参数,指定要更新的集群的 UUID 或名称。

<op>

这是第二个参数,指定要对集群属性进行的所需更改。允许的更改是 ‘add’、‘replace’ 和 ‘remove’。

<attribute=value>

这是第三个参数,指定集群中以空格分隔的的目标属性。要添加或替换属性,需要指定该属性的值。要删除属性,只需指定属性的名称即可。目前,只能替换或删除 ‘node_count’ 属性。属性 ‘name’、‘master_count’ 和 ‘discovery_url’ 不能被替换或删除。下表总结了对集群的可能更改。

属性

添加

替换

删除

node_count

添加/删除默认 worker 节点组中的节点。

重置为默认值 1

master_count

name

discovery_url

当另一个操作正在进行时,无法启动 ‘cluster-update’ 操作。

注意: cluster-update 中的属性名称与 cluster-create 命令中相应的名称略有不同:破折号 ‘-’ 被下划线 ‘_’ 替换。例如,cluster-create 中的 ‘node-count’ 在 cluster-update 中是 ‘node_count’。

扩展

扩展集群意味着向集群添加服务器或从集群中删除服务器。目前,这是通过修改 node-count 属性执行 ‘cluster-update’ 操作来实现的,例如

openstack coe cluster update mycluster replace node_count=2

当删除一些节点时,Magnum 将尝试找到没有容器的节点进行删除。如果必须删除一些带有容器的节点,Magnum 将记录警告消息。

删除

‘cluster-delete’ 操作通过删除所有资源(例如服务器、网络、存储)来删除集群,例如

openstack coe cluster delete mycluster

cluster-delete 命令的唯一参数是要删除的集群的 ID 或名称。可以指定多个集群,并用空格分隔。

如果操作失败,可能仍存在尚未删除的一些剩余资源。在这种情况下,可以通过 Heat 进行故障排除。如果在 Heat 中手动删除模板,可以删除 Magnum 中的集群以清理 Magnum 数据库中的集群。

当另一个操作仍在进行时,可以启动 ‘cluster-delete’ 操作。

Python 客户端

安装

按照 OpenStack 安装指南中的说明启用发行版的存储库

使用 RHEL/CentOS/Fedora 的发行版包进行安装

$ sudo dnf install python3-magnumclient

使用 Ubuntu/Debian 的发行版包进行安装

$ sudo apt-get install python3-magnumclient

使用 openSUSE 和 SUSE Enterprise Linux 的发行版包进行安装

$ sudo zypper install python3-magnumclient

验证安装

执行 openstack coe cluster list 命令以确认已安装客户端并位于系统路径中

$ openstack coe cluster list

使用命令行客户端

请参阅 OpenStack 命令行界面参考,以获取 openstack coe 命令行客户端支持的所有命令的完整列表。

Horizon 界面

Magnum 提供了一个 Horizon 插件,以便用户可以通过 OpenStack 基于浏览器的图形用户界面访问容器基础设施管理服务。该插件可在 magnum-ui 上找到。它默认情况下未安装在标准的 Horizon 服务中,但您可以按照 安装 Horizon 插件 的说明进行操作。

在 Horizon 中,容器基础设施面板是 ‘Project’ 视图的一部分,目前支持以下操作

  • 查看集群模板列表

  • 查看集群模板的详细信息

  • 创建一个集群模板

  • 删除集群模板

  • 查看集群列表

  • 查看集群的详细信息

  • 创建一个集群

  • 删除集群

  • 获取集群的证书颁发机构

  • 签署用户密钥并获取用于访问集群中受保护的 COE API 端点的已签名证书。

其他操作尚未支持,应使用 CLI 进行这些操作。

以下是显示集群模板列表的 Horizon 视图的屏幕截图。

../_images/cluster-template.png

以下是显示集群模板详细信息的 Horizon 视图的屏幕截图。

../_images/cluster-template-details.png

以下是创建新集群的对话框的屏幕截图。

../_images/cluster-create.png

集群驱动程序

集群驱动程序是针对特定发行版上的特定 COE 的 Python 代码、Heat 模板、脚本、图像和文档的集合。Magnum 提出了 ClusterTemplates 和集群的概念。特定集群类型的实现由集群驱动程序提供。换句话说,集群驱动程序配置和管理 COE 的基础设施。Magnum 包含以下 COE 和发行版对的默认驱动程序

COE

发行版

Kubernetes

Fedora CoreOS

Magnum 旨在容纳新的集群驱动程序以支持自定义 COE,本节介绍如何在 Magnum 中构建和启用新的集群驱动程序。

目录结构

Magnum 期望组件在 ‘drivers’ 目录下的以下目录结构中组织

COE_Distro/
   image/
   templates/
   api.py
   driver.py
   monitor.py
   scale.py
   template_def.py
   version.py

所需的最低组件是

driver.py

实现特定 COE 的控制器操作的 Python 代码。驱动程序必须实现:当前支持:cluster_createcluster_updatecluster_delete

templates

用于管理集群生命周期的编排模板的目录,包括创建、配置、更新和删除。目前仅支持 Heat 模板,但将来可能会支持其他编排机制,例如 Ansible。

template_def.py

Python 代码,用于将 ClusterTemplate 中的参数映射到编排的输入参数,并调用模板目录中的编排。

version.py

跟踪此目录中驱动程序的最新版本。这由 version 属性定义,并表示为 1.0.0 的形式。它还应包含一个 Driver 属性,其中包含描述性名称,例如 k8s_fedora_coreos

其余组件是可选的

image

获取或构建适合 COE 的镜像的说明。

api.py

用于与 COE 交互的 Python 代码。

monitor.py

用于监控集群的资源利用率的 Python 代码。

scale.py

用于通过添加或删除节点来扩展集群的 Python 代码。

示例集群驱动程序

为了帮助开发人员创建新的 COE 驱动程序,提供了一个最小的集群驱动程序作为示例。‘docker’ 集群驱动程序将简单地部署运行 Ubuntu 且安装了最新 Docker 版本的单个 VM。它不是一个真正的集群,但其简单性将有助于说明关键概念。

待填充

安装集群驱动程序

待填充

Heat 堆栈模板

Heat 堆栈模板是 Magnum 传递给 Heat 以生成集群的内容。对于 Magnum 中的每个 ClusterTemplate 资源,都会创建一个 Heat 堆栈来安排支持容器编排环境所需的所有云资源。这些 Heat 堆栈模板提供 Magnum 对象属性到 Heat 模板参数的映射,以及 Magnum 可消耗的堆栈输出。Magnum 将 Heat 堆栈模板传递给 Heat 服务以创建 Heat 堆栈。结果是一个完整的容器编排环境。

选择 COE

选择要使用的 COE 取决于您希望在启动应用程序后用于管理容器的工具。

Kubernetes 提供了一个有吸引力的 YAML 文件描述符,用于描述 Pod,Pod 是作为分布式应用程序的一部分一起运行的容器的集合。这种文件格式允许您使用声明式风格来建模您的应用程序部署。它支持自动伸缩和故障恢复,以及允许进行复杂软件部署的功能,包括金丝雀部署和蓝绿部署。Kubernetes 非常受欢迎,尤其是在 Web 应用程序中。

为您的工作负载找到合适的 COE 取决于您,但 Magnum 提供了在流行的领先选项中进行选择的机会。一旦您决定,请参阅下一节,了解如何使用您想要的 COE 创建集群的示例。

原生客户端

Magnum 保留了 COE 的原生用户体验,不提供单独的 API 或客户端。这意味着您需要使用特定集群类型的原生客户端来与集群交互。通常情况下,需要考虑两种客户端

COE 级别

这是编排或管理级别,例如 Kubernetes 及其框架。

容器级别

这是底层的容器操作。目前,所有集群都使用 Docker。

客户端可以是 CLI 和/或基于浏览器的。您需要参考特定原生客户端和适当版本的文档以获取详细信息,但以下是一些参考:

Kubernetes CLI 是工具 ‘kubectl’,可以从集群中的一个节点简单地复制,也可以从 Kubernetes 发布版中下载。例如,如果集群正在运行 Kubernetes 发布版 1.2.0,则可以下载 ‘kubectl’ 的二进制文件并如下本地设置:

curl -O https://storage.googleapis.com/kubernetes-release/release/v1.2.0/bin/linux/amd64/kubectl
chmod +x kubectl
sudo mv kubectl /usr/local/bin/kubectl

Kubernetes 还提供了一个浏览器 UI。如果集群正在运行 Kubernetes Dashboard,可以使用以下方式访问:

eval $(openstack coe cluster config <cluster-name>)
kubectl proxy

The browser can be accessed at https://:8001/ui

根据客户端的要求,您可能需要使用与集群中版本匹配的客户端版本。要确定 COE 和容器的版本,请使用命令 ‘cluster-show’ 并查找属性 coe_versioncontainer_version

openstack coe cluster show k8s-cluster
+--------------------+------------------------------------------------------------+
| Property           | Value                                                      |
+--------------------+------------------------------------------------------------+
| status             | CREATE_COMPLETE                                            |
| uuid               | 04952c60-a338-437f-a7e7-d016d1d00e65                       |
| stack_id           | b7bf72ce-b08e-4768-8201-e63a99346898                       |
| status_reason      | Stack CREATE completed successfully                        |
| created_at         | 2016-07-25T23:14:06+00:00                                  |
| updated_at         | 2016-07-25T23:14:10+00:00                                  |
| create_timeout     | 60                                                         |
| coe_version        | v1.2.0                                                     |
| api_address        | https://192.168.19.86:6443                                 |
| cluster_template_id| da2825a0-6d09-4208-b39e-b2db666f1118                       |
| master_addresses   | ['192.168.19.87']                                          |
| node_count         | 1                                                          |
| node_addresses     | ['192.168.19.88']                                          |
| master_count       | 1                                                          |
| container_version  | 1.9.1                                                      |
| discovery_url      | https://discovery.etcd.io/3b7fb09733429d16679484673ba3bfd5 |
| name               | k8s-cluster                                                |
+--------------------+------------------------------------------------------------+

Kubernetes

Kubernetes 使用我们在此指南中引用的一系列术语。我们为您的参考在 词汇表 中定义这些常用术语。

当 Magnum 部署 Kubernetes 集群时,它会使用在 ClusterTemplate 中定义的参数以及在 cluster-create 命令中指定的参数,例如:

openstack coe cluster template create k8s-cluster-template \
                           --image fedora-coreos-latest \
                           --keypair testkey \
                           --external-network public \
                           --dns-nameserver 8.8.8.8 \
                           --flavor m1.small \
                           --docker-volume-size 5 \
                           --network-driver flannel \
                           --coe kubernetes

openstack coe cluster create k8s-cluster \
                      --cluster-template k8s-cluster-template \
                      --master-count 3 \
                      --node-count 8

请参阅 ClusterTemplateCluster 部分,以获取完整的参数列表。以下是与 Kubernetes 集群相关的更多详细信息:

主节点数量 (master-count)

在 cluster-create 命令中指定,以指示将有多少服务器作为集群中的主节点运行。拥有多个主节点将提供高可用性。主节点将位于负载均衡器池中,负载均衡器的虚拟 IP 地址 (VIP) 将作为 Kubernetes API 端点。对于外部访问,与此 VIP 关联的浮动 IP 可用,这是 ‘cluster-show’ 命令中显示的 Kubernetes 端点。

节点数量 (node-count)

在 cluster-create 命令中指定,以指示将有多少服务器作为节点运行,以托管用户的 Pod。节点使用 Nova 实例名称在 Kubernetes 中注册。

网络驱动程序 (network-driver)

在 ClusterTemplate 中指定以选择网络驱动程序。支持且默认的网络驱动程序是 ‘flannel’,它是一种为所有 Pod 提供扁平网络的覆盖网络。有关更多详细信息,请参阅 网络 部分。

卷驱动程序 (volume-driver)

在 ClusterTemplate 中指定以选择卷驱动程序。支持的卷驱动程序是 ‘cinder’,允许将 Cinder 卷挂载到容器中,用作持久存储。写入这些卷的数据在容器退出后将保留,并且可以从其他容器再次访问,而写入托管容器的联合文件系统的数据将被删除。有关更多详细信息,请参阅 存储 部分。

存储驱动程序 (docker-storage-driver)

在 ClusterTemplate 中指定以选择 Docker 存储驱动程序。默认值为 ‘devicemapper’。有关更多详细信息,请参阅 存储 部分。

注意:对于 Fedora CoreOS 驱动程序,不支持 devicemapper。

镜像 (image)

在 ClusterTemplate 中指定,以指示启动服务器的镜像。镜像二进制文件加载到 Glance 中,属性为 ‘os_distro = fedora-coreos’。当前支持的镜像为 Fedora CoreOS(从 Fedora CoreOS 下载)。

TLS (tls-disabled)

默认情况下启用传输层安全性,因此您需要密钥和签名证书才能访问 Kubernetes API 和 CLI。Magnum 在与 Kubernetes 集群交互时处理自己的密钥和证书。在开发模式下,可以禁用 TLS。有关更多详细信息,请参阅 ‘传输层安全性’_ 部分。

服务器上运行的内容

Kubernetes 主服务器的服务器在 ‘kube-system’ 命名空间中托管容器,以运行 Kubernetes 代理、调度器和控制器管理器。主节点不会托管用户的 Pod。Kubernetes API 服务器、docker 守护程序、etcd 和 flannel 作为 systemd 服务运行。Kubernetes 节点的服务器还托管一个在 ‘kube-system’ 命名空间中运行的容器,以运行 Kubernetes 代理,同时 Kubernetes kubelet、docker 守护程序和 flannel 作为 systemd 服务运行。

登录到服务器

您可以使用 ClusterTemplate 中指定的登录名 ‘fedora’ 和密钥对登录到主服务器。

除了 ClusterTemplate 中的常见属性外,您还可以指定使用 labels 属性特定于 Kubernetes 的以下属性:

admission_control_list

此标签对应于 Kubernetes API 服务器参数 ‘–admission-control’。有关更多详细信息,请参阅 准入控制器。默认值对应于我们当前 Kubernetes 版本中此文档中推荐的值。

boot_volume_size

此标签会覆盖实例的 default_boot_volume_size,如果您的 flavor 仅从卷启动,则很有用。默认值为 0,表示集群实例将不会从卷启动。

boot_volume_type

此标签会覆盖实例的 default_boot_volume_type,如果您的 flavor 仅从卷启动,则很有用。默认值为 ‘’,表示 Magnum 将从所有可用选项中随机选择 Cinder 卷类型。

etcd_volume_size

此标签设置保存 etcd 存储数据的卷的大小。默认值为 0,表示 etcd 数据未持久化(无卷)。

etcd_volume_type

此标签会覆盖保存 etcd 存储数据的 default_etcd_volume_type。默认值为 ‘’,表示 Magnum 将从所有可用选项中随机选择 Cinder 卷类型。

container_infra_prefix

所有容器镜像的前缀(kubernetes 组件、coredns、kubernetes-dashboard、node-exporter)。例如,kubernetes-apiserver 从 docker.io/openstackmagnum/kubernetes-apiserver 拉取,使用此标签可以将其更改为 myregistry.example.com/mycloud/kubernetes-apiserver。类似地,集群中使用的所有其他组件都将使用此标签进行前缀,假设操作员已将所有预期的镜像克隆到 myregistry.example.com/mycloud 中。

必须镜像的镜像

  • docker.io/coredns/coredns:1.3.1

  • quay.io/coreos/etcd:v3.4.6

  • docker.io/k8scloudprovider/k8s-keystone-auth:v1.18.0

  • docker.io/k8scloudprovider/openstack-cloud-controller-manager:v1.18.0

  • gcr.io/google_containers/pause:3.1

当 ‘use_podman’ 为 ‘false’ 时可能需要的镜像

  • docker.io/openstackmagnum/kubernetes-apiserver

  • docker.io/openstackmagnum/kubernetes-controller-manager

  • docker.io/openstackmagnum/kubernetes-kubelet

  • docker.io/openstackmagnum/kubernetes-proxy

  • docker.io/openstackmagnum/kubernetes-scheduler

可能需要的镜像

  • k8s.gcr.io/hyperkube:v1.18.2

  • docker.io/grafana/grafana:5.1.5

  • docker.io/prom/node-exporter:latest

  • docker.io/prom/prometheus:latest

  • docker.io/traefik:v1.7.28

  • gcr.io/google_containers/kubernetes-dashboard-amd64:v1.5.1

  • gcr.io/google_containers/metrics-server-amd64:v0.3.6

  • k8s.gcr.io/node-problem-detector:v0.6.2

  • docker.io/planetlabs/draino:abf028a

  • docker.io/openstackmagnum/cluster-autoscaler:v1.18.1

  • quay.io/calico/cni:v3.13.1

  • quay.io/calico/pod2daemon-flexvol:v3.13.1

  • quay.io/calico/kube-controllers:v3.13.1

  • quay.io/calico/node:v3.13.1

  • quay.io/coreos/flannel-cni:v0.3.0

  • quay.io/coreos/flannel:v0.12.0-amd64

如果 ‘monitoring_enabled’ 为 ‘true’ 时可能需要的镜像

  • quay.io/prometheus/alertmanager:v0.20.0

  • docker.io/squareup/ghostunnel:v1.5.2

  • docker.io/jettech/kube-webhook-certgen:v1.0.0

  • quay.io/coreos/prometheus-operator:v0.37.0

  • quay.io/coreos/configmap-reload:v0.0.1

  • quay.io/coreos/prometheus-config-reloader:v0.37.0

  • quay.io/prometheus/prometheus:v2.15.2

如果 ‘cinder_csi_enabled’ 为 ‘true’ 时可能需要的镜像

  • docker.io/k8scloudprovider/cinder-csi-plugin:v1.18.0

  • quay.io/k8scsi/csi-attacher:v2.0.0

  • quay.io/k8scsi/csi-provisioner:v1.4.0

  • quay.io/k8scsi/csi-snapshotter:v1.2.2

  • quay.io/k8scsi/csi-resizer:v0.3.0

  • quay.io/k8scsi/csi-node-driver-registrar:v1.1.0

hyperkube_prefix

此标签允许用户为 kube_tag 大于 1.18.x 时指定 Hyperkube 容器源的自定义前缀。如果您希望使用 1.19.x 及更高版本,您可能需要使用非官方来源,例如 docker.io/rancher/ghcr.io/openstackmagnum/ 或您自己的容器注册表。如果定义了 container_infra_prefix 标签,它仍然优先于此标签。默认值:docker.io/rancher/

kube_tag

此标签允许用户根据其容器标签为 Fedora CoreOS 镜像 选择特定的 Kubernetes 发布版。如果未设置,将安装当前 Magnum 版本的默认 Kubernetes 发布版。Stein 默认值:v1.11.6 Train 默认值:v1.15.7 Ussuri 默认值:v1.18.2 Victoria 默认值:v1.18.16 Yoga 默认值:v1.23.3-rancher1

heapster_enabled

heapster_enabled 用于启用或禁用 heapster 的安装。Ussuri 默认值:false Train 默认值:true

cloud_provider_tag

此标签允许用户覆盖默认的 openstack-cloud-controller-manager 容器镜像标签。有关可用标签,请参阅 openstack-cloud-controller-manager 页面。Stein 默认值:v0.2.0 Train 默认值:v1.15.0 Ussuri 默认值:v1.18.0

etcd_tag

此标签允许用户根据其容器标签选择 特定的 etcd 版本。如果未设置,将使用当前 Magnum 版本的默认 etcd 版本。Stein 默认值:v3.2.7 Train 默认值:3.2.26 Ussuri 默认值:v3.4.6

coredns_tag

此标签允许用户根据其容器标签选择 特定的 coredns 版本。如果未设置,将使用当前 Magnum 版本的默认 etcd 版本。Stein 默认值:1.3.1 Train 默认值:1.3.1 Ussuri 默认值:1.6.6

flannel_tag

此标签允许用户根据其容器标签选择特定的 flannel 版本

如果未设置,将使用默认版本。

flannel_cni_tag

此标签允许用户根据其容器标签选择 特定的 flannel_cni 版本。此容器在主机下的 /opt/cni/bin 中添加 cni 插件。如果未设置,将使用当前 Magnum 版本的默认 flannel 版本。Stein 默认值:v0.3.0 Train 默认值:v0.3.0 Ussuri 默认值:v0.3.0

heat_container_agent_tag

此标签允许用户根据其容器标签选择 特定的 heat_container_agent 版本。Train 默认值:train-stable-3 Ussuri 默认值:ussuri-stable-1 Victoria 默认值:victoria-stable-1 Wallaby 默认值:wallaby-stable-1

kube_dashboard_enabled

此标签触发 kubernetes dashboard 的部署。默认值为 1,表示它将被启用。

cert_manager_api

此标签启用 kubernetes 证书管理器 API

kubelet_options

此标签可以包含要传递给 kubelet 的任何其他选项。有关更多详细信息,请参阅 kubelet 管理员指南。默认情况下,不传递任何其他选项。

kubeproxy_options

此标签可以包含要传递给 kube proxy 的任何其他选项。有关更多详细信息,请参阅 kube proxy 管理员指南。默认情况下,不传递任何其他选项。

kubecontroller_options

此标签可以包含要传递给 kube 控制器管理器的任何其他选项。有关更多详细信息,请参阅 kube 控制器管理器管理员指南。默认情况下,不传递任何其他选项。

kubeapi_options

此标签可以包含要传递给 kube API 服务器的任何其他选项。有关更多详细信息,请参阅 kube api 管理员指南。默认情况下,不传递任何其他选项。

kubescheduler_options

此标签可以包含要传递给 kube 调度器的任何其他选项。有关更多详细信息,请参阅 kube 调度器管理员指南。默认情况下,不传递任何其他选项。

influx_grafana_dashboard_enabled

kubernetes dashboard 带有 heapster 启用。如果设置此标签,将部署 influxdb 和 grafana 实例,heapster 将把数据推送到 influx,grafana 将投影它们。

cgroup_driver

此标签告诉 kubelet 使用哪个 Cgroup 驱动程序。理想情况下,这应该与 Docker 启动的 Cgroup 驱动程序相同。

cloud_provider_enabled

为 k8s_fedora_atomic 驱动程序添加 ‘cloud_provider_enabled’ 标签。默认值为 ‘cluster_user_trust’ 的值(默认值为 ‘false’,除非在 magnum.conf 中显式设置为 ‘true’,这是由于 CVE-2016-7404 造成的)。因此,当 ‘cluster_user_trust’ 解析为 ‘false’ 时,无法将 ‘cloud_provider_enabled’ 标签覆盖为 ‘true’。对于特定的 kubernetes 版本,如果将 ‘cinder’ 选定为 ‘volume_driver’,则意味着将启用云提供程序,因为它们是组合在一起的。

cinder_csi_enabled

当设置为 ‘true’ 时,将启用树外 Cinder CSI 驱动程序。需要将 ‘cinder’ 选定为 ‘volume_driver’,因此也需要标签 ‘cloud_provider_enabled’ 为 ‘true’(请参阅 ‘cloud_provider_enabled’ 部分)。Ussuri 默认值:false Victoria 默认值:true

cinder_csi_plugin_tag

此标签允许用户覆盖默认 cinder-csi-plugin 容器镜像标签。请参阅 cinder-csi-plugin 页面 以获取可用标签。Train 默认值:v1.16.0 Ussuri 默认值:v1.18.0 Yoga 默认值:v1.23.0

csi_attacher_tag

此标签允许用户覆盖 CSI attacher 的默认容器标签。有关其他标签,请参阅 CSI attacher 页面。Ussuri 默认值:v2.0.0 Yoga 默认值:v3.3.0

csi_provisioner_tag

此标签允许用户覆盖 CSI provisioner 的默认容器标签。有关其他标签,请参阅 CSI provisioner 页面。Ussuri 默认值:v1.4.0 Yoga 默认值:v3.0.0

csi_snapshotter_tag

此标签允许用户覆盖 CSI snapshotter 的默认容器标签。有关其他标签,请参阅 CSI snapshotter 页面。Ussuri 默认值:v1.2.2 Yoga 默认值:v4.2.1

csi_resizer_tag

此标签允许用户覆盖 CSI resizer 的默认容器标签。有关其他标签,请参阅 CSI resizer 页面。Ussuri 默认值:v0.3.0 Yoga 默认值:v1.3.0

csi_node_driver_registrar_tag

此标签允许用户覆盖 CSI node driver registrar 的默认容器标签。有关其他标签,请参阅 CSI node driver registrar 页面。Ussuri 默认值:v1.1.0 Yoga 默认值:v2.4.0

-csi_liveness_probe_tag

此标签允许用户覆盖 CSI liveness probe 的默认容器标签。Yoga 默认值:v2.5.0

keystone_auth_enabled

如果将此标签设置为 True,Kubernetes 将支持使用 Keystone 进行授权和身份验证。

k8s_keystone_auth_tag

此标签允许用户覆盖默认 k8s-keystone-auth 容器镜像标签。请参阅 k8s-keystone-auth 页面 以获取可用标签。Stein 默认值:v1.13.0 Train 默认值:v1.14.0 Ussuri 默认值:v1.18.0

helm_client_url

helm 客户端二进制文件的 URL。默认值:‘’

helm_client_sha256

helm 客户端二进制文件的 SHA256 校验和。Ussuri 默认值:018f9908cb950701a5d59e757653a790c66d8eda288625dbb185354ca6f41f6b

helm_client_tag

此标签允许用户覆盖 Helm 客户端的默认容器标签。有关其他标签,请参阅 Helm 客户端页面。Ussuri 默认值:v3.2.1

master_lb_floating_ip_enabled

控制 Magnum 是否为 master 节点的负载均衡器分配浮动 IP。此标签仅在模板属性 master_lb_enabled 设置时生效。如果未指定,则默认值与模板属性 floating_ip_enabled 相同。

master_lb_allowed_cidrs

用于控制 master 节点负载均衡器访问权限的 CIDR 列表。输入格式为逗号分隔的列表。例如,192.168.0.0/16,10.0.0.0/24。默认值:“” (这将打开到 0.0.0.0/0)

auto_healing_enabled

如果设置为 true,将启用自动修复功能。默认值为 false。

auto_healing_controller

此标签设置要使用的自动修复服务。目前支持 drainomagnum-auto-healer。默认值为 draino。有关更多详细信息,请参阅 draino 文档magnum-auto-healer 文档

draino_tag

此标签允许用户选择特定的 Draino 版本。

magnum_auto_healer_tag

此标签允许用户覆盖 magnum-auto-healer 容器镜像的默认标签。请参阅 magnum-auto-healer 页面 以获取可用标签。Stein 默认值:v1.15.0 Train 默认值:v1.15.0 Ussuri 默认值:v1.18.0

auto_scaling_enabled

如果设置为 true,将启用自动缩放功能。默认值:false。

autoscaler_tag

此标签允许用户覆盖 cluster-autoscaler 容器镜像的默认标签。请参阅 cluster-autoscaler 页面 以获取可用标签。Stein 默认值:v1.0 Train 默认值:v1.0 Ussuri 默认值:v1.18.1

npd_enabled

设置节点问题检测器服务启用或禁用。默认值:true

node_problem_detector_tag

此标签允许用户选择特定的节点问题检测器版本。

min_node_count

在进行自动缩放或自动修复时,集群的最小节点数。默认值:1

max_node_count

在进行自动缩放或自动修复时,集群的最大节点数。

use_podman

选择是否使用 podman 或 atomic 安装系统容器 etcd、kubernetes 和 heat-agent。此标签与 k8s_fedora 驱动程序相关。

k8s_fedora_atomic_v1 默认使用 use_podman=false,这意味着将使用 atomic 从 docker.io/openstackmagnum 拉取容器。也接受 use_podman=true,这将通过 k8s.gcr.io 拉取容器。

k8s_fedora_coreos_v1 默认且仅接受 use_podman=true。

请注意,要使用 kubernetes 版本大于或等于 v1.16.0 的 k8s_fedora_atomic_v1 驱动程序,需要将 use_podman=true。这是必要的,因为 v1.16 在 kubelet 中删除了 –containerized 标志。https://github.com/kubernetes/kubernetes/pull/80043/files

selinux_mode

选择 SELinux 模式,包括 enforcing、permissive 和 disabled。此标签当前仅与 k8s_fedora 驱动程序相关。

k8s_fedora_atomic_v1 驱动程序默认 selinux_mode=permissive,因为这是 atomic 容器启动 Kubernetes 服务的唯一方法。另一方面,如果提供了 opt-in use_podman=true 标签,则支持 selinux_mode=enforcing。请注意,如果选择 selinux_mode=disabled,则只有在手动重新启动实例后才能完全生效,但在此期间它们将被设置为 permissive 模式。

k8s_fedora_coreos_v1 驱动程序默认 selinux_mode=enforcing。

container_runtime

要使用的容器运行时。空值表示使用主机上的 docker。从 ussuri 开始,除了空值(主机 docker)之外,containerd 也是一个选项。

containerd_version

containerd 版本,如 https://github.com/containerd/containerd/releaseshttps://storage.googleapis.com/cri-containerd-release/ 中发布。Victoria 默认值:1.4.4 Ussuri 默认值:1.2.8

containerd_tarball_url

包含 containerd 二进制文件的 tarball 的 URL。

containerd_tarball_sha256

使用 containerd_tarball_url 获取的 tarball 的 sha256,或从 https://github.com/containerd/containerd/releases 获取的 sha256。

kube_dashboard_version

Kubernetes dashboard 的默认版本。Train 默认值:v1.8.3 Ussuri 默认值:v2.0.0

metrics_scraper_tag

kubernetes dashboard 使用的 metrics-scraper 的版本。Ussuri 默认值:v1.0.4

fixed_subnet_cidr

在用户在创建集群期间未指定现有的 fixed_subnet 时,Magnum 创建的固定子网的 CIDR。Ussuri 默认值:10.0.0.0/24

octavia_provider

用于创建负载均衡器的 Octavia 提供程序驱动程序。

octavia_lb_algorithm

用于 LoadBalancer 类型服务的 Octavia Octavia lb 算法。默认值:ROUND_ROBIN

octavia_lb_healthcheck

如果为 true,则启用 Octavia 负载均衡器健康检查。默认值:true

支持的版本

Kubernetes 和操作系统的支持(经过测试)版本如下

版本

kube_tag

操作系统发行版和版本

19.0.0 (Dalmatian)

v1.28.9-rancher1

fedora-coreos-38.20230806.3.0

18.0.0 (Caracal)

v1.27.8-rancher2

fedora-coreos-38.20230806.3.0

17.0.0 (Bobcat)

v1.26.8-rancher1

fedora-coreos-38.20230806.3.0

16.0.0 (Antelope)

v1.23.3-rancher1

fedora-coreos-35.20220116.3.0

15.0.0 (Zed)

v1.23.3-rancher1

fedora-coreos-35.20220116.3.0

14.0.0 (Yoga)

v1.23.3-rancher1

fedora-coreos-35.20220116.3.0

13.0.0 (Xena)

v1.21.x

fedora-coreos-31.20200323.3.2

12.0.0 (Wallaby)

v1.21.x

fedora-coreos-31.20200323.3.2

11.1.1 (Victoria)

v1.21.x

fedora-coreos-31.20200323.3.2

注意:尝试使用经过测试的确切镜像版本非常重要。有时 Fedora 会在同一主要版本中更新软件包,因此如果它期望不同的软件版本,Magnum 可能无法工作。例如:

  • fedora-coreos-35.20220116.3.0 - containerd 1.5

  • fedora-coreos-35.20220424.3.0 - containerd 1.6

由于 containerd 1.5 和 1.6 之间的配置文件差异,较新的 fcos 35 版本在没有补丁的情况下将无法工作。

支持的标签

每个版本的经过测试的标签如下

  • Dalmatian

    kube_tag=v1.28.9-rancher1,container_runtime=containerd,containerd_version=1.6.31,containerd_tarball_sha256=75afb9b9674ff509ae670ef3ab944ffcdece8ea9f7d92c42307693efa7b6109d,cloud_provider_tag=v1.27.3,cinder_csi_plugin_tag=v1.27.3,k8s_keystone_auth_tag=v1.27.3,magnum_auto_healer_tag=v1.27.3,octavia_ingress_controller_tag=v1.27.3,calico_tag=v3.26.4

    kube_tag=v1.27.8-rancher2,container_runtime=containerd,containerd_version=1.6.31,containerd_tarball_sha256=75afb9b9674ff509ae670ef3ab944ffcdece8ea9f7d92c42307693efa7b6109d,cloud_provider_tag=v1.27.3,cinder_csi_plugin_tag=v1.27.3,k8s_keystone_auth_tag=v1.27.3,magnum_auto_healer_tag=v1.27.3,octavia_ingress_controller_tag=v1.27.3,calico_tag=v3.26.4

  • Caracal

    kube_tag=v1.27.8-rancher2,container_runtime=containerd,containerd_version=1.6.28,containerd_tarball_sha256=f70736e52d61e5ad225f4fd21643b5ca1220013ab8b6c380434caeefb572da9b,cloud_provider_tag=v1.27.3,cinder_csi_plugin_tag=v1.27.3,k8s_keystone_auth_tag=v1.27.3,magnum_auto_healer_tag=v1.27.3,octavia_ingress_controller_tag=v1.27.3,calico_tag=v3.26.4

  • Bobcat

    kube_tag=v1.25.9-rancher1,flannel_tag=v0.21.5,master_lb_floating_ip_enabled=true,cinder_csi_enabled=true,ingress_controller=octavia,container_runtime=containerd,containerd_version=1.6.20,containerd_tarball_sha256=1d86b534c7bba51b78a7eeb1b67dd2ac6c0edeb01c034cc5f590d5ccd824b416,cloud_provider_tag=v1.25.5,cinder_csi_plugin_tag=v1.25.5,k8s_keystone_auth_tag=v1.25.5,octavia_ingress_controller_tag=v1.25.5,coredns_tag=1.10.1,csi_snapshotter_tag=v6.2.1,csi_attacher_tag=v4.2.0,csi_resizer_tag=v1.7.0,csi_provisioner_tag=v3.4.1,csi_node_driver_registrar_tag=v2.8.0

    kube_tag=v1.26.8-rancher1,flannel_tag=v0.21.5,master_lb_floating_ip_enabled=true,cinder_csi_enabled=true,ingress_controller=octavia,container_runtime=containerd,containerd_version=1.6.20,containerd_tarball_sha256=1d86b534c7bba51b78a7eeb1b67dd2ac6c0edeb01c034cc5f590d5ccd824b416,cloud_provider_tag=v1.26.3,cinder_csi_plugin_tag=v1.26.3,k8s_keystone_auth_tag=v1.26.3,octavia_ingress_controller_tag=v1.26.3,coredns_tag=1.10.1,csi_snapshotter_tag=v6.2.1,csi_attacher_tag=v4.2.0,csi_resizer_tag=v1.7.0,csi_provisioner_tag=v3.4.1,csi_node_driver_registrar_tag=v2.8.0

  • Antelope

    kube_tag=v1.23.8-rancher1,flannel_tag=v0.18.1,master_lb_floating_ip_enabled=true,cinder_csi_enabled=true,ingress_controller=octavia,container_runtime=containerd,containerd_version=1.6.6,containerd_tarball_sha256=a64568c8ce792dd73859ce5f336d5485fcbceab15dc3e06d5d1bc1c3353fa20f,cloud_provider_tag=v1.23.4,cinder_csi_plugin_tag=v1.23.4,k8s_keystone_auth_tag=v1.23.4,magnum_auto_healer_tag=v1.23.4,octavia_ingress_controller_tag=v1.23.4,autoscaler_tag=v1.23.0,coredns_tag=1.9.3,csi_snapshotter_tag=v4.2.1,csi_attacher_tag=v3.3.0,csi_resizer_tag=v1.3.0,csi_provisioner_tag=v3.0.0,csi_node_driver_registrar_tag=v2.4.0

镜像

支持的镜像可以从以下位置下载

服务外部负载均衡器

在集群中创建的所有 Kubernetes Pod 和服务都分配了在私有容器网络上的 IP 地址,以便它们可以相互访问和访问外部互联网。但是,这些 IP 地址无法从外部网络访问。

为了发布服务端点以供外部访问,Kubernetes 提供了外部负载均衡器功能。这通过在服务清单中简单地指定“type: LoadBalancer”来完成。Magnum 启用并配置 Kubernetes 插件,以便它可以与 Neutron 接口并管理必要的网络资源。

创建服务时,Kubernetes 将在服务前面添加一个外部负载均衡器,以便该服务除了容器网络上的内部 IP 地址外,还具有一个外部 IP 地址。然后可以使用此外部 IP 地址访问服务端点。Kubernetes 在修改服务后面的 Pod 时以及删除服务时处理所有生命周期操作。

请参阅 Kubernetes 外部负载均衡器 部分以获取更多详细信息。

Ingress 控制器

除了上述 LoadBalancer 之外,Kubernetes 还可以配置 Ingress 控制器。Ingress 可以提供负载均衡、SSL 终止和基于名称的虚拟主机。

Magnum 允许通过 ‘ingress_controller’ 标签选择多个控制器选项。请查看 Kubernetes 文档以定义您自己的 Ingress 资源。

Traefik:Traefik 的 Pod 默认在节点上暴露端口 80 和 443 以进行 http(s) 流量。在 kubernetes 集群中,这些端口默认情况下是关闭的。集群管理员需要在工作节点安全组中添加一条规则。例如

openstack security group rule create <SECURITY_GROUP> \
  --protocol tcp \
  --dst-port 80:80
openstack security group rule create <SECURITY_GROUP> \
  --protocol tcp \
  --dst-port 443:443
ingress_controller

此标签设置要使用的 Ingress 控制器。目前支持 ‘traefik’、‘nginx’ 和 ‘octavia’。默认值为 ‘’,表示未配置 Ingress 控制器。有关 octavia-ingress-controller 的更多详细信息,请参阅 cloud-provider-openstack 文档

ingress_controller_role

此标签定义节点在运行 Ingress 控制器实例时应具有的角色。这使操作员可以完全控制应运行控制器实例的节点,并且应在多个节点中设置以实现可用性。默认值为 ‘ingress’。在 Kubernetes 节点上设置此值的示例是

kubectl label node <node-name> role=ingress

此标签不用于 octavia-ingress-controller。

octavia_ingress_controller_tag

octavia-ingress-controller 的图像标签。Train 默认值:v1.15.0

nginx_ingress_controller_tag

nginx-ingress-controller 的图像标签。Stein 默认值:0.23.0 Train 默认值:0.26.1 Ussuru 默认值:0.26.1 Victoria 默认值:0.32.0

nginx_ingress_controller_chart_tag

nginx-ingress-controller 的图表版本。Train 默认值:v1.24.7 Ussuru 默认值:v1.24.7 Victoria 默认值:v1.36.3

traefik_ingress_controller_tag

The image tag for traefik_ingress_controller_tag. Stein-default: v1.7.10

DNS

CoreDNS 是 Kubernetes 集群中用于服务发现的关键服务。为了获得 CoreDNS pod 的高可用性,Magnum 现在支持使用 cluster-proportional-autoscaler 对 CoreDNS 进行自动缩放。借助 cluster-proportional-autoscaler,CoreDNS pod 的副本数将根据集群中的节点和核心数进行自动缩放,以防止单点故障。

缩放参数和数据点通过 ConfigMap 提供给自动缩放器,并且它会在每次轮询间隔刷新其参数表,以保持与最新的期望缩放参数同步。使用 ConfigMap 意味着用户可以在不重建或重新启动缩放器容器/pod 的情况下进行实时更改(包括控制模式)。请参阅 集群中自动缩放 DNS 服务 以获取更多信息。

Keystone authN 和 authZ

现在 cloud-provider-openstack 提供了一个良好的 webhook,用于在 OpenStack Keystone 和 Kubernetes 之间进行连接,以便用户可以使用 Keystone 用户/角色对 Kubernetes 集群进行授权和身份验证。如果标签 keystone-auth-enabled 设置为 True,则用户可以使用他们的 OpenStack 凭证和角色来访问 Kubernetes 中的资源。

假设您已经使用命令 eval $(openstack coe cluster config <cluster ID>) 获取了配置,那么要配置 kubectl 客户端,需要以下命令

  1. 运行 kubectl config set-credentials openstackuser –auth-provider=openstack

  2. 运行 kubectl config set-context –cluster=<your cluster name> –user=openstackuser openstackuser@kubernetes

  3. 运行 kubectl config use-context openstackuser@kubernetes 以激活上下文

注意: 请确保 kubectl 的版本为 1.8+,并确保 OS_DOMAIN_NAME 包含在 rc 文件中。

现在尝试 kubectl get pods,您应该能够根据当前用户的角色从 Kubernetes 获得响应。

请参阅 cloud-provider-openstack 中的 k8s-keystone-auth 的文档以获取更多信息。

传输层安全

Magnum 使用 TLS 来保护集群的服务与外部世界之间的通信。TLS 是一个复杂的主题,已经存在许多关于它的指南。本指南不会尝试完全描述 TLS,而是只会涵盖设置客户端与具有 TLS 的集群进行通信的必要步骤。可以在 OpenSSL Cookbook(Ivan Ristić 著)中找到关于 TLS 的更深入的指南。

TLS 在集群中应用于 3 个点

  1. Magnum 与集群 API 端点通信

  2. 集群工作节点与主节点通信

  3. 最终用户在使用本机客户端库与集群交互时。这适用于 CLI 或使用特定集群客户端的程序。每个客户端都需要有效的证书才能进行身份验证并与集群进行通信。

前两种情况由 Magnum 内部实现,未暴露给用户,而最后一种情况涉及用户,并在下面更详细地描述。

部署安全集群

当前的 TLS 支持总结如下

COE

TLS 支持

Kubernetes

对于具有 TLS 支持的集群类型,例如 Kubernetes,TLS 默认启用。要在 Magnum 中禁用 TLS,可以在 ClusterTemplate 中指定参数 ‘–tls-disabled’。请注意,由于安全原因,不建议禁用 TLS。

在以下示例中,Kubernetes 用于说明安全集群,但步骤对于其他具有 TLS 支持的集群类型是相似的。

首先,创建一个 ClusterTemplate;默认情况下,Magnum 中 TLS 已启用,因此无需通过参数指定它

openstack coe cluster template create secure-kubernetes \
                           --keypair default \
                           --external-network public \
                           --image fedora-coreos-latest \
                           --dns-nameserver 8.8.8.8 \
                           --flavor m1.small \
                           --docker-volume-size 3 \
                           --coe kubernetes \
                           --network-driver flannel

+-----------------------+--------------------------------------+
| Property              | Value                                |
+-----------------------+--------------------------------------+
| insecure_registry     | None                                 |
| http_proxy            | None                                 |
| updated_at            | None                                 |
| master_flavor_id      | None                                 |
| uuid                  | 5519b24a-621c-413c-832f-c30424528b31 |
| no_proxy              | None                                 |
| https_proxy           | None                                 |
| tls_disabled          | False                                |
| keypair_id            | time4funkey                          |
| public                | False                                |
| labels                | {}                                   |
| docker_volume_size    | 5                                    |
| server_type           | vm                                   |
| external_network_id   | public                               |
| cluster_distro        | fedora-coreos                        |
| image_id              | fedora-coreos-latest                 |
| volume_driver         | None                                 |
| registry_enabled      | False                                |
| docker_storage_driver | devicemapper                         |
| apiserver_port        | None                                 |
| name                  | secure-kubernetes                    |
| created_at            | 2016-07-25T23:09:50+00:00            |
| network_driver        | flannel                              |
| fixed_network         | None                                 |
| coe                   | kubernetes                           |
| flavor_id             | m1.small                             |
| dns_nameserver        | 8.8.8.8                              |
+-----------------------+--------------------------------------+

现在创建一个集群。使用 ClusterTemplate 名称作为集群创建的模板

openstack coe cluster create secure-k8s-cluster \
                      --cluster-template secure-kubernetes \
                      --node-count 1

+--------------------+------------------------------------------------------------+
| Property           | Value                                                      |
+--------------------+------------------------------------------------------------+
| status             | CREATE_IN_PROGRESS                                         |
| uuid               | 3968ffd5-678d-4555-9737-35f191340fda                       |
| stack_id           | c96b66dd-2109-4ae2-b510-b3428f1e8761                       |
| status_reason      | None                                                       |
| created_at         | 2016-07-25T23:14:06+00:00                                  |
| updated_at         | None                                                       |
| create_timeout     | 0                                                          |
| api_address        | None                                                       |
| coe_version        | -                                                          |
| cluster_template_id| 5519b24a-621c-413c-832f-c30424528b31                       |
| master_addresses   | None                                                       |
| node_count         | 1                                                          |
| node_addresses     | None                                                       |
| master_count       | 1                                                          |
| container_version  | -                                                          |
| discovery_url      | https://discovery.etcd.io/ba52a8178e7364d43a323ee4387cf28e |
| name               | secure-k8s-cluster                                          |
+--------------------+------------------------------------------------------------+

现在运行 cluster-show 命令以获取集群的详细信息,并验证 api_address 是否为 ‘https’

openstack coe cluster show secure-k8scluster
+--------------------+------------------------------------------------------------+
| Property           | Value                                                      |
+--------------------+------------------------------------------------------------+
| status             | CREATE_COMPLETE                                            |
| uuid               | 04952c60-a338-437f-a7e7-d016d1d00e65                       |
| stack_id           | b7bf72ce-b08e-4768-8201-e63a99346898                       |
| status_reason      | Stack CREATE completed successfully                        |
| created_at         | 2016-07-25T23:14:06+00:00                                  |
| updated_at         | 2016-07-25T23:14:10+00:00                                  |
| create_timeout     | 60                                                         |
| coe_version        | v1.2.0                                                     |
| api_address        | https://192.168.19.86:6443                                 |
| cluster_template_id| da2825a0-6d09-4208-b39e-b2db666f1118                       |
| master_addresses   | ['192.168.19.87']                                          |
| node_count         | 1                                                          |
| node_addresses     | ['192.168.19.88']                                          |
| master_count       | 1                                                          |
| container_version  | 1.9.1                                                      |
| discovery_url      | https://discovery.etcd.io/3b7fb09733429d16679484673ba3bfd5 |
| name               | secure-k8s-cluster                                          |
+--------------------+------------------------------------------------------------+

您可以看到 URL 中包含 https,表明 Kubernetes 服务已使用 SSL 证书安全配置,现在任何与 kube-apiserver 的通信都将通过 https 进行。

与安全集群交互

要与安全集群的 API 端点进行通信,您需要提供 3 个 SSL 工件

  1. 您的客户端密钥

  2. 一个已由证书颁发机构 (CA) 签名的客户端证书

  3. CA 的证书

有两种方法可以获得这 3 个工件。

自动化

Magnum 提供了 ‘cluster-config’ 命令来帮助用户设置环境和 TLS 的工件,例如

openstack coe cluster config kubernetes-cluster --dir myclusterconfig

这将显示必要的环境变量,您可以将其添加到您的环境中

export DOCKER_HOST=tcp://172.24.4.5:2376
export DOCKER_CERT_PATH=myclusterconfig
export DOCKER_TLS_VERIFY=True

工件放置在指定的目录中

ca.pem
cert.pem
key.pem

现在您可以使用本机客户端与 COE 交互。变量和工件是唯一的集群。

‘coe cluster config’ 的参数如下

–dir <dirname>

保存证书和配置文件目录。

--force

覆盖指定目录中现有的文件。

手动

您可以使用以下步骤手动创建密钥和证书。

客户端密钥

您的个人私钥本质上是经过密码学生成的字节字符串。它应以与密码相同的方式受到保护。要生成 RSA 密钥,可以使用 ‘openssl’ 工具的 ‘genrsa’ 命令

openssl genrsa -out key.pem 4096

此命令在 key.pem 中生成一个 4096 字节的 RSA 密钥。

已签名证书

要验证您的密钥,您需要让它由 CA 签名。首先生成证书签名请求 (CSR)。CSR 将由 Magnum 用于生成您将用于与集群通信的已签名证书。要生成 CSR,openssl 需要一个配置文件,该文件指定几个值。使用下面的示例模板,您可以在 ‘CN’ 值中填写您的姓名并将其保存为 client.conf

$ cat > client.conf << END
[req]
distinguished_name = req_distinguished_name
req_extensions     = req_ext
prompt = no
[req_distinguished_name]
CN = Your Name
[req_ext]
extendedKeyUsage = clientAuth
END

对于启用了 RBAC 的 kubernetes 集群,您需要使用 admin 和 system:masters 作为组织 (O=)

$ cat > client.conf << END
[req]
distinguished_name = req_distinguished_name
req_extensions     = req_ext
prompt = no
[req_distinguished_name]
CN = admin
O = system:masters
OU=OpenStack/Magnum
C=US
ST=TX
L=Austin
[req_ext]
extendedKeyUsage = clientAuth
END

一旦您拥有 client.conf,您就可以运行 openssl ‘req’ 命令来生成 CSR

openssl req -new -days 365 \
    -config client.conf \
    -key key.pem \
    -out client.csr

现在您拥有客户端 CSR,您可以使用 Magnum CLI 将其发送到 Magnum 以进行签名

openstack coe ca sign secure-k8s-cluster client.csr > cert.pem
证书颁发机构

您需要检索的最后一个工件是集群的 CA 证书。您的本机客户端使用它来确保您仅与 Magnum 设置的主机进行通信

openstack coe ca show secure-k8s-cluster > ca.pem
轮换证书

要轮换集群的 CA 证书并使所有用户证书失效,您可以使用以下命令

openstack coe ca rotate secure-k8s-cluster

请注意,现在 CA 轮换功能仅受 Fedora CoreOS 驱动程序支持。

用户示例

这里有一些关于在安全 Kubernetes 集群上使用 CLI 的示例。您可以通过以下方式自动设置所有 TLS 设置

eval $(openstack coe cluster config <cluster-name>)

或者,您可以执行上述手动步骤,并在 CLI 上指定 TLS 选项。假设 SSL 工件保存在本地文件中,如下所示

- key.pem: your SSL key
- cert.pem: signed certificate
- ca.pem: certificate for cluster CA

对于 Kubernetes,您需要获取 ‘kubectl’,一个 kubernetes CLI 工具,才能与集群进行通信

curl -O https://storage.googleapis.com/kubernetes-release/release/v1.2.0/bin/linux/amd64/kubectl
chmod +x kubectl
sudo mv kubectl /usr/local/bin/kubectl

现在让我们运行一些 ‘kubectl’ 命令来检查安全通信。如果您使用了 ‘cluster-config’,那么您可以简单地运行 ‘kubectl’ 命令而无需指定 TLS 选项,因为它们已在环境中定义

kubectl version
Client Version: version.Info{Major:"1", Minor:"0", GitVersion:"v1.2.0", GitCommit:"cffae0523cfa80ddf917aba69f08508b91f603d5", GitTreeState:"clean"}
Server Version: version.Info{Major:"1", Minor:"0", GitVersion:"v1.2.0", GitCommit:"cffae0523cfa80ddf917aba69f08508b91f603d5", GitTreeState:"clean"}

您可以手动指定 TLS 选项如下

KUBERNETES_URL=$(openstack coe cluster show secure-k8s-cluster |
                 awk '/ api_address /{print $4}')
kubectl version --certificate-authority=ca.pem \
                --client-key=key.pem \
                --client-certificate=cert.pem -s $KUBERNETES_URL

kubectl create -f redis-master.yaml --certificate-authority=ca.pem \
                                    --client-key=key.pem \
                                    --client-certificate=cert.pem -s $KUBERNETES_URL

pods/test2

kubectl get pods --certificate-authority=ca.pem \
                 --client-key=key.pem \
                 --client-certificate=cert.pem -s $KUBERNETES_URL
NAME           READY     STATUS    RESTARTS   AGE
redis-master   2/2       Running   0          1m

除了使用环境变量,您还可以配置 ‘kubectl’ 以记住 TLS 选项

kubectl config set-cluster secure-k8s-cluster --server=${KUBERNETES_URL} \
    --certificate-authority=${PWD}/ca.pem
kubectl config set-credentials client --certificate-authority=${PWD}/ca.pem \
    --client-key=${PWD}/key.pem --client-certificate=${PWD}/cert.pem
kubectl config set-context secure-k8scluster --cluster=secure-k8scluster --user=client
kubectl config use-context secure-k8scluster

然后您可以使用 ‘kubectl’ 命令而无需证书

kubectl get pods
NAME           READY     STATUS    RESTARTS   AGE
redis-master   2/2       Running   0          1m

访问 Kubernetes 用户界面

curl -L ${KUBERNETES_URL}/ui --cacert ca.pem --key key.pem \
    --cert cert.pem

您还可以设置 ‘kubectl’ 代理,它将使用您的客户端证书允许您浏览到本地地址以使用 UI 而无需在浏览器中安装证书

kubectl proxy --api-prefix=/ --certificate-authority=ca.pem --client-key=key.pem \
              --client-certificate=cert.pem -s $KUBERNETES_URL

您可以在浏览器中打开 https://:8001/ui

Docker 的示例类似。使用 ‘cluster-config’ 设置后,您可以运行 docker 命令而无需 TLS 选项。要手动指定 TLS 选项

docker -H tcp://192.168.19.86:2376 --tlsverify \
       --tlscacert ca.pem \
       --tlskey key.pem \
       --tlscert cert.pem \
       info

存储证书

Magnum 为每个集群生成并维护一个证书,以便它也可以与集群安全地通信。因此,有必要以安全的方式存储证书。Magnum 提供了以下存储证书的方法,这在 /etc/magnum/magnum.conf 的 [certificates] 部分中配置,参数为 ‘cert_manager_type’。

  1. Barbican:Barbican 是 OpenStack 中用于存储密钥的服务。当 cert_manager_type 配置为

    cert_manager_type = barbican
    

    时,它由 Magnum 用于存储证书。这是生产环境的推荐配置。Magnum 将与 Barbican 交互以存储和检索证书,将保护证书的任务委托给 Barbican。

  2. Magnum 数据库:在某些情况下,用户可能希望使用替代方案来存储证书,而无需 Barbican。这可能是开发环境,或者已通过其他方式保护的私有云。Magnum 可以将其证书存储在其自己的数据库中;这是通过配置完成的

    cert_manager_type = x509keypair
    

    此存储模式仅与托管 OpenStack 服务的控制器服务器一样安全。

  3. 本地存储:作为不需要 Barbican 的另一种替代方案,Magnum 可以简单地将证书存储在运行 conductor 的本地主机文件系统上,使用配置

    cert_manager_type = local
    

    请注意,仅当有一个 Magnum conductor 运行时才支持此模式,因为证书存储在本地。‘local’ 模式不推荐用于生产环境。

对于节点,用于与主节点通信的证书存储在本地,并且假定节点是安全的。

网络

集群的网络由两个组件组成。

  1. 集群的 Neutron 基础设施:这包括私有网络、子网、端口、路由器、负载均衡器等。

  2. 呈现给容器的网络模型:这是容器在相互之间以及与外部世界通信时看到的内容。通常,这由部署在每个节点上的驱动程序组成。

这两个组件是单独部署和管理的。Neutron 基础设施与 OpenStack 集成;因此,它在不同的 COE 类型中是稳定且大致相同的。另一方面,网络模型是 COE 类型特定的,并且仍在各个 COE 社区中积极开发,例如 Docker libnetworkKubernetes Container Networking。因此,网络模型的实现正在演变,并且未来可能会引入新的模型。

对于 Neutron 基础设施,可以在 ClusterTemplate 中设置以下配置

external-network

连接到此集群的外部 Neutron 网络 ID。这用于将集群连接到外部互联网,允许集群中的节点访问外部 URL 以进行发现、镜像下载等。如果未指定,则默认值为“public”,这对于典型的 devstack 有效。

fixed-network

用于集群节点的私有网络的 Neutron 网络。如果未指定,将创建一个新的 Neutron 私有网络。

dns-nameserver

用于此集群的 DNS 服务器。这是服务器的 IP 地址,它用于配置集群的 Neutron 子网 (dns_nameservers)。如果未指定,则默认 DNS 为 8.8.8.8,即公开可用的 DNS。

http-proxy, https-proxy, no-proxy

集群中节点的代理,用于在集群位于防火墙后面且容器无法直接访问外部互联网 URL 时使用。对于 http-proxy 和 https-proxy 参数,提供的值是一个 URL,它将在节点中设置为环境变量 HTTP_PROXY 和 HTTPS_PROXY。对于 no-proxy 参数,提供的值是一个 IP 或用逗号分隔的 IP 列表。同样,该值将在节点中的环境变量 NO_PROXY 中设置。

对于容器的网络模型,可以在 ClusterTemplate 中设置以下配置

network-driver

用于实例化容器网络的网络驱动程序名称。当前支持以下网络驱动程序

驱动程序

Kubernetes

Flannel

支持

Calico

支持

如果未指定,则 Kubernetes 的默认驱动程序为 Flannel。

特定的网络驱动程序可能需要其自己的参数集进行配置,这些参数通过 ClusterTemplate 中的标签指定。标签是任意的键=值对。

当指定 Flannel 作为网络驱动程序时,可以添加以下可选标签

flannel_network_cidr

用于整个 Flannel 网络的 CIDR 格式的 IPv4 网络。如果未指定,则默认值为 10.100.0.0/16。

flannel_network_subnetlen

分配给每个主机的子网的大小。如果未指定,则默认值为 24。

flannel_backend

Flannel 的后端类型。可能的值为 udp, vxlan, host-gw。如果未指定,则默认值为 vxlan。选择最佳后端取决于您的网络。通常,udp 是最常用的后端,因为它对网络的要求最少,但通常提供最低的性能。vxlan 后端性能更好,但需要内核中支持 vxlan,因此用于配置节点的镜像需要包含此支持。host-gw 后端提供最佳性能,因为它实际上不封装消息,但它要求所有节点都在同一个 L2 网络上。Magnum 创建的私有 Neutron 网络满足此要求;因此,如果 ClusterTemplate 中未指定参数 fixed_network,则 host-gw 是 Flannel 后端的最佳选择。

当指定 Calico 作为网络驱动程序时,可以添加以下可选标签

calico_ipv4pool

用于创建启动时 IPv4 池的 CIDR 格式的网络。如果未指定,则默认值为 10.100.0.0/16。Stein 默认值:192.168.0.0/16 Train 默认值:192.168.0.0/16 Ussuri 默认值:10.100.0.0/16

calico_ipv4pool_ipip

用于 IPv4 POOL 的 IPIP 模式。Ussuri 默认值:Off

calico_tag

用于配置 calico 节点的 calico 容器的标签 Stein 默认值:v2.6.7 Train 默认值:v3.3.6 Ussuri 默认值:v3.13.1 Victoria 默认值:v3.13.1 Wallaby 默认值:v3.13.1

此外,Calico 网络驱动程序需要 kube_tag 与 v1.9.3 或更高版本,因为 Calico 需要 kubelet 容器的额外挂载。有关更多信息,请参阅 atomic-system-containers 的提交

注意: 我们已经看到在使用 systemd 作为 cgroup-driver 与 Calico 一起使用时出现了一些问题,因此我们强烈建议使用 cgroupfs 作为 Calico 的 cgroup-driver。

VM 的网络

每个集群都有自己的私有网络,该网络与集群一起创建。所有集群节点还在外部网络上获得一个浮动 IP。这种方法默认有效,但在复杂性和成本方面可能很昂贵(公共 Ipv4)。为了降低这种成本,可以使用以下方法

  1. 创建私有网络,但不分配浮动IP 采用这种方法,集群将无法从外部访问。用户可以添加浮动IP来访问它,但证书将无法工作。

  2. 创建私有网络和主节点(s)的负载均衡器 magnum中有两种类型的负载均衡器,一种用于api,另一种用于节点上运行的服务。有关kubernetes LoadBalancer服务类型,请参见:Kubernetes外部负载均衡器。不建议在仅使用单个主节点时使用,因为它会添加2个amphora虚拟机:一个用于kube API,另一个用于etcd,从而成本更高。

以上所有操作也可以通过传递现有的私有网络来完成,而不是使用–fixed-network和–fixed-subnet创建新的网络。

Flannel

在使用flannel时,如果需要性能,后端应为‘host-gw’,‘udp’太慢,‘vxlan’会在现有的neutron网络之上创建另一个叠加网络。另一方面,在扁平网络中,应使用‘vxlan’进行网络隔离。

Calico

Calico允许用户在kubernetes策略中设置网络策略进行网络隔离。

高可用性

对高可用性集群的支持正在进行中,目标是启用跨多个可用区的集群。

目前,您可以为集群指定单个可用区。

availability_zone

集群节点应部署到的可用区。如果未指定,则默认为None。

扩展

周期性任务的性能调优

Magnum的周期性任务对每个集群的底层Heat堆栈执行stack-get操作。如果您有大量的集群,这可能会给Heat API带来相当大的负载。为了减少该负载,您可以配置Magnum在每个周期性任务中执行一个全局stack-list,而不是每个集群一个。默认情况下,这在Heat和Magnum侧都是禁用的,因为它会导致安全问题,尽管:如果Heat配置允许Magnum执行,则任何租户中持有admin角色的任何用户都可以执行全局stack-list操作。如果您仍然想启用它,请按如下步骤操作

  1. 将magnum.conf中的periodic_global_stack_list设置为True(默认值为False)。

  2. 更新heat策略以允许magnum列出堆栈。为此,请编辑您的heat策略文件,通常是etc/heat/policy.yaml``

    ...
    stacks:global_index: "rule:context_is_admin"
    

    现在重启heat。

容器和节点

扩展容器和节点是指增加或减少分配的系统资源。扩展是一个广泛的话题,涉及许多维度。在Magnum的上下文中,在本指南中,我们考虑以下问题

  • 扩展容器和扩展集群节点(基础设施)

  • 手动和自动扩展

由于这是一个活跃的开发领域,目前还没有涵盖所有问题的完整解决方案,但正在出现部分解决方案。

扩展容器涉及通过复制或删除实例来管理容器实例的数量。这可用于响应应用程序所支持的工作负载的变化;在这种情况下,它通常由与应用程序相关的某些指标驱动,例如响应时间等。其他用例包括滚动升级,其中新版本的服务可以逐渐扩展,而旧版本可以逐渐缩小。容器扩展在COE级别支持,并且也特定于每个COE以及COE的版本。您需要参考适当的COE版本文档以获取完整详细信息,但以下是一些参考指针。

对于Kubernetes,pod通过在复制控制器中设置计数来手动扩展。Kubernetes版本1.3及更高版本也支持自动扩展

扩展集群节点涉及通过添加更多节点或删除节点来管理集群中的节点数量。节点数量与可以托管的容器数量之间没有直接相关性,因为消耗的资源(内存、CPU等)取决于容器。但是,如果集群中的某个资源耗尽,添加更多节点将为托管更多容器添加更多资源。作为基础设施管理的一部分,Magnum通过集群中的‘node_count’属性支持手动扩展,因此您可以简单地更改此属性来扩展集群

openstack coe cluster update mycluster replace node_count=2

有关更多详细信息,请参阅Scale生命周期操作。

将节点添加到集群很简单:Magnum通过heat模板部署额外的虚拟机或裸机服务器,并调用COE特定的机制来注册新节点,以更新集群中的可用资源。之后,由COE或用户重新平衡工作负载,通过启动新的容器实例或在新节点上重新启动死去的实例。

从集群中删除节点需要更加小心,以确保容器的连续运行,因为正在删除的节点可能正在主动托管一些容器。Magnum执行一个简单的启发式方法,该方法特定于COE,以找到最佳的删除节点候选者,如下所示

Kubernetes

Magnum扫描‘Default’命名空间中的pod,以确定哪些节点托管任何pod(空节点)。如果要删除的节点数量等于或小于这些空节点的数量,则这些节点将从集群中删除。如果要删除的节点数量大于空节点的数量,则将向Magnum日志发送警告消息,并且空节点以及其他节点将被从集群中删除。将随机选择其他节点,并且运行在这些节点上的pod将被删除,恕不另行通知。因此,良好的做法是通过复制控制器管理pod,以便删除的pod将在集群中的其他地方重新启动。请注意,即使仅删除空节点,也不能保证不会删除任何pod,因为没有锁定机制来确保Kubernetes不会在Magnum扫描pod之后在这些节点上启动新的pod。

目前,容器扩展和集群节点扩展是分别处理的,但在许多用例中,这两个操作之间存在交互。例如,扩展容器可能会耗尽集群中的可用资源,从而需要扩展集群节点。管理这种交互涉及许多复杂的问题。OpenStack Tokyo Summit 2015的一次演讲涵盖了其中一些问题以及一些早期提案,探索Magnum和Senlin集成以进行容器自动扩展。这仍然是一个活跃的讨论和研究领域。

存储

目前,Cinder为容器提供块存储,存储以两种方式提供:作为临时存储和作为持久存储。

临时存储

容器的文件系统由来自镜像的多个层和保存容器所做的修改的顶部层组成。此顶部层需要存储空间,存储在Docker守护程序中通过许多存储选项进行配置。当删除容器时,分配给特定容器的存储也会被删除。

Magnum可以管理容器的文件系统有两种方式,将它们存储在计算实例的本地磁盘上,或者为集群中的每个节点创建一个单独的Cinder块卷,将其挂载到节点并配置为用作临时存储。用户可以使用ClusterTemplate属性‘docker-volume-size’指定Cinder卷的大小。目前,块大小在集群创建时固定,但未来的生命周期操作可能会允许在集群的生命周期内修改块大小。

docker_volume_type

对于支持容器存储的附加卷的驱动程序,会公开一个名为‘docker_volume_type’的标签,以便用户可以选择用于其卷的不同cinder卷类型。默认卷必须在magnum.conf的‘cinder’部分中的‘default_docker_volume_type’中设置,一个明显的值是cinder部署的cinder.conf中设置的默认卷类型。请注意,docker_volume_type指的是cinder卷类型,与docker或kubernetes卷无关。

本地磁盘和Cinder块存储都可以与许多可用的Docker存储驱动程序一起使用。

  • ‘devicemapper’:当与专用的Cinder卷一起使用时,它使用direct-lvm进行配置,并提供非常好的性能。如果它与计算实例的本地磁盘一起使用,则使用loopback设备,提供较差的性能,不建议在生产环境中使用。使用‘devicemapper’驱动程序允许使用SELinux。

  • ‘overlay’ 当与专用的Cinder卷一起使用时,提供与devicemapper一样好或更好的性能。如果用于计算实例的本地磁盘(尤其是具有高IOPS驱动器),可以获得显着的性能提升。但是,对于内核版本低于4.9,必须禁用容器内的SELinux,从而导致较差的容器隔离,尽管它仍然在集群计算实例上以强制模式运行。

  • ‘overlay2’是首选的存储驱动程序,适用于所有当前支持的Linux发行版,并且不需要额外的配置。在可能的情况下,overlay2是推荐的存储驱动程序。首次安装Docker时,overlay2默认使用。

持久存储

在某些用例中,容器读取/写入的数据需要持久保存,以便以后可以访问它。为了持久保存数据,可以在主机上挂载带有文件系统的Cinder卷,并使其可供容器使用,然后在容器退出时卸载它。

Kubernetes允许将先前创建的Cinder块挂载到pod,这通过在pod YAML文件中指定块ID来完成。当pod在节点上调度时,Kubernetes将与Cinder接口以请求将卷挂载到此节点,然后Kubernetes将启动Docker容器,并使用适当的选项使pod中的文件系统可供容器访问。当pod退出时,Kubernetes将再次发送请求到Cinder以卸载卷的文件系统,使其可用于挂载到其他节点。

Magnum支持这些功能,使用Cinder作为持久存储,使用ClusterTemplate属性‘volume-driver’,COE类型的支持矩阵如下

驱动程序

Kubernetes

cinder

支持

以下是一些使用Cinder作为持久存储的示例。

在Kubernetes中使用Cinder

注意: 此功能需要Kubernetes版本1.5.0或更高版本。Atomic的公共Fedora镜像目前满足此要求。

  1. 创建ClusterTemplate。

    将‘cinder’指定为Kubernetes的volume-driver

    openstack coe cluster template create k8s-cluster-template \
                               --image fedora-23-atomic-7 \
                               --keypair testkey \
                               --external-network public \
                               --dns-nameserver 8.8.8.8 \
                               --flavor m1.small \
                               --docker-volume-size 5 \
                               --network-driver flannel \
                               --coe kubernetes \
                               --volume-driver cinder
    
  2. 创建集群

    openstack coe cluster create k8s-cluster \
                          --cluster-template k8s-cluster-template \
                          --node-count 1
    

Kubernetes现在已准备好使用Cinder进行持久存储。以下是一个说明如何在pod中使用Cinder的示例。

  1. 创建cinder卷

    cinder create --display-name=test-repo 1
    
    ID=$(cinder create --display-name=test-repo 1 | awk -F'|' '$2~/^[[:space:]]*id/ {print $3}')
    

    该命令将生成带有ID的卷。卷ID将在步骤2中指定。

  2. 在此集群中创建一个pod并将此cinder卷挂载到pod。创建一个描述pod的文件(例如nginx-cinder.yaml)

    cat > nginx-cinder.yaml << END
    apiVersion: v1
    kind: Pod
    metadata:
      name: aws-web
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              hostPort: 8081
              protocol: TCP
          volumeMounts:
            - name: html-volume
              mountPath: "/usr/share/nginx/html"
      volumes:
        - name: html-volume
          cinder:
            # Enter the volume ID below
            volumeID: $ID
            fsType: ext4
    END
    

注意: Cinder卷ID需要在YAML文件中配置,以便通过在pod清单中指定卷ID将现有的Cinder卷挂载到pod中,如下所示

volumes:
- name: html-volume
  cinder:
    volumeID: $ID
    fsType: ext4
  1. 通过正常的Kubernetes接口创建pod

    kubectl create -f nginx-cinder.yaml
    

您可以启动容器中的shell以检查mountPath是否存在,并在OpenStack客户端上运行命令‘cinder list’以验证cinder卷状态是否为‘in-use’。

镜像管理

当部署COE时,Glance中的镜像用于启动集群中的节点,然后软件将在节点上配置和启动以启动完整的集群。镜像基于特定的发行版,例如Fedora、Ubuntu等,并预构建了COE特定的软件,例如Kubernetes。镜像与Magnum紧密耦合

  1. Heat模板来编排配置。

  2. 模板定义,用于将ClusterTemplate参数映射到Heat模板参数。

  3. 用于配置软件的脚本集。

总的来说,它们构成了特定COE和特定发行版的驱动程序;因此,开发新镜像需要与开发这些其他组件同时进行。可以使用各种方法构建镜像,例如diskimagebuilder,或者在某些情况下,可以直接使用发行版镜像。Magnum支持许多驱动程序和相关的镜像作为参考实现。在本节中,我们主要关注受支持的镜像。

所有镜像必须包含对cloud-init和heat软件配置实用程序的支持

  • os-collect-config

  • os-refresh-config

  • os-apply-config

  • heat-config

  • heat-config-script

描述了其他软件。

Fedora CoreOS上的Kubernetes

Fedoara CoreOS发布了一个库存OpenStack镜像,该镜像用于部署Kubernetes。

以下软件作为systemd服务管理

  • kube-apiserver

  • kube-controller-manager

  • kube-scheduler

  • kube-proxy

  • kubelet

  • docker

  • etcd

此镜像的登录用户为core

通知

Magnum提供有关使用情况数据的通知,以便第三方应用程序可以使用该数据进行审计、计费、监控或配额目的。本文档描述了Magnum通知的当前包含和排除项。

Magnum使用云审计数据联合(CADF)通知作为其通知格式,以更好地支持审计,有关CADF的详细信息如下所述。

使用CADF进行审计

Magnum使用PyCADF库来发出CADF通知,这些事件符合DMTF CADF规范。该标准为符合安全、运营和业务流程的审计能力提供支持,并支持联合和聚合的标准化和分类的事件数据。

下表描述了每个组件的事件模型组件和语义

模型组件

CADF定义

OBSERVER

生成CADF事件记录的RESOURCE,基于其对实际事件的观察(直接或间接)。

INITIATOR

根据OBSERVER发起的、发起的或促使事件ACTION的RESOURCE。

ACTION

INITIATOR对事件TARGET执行、尝试执行或待执行的操作,根据OBSERVER。

TARGET

ACTION作用于、尝试作用于或待作用于的RESOURCE,根据OBSERVER。

OUTCOME

根据OBSERVER,ACTION对TARGET的结果或状态。

CADF通知的payload部分是CADF event,表示为JSON字典。例如

{
    "typeURI": "http://schemas.dmtf.org/cloud/audit/1.0/event",
    "initiator": {
        "typeURI": "service/security/account/user",
        "host": {
            "agent": "curl/7.22.0(x86_64-pc-linux-gnu)",
            "address": "127.0.0.1"
        },
        "id": "<initiator_id>"
    },
    "target": {
        "typeURI": "<target_uri>",
        "id": "openstack:1c2fc591-facb-4479-a327-520dade1ea15"
    },
    "observer": {
        "typeURI": "service/security",
        "id": "openstack:3d4a50a9-2b59-438b-bf19-c231f9c7625a"
    },
    "eventType": "activity",
    "eventTime": "2014-02-14T01:20:47.932842+00:00",
    "action": "<action>",
    "outcome": "success",
    "id": "openstack:f5352d7b-bee6-4c22-8213-450e7b646e9f",
}

以下定义了

  • <initiator_id>:执行操作的用户 ID

  • <target_uri>:CADF 特定的目标 URI(例如:data/security/project)

  • <action>:正在执行的操作,通常为:<operation><resource_type>

此外,根据执行的操作,可能存在额外的键,这些将在下面讨论。

请注意,CADF payload 的 eventType 属性与通知的 event_type 属性不同。前者 (eventType) 是 CADF 关键字,用于指定正在度量的事件类型,可以是:activitymonitorcontrol。而后者 (event_type) 如前几节所述:magnum.<resource_type>.<operation>

支持的事件

下表显示了资源类型和操作之间的对应关系。

资源类型

支持的操作

typeURI

cluster

create, update, delete

service/magnum/cluster

示例通知 - 集群创建

以下是一个集群创建时发送的通知示例。此示例可用于表上看到的任何 createupdatedelete 事件。 <action>typeURI 字段将会改变。

{
    "event_type": "magnum.cluster.created",
    "message_id": "0156ee79-b35f-4cef-ac37-d4a85f231c69",
    "payload": {
        "typeURI": "http://schemas.dmtf.org/cloud/audit/1.0/event",
        "initiator": {
            "typeURI": "service/security/account/user",
            "id": "c9f76d3c31e142af9291de2935bde98a",
            "user_id": "0156ee79-b35f-4cef-ac37-d4a85f231c69",
            "project_id": "3d4a50a9-2b59-438b-bf19-c231f9c7625a"
        },
        "target": {
            "typeURI": "service/magnum/cluster",
            "id": "openstack:1c2fc591-facb-4479-a327-520dade1ea15"
        },
        "observer": {
            "typeURI": "service/magnum/cluster",
            "id": "openstack:3d4a50a9-2b59-438b-bf19-c231f9c7625a"
        },
        "eventType": "activity",
        "eventTime": "2015-05-20T01:20:47.932842+00:00",
        "action": "create",
        "outcome": "success",
        "id": "openstack:f5352d7b-bee6-4c22-8213-450e7b646e9f",
        "resource_info": "671da331c47d4e29bb6ea1d270154ec3"
    }
    "priority": "INFO",
    "publisher_id": "magnum.host1234",
    "timestamp": "2016-05-20 15:03:45.960280"
}

容器监控

目前,仅支持 Kubernetes 集群的监控。有关详细信息,请参阅 Kubernetes 中的容器监控 文档。

Kubernetes 安装后清单

[kubernetes] 部分下添加了一个新的配置选项 post_install_manifest_url,用于支持在配置 k8s 集群后安装云提供商/供应商特定的清单。它是一个指向清单文件的 URL。例如,云管理员可以将他们的特定 StorageClass 放入此文件中,然后在用户创建集群后自动设置。

注意: 创建集群时,主节点必须能够访问该 URL。

Kubernetes 外部负载均衡器

在 Kubernetes 集群中,所有主节点和从节点都连接到私有 Neutron 子网,该子网又通过路由器连接到公共网络。这允许节点之间以及与外部互联网进行访问。

在集群中创建的所有 Kubernetes Pod 和服务都连接到私有容器网络,默认情况下为 Flannel,这是一种运行在 Neutron 私有子网之上的覆盖网络。Pod 和服务从该容器网络分配 IP 地址,并且可以相互访问以及外部互联网。但是,这些 IP 地址无法从外部网络访问。

为了发布外部服务端点,以便可以从外部网络访问该服务,Kubernetes 提供了外部负载均衡器功能。这通过在服务清单中简单地指定属性“type: LoadBalancer”来完成。创建服务时,Kubernetes 将在服务前面添加一个外部负载均衡器,以便该服务除了容器网络上的内部 IP 地址外,还具有外部 IP 地址。然后可以使用此外部 IP 地址访问服务端点。有关更多详细信息,请参阅 Kubernetes 服务文档

由 Magnum 部署的 Kubernetes 集群将具有外部负载均衡器所需的所有必要配置。本文档描述了如何使用此功能。

集群管理员的步骤

由于 Kubernetes 主节点需要与 OpenStack 接口以创建和管理 Neutron 负载均衡器,因此我们需要提供 Kubernetes 用于身份验证的凭据。

在当前实现中,集群管理员需要手动执行此步骤。我们正在研究几种方法,以便让 Magnum 以安全的方式自动执行此步骤。这意味着在 Kubernetes 集群最初部署后,负载均衡器支持将被禁用。如果管理员不想启用此功能,则无需采取进一步的操作。所有服务都将正常创建;指定负载均衡器的服务也将成功创建,但不会创建负载均衡器。

请注意,不同版本的 Kubernetes 需要 OpenStack 实例上运行的不同版本的 Neutron LBaaS 插件

============================  ==============================
Kubernetes Version on Master  Neutron LBaaS Version Required
============================  ==============================
1.2                           LBaaS v1
1.3 or later                  LBaaS v2
============================  ==============================

在启用 Kubernetes 负载均衡器功能之前,请确认 OpenStack 实例正在运行所需的 Neutron LBaaS 插件版本。要确定您的 OpenStack 实例是否正在运行 LBaaS v1,请尝试从您的 OpenStack 控制节点运行以下命令

neutron lb-pool-list

或者在 neutron.conf 或 neutron_lbaas.conf 中查找以下配置

service_provider = LOADBALANCER:Haproxy:neutron_lbaas.services.loadbalancer.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default

要确定您的 OpenStack 实例是否正在运行 LBaaS v2,请尝试从您的 OpenStack 控制节点运行以下命令

neutron lbaas-pool-list

或者在 neutron.conf 或 neutron_lbaas.conf 中查找以下配置

service_plugins = neutron.plugins.services.agent_loadbalancer.plugin.LoadBalancerPluginv2

要配置 LBaaS v1 或 v2,请参阅 Neutron 文档。

在删除 Kubernetes 集群之前,请确保删除创建了负载均衡器的所有服务。由于 Kubernetes 创建的 Neutron 对象不由 Heat 管理,因此 Heat 不会删除它们,这将导致集群删除操作失败。如果发生这种情况,请手动删除 neutron 对象(lb-pool、lb-vip、lb-member、lb-healthmonitor),然后再次运行 cluster-delete。

用户的步骤

此功能要求启用 OpenStack 云提供程序。为此,请启用 cinder 支持(–volume-driver cinder)。

对于用户,发布服务端点外部涉及以下 2 个步骤

  1. 在服务清单中指定“type: LoadBalancer”

  2. 创建服务后,将浮动 IP 与负载均衡器池的 VIP 关联。

以下示例说明了如何为运行 nginx 的 Pod 创建外部端点。

创建一个文件(例如 nginx.yaml)来描述运行 nginx 的 Pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
   app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

创建一个文件(例如 nginx-service.yaml)来描述 nginx Pod 的服务

apiVersion: v1
kind: Service
metadata:
  name: nginxservice
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: nginx
  type: LoadBalancer

请参阅 开发者快速入门,了解如何连接到已启动集群上运行的 Kubernetes。假设已创建名为 k8sclusterv1 的 Kubernetes 集群,请使用以下命令部署 Pod 和服务

kubectl create -f nginx.yaml

kubectl create -f nginx-service.yaml

有关更多详细信息,请参阅以下关于其工作原理的部分,以验证 OpenStack 中的负载均衡器。

接下来,将浮动 IP 与负载均衡器关联。这可以通过在 Horizon 中导航到以下位置轻松完成

Compute -> Access & Security -> Floating IPs

单击“Allocate IP To Project”,然后单击新浮动 IP 的“Associate”。

或者,可以通过命令行分配浮动 IP、查找 VIP 的端口并将浮动 IP 与端口关联来关联浮动 IP。以下命令仅用于说明目的,并假定集群中只有一个具有负载均衡器的服务,并且不存在其他负载均衡器,除了为集群创建的负载均衡器。

首先在公共网络上创建一个浮动 IP

neutron floatingip-create public

Created a new floatingip:

+---------------------+--------------------------------------+
| Field               | Value                                |
+---------------------+--------------------------------------+
| fixed_ip_address    |                                      |
| floating_ip_address | 172.24.4.78                          |
| floating_network_id | 4808eacb-e1a0-40aa-97b6-ecb745af2a4d |
| id                  | b170eb7a-41d0-4c00-9207-18ad1c30fecf |
| port_id             |                                      |
| router_id           |                                      |
| status              | DOWN                                 |
| tenant_id           | 012722667dc64de6bf161556f49b8a62     |
+---------------------+--------------------------------------+

请注意已分配的浮动 IP 172.24.4.78。此浮动 IP 的 ID 如下所示,也可以通过以下方式查询

FLOATING_ID=$(neutron floatingip-list | grep "172.24.4.78" | awk '{print $2}')

接下来找到负载均衡器的 VIP

VIP_ID=$(neutron lb-vip-list | grep TCP | grep -v pool | awk '{print $2}')

找到此 VIP 的端口

PORT_ID=$(neutron lb-vip-show $VIP_ID | grep port_id | awk '{print $4}')

最后将浮动 IP 与 VIP 的端口关联

neutron floatingip-associate $FLOATING_ID $PORT_ID

现在可以通过此浮动 IP 在浏览器中访问 nginx 的端点

http://172.24.4.78:80

或者,可以通过以下方式检查 nginx 的“welcome”消息

curl http://172.24.4.78:80

注意:这里没有必要指定端口:80,但显示是为了与服务清单中指定的端口相关联。

工作原理

Kubernetes 旨在与不同的云(例如 Google Compute Engine (GCE)、Amazon Web Services (AWS) 和 OpenStack)一起工作;因此,需要在特定的云上创建不同的负载均衡器以用于服务。这是通过为每个云提供一个插件来完成的,而 OpenStack 插件是由 Angus Lees 开发的

https://github.com/kubernetes/kubernetes/blob/release-1.0/pkg/cloudprovider/openstack/openstack.go

当 Kubernetes 组件 kube-apiserver 和 kube-controller-manager 启动时,它们将使用提供的凭据来验证客户端,以便与 OpenStack 接口。

创建具有负载均衡器的服务时,插件代码将按以下顺序与 Neutron 接口

  1. 为 Kubernetes 服务创建 lb-pool

  2. 为从节点创建 lb-member

  3. 创建 lb-healthmonitor

  4. 在 Kubernetes 集群的私有网络上创建 lb-vip

可以按如下方式验证这些 Neutron 对象。对于负载均衡器池

neutron lb-pool-list
+--------------------------------------+--------------------------------------------------+----------+-------------+----------+----------------+--------+
| id                                   | name                                             | provider | lb_method   | protocol | admin_state_up | status |
+--------------------------------------+--------------------------------------------------+----------+-------------+----------+----------------+--------+
| 241357b3-2a8f-442e-b534-bde7cd6ba7e4 | a1f03e40f634011e59c9efa163eae8ab                 | haproxy  | ROUND_ROBIN | TCP      | True           | ACTIVE |
| 82b39251-1455-4eb6-a81e-802b54c2df29 | k8sclusterv1-iypacicrskib-api_pool-fydshw7uvr7h  | haproxy  | ROUND_ROBIN | HTTP     | True           | ACTIVE |
| e59ea983-c6e8-4cec-975d-89ade6b59e50 | k8sclusterv1-iypacicrskib-etcd_pool-qbpo43ew2m3x | haproxy  | ROUND_ROBIN | HTTP     | True           | ACTIVE |
+--------------------------------------+--------------------------------------------------+----------+-------------+----------+----------------+--------+

请注意,为了实现集群的高可用性,已经存在 2 个负载均衡器(api 和 ectd)。Kubernetes 服务的新的负载均衡器使用 TCP 协议,并由 Kubernetes 分配名称。

对于池的成员

neutron lb-member-list
+--------------------------------------+----------+---------------+--------+----------------+--------+
| id                                   | address  | protocol_port | weight | admin_state_up | status |
+--------------------------------------+----------+---------------+--------+----------------+--------+
| 9ab7dcd7-6e10-4d9f-ba66-861f4d4d627c | 10.0.0.5 |          8080 |      1 | True           | ACTIVE |
| b179c1ad-456d-44b2-bf83-9cdc127c2b27 | 10.0.0.5 |          2379 |      1 | True           | ACTIVE |
| f222b60e-e4a9-4767-bc44-ffa66ec22afe | 10.0.0.6 |         31157 |      1 | True           | ACTIVE |
+--------------------------------------+----------+---------------+--------+----------------+--------+

同样,为了实现高可用性,已经存在 2 个成员,它们为位于 10.0.0.5 的主节点提供服务。新的成员为位于 10.0.0.6 的从节点提供服务,该从节点托管 Kubernetes 服务。

对于池的监视器

neutron lb-healthmonitor-list
+--------------------------------------+------+----------------+
| id                                   | type | admin_state_up |
+--------------------------------------+------+----------------+
| 381d3d35-7912-40da-9dc9-b2322d5dda47 | TCP  | True           |
| 67f2ae8f-ffc6-4f86-ba5f-1a135f4af85c | TCP  | True           |
| d55ff0f3-9149-44e7-9b52-2e055c27d1d3 | TCP  | True           |
+--------------------------------------+------+----------------+

对于池的 VIP

neutron lb-vip-list
+--------------------------------------+----------------------------------+----------+----------+----------------+--------+
| id                                   | name                             | address  | protocol | admin_state_up | status |
+--------------------------------------+----------------------------------+----------+----------+----------------+--------+
| 9ae2ebfb-b409-4167-9583-4a3588d2ff42 | api_pool.vip                     | 10.0.0.3 | HTTP     | True           | ACTIVE |
| c318aec6-8b7b-485c-a419-1285a7561152 | a1f03e40f634011e59c9efa163eae8ab | 10.0.0.7 | TCP      | True           | ACTIVE |
| fc62cf40-46ad-47bd-aa1e-48339b95b011 | etcd_pool.vip                    | 10.0.0.4 | HTTP     | True           | ACTIVE |
+--------------------------------------+----------------------------------+----------+----------+----------------+--------+

请注意,VIP 在集群的私有网络上创建;因此,它具有内部 IP 地址 10.0.0.7。此地址也作为 Kubernetes 服务的“外部地址”关联。可以通过运行以下命令在 Kubernetes 中验证此信息

kubectl get services
NAME           LABELS                                    SELECTOR    IP(S)            PORT(S)
kubernetes     component=apiserver,provider=kubernetes   <none>      10.254.0.1       443/TCP
nginxservice   app=nginx                                 app=nginx   10.254.122.191   80/TCP
                                                                     10.0.0.7

在 GCE 上,网络实现会自动为负载均衡器提供外部地址。在 OpenStack 上,我们需要采取将浮动 IP 与负载均衡器关联的额外步骤。

Kubernetes 的 Keystone 身份验证和授权

目前,有几种方法可以访问 Kubernetes API,例如 RBAC、ABAC、Webhook 等。虽然 RBAC 是大多数情况下的最佳方法,但 Webhook 提供了一种很好的方法,用于 Kubernetes 在确定用户权限时查询外部 REST 服务。换句话说,我们可以使用 Webhook 将其他 IAM 服务集成到 Kubernetes 中。在我们的例子中,在 OpenStack 的上下文中,我们正在引入与 Keystone auth 集成以用于 Kubernetes。

从 Rocky 版本开始,我们引入了一个名为 keystone_auth_enabled 的新标签,默认情况下为 True,这意味着用户可以开箱即用地获得这个很好的功能。

创建角色

作为云提供程序,需要为不同的用户创建必要的 Keystone 角色,用于 Kubernetes 集群操作,例如 k8s_admin、k8s_developer、k8s_viewer

  • k8s_admin 角色可以创建/更新/删除 Kubernetes 集群,还可以将角色关联到租户内的其他普通用户

  • k8s_developer 可以创建/更新/删除/监视 Kubernetes 集群资源

  • k8s_viewer 只能具有对 Kubernetes 集群资源的只读访问权限

注意:这些角色将在 devstack 中自动创建。以下是创建它们的示例命令。

source ~/openstack_admin_credentials
for role in "k8s_admin" "k8s_developer" "k8s_viewer"; do openstack role create $role; done

openstack user create demo_viewer --project demo --password password
openstack role add --user demo_viewer --project demo k8s_viewer

openstack user create demo_editor --project demo --password password
openstack role add --user demo_developer --project demo k8s_developer

openstack user create demo_admin --project demo --password password
openstack role add --user demo_admin --project demo k8s_admin

这些角色应该是公开的,并且可以由任何项目访问,以便用户可以使用这些角色配置其集群的角色策略。

设置授权策略的 configmap

虽然 k8s-keystone-auth 服务默认在集群中启用,但用户需要指定自己的授权策略才能开始使用此功能。

用户可以通过以下方式指定自己的授权策略

  • 更新默认在 kube-system 命名空间中创建的占位符 k8s-keystone-auth-policy configmap。这不需要重新启动 k8s-keystone-auth 服务。

  • 从默认策略文件读取策略。在 devstack 中,策略文件会自动创建。

目前,k8s-keystone-auth 服务支持四种类型的策略

  • user。Keystone 用户 ID 或名称。

  • project。Keystone 项目 ID 或名称。

  • role。Keystone 中定义的用户角色。

  • group。实际上,group 不是 Keystone 概念,而是为了向后兼容而支持的,可以将 group 作为项目 ID 使用。

例如,如果我们希望配置一个策略,仅允许 OpenStack 中 demo 项目中具有 k8s-viewer 角色的用户查询所有命名空间的 Pod 信息,那么我们可以将默认 k8s-keystone-auth-policy configmap 更新如下。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: k8s-keystone-auth-policy
namespace: kube-system
data:
policies: |
    [
    {
        "resource": {
        "verbs": ["get", "list", "watch"],
        "resources": ["pods"],
        "version": "*",
        "namespace": "default"
        },
        "match": [
        {
            "type": "role",
            "values": ["k8s-viewer"]
        },
        {
            "type": "project",
            "values": ["demo"]
        }
        ]
    }
    ]
EOF

有关 keystone 授权策略的更多信息,请参阅 kubernetes/cloud-provider-openstack 文档中的 使用 Keystone Webhook 身份验证器和授权器

注意:如果用户希望使用 k8s-keystone-auth-policy configmap 的替代名称,他们需要更新传递给 k8s-keystone-auth 服务的 –policy-configmap-name 参数的值,然后重新启动该服务。

接下来,用户需要从 Keystone 获取一个 token,以便为 kubectl 准备 kubeconfig。用户也可以使用 Magnum python 客户端获取配置。

这是一个 kubeconfig 示例

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: CERT-DATA==
    server: https://172.24.4.25:6443
name: k8s-2
contexts:
- context:
    cluster: k8s-2
    user: openstackuser
name: openstackuser@kubernetes
current-context: openstackuser@kubernetes
kind: Config
preferences: {}
users:
- name: openstackuser
user:
    exec:
    command: /bin/bash
    apiVersion: client.authentication.k8s.io/v1alpha1
    args:
    - -c
    - >
        if [ -z ${OS_TOKEN} ]; then
            echo 'Error: Missing OpenStack credential from environment variable $OS_TOKEN' > /dev/stderr
            exit 1
        else
            echo '{ "apiVersion": "client.authentication.k8s.io/v1alpha1", "kind": "ExecCredential", "status": { "token": "'"${OS_TOKEN}"'"}}'
        fi

将 Keystone token 导出到 OS_TOKEN 环境变量后,用户应该能够使用 kubectl 列出 Pod。

设置角色同步策略的 configmap

为了开始利用 Kubernetes 和 OpenStack 之间的角色同步,用户需要指定一个 身份验证同步策略

用户可以通过以下方式指定自己的策略

  • 更新默认在 kube-system 命名空间中创建的占位符 keystone-sync-policy configmap。这不需要重新启动 k8s-keystone-auth

  • 从本地配置文件读取策略。这需要重新启动 k8s-keystone-auth 服务。

例如,要设置一个策略,将 Kubernetes 中的 project-1 组分配给在 Keystone 中分配了 member 角色的用户,用户可以将默认 keystone-sync-policy configmap 更新如下。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: keystone-sync-policy
  namespace: kube-system
data:
  syncConfig: |
    role-mappings:
      - keystone-role: member
        groups: ["project-1"]
EOF

如果用户希望使用 keystone-sync-policy configmap 的替代名称,他们需要更新传递给 k8s-keystone-auth 服务的 --sync-configmap-name 参数的值,然后重新启动服务。

有关更多示例和有关配置和使用授权同步策略的信息,请参阅 kubernetes/cloud-provider-openstack 文档中的 Keystone 和 Kubernetes 之间的身份验证同步

节点组

节点组可用于创建异构集群。

此功能仅支持 Kubernetes 集群。

创建集群时,它已经具有两个节点组,default-masterdefault-worker

$ openstack coe cluster list
+--------------------------------------+------+-----------+------------+--------------+-----------------+---------------+
| uuid                                 | name | keypair   | node_count | master_count | status          | health_status |
+--------------------------------------+------+-----------+------------+--------------+-----------------+---------------+
| ef7011bb-d404-4198-a145-e8808204cde3 | kube | default   |          1 |            1 | CREATE_COMPLETE | HEALTHY       |
+--------------------------------------+------+-----------+------------+--------------+-----------------+---------------+

$ openstack coe nodegroup list kube
+--------------------------------------+----------------+-----------+----------------------------------------+------------+-----------------+--------+
| uuid                                 | name           | flavor_id | image_id                               | node_count | status          | role   |
+--------------------------------------+----------------+-----------+----------------------------------------+------------+-----------------+--------+
| adc3ecfa-d11e-4da7-8c44-4092ea9dddd9 | default-master | m1.small  | Fedora-AtomicHost-29-20190820.0.x86_64 |          1 | CREATE_COMPLETE | master |
| 186e131f-8103-4285-a900-eb0dcf18a670 | default-worker | m1.small  | Fedora-AtomicHost-29-20190820.0.x86_64 |          1 | CREATE_COMPLETE | worker |
+--------------------------------------+----------------+-----------+----------------------------------------+------------+-----------------+--------+

无法删除或重新配置 default-worker 节点组,因此初始集群配置应考虑到这一点。

创建新的节点组

要添加新的节点组,请使用 openstack coe nodegroup create。 唯一必需的参数是集群 ID 和新节点组的名称,但有几个额外的选项可用。

角色

角色可用于显示节点组的目的,如果它们具有共同的目的,则可以向多个节点组分配相同的角色。

$ openstack coe nodegroup create kube test-ng --node-count 1 --role test

列出节点组时,可以使用角色作为过滤器

$ openstack coe nodegroup list kube --role test
+--------------------------------------+---------+-----------+----------------------------------------+------------+--------------------+------+
| uuid                                 | name    | flavor_id | image_id                               | node_count | status             | role |
+--------------------------------------+---------+-----------+----------------------------------------+------------+--------------------+------+
| b4ab1fcb-f23a-4d1f-b583-d699a2f1e2d7 | test-ng | m1.small  | Fedora-AtomicHost-29-20190820.0.x86_64 |          1 | CREATE_IN_PROGRESS | test |
+--------------------------------------+---------+-----------+----------------------------------------+------------+--------------------+------+

如果未设置,节点组角色将默认设置为“worker”,并且唯一的保留角色是“master”。

角色信息在 Kubernetes 中作为节点上的标签提供。

$ kubectl get nodes -L magnum.openstack.org/role
NAME                               STATUS   AGE    VERSION   ROLE
kube-r6cyw4bjb4lr-master-0         Ready    5d5h   v1.16.0   master
kube-r6cyw4bjb4lr-node-0           Ready    5d5h   v1.16.0   worker
kube-test-ng-lg7bkvjgus4y-node-0   Ready    61s    v1.16.0   test

可以使用它来进行调度,使用 节点选择器

nodeSelector:
  magnum.openstack.org/role: test

标签 magnum.openstack.org/nodegroup 也可用于选择特定的节点组。

风味

节点组风味将默认设置为创建集群时给定的 minion 风味,但可以为每个新的节点组更改。

$ openstack coe nodegroup create ef7011bb-d404-4198-a145-e8808204cde3 large-ng --flavor m2.large

如果需要在同一集群中需要不同大小的节点,或者通过创建新的节点组并删除旧的节点组来从一种风味切换到另一种风味,可以使用它。

可用区

要创建跨越多个可用区的集群,必须使用多个节点组。 可用区作为标签传递给节点组。

$ openstack coe nodegroup create kube zone-a --labels availability_zone=zone-a --labels ...
$ openstack coe nodegroup create kube zone-b --labels availability_zone=zone-b --labels ...
$ openstack coe nodegroup create kube zone-c --labels availability_zone=zone-c --labels ...

其中 --labels ... 是集群创建时其余的标签,可以使用此脚本从集群获取。

$ openstack coe cluster show -f json <CLUSTER_ID> |
    jq --raw-output '.labels | to_entries |
    map("--labels \(.key)=\"\(.value)\"") | join(" ")'

可用区信息在集群中作为每个节点上的标签 topology.kubernetes.io/zone 提供,或者作为现在已弃用的标签 failure-domain.beta.kubernetes.io/zone

从 Kubernetes 1.16 及更高版本开始,可以 跨可用区(或任何其他标签)平衡部署中 Pod 的数量

调整大小

调整节点组的大小使用与调整集群大小相同的 API,但必须使用 --nodegroup 参数。

$ openstack coe cluster resize kube --nodegroup default-worker 2
Request to resize cluster ef7011bb-d404-4198-a145-e8808204cde3 has been accepted.

与往常一样,可以使用 --nodes-to-remove 参数在减小节点组大小时删除特定的节点。

删除

可以删除任何节点组,但默认的 master 和 worker 节点组除外,方法是指定集群和节点组名称或 ID。

$ openstack coe nodegroup delete ef7011bb-d404-4198-a145-e8808204cde3 test-ng

Kubernetes 健康监控

目前 Magnum 可以支持 Kubernetes 集群的健康监控。 现在支持两种场景:内部和外部。

内部健康监控

Magnum 具有定期作业,用于轮询 k8s 集群是否为可访问的集群。 如果启用了浮动 IP,或者启用了 master 负载均衡器并且 master 负载均衡器具有关联的浮动 IP,则 Magnum 会将此集群视为可访问。 然后,Magnum 将每 10 秒调用一次 k8s API 以轮询集群的健康状态,然后更新两个属性:health_statushealth_status_reason

外部健康监控

目前,只有 magnum-auto-healer 能够更新集群的 health_statushealth_status_reason 属性。 必须设置这两个标签 auto_healing_enabled=Trueauto_healing_controller=magnum-auto-healer,否则,这两个属性的值将被覆盖为“UNKNOWN”和“集群不可访问”。 health_status 属性可以是 HEALTHYUNHEALTHYUNKNOWN 中的任何一个,health_status_reason 是主机名及其当前健康状态的字典以及 API 健康状态。