Merge "OpenShift/k8s Provider: Basic Support for k8s nodeSelectors"

This commit is contained in:
Zuul 2020-09-07 12:33:11 +00:00 committed by Gerrit Code Review
commit e8b9bfe139
8 changed files with 65 additions and 14 deletions

View File

@ -1423,6 +1423,14 @@ Selecting the kubernetes driver adds the following options to the
The value of the environment variable passed to the Pod. The value of the environment variable passed to the Pod.
.. attr:: node-selector
:type: dict
Only used by the
:value:`providers.[kubernetes].pools.labels.type.pod` label type;
A map of key-value pairs to ensure the Kubernetes scheduler
places the Pod on a node with specific node labels.
Openshift Driver Openshift Driver
---------------- ----------------
@ -1594,6 +1602,14 @@ Selecting the openshift driver adds the following options to the
The value of the environment variable passed to the Pod. The value of the environment variable passed to the Pod.
.. attr:: node-selector
:type: dict
Only used by the
:value:`providers.[openshift].labels.type.pod` label type;
A map of key-value pairs to ensure the OpenShift scheduler
places the Pod on a node with specific node labels.
Openshift Pods Driver Openshift Pods Driver
--------------------- ---------------------
@ -1724,6 +1740,12 @@ Selecting the openshift pods driver adds the following options to the
The value of the environment variable passed to the Pod. The value of the environment variable passed to the Pod.
.. attr:: node-selector
:type: dict
A map of key-value pairs to ensure the OpenShift scheduler
places the Pod on a node with specific node labels.
AWS EC2 Driver AWS EC2 Driver
-------------- --------------

View File

@ -31,7 +31,8 @@ class KubernetesLabel(ConfigValue):
other.image == self.image and other.image == self.image and
other.cpu == self.cpu and other.cpu == self.cpu and
other.memory == self.memory and other.memory == self.memory and
other.env == self.env) other.env == self.env and
other.node_selector == self.node_selector)
return False return False
def __repr__(self): def __repr__(self):
@ -63,6 +64,7 @@ class KubernetesPool(ConfigPool):
pl.cpu = label.get('cpu') pl.cpu = label.get('cpu')
pl.memory = label.get('memory') pl.memory = label.get('memory')
pl.env = label.get('env', []) pl.env = label.get('env', [])
pl.node_selector = label.get('node-selector')
pl.pool = self pl.pool = self
self.labels[pl.name] = pl self.labels[pl.name] = pl
full_config.labels[label['name']].pools.append(self) full_config.labels[label['name']].pools.append(self)
@ -113,6 +115,7 @@ class KubernetesProviderConfig(ProviderConfig):
'cpu': int, 'cpu': int,
'memory': int, 'memory': int,
'env': [env_var], 'env': [env_var],
'node-selector': dict,
} }
pool = ConfigPool.getCommonSchemaDict() pool = ConfigPool.getCommonSchemaDict()

View File

@ -274,7 +274,7 @@ class KubernetesProvider(Provider, QuotaSupport):
return resource return resource
def createPod(self, node, pool, label): def createPod(self, node, pool, label):
spec_body = { container_body = {
'name': label.name, 'name': label.name,
'image': label.image, 'image': label.image,
'imagePullPolicy': label.image_pull, 'imagePullPolicy': label.image_pull,
@ -285,22 +285,27 @@ class KubernetesProvider(Provider, QuotaSupport):
} }
if label.cpu or label.memory: if label.cpu or label.memory:
spec_body['resources'] = {} container_body['resources'] = {}
for rtype in ('requests', 'limits'): for rtype in ('requests', 'limits'):
rbody = {} rbody = {}
if label.cpu: if label.cpu:
rbody['cpu'] = int(label.cpu) rbody['cpu'] = int(label.cpu)
if label.memory: if label.memory:
rbody['memory'] = '%dMi' % int(label.memory) rbody['memory'] = '%dMi' % int(label.memory)
spec_body['resources'][rtype] = rbody container_body['resources'][rtype] = rbody
spec_body = {
'containers': [container_body]
}
if label.node_selector:
spec_body['nodeSelector'] = label.node_selector
pod_body = { pod_body = {
'apiVersion': 'v1', 'apiVersion': 'v1',
'kind': 'Pod', 'kind': 'Pod',
'metadata': {'name': label.name}, 'metadata': {'name': label.name},
'spec': { 'spec': spec_body,
'containers': [spec_body],
},
'restartPolicy': 'Never', 'restartPolicy': 'Never',
} }

View File

@ -32,7 +32,8 @@ class OpenshiftLabel(ConfigValue):
other.cpu == self.cpu and other.cpu == self.cpu and
other.memory == self.memory and other.memory == self.memory and
other.python_path == self.python_path and other.python_path == self.python_path and
other.env == self.env) other.env == self.env and
other.node_selector == self.node_selector)
return False return False
def __repr__(self): def __repr__(self):
@ -64,6 +65,7 @@ class OpenshiftPool(ConfigPool):
pl.memory = label.get('memory') pl.memory = label.get('memory')
pl.python_path = label.get('python-path', 'auto') pl.python_path = label.get('python-path', 'auto')
pl.env = label.get('env', []) pl.env = label.get('env', [])
pl.node_selector = label.get('node-selector')
pl.pool = self pl.pool = self
self.labels[pl.name] = pl self.labels[pl.name] = pl
full_config.labels[label['name']].pools.append(self) full_config.labels[label['name']].pools.append(self)
@ -115,6 +117,7 @@ class OpenshiftProviderConfig(ProviderConfig):
'memory': int, 'memory': int,
'python-path': str, 'python-path': str,
'env': [env_var], 'env': [env_var],
'node-selector': dict,
} }
pool = ConfigPool.getCommonSchemaDict() pool = ConfigPool.getCommonSchemaDict()

View File

@ -204,7 +204,7 @@ class OpenshiftProvider(Provider):
def createPod(self, project, pod_name, label): def createPod(self, project, pod_name, label):
self.log.debug("%s: creating pod in project %s" % (pod_name, project)) self.log.debug("%s: creating pod in project %s" % (pod_name, project))
spec_body = { container_body = {
'name': label.name, 'name': label.name,
'image': label.image, 'image': label.image,
'imagePullPolicy': label.image_pull, 'imagePullPolicy': label.image_pull,
@ -214,23 +214,30 @@ class OpenshiftProvider(Provider):
'env': label.env, 'env': label.env,
} }
if label.cpu or label.memory: if label.cpu or label.memory:
spec_body['resources'] = {} container_body['resources'] = {}
for rtype in ('requests', 'limits'): for rtype in ('requests', 'limits'):
rbody = {} rbody = {}
if label.cpu: if label.cpu:
rbody['cpu'] = int(label.cpu) rbody['cpu'] = int(label.cpu)
if label.memory: if label.memory:
rbody['memory'] = '%dMi' % int(label.memory) rbody['memory'] = '%dMi' % int(label.memory)
spec_body['resources'][rtype] = rbody container_body['resources'][rtype] = rbody
spec_body = {
'containers': [container_body]
}
if label.node_selector:
spec_body['nodeSelector'] = label.node_selector
pod_body = { pod_body = {
'apiVersion': 'v1', 'apiVersion': 'v1',
'kind': 'Pod', 'kind': 'Pod',
'metadata': {'name': pod_name}, 'metadata': {'name': pod_name},
'spec': { 'spec': spec_body,
'containers': [spec_body],
},
'restartPolicy': 'Never', 'restartPolicy': 'Never',
} }
self.k8s_client.create_namespaced_pod(project, pod_body) self.k8s_client.create_namespaced_pod(project, pod_body)
def waitForPod(self, project, pod_name): def waitForPod(self, project, pod_name):

View File

@ -57,6 +57,7 @@ class OpenshiftPodsProviderConfig(OpenshiftProviderConfig):
'memory': int, 'memory': int,
'python-path': str, 'python-path': str,
'env': [env_var], 'env': [env_var],
'node-selector': dict
} }
pool = ConfigPool.getCommonSchemaDict() pool = ConfigPool.getCommonSchemaDict()

View File

@ -143,6 +143,8 @@ providers:
value: hello value: hello
- name: BAR - name: BAR
value: world value: world
node-selector:
storageType: ssd
- name: openshift - name: openshift
driver: openshift driver: openshift
@ -163,6 +165,8 @@ providers:
value: hello value: hello
- name: BAR - name: BAR
value: world value: world
node-selector:
storageType: ssd
- name: ec2-us-east-2 - name: ec2-us-east-2
driver: aws driver: aws

View File

@ -0,0 +1,6 @@
---
features:
- |
Basic support for specifying k8s/OpenShift `nodeSelectors` on Pod node
labels. This allows to schedule a Pod on k8s nodes with specific labels,
e.g., having certain capabilities.