![Nikolay Mahotkin](/assets/img/avatar_default.png)
* According to http://kubernetes.io/docs/user-guide/volumes/#types-of-volumes anda1b5325011
there is hostPath volume type instead of hostDir; And there is no 'source' keyword anymore. * Replacing 'kubectl update' on 'kubectl replace': kubectl update is deprecated, need to use 'replace':9b3d42c090
Closes-Bug: #1604766 Change-Id: I1029caeb2827fc9de271b457c7a61b043d0189cb
356 lines
11 KiB
YAML
356 lines
11 KiB
YAML
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
Namespaces:
|
|
=: com.mirantis.docker.kubernetes
|
|
docker: com.mirantis.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)
|
|
Usage: InOut
|
|
|
|
|
|
Methods:
|
|
.init:
|
|
Body:
|
|
- $._environment: $.find(std:Environment).require()
|
|
- $._podDefinition: null
|
|
|
|
|
|
# this is a workaround for early initialization. If docker application was deleted
|
|
# its destroy method will call deleteContainer method that will change _podDefinition
|
|
# on KubernetesPod loaded from ObjectsCopy
|
|
# but ininitialize method on a KubernetesPod from Objects is called before destruction
|
|
# and because we have 2 different KubernetesPod objects that share attributes but
|
|
# not private variables _podDefinition of real object will still contain outdated data
|
|
_loadCurrentPodDefinition:
|
|
Body:
|
|
- If: $._podDefinition = null
|
|
Then:
|
|
- $podName: $._getPodName()
|
|
- $podDefinition: $.getAttr(lastPodDeployed, null)
|
|
- If: $podDefinition = null
|
|
Then:
|
|
- $podDefinition:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: $podName
|
|
labels: $._getPodLabels($podName)
|
|
spec:
|
|
containers: []
|
|
volumes: []
|
|
|
|
- $.setAttr(lastPodDeployed, $podDefinition)
|
|
- $._podDefinition: $podDefinition
|
|
- Return: $._podDefinition
|
|
|
|
|
|
_getPodName:
|
|
Body:
|
|
- Return: $.name.toLower()
|
|
|
|
_getPodLabels:
|
|
Arguments:
|
|
- podName:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
Return: $.labels2Map($.labels.toLower()).mergeWith(dict(id => $podName))
|
|
|
|
hostContainer:
|
|
Arguments:
|
|
- container:
|
|
Contract: $.class(docker:DockerContainer)
|
|
Body:
|
|
- $._loadCurrentPodDefinition()
|
|
- $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: $container.name.toLower()
|
|
image: $container.image
|
|
args: $container.commands
|
|
ports: $container.ports.select($this._getPortDefinition($))
|
|
volumeMounts: $container.volumes.keys().select(
|
|
dict(
|
|
name => $this._generateVolumeName($container.name, $container.volumes.get($)),
|
|
mountPath => $
|
|
))
|
|
env: $container.env.keys().select(dict(name => $, value => $container.env.get($)))
|
|
securityContext:
|
|
privileged: $container.privileged
|
|
|
|
- $newVolumes: $container.volumes.values().select(
|
|
$this._buildVolumeEntry($container.name, $))
|
|
|
|
- $diff:
|
|
spec:
|
|
containers: [$containerDef]
|
|
volumes: $newVolumes
|
|
- $._podDefinition: $._podDefinition.mergeWith($diff)
|
|
- $.deploy()
|
|
- $._environment.reporter.report($, 'Creating services for Pod {0}'.format($.name))
|
|
- $.kubernetesCluster.createService(
|
|
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
|
|
and $.podId = $this._getPodName()
|
|
)
|
|
|
|
|
|
_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:
|
|
- name:
|
|
Contract: $.string().notNull()
|
|
- volume:
|
|
Contract: $.class(docker:DockerVolume).notNull()
|
|
Body:
|
|
- $type: $volume.getType()
|
|
- Value: $type
|
|
Match:
|
|
HostPath:
|
|
- $spec:
|
|
hostPath:
|
|
path: $volume.getParameters()
|
|
TempVolume:
|
|
- $spec:
|
|
emptyDir: {}
|
|
Default:
|
|
- Throw: UnknownDockerVolumeType
|
|
Message: format('Unknown docker volume type {0}', $type)
|
|
- $result:
|
|
name: $._generateVolumeName($name, $volume)
|
|
|
|
- Return: $result.mergeWith($spec)
|
|
|
|
|
|
_deleteContainer:
|
|
Arguments:
|
|
- name:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $lenBefore: len($._podDefinition.spec.containers) + len($._podDefinition.spec.volumes)
|
|
- $containerName: $name.toLower()
|
|
- $newContainers: $._podDefinition.spec.containers.where($.name != $containerName)
|
|
- $volumeNameMap: $.getAttr(volumeNameMap, dict())
|
|
- $newVolumeNameMap: {}
|
|
- $volumesToDelete: []
|
|
- $prefix: format('{0}/'.format($name))
|
|
- For: key
|
|
In: $volumeNameMap.keys()
|
|
Do:
|
|
- $volumeName: $volumeNameMap.get($key)
|
|
- If: $key.startsWith($prefix)
|
|
Then:
|
|
- $volumesToDelete: $volumesToDelete + list($volumeName)
|
|
Else:
|
|
- $newVolumeNameMap[$key]: $volumeName
|
|
- $.setAttr(volumeNameMap, $newVolumeNameMap)
|
|
|
|
- $newVolumes: $._podDefinition.spec.volumes.where(
|
|
not ($.name in $volumesToDelete))
|
|
- If: len($newContainers) + len($newVolumes) != $lenBefore
|
|
Then:
|
|
- $._podDefinition.spec.containers: $newContainers
|
|
- $._podDefinition.spec.volumes: $newVolumes
|
|
|
|
|
|
deleteContainer:
|
|
Arguments:
|
|
- name:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- If: $.kubernetesCluster.isAvailable()
|
|
Then:
|
|
- $._loadCurrentPodDefinition()
|
|
- $._deleteContainer($name)
|
|
- $.kubernetesCluster.deleteServices(
|
|
applicationName => $name,
|
|
podId => $._getPodName())
|
|
- $.deploy()
|
|
|
|
|
|
_generateVolumeName:
|
|
Arguments:
|
|
- name:
|
|
Contract: $.string().notNull()
|
|
- volume:
|
|
Contract: $.class(docker:DockerVolume).notNull()
|
|
Body:
|
|
- $key: format('{0}/{1}', $name, $volume.name)
|
|
- $map: $.getAttr(volumeNameMap, dict())
|
|
- $volumeName: $map.get($key)
|
|
- If: $volumeName = null
|
|
Then:
|
|
- $volumeName: randomName()
|
|
- $map[$key]: $volumeName
|
|
- $.setAttr(volumeNameMap, $map)
|
|
- Return: $volumeName
|
|
|
|
|
|
deploy:
|
|
Body:
|
|
- $._loadCurrentPodDefinition()
|
|
- $prevPod: $.getAttr(lastPodDeployed, null)
|
|
- $prevReplicas: $.getAttr(lastReplicas, 0)
|
|
|
|
- $podDefinition: $._podDefinition
|
|
- $replicas: $.replicas
|
|
- If: len($podDefinition.spec.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 and len($prevPod.spec.containers) > 0
|
|
Then:
|
|
- $.kubernetesCluster.deletePods(dict(id => $._getPodName()))
|
|
- If: $.replicas = 0 and len($podDefinition.spec.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:
|
|
apiVersion: v1
|
|
kind: ReplicationController
|
|
metadata:
|
|
name: $._getReplicationControllerId()
|
|
labels: $podDefinition.metadata.labels
|
|
spec:
|
|
replicas: $.replicas
|
|
selector:
|
|
id: $._getPodName()
|
|
template:
|
|
metadata:
|
|
labels: $podDefinition.metadata.labels
|
|
spec: $podDefinition.spec
|
|
|
|
|
|
_getReplicationControllerId:
|
|
Body:
|
|
- Return: $._getPodName()
|
|
|
|
|
|
getInternalScopeId:
|
|
Body:
|
|
Return: id($.kubernetesCluster)
|
|
|
|
scalePodDown:
|
|
Usage: Action
|
|
Body:
|
|
- If: $.replicas > 1
|
|
Then:
|
|
- $._environment.reporter.report($this, 'Scaling Pod down')
|
|
- $.replicas: $.replicas - 1
|
|
- $.kubernetesCluster.scaleRc(rcName => $._getReplicationControllerId(), newSize => $.replicas)
|
|
Else:
|
|
- $._environment.reporter.report($this, 'Cannot scale Pod down')
|
|
|
|
|
|
scalePodUp:
|
|
Usage: Action
|
|
Body:
|
|
- If: $.replicas > 0
|
|
Then:
|
|
- $._environment.reporter.report($this, 'Scaling Pod up')
|
|
- $.replicas: $.replicas + 1
|
|
- $.kubernetesCluster.scaleRc(rcName => $._getReplicationControllerId(), newSize => $.replicas)
|
|
Else:
|
|
- $._environment.reporter.report($this, 'Cannot scale Pod up')
|
|
|
|
|
|
recreatePod:
|
|
Usage: Action
|
|
Body:
|
|
- $._environment.reporter.report($this, 'Recreating Pod {0}'.format($.name))
|
|
- $.kubernetesCluster.deletePods(dict(id => $._getPodName()))
|
|
- If: $.replicas = 0
|
|
Then:
|
|
- $._loadCurrentPodDefinition()
|
|
- $.kubernetesCluster.createPod(definition => $._podDefinition, isNew => true)
|
|
- $._environment.reporter.report($this, 'Pod {0} recreated'.format($.name))
|
|
|
|
|
|
restartContainers:
|
|
Usage: Action
|
|
Body:
|
|
- $.kubernetesCluster.restartContainers(podName => $._getPodName())
|