
Kubernetes doesn't allow to add containers to a Pod that is already deployed. With this change old pods will be deleted and either new pod created which will include new container or Replication Controller will be modified (before Pod delete so that updated Pods be created instead) Also now Pods are created only when replica number set to 0. Otherwise Pods created by ReplicationController alone. Change-Id: I8552793f39083de47ad07e7013dedb72e0550885 Closes-Bug: #1444208
245 lines
7.4 KiB
YAML
245 lines
7.4 KiB
YAML
Namespaces:
|
|
=: io.murano.apps.docker.kubernetes
|
|
docker: io.murano.apps.docker
|
|
std: io.murano
|
|
sys: io.murano.system
|
|
|
|
Name: KubernetesPod
|
|
|
|
Extends:
|
|
- docker:DockerContainerHost
|
|
- docker:DockerHelpers
|
|
|
|
Properties:
|
|
name:
|
|
Contract: $.string().notNull()
|
|
|
|
kubernetesCluster:
|
|
Contract: $.class(KubernetesCluster).notNull()
|
|
|
|
labels:
|
|
Contract: $.string().notNull() # convert to key-value map as soon as it will be possible to input it in UI
|
|
Default: ''
|
|
|
|
replicas:
|
|
Contract: $.int().notNull().check($ >= 0)
|
|
|
|
|
|
Methods:
|
|
initialize:
|
|
Body:
|
|
- $._environment: $.find(std:Environment).require()
|
|
|
|
- $podName: $._getPodName()
|
|
- $podDefinition: $.getAttr(lastPodDeployed, null)
|
|
- If: $podDefinition = null
|
|
Then:
|
|
- $podDefinition:
|
|
id: $podName
|
|
kind: Pod
|
|
apiVersion: v1beta1
|
|
desiredState:
|
|
manifest:
|
|
version: v1beta1
|
|
id: $podName
|
|
containers: []
|
|
volumes: []
|
|
labels: $._getPodLabels($podName)
|
|
|
|
- $.setAttr(lastPodDeployed, $podDefinition)
|
|
- $._podDefinition: $podDefinition
|
|
|
|
_getPodName:
|
|
Body:
|
|
- Return: toLower($.name)
|
|
|
|
_getPodLabels:
|
|
Arguments:
|
|
- podName:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
Return: $.labels2Map(toLower($.labels)).mergeWith(dict(id => $podName))
|
|
|
|
hostContainer:
|
|
Arguments:
|
|
- container:
|
|
Contract: $.class(docker:DockerContainer)
|
|
Body:
|
|
- $podName: $._getPodName()
|
|
- For: port
|
|
In: $container.ports
|
|
Do:
|
|
- $endpoints: $.kubernetesCluster.serviceEndpoints.where(
|
|
$.containerPort = $port.port and $.protocol = $port.protocol and $.podId = $podName)
|
|
- If: len($endpoints) > 0
|
|
Then:
|
|
- $msg: format('Port {0} is already used in the Pod {1}', $port.port, $.name)
|
|
- Throw: PortConflictException
|
|
Message: $msg
|
|
- $._deleteContainer($container.name)
|
|
|
|
- $containerDef:
|
|
name: toLower($container.name)
|
|
image: $container.image
|
|
command: $container.commands
|
|
ports: $container.ports.select($this._getPortDefinition($))
|
|
volumeMounts: $container.volumes.keys().select(dict(name => $this._generateVolumeName($container.volumes.get($)), mountPath => $))
|
|
env: $container.env.keys().select(dict(key => $, value => $container.env.get($)))
|
|
|
|
- $newVolumes: $container.volumes.values().where(not $this._generateVolumeName($) in $this._podDefinition.desiredState.volumes.name).
|
|
select($this._buildVolumeEntry($))
|
|
|
|
- $diff:
|
|
desiredState:
|
|
manifest:
|
|
containers: [$containerDef]
|
|
volumes: $newVolumes
|
|
- $._podDefinition: $._podDefinition.mergeWith($diff)
|
|
- $.deploy()
|
|
- $._environment.reporter.report($, 'Creating services for Pod {0}'.format($.name))
|
|
- $.kubernetesCluster.createServices(
|
|
applicationName => $container.name,
|
|
applicationPorts => $container.ports,
|
|
podId => $podName)
|
|
- Return: $.getEndpoints($container.name)
|
|
|
|
|
|
getEndpoints:
|
|
Arguments:
|
|
- applicationName:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- Return: $.kubernetesCluster.serviceEndpoints.where($.applicationName = $applicationName)
|
|
|
|
|
|
_getPortDefinition:
|
|
Arguments:
|
|
- port:
|
|
Contract: $.class(docker:ApplicationPort).notNull()
|
|
Body:
|
|
- $result:
|
|
containerPort: $port.port
|
|
- If: $port.scope = node
|
|
Then:
|
|
$result.hostPort: $port.port
|
|
- Return: $result
|
|
|
|
|
|
_buildVolumeEntry:
|
|
Arguments:
|
|
- volume:
|
|
Contract: $.class(docker:DockerVolume).notNull()
|
|
Body:
|
|
- $type: $volume.getType()
|
|
- Value: $type
|
|
Match:
|
|
HostDir:
|
|
- $spec:
|
|
hostDir:
|
|
path: $volume.getParameters()
|
|
TempVolume:
|
|
- $spec:
|
|
emptyDir: {}
|
|
Default:
|
|
- Throw: UnknownDockerVolumeType
|
|
Message: format('Unknown docker volume type {0}', $type)
|
|
- Return:
|
|
name: $._generateVolumeName($volume)
|
|
source: $spec
|
|
|
|
|
|
_deleteContainer:
|
|
Arguments:
|
|
- name:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $lenBefore: len($._podDefinition.desiredState.manifest.containers) + len($._podDefinition.desiredState.manifest.volumes)
|
|
- $newContainers: $._podDefinition.desiredState.manifest.containers.where($.name != $name)
|
|
- $newVolumes: $._podDefinition.desiredState.manifest.volumes.where(
|
|
$.name in $._podDefinition.desiredState.manifest.containers.volumeMounts.name)
|
|
- If: len($newContainers) + len($newVolumes) != $lenBefore
|
|
Then:
|
|
- $._podDefinition.desiredState.manifest.containers: $newContainers
|
|
- $._podDefinition.desiredState.manifest.volumes: $newVolumes
|
|
|
|
|
|
deleteContainer:
|
|
Arguments:
|
|
- name:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $._deleteContainer($name)
|
|
- $.kubernetesCluster.deleteService(
|
|
applicationName => $name,
|
|
podId => $._getPodName())
|
|
- $.deploy()
|
|
|
|
|
|
_generateVolumeName:
|
|
Arguments:
|
|
- volume:
|
|
Contract: $.class(docker:DockerVolume).notNull()
|
|
Body:
|
|
Return: toLower($volume.name)
|
|
|
|
|
|
deploy:
|
|
Body:
|
|
- $prevPod: $.getAttr(lastPodDeployed, null)
|
|
- $prevReplicas: $.getAttr(lastReplicas, 0)
|
|
|
|
- $podDefinition: $._podDefinition
|
|
- $replicas: $.replicas
|
|
- If: len($podDefinition.desiredState.manifest.containers) = 0
|
|
Then:
|
|
- $replicas: 0
|
|
- $.setAttr(lastReplicas, $replicas)
|
|
- If: $replicas != $prevReplicas or $prevPod != $podDefinition
|
|
Then:
|
|
- If: $replicas > 0
|
|
Then:
|
|
- $._environment.reporter.report($, 'Deploying Replication Controller for Pod {0}'.format($.name))
|
|
- $rcDefinition: $._buildReplicationControllerDefinition($podDefinition)
|
|
- $.kubernetesCluster.createReplicationController(
|
|
definition => $rcDefinition, isNew => $prevReplicas = 0)
|
|
- If: $replicas = 0 and $prevReplicas > 0
|
|
Then:
|
|
- $.kubernetesCluster.deleteReplicationController($._getReplicationControllerId())
|
|
- If: $prevPod != $podDefinition
|
|
Then:
|
|
- $.kubernetesCluster.deletePods(dict(id => $._getPodName()))
|
|
- If: $.replicas = 0 and len($podDefinition.desiredState.manifest.containers) > 0
|
|
Then:
|
|
- $.kubernetesCluster.createPod(definition => $podDefinition, isNew => true)
|
|
|
|
- $._environment.reporter.report($, 'Pod {0} is ready'.format($.name))
|
|
- $.setAttr(lastPodDeployed, $podDefinition)
|
|
|
|
|
|
_buildReplicationControllerDefinition:
|
|
Arguments:
|
|
- podDefinition:
|
|
Contract: {}
|
|
Body:
|
|
Return:
|
|
id: $._getReplicationControllerId()
|
|
kind: ReplicationController
|
|
apiVersion: v1beta1
|
|
desiredState:
|
|
replicas: $.replicas
|
|
replicaSelector:
|
|
id: $._getPodName()
|
|
podTemplate:
|
|
desiredState: $podDefinition.desiredState
|
|
labels: $podDefinition.labels
|
|
|
|
|
|
_getReplicationControllerId:
|
|
Body:
|
|
- Return: $._getPodName()
|
|
|
|
|
|
getInternalScopeId:
|
|
Body:
|
|
Return: $.kubernetesCluster.id()
|