Kubernetes integration with OpenStack networking
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

338 lines
15 KiB

  1. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  2. # not use this file except in compliance with the License. You may obtain
  3. # a copy of the License at
  4. #
  5. # http://www.apache.org/licenses/LICENSE-2.0
  6. #
  7. # Unless required by applicable law or agreed to in writing, software
  8. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  9. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  10. # License for the specific language governing permissions and limitations
  11. # under the License.
  12. import os
  13. import sys
  14. from kuryr.lib._i18n import _
  15. from kuryr.lib import config as lib_config
  16. from oslo_config import cfg
  17. from oslo_log import log as logging
  18. from kuryr_kubernetes import constants
  19. from kuryr_kubernetes import version
  20. LOG = logging.getLogger(__name__)
  21. kuryr_k8s_opts = [
  22. cfg.StrOpt('pybasedir',
  23. help=_('Directory where Kuryr-kubernetes python module is '
  24. 'installed.'),
  25. default=os.path.abspath(
  26. os.path.join(os.path.dirname(__file__),
  27. '../../'))),
  28. ]
  29. daemon_opts = [
  30. cfg.StrOpt('bind_address',
  31. help=_('Bind address for CNI daemon HTTP server. It is '
  32. 'recommened to allow only local connections.'),
  33. default='127.0.0.1:5036'),
  34. cfg.IntOpt('worker_num',
  35. help=_('Maximum number of processes that will be spawned to '
  36. 'process requests from CNI driver.'),
  37. default=30),
  38. cfg.IntOpt('vif_annotation_timeout',
  39. help=_('Time (in seconds) the CNI daemon will wait for VIF '
  40. 'annotation to appear in pod metadata before failing '
  41. 'the CNI request.'),
  42. default=60),
  43. cfg.IntOpt('pyroute2_timeout',
  44. help=_('Kuryr uses pyroute2 library to manipulate networking '
  45. 'interfaces. When processing a high number of Kuryr '
  46. 'requests in parallel, it may take kernel more time to '
  47. 'process all networking stack changes. This option '
  48. 'allows to tune internal pyroute2 timeout.'),
  49. default=10),
  50. cfg.BoolOpt('docker_mode',
  51. help=_('Set to True when you are running kuryr-daemon inside '
  52. 'a Docker container on Kubernetes host. E.g. as '
  53. 'DaemonSet on Kubernetes cluster Kuryr is supposed to '
  54. 'provide networking for. This mainly means that '
  55. 'kuryr-daemon will look for network namespaces in '
  56. '$netns_proc_dir instead of /proc.'),
  57. default=False),
  58. cfg.StrOpt('netns_proc_dir',
  59. help=_("When docker_mode is set to True, this config option "
  60. "should be set to where host's /proc directory is "
  61. "mounted. Please note that mounting it is necessary to "
  62. "allow Kuryr-Kubernetes to move host interfaces between "
  63. "host network namespaces, which is essential for Kuryr "
  64. "to work."),
  65. default=None),
  66. cfg.IntOpt('cni_failures_count',
  67. help=_('Maximum number of consecutive failures of kuryr-daemon '
  68. 'when processing requests. If this number is exceeded, '
  69. 'kuryr-daemon will be marked as unhealthy.'),
  70. default=3),
  71. ]
  72. k8s_opts = [
  73. cfg.StrOpt('api_root',
  74. help=_("The root URL of the Kubernetes API"),
  75. default=os.environ.get('K8S_API', 'http://localhost:8080')),
  76. cfg.StrOpt('ssl_client_crt_file',
  77. help=_("Absolute path to client cert to "
  78. "connect to HTTPS K8S_API")),
  79. cfg.StrOpt('ssl_client_key_file',
  80. help=_("Absolute path client key file to "
  81. "connect to HTTPS K8S_API")),
  82. cfg.StrOpt('ssl_ca_crt_file',
  83. help=_("Absolute path to ca cert file to "
  84. "connect to HTTPS K8S_API")),
  85. cfg.BoolOpt('ssl_verify_server_crt',
  86. help=_("HTTPS K8S_API server identity verification"),
  87. default=False),
  88. cfg.StrOpt('token_file',
  89. help=_("The token to talk to the k8s API"),
  90. default=''),
  91. cfg.StrOpt('pod_project_driver',
  92. help=_("The driver to determine OpenStack "
  93. "project for pod ports"),
  94. default='default'),
  95. cfg.StrOpt('service_project_driver',
  96. help=_("The driver to determine OpenStack "
  97. "project for services"),
  98. default='default'),
  99. cfg.StrOpt('namespace_project_driver',
  100. help=_("The driver to determine OpenStack "
  101. "project for namespaces"),
  102. default='default'),
  103. cfg.StrOpt('network_policy_project_driver',
  104. help=_("The driver to determine OpenStack "
  105. "project for network policies"),
  106. default='default'),
  107. cfg.StrOpt('pod_subnets_driver',
  108. help=_("The driver to determine Neutron "
  109. "subnets for pod ports"),
  110. default='default'),
  111. cfg.StrOpt('service_subnets_driver',
  112. help=_("The driver to determine Neutron "
  113. "subnets for services"),
  114. default='default'),
  115. cfg.StrOpt('pod_security_groups_driver',
  116. help=_("The driver to determine Neutron "
  117. "security groups for pods"),
  118. default='default'),
  119. cfg.StrOpt('service_security_groups_driver',
  120. help=_("The driver to determine Neutron "
  121. "security groups for services"),
  122. default='default'),
  123. cfg.StrOpt('pod_vif_driver',
  124. help=_("The driver that provides VIFs for Kubernetes Pods."),
  125. default='neutron-vif'),
  126. cfg.StrOpt('endpoints_lbaas_driver',
  127. help=_("The driver that provides LoadBalancers for "
  128. "Kubernetes Endpoints"),
  129. default='lbaasv2'),
  130. cfg.StrOpt('endpoints_driver_octavia_provider',
  131. help=_("The Octavia load balancer provider that will be used "
  132. "to support Kubernetes Endpoints"),
  133. default='default'),
  134. cfg.StrOpt('vif_pool_driver',
  135. help=_("The driver that manages VIFs pools for "
  136. "Kubernetes Pods"),
  137. default='noop'),
  138. cfg.BoolOpt('port_debug',
  139. help=_('Enable port debug to force kuryr port names to be '
  140. 'set to their corresponding pod names.'),
  141. default=False),
  142. cfg.StrOpt('service_public_ip_driver',
  143. help=_("The driver that provides external IP for LB at "
  144. "Kubernetes"),
  145. default='neutron_floating_ip'),
  146. cfg.BoolOpt('enable_manager',
  147. help=_("Enable Manager to manage the pools."),
  148. default=False),
  149. cfg.IntOpt('watch_retry_timeout',
  150. help=_('Time (in seconds) the watcher retries watching for.'),
  151. default=60),
  152. cfg.IntOpt('watch_connection_timeout',
  153. help=_('TCP connection timeout (in seconds) for the watcher '
  154. 'connections to K8s API.'),
  155. default=30),
  156. cfg.IntOpt('watch_read_timeout',
  157. help=_('TCP read timeout (in seconds) for the watcher '
  158. 'connections to K8s API. This affects reaction to time '
  159. 'when there are no events being streamed from K8s API. '
  160. 'When too low, Kuryr will reconnect more often. When '
  161. 'too high, Kuryr will take longer to reconnect when K8s '
  162. 'API stream was being silently broken.'),
  163. default=60),
  164. cfg.ListOpt('enabled_handlers',
  165. help=_("The comma-separated handlers that should be "
  166. "registered for watching in the pipeline."),
  167. default=['vif', 'lb', 'lbaasspec']),
  168. cfg.BoolOpt('controller_ha',
  169. help=_('Enable kuryr-controller active/passive HA. Only '
  170. 'supported in containerized deployments on Kubernetes '
  171. 'or OpenShift.'),
  172. default=False),
  173. cfg.PortOpt('controller_ha_elector_port',
  174. help=_('Port on which leader-elector pod is listening to.'),
  175. default=16401),
  176. cfg.StrOpt('network_policy_driver',
  177. help=_("Driver for network policies"),
  178. default='default'),
  179. cfg.ListOpt('multi_vif_drivers',
  180. help=_("The drivers that provide additional VIFs for "
  181. "Kubernetes Pods."),
  182. default='noop'),
  183. ]
  184. neutron_defaults = [
  185. cfg.StrOpt('project',
  186. help=_("Default OpenStack project ID for "
  187. "Kubernetes resources")),
  188. cfg.StrOpt('pod_subnet',
  189. help=_("Default Neutron subnet ID for Kubernetes pods")),
  190. cfg.ListOpt('pod_security_groups',
  191. help=_("Default Neutron security groups' IDs "
  192. "for Kubernetes pods")),
  193. cfg.StrOpt('ovs_bridge',
  194. help=_("Default OpenVSwitch integration bridge"),
  195. sample_default="br-int"),
  196. cfg.StrOpt('service_subnet',
  197. help=_("Default Neutron subnet ID for Kubernetes services")),
  198. cfg.StrOpt('external_svc_net',
  199. help=_("Default external network ID for Kubernetes services")),
  200. cfg.StrOpt('external_svc_subnet',
  201. help=_("Optional external subnet ID for Kubernetes services"),
  202. default=None),
  203. cfg.IntOpt('network_device_mtu',
  204. help='Default MTU setting for network interface.',
  205. default=1500,),
  206. cfg.IntOpt('lbaas_activation_timeout',
  207. help=_("Time (in seconds) that kuryr controller waits for "
  208. "neutron LBaaS to be activated"),
  209. default=300),
  210. cfg.DictOpt('subnet_mapping',
  211. help=_("A mapping of default subnets for certain driverType "
  212. "in a form of <driverType>:<SUBNET-ID>"),
  213. default={}),
  214. cfg.ListOpt('resource_tags',
  215. help=_("List of tags that will be applied to all OpenStack "
  216. "(Neutron and Octavia) resources created by Kuryr. "
  217. "This can be used to identify and garbage-collect "
  218. "them when Kubernetes cluster Kuryr was serving is no "
  219. "longer needed."),
  220. default=[])
  221. ]
  222. octavia_defaults = [
  223. cfg.StrOpt('member_mode',
  224. help=_("Define the communication mode between load balanacer "
  225. "and its members"),
  226. default='L3'),
  227. cfg.StrOpt('sg_mode',
  228. help=_("Define the LBaaS SG policy."),
  229. choices=[('create', 'replace the VIP SG with a new one'),
  230. ('update', 'add rules to the existing VIP SG')],
  231. default='update'),
  232. cfg.BoolOpt('enforce_sg_rules',
  233. help=_("Enable the enforcement of SG rules at the LB SG "
  234. "in case the LB does not maintain the source IP "
  235. "of the caller resource"),
  236. default=True),
  237. ]
  238. cache_defaults = [
  239. cfg.BoolOpt('enabled',
  240. help=_("Enable caching."),
  241. default=True),
  242. cfg.StrOpt('backend',
  243. help=_("Select backend cache option."),
  244. default="dogpile.cache.memory"),
  245. ]
  246. ingress = [
  247. cfg.StrOpt('l7_router_uuid',
  248. help=_("UUID of the L7 Router")),
  249. ]
  250. nested_vif_driver_opts = [
  251. cfg.StrOpt('worker_nodes_subnet',
  252. help=_("Neutron subnet ID for k8s worker node vms."),
  253. default=''),
  254. ]
  255. DEFAULT_PHYSNET_SUBNET_MAPPINGS = {}
  256. DEFAULT_DEVICE_MAPPINGS = []
  257. sriov_opts = [
  258. cfg.StrOpt('kubelet_root_dir',
  259. help=_("The root directory of the Kubelet daemon"),
  260. default='/var/lib/kubelet'),
  261. cfg.BoolOpt('enable_pod_resource_service',
  262. help=_("Enable PodResources service"),
  263. default=False),
  264. cfg.DictOpt('default_physnet_subnets',
  265. help=_("A mapping of default subnets for certain physnets "
  266. "in a form of physnet-name:<SUBNET-ID>"),
  267. default=DEFAULT_PHYSNET_SUBNET_MAPPINGS),
  268. cfg.ListOpt('physical_device_mappings',
  269. default=DEFAULT_DEVICE_MAPPINGS,
  270. help=_("Comma-separated list of "
  271. "<physical_network>:<network_device> tuples mapping "
  272. "physical network names to the agent's node-specific "
  273. "physical network device interfaces of SR-IOV physical "
  274. "function to be used for VLAN networks.")),
  275. cfg.DictOpt('physnet_resource_mappings',
  276. help=_("A mapping of physnets for certain sriov dp "
  277. "resource name in a form of "
  278. "physnet-name:resource name. "
  279. "Resource name is listed in sriov device plugin "
  280. "configuation file."),
  281. default=DEFAULT_PHYSNET_SUBNET_MAPPINGS),
  282. cfg.StrOpt('device_plugin_resource_prefix',
  283. help=_("This prefix is used by sriov-network-device-plugin "
  284. "It concatenates with resource suffix defined in "
  285. "sriov device plugin configuration file."),
  286. default=constants.K8S_SRIOV_PREFIX),
  287. cfg.DictOpt('resource_driver_mappings',
  288. help=_("A mappping driver names for certain resource "
  289. "names. Expected that device of VIF related to "
  290. "exact physnet should be binded on specified driver."),
  291. default=DEFAULT_PHYSNET_SUBNET_MAPPINGS),
  292. ]
  293. CONF = cfg.CONF
  294. CONF.register_opts(kuryr_k8s_opts)
  295. CONF.register_opts(daemon_opts, group='cni_daemon')
  296. CONF.register_opts(k8s_opts, group='kubernetes')
  297. CONF.register_opts(neutron_defaults, group='neutron_defaults')
  298. CONF.register_opts(octavia_defaults, group='octavia_defaults')
  299. CONF.register_opts(cache_defaults, group='cache_defaults')
  300. CONF.register_opts(ingress, group='ingress')
  301. CONF.register_opts(nested_vif_driver_opts, group='pod_vif_nested')
  302. CONF.register_opts(sriov_opts, group='sriov')
  303. CONF.register_opts(lib_config.core_opts)
  304. CONF.register_opts(lib_config.binding_opts, 'binding')
  305. lib_config.register_neutron_opts(CONF)
  306. logging.register_options(CONF)
  307. def init(args, **kwargs):
  308. version_k8s = version.version_info.version_string()
  309. CONF(args=args, project='kuryr-k8s', version=version_k8s, **kwargs)
  310. def setup_logging():
  311. logging.setup(CONF, 'kuryr-kubernetes')
  312. logging.set_defaults(default_log_levels=logging.get_default_log_levels())
  313. version_k8s = version.version_info.version_string()
  314. LOG.info("Logging enabled!")
  315. LOG.info("%(prog)s version %(version)s",
  316. {'prog': sys.argv[0], 'version': version_k8s})