05e6967318
this commit provides ability to choose the network. Calico is default. Change-Id: I9dd97385d981db91791cc51ebb9f3265188fa984
555 lines
17 KiB
YAML
555 lines
17 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
|
|
std: io.murano
|
|
res: io.murano.resources
|
|
sys: io.murano.system
|
|
docker: com.mirantis.docker
|
|
|
|
|
|
Name: KubernetesCluster
|
|
|
|
Extends: std:Application
|
|
|
|
Properties:
|
|
name:
|
|
Contract: $.string().notNull()
|
|
|
|
masterNode:
|
|
Contract: $.class(KubernetesMasterNode).notNull()
|
|
|
|
minionNodes:
|
|
Contract:
|
|
- $.class(KubernetesMinionNode).notNull()
|
|
- 1
|
|
|
|
nodeCount:
|
|
Contract: $.int().notNull().check($ > 0)
|
|
Usage: InOut
|
|
|
|
gatewayCount:
|
|
Contract: $.int().notNull().check($ > 0)
|
|
Usage: InOut
|
|
|
|
gatewayNodes:
|
|
Contract:
|
|
- $.class(KubernetesGatewayNode).notNull()
|
|
- 1
|
|
|
|
useFlannel:
|
|
Contract: $.bool().notNull()
|
|
Default: false
|
|
|
|
dockerRegistry:
|
|
Contract: $.string()
|
|
|
|
dockerMirror:
|
|
Contract: $.string()
|
|
|
|
gcloudKey:
|
|
Contract: $.string()
|
|
|
|
serviceEndpoints:
|
|
Contract:
|
|
- port: $.int().notNull().check($ > 0)
|
|
address: $.string().notNull()
|
|
scope: $.string().notNull().check($ in list(public, cloud, internal, host))
|
|
portScope: $.string().notNull().check($ in list(public, cloud, internal, host))
|
|
containerPort: $.int().notNull().check($ > 0)
|
|
protocol: $.string().notNull().check($ in list(TCP, UDP))
|
|
applicationName: $.string().notNull()
|
|
podId: $.string().notNull()
|
|
serviceName: $.string()
|
|
Default: []
|
|
Usage: Out
|
|
|
|
Methods:
|
|
.init:
|
|
Body:
|
|
- $._environment: $.find(std:Environment).require()
|
|
|
|
|
|
isAvailable:
|
|
Body:
|
|
- Return: $.masterNode.isAvailable()
|
|
|
|
|
|
deploy:
|
|
Body:
|
|
- $.serviceEndpoints: $.getAttr(serviceEndpoints, list())
|
|
- If: not $.getAttr(deployed, false)
|
|
Then:
|
|
- $._environment.reporter.report($this, 'Creating VMs for Kubernetes cluster')
|
|
- $securityGroupIngress:
|
|
- ToPort: 4001
|
|
FromPort: 4001
|
|
IpProtocol: tcp
|
|
External: false
|
|
- ToPort: 7001
|
|
FromPort: 7001
|
|
IpProtocol: tcp
|
|
External: false
|
|
- ToPort: 10250
|
|
FromPort: 10250
|
|
IpProtocol: tcp
|
|
External: false
|
|
- ToPort: 8080
|
|
FromPort: 8080
|
|
IpProtocol: tcp
|
|
External: $.masterNode.instance.assignFloatingIp
|
|
- ToPort: 2380
|
|
FromPort: 2380
|
|
IpProtocol: tcp
|
|
External: false
|
|
- ToPort: 8285
|
|
FromPort: 8285
|
|
IpProtocol: udp
|
|
External: false
|
|
- $._environment.securityGroupManager.addGroupIngress($securityGroupIngress)
|
|
- $.setAttr(deployed, true)
|
|
|
|
- $prevNodeCount: $.getAttr(lastNodeCount, 0)
|
|
- $prevGatewayCount: $.getAttr(lastGatewayCount, 0)
|
|
|
|
- If: $prevNodeCount != $.nodeCount or $prevGatewayCount != $.gatewayCount
|
|
Then:
|
|
- $._environment.reporter.report($this, 'Setting up Kubernetes cluster')
|
|
- Parallel:
|
|
- $.masterNode.deployInstance()
|
|
- $.minionNodes.take($.nodeCount).pselect($.deployInstance())
|
|
- $.gatewayNodes.take($.gatewayCount).pselect($.deployInstance())
|
|
|
|
- $.masterNode.setupEtcd()
|
|
- $.minionNodes.skip($.nodeCount).select($.removeFromCluster())
|
|
- $.gatewayNodes.skip($.gatewayCount).select($.removeFromCluster())
|
|
|
|
- $.minionNodes.take($.nodeCount).select($.setupEtcd())
|
|
- $.gatewayNodes.take($.gatewayCount).select($.setupEtcd())
|
|
|
|
- $._deployContainersNetwork()
|
|
- $.masterNode.setupNode()
|
|
|
|
- Parallel:
|
|
- $.minionNodes.take($.nodeCount).pselect($.setupNode())
|
|
- $.gatewayNodes.take($.gatewayCount).pselect($.setupNode())
|
|
|
|
- $._environment.stack.push()
|
|
- $._updateServicePublicIps()
|
|
- $.setAttr(lastNodeCount, $.nodeCount)
|
|
- $.setAttr(lastGatewayCount, $.gatewayCount)
|
|
- $._environment.reporter.report($this, 'Kubernetes cluster is up and running')
|
|
- $.setAttr(serviceEndpoints, $.serviceEndpoints)
|
|
|
|
|
|
getIp:
|
|
Body:
|
|
Return: $.masterNode.getIp()
|
|
|
|
|
|
_deployContainersNetwork:
|
|
Body:
|
|
- If: $.useFlannel
|
|
Then:
|
|
- $.masterNode.setupFlannel()
|
|
- Parallel:
|
|
- $.minionNodes.take($.nodeCount).pselect($.setupFlannel())
|
|
- $.gatewayNodes.take($.gatewayCount).pselect($.setupFlannel())
|
|
Else:
|
|
- Parallel:
|
|
- $.masterNode.setupCalico()
|
|
- $.minionNodes.take($.nodeCount).pselect($.setupCalico())
|
|
- $.gatewayNodes.take($.gatewayCount).pselect($.setupCalico())
|
|
|
|
|
|
createPod:
|
|
Arguments:
|
|
- definition:
|
|
Contract: {}
|
|
- isNew:
|
|
Contract: $.bool().notNull()
|
|
Default: true
|
|
Body:
|
|
- $.deploy()
|
|
- $resources: new(sys:Resources)
|
|
- $template: $resources.yaml('UpdatePod.template').bind(dict(
|
|
podDefinition => $definition,
|
|
isNew => $isNew
|
|
))
|
|
- $.masterNode.instance.agent.call($template, $resources)
|
|
|
|
|
|
createReplicationController:
|
|
Arguments:
|
|
- definition:
|
|
Contract: {}
|
|
- isNew:
|
|
Contract: $.bool().notNull()
|
|
Default: true
|
|
Body:
|
|
- $.deploy()
|
|
- $resources: new(sys:Resources)
|
|
- $template: $resources.yaml('UpdateReplicationController.template').bind(dict(
|
|
controllerDefinition => $definition,
|
|
isNew => $isNew
|
|
))
|
|
- $.masterNode.instance.agent.call($template, $resources)
|
|
|
|
|
|
deleteReplicationController:
|
|
Arguments:
|
|
- id:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $.deploy()
|
|
- $resources: new(sys:Resources)
|
|
- $template: $resources.yaml('DeleteReplicationController.template').bind(dict(rcId => $id))
|
|
- $.masterNode.instance.agent.call($template, $resources)
|
|
|
|
|
|
deletePods:
|
|
Arguments:
|
|
- labels:
|
|
Contract:
|
|
$.string().notNull(): $.string().notNull()
|
|
Body:
|
|
- $.deploy()
|
|
- $resources: new(sys:Resources)
|
|
- $template: $resources.yaml('DeletePods.template').bind(dict(labels => $labels))
|
|
- $.masterNode.instance.agent.call($template, $resources)
|
|
|
|
createService:
|
|
Arguments:
|
|
- applicationName:
|
|
Contract: $.string().notNull()
|
|
- applicationPorts:
|
|
Contract:
|
|
- $.class(docker:ApplicationPort)
|
|
- podId:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $.serviceEndpoints: $.getAttr(serviceEndpoints, list())
|
|
- $currentEndpoints: $.serviceEndpoints.where($.applicationName = $applicationName and $.podId = $podId and $.scope = internal)
|
|
- $serviceName: format('{0}-{1}', randomName(), $applicationName).substring(0, 24).toLower()
|
|
- $endpointMap: {}
|
|
- For: endpoint
|
|
In: $currentEndpoints
|
|
Do:
|
|
- $serviceName: $endpoint.serviceName
|
|
- $key: format('{0}-{1}', $endpoint.containerPort, $endpoint.protocol)
|
|
- $endpointMap[$key]: $endpoint
|
|
|
|
- $serviceChanged: len(list($applicationPorts.where($.scope != host))) != len($currentEndpoints)
|
|
|
|
- $servicePorts: []
|
|
- For: applicationPort
|
|
In: $applicationPorts.where($.scope != host)
|
|
Do:
|
|
- $key: format('{0}-{1}', $applicationPort.port, $applicationPort.protocol)
|
|
- $endpoint: $endpointMap.get($key)
|
|
- If: $endpoint != null
|
|
Then:
|
|
- $record:
|
|
- assignedPort: $endpoint.port
|
|
applicationPort: $applicationPort
|
|
Else:
|
|
- $port: $._findUnusedPort($applicationPort.port, $applicationPort.protocol)
|
|
- $record:
|
|
- assignedPort: $port
|
|
applicationPort: $applicationPort
|
|
- $serviceChanged: true
|
|
|
|
- $securityGroupIngress:
|
|
- ToPort: $port
|
|
FromPort: $port
|
|
IpProtocol: $applicationPort.protocol.toLower()
|
|
External: $applicationPort.scope = public
|
|
- $._environment.securityGroupManager.addGroupIngress($securityGroupIngress)
|
|
|
|
- $servicePorts: $servicePorts + $record
|
|
|
|
- If: $serviceChanged
|
|
Then:
|
|
- $serviceIp: $._createOrUpdateService(
|
|
name => $serviceName,
|
|
ports => $servicePorts,
|
|
podId => $podId,
|
|
isNew => len($currentEndpoints) = 0
|
|
)
|
|
- $._updateEndpoints(
|
|
ports => $servicePorts,
|
|
applicationName => $applicationName,
|
|
podId => $podId,
|
|
serviceName => $serviceName,
|
|
serviceIp => $serviceIp
|
|
)
|
|
- $._environment.stack.push()
|
|
- $.setAttr(serviceEndpoints, $.serviceEndpoints)
|
|
|
|
|
|
_createOrUpdateService:
|
|
Arguments:
|
|
- name:
|
|
Contract: $.string().notNull()
|
|
- ports:
|
|
Contract:
|
|
- assignedPort: $.int().notNull()
|
|
applicationPort: $.class(docker:ApplicationPort).notNull()
|
|
- podId:
|
|
Contract: $.string().notNull()
|
|
- isNew:
|
|
Contract: $.bool().notNull()
|
|
|
|
Body:
|
|
- $serviceDefinition:
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
labels:
|
|
name: $name
|
|
name: $name
|
|
spec:
|
|
ports: $ports.select(dict(
|
|
port => $.assignedPort,
|
|
targetPort => $.applicationPort.port,
|
|
protocol => $.applicationPort.protocol,
|
|
name => str($.assignedPort)
|
|
))
|
|
selector:
|
|
id: $podId
|
|
|
|
- If: $.gatewayCount = 0
|
|
Then:
|
|
- $serviceDefinition.spec.publicIPs: $.minionNodes.take($.nodeCount).select($.getIp())
|
|
|
|
- $resources: new(sys:Resources)
|
|
- $template: $resources.yaml('UpdateService.template').bind(dict(
|
|
serviceDefinition => $serviceDefinition,
|
|
isNew => $isNew
|
|
))
|
|
- Return: $.masterNode.instance.agent.call($template, $resources)
|
|
|
|
|
|
_updateEndpoints:
|
|
Arguments:
|
|
- ports:
|
|
Contract:
|
|
- assignedPort: $.int().notNull()
|
|
applicationPort: $.class(docker:ApplicationPort).notNull()
|
|
- applicationName:
|
|
Contract: $.string().notNull()
|
|
- podId:
|
|
Contract: $.string().notNull()
|
|
- serviceName:
|
|
Contract: $.string().notNull()
|
|
- serviceIp:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $.serviceEndpoints: $.serviceEndpoints.where($.applicationName != $applicationName or $.podId != $podId)
|
|
- For: port
|
|
In: $ports
|
|
Do:
|
|
- $newEndpoint:
|
|
port: $port.assignedPort
|
|
address: $serviceIp
|
|
scope: internal
|
|
portScope: $port.applicationPort.scope
|
|
applicationName: $applicationName
|
|
containerPort: $port.applicationPort.port
|
|
protocol: $port.applicationPort.protocol
|
|
podId: $podId
|
|
serviceName: $serviceName
|
|
|
|
- $.serviceEndpoints: $.serviceEndpoints + list($newEndpoint)
|
|
- If: $port.applicationPort.scope in list(public, cloud)
|
|
Then:
|
|
- If: $.gatewayCount > 0
|
|
Then:
|
|
- $nodes: $.gatewayNodes.take($.gatewayCount)
|
|
Else:
|
|
- $nodes: $.minionNodes.take($.nodeCount)
|
|
|
|
- For: t
|
|
In: $nodes
|
|
Do:
|
|
- $newEndpoint.address: $t.getIp()
|
|
- $newEndpoint.scope: cloud
|
|
- $.serviceEndpoints: $.serviceEndpoints + list($newEndpoint)
|
|
|
|
- If: $t.instance.floatingIpAddress != null and $port.applicationPort.scope = public
|
|
Then:
|
|
- $newEndpoint.address: $t.instance.floatingIpAddress
|
|
- $newEndpoint.scope: public
|
|
- $.serviceEndpoints: $.serviceEndpoints + list($newEndpoint)
|
|
- $newEndpoint:
|
|
port: $port.applicationPort.port
|
|
address: '127.0.0.1'
|
|
scope: host
|
|
portScope: $port.applicationPort.scope
|
|
containerPort: $port.applicationPort.port
|
|
protocol: $port.applicationPort.protocol
|
|
applicationName: $applicationName
|
|
podId: $podId
|
|
serviceName: null
|
|
- $.serviceEndpoints: $.serviceEndpoints + list($newEndpoint)
|
|
|
|
|
|
_updateServicePublicIps:
|
|
Body:
|
|
- $prevNodeCount: $.getAttr(lastNodeCount, 0)
|
|
- $prevGatewayCount: $.getAttr(lastGatewayCount, 0)
|
|
- $gatewayModeChanged: $prevGatewayCount != $.gatewayCount and $prevGatewayCount * $.gatewayCount = 0
|
|
- If: $prevGatewayCount > 0 and $.gatewayCount > 0
|
|
Then:
|
|
- Return:
|
|
- If: $prevGatewayCount = 0 and $.gatewayCount = 0 and $prevNodeCount = $.nodeCount
|
|
Then:
|
|
- Return:
|
|
- $serviceNameMap: {}
|
|
- For: endpoint
|
|
In: $.serviceEndpoints
|
|
Do:
|
|
- $serviceName: $endpoint.serviceName
|
|
- If: $serviceName != null
|
|
Then:
|
|
- $serviceNameMap[$serviceName]: true
|
|
- $uniqueServiceNames: $serviceNameMap.keys()
|
|
- If: len($uniqueServiceNames) > 0
|
|
Then:
|
|
- $publicIPs: $.minionNodes.take($.nodeCount).select($.getIp())
|
|
- $resources: new(sys:Resources)
|
|
- $template: $resources.yaml('PatchServices.template').bind(dict(
|
|
services => $uniqueServiceNames,
|
|
publicIPs => $publicIPs
|
|
))
|
|
- $.masterNode.instance.agent.call($template, $resources)
|
|
|
|
|
|
deleteServices:
|
|
Arguments:
|
|
- applicationName:
|
|
Contract: $.string().notNull()
|
|
- podId:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $.serviceEndpoints: $.getAttr(serviceEndpoints, list())
|
|
- $resources: new(sys:Resources)
|
|
- $services: $.serviceEndpoints.where($.scope = internal and $.podId = $podId).select($.serviceName)
|
|
- $template: $resources.yaml('DeleteServices.template').bind(dict(
|
|
services => $services
|
|
))
|
|
- $.masterNode.instance.agent.call($template, $resources)
|
|
- $.serviceEndpoints: $.serviceEndpoints.where($.podId != $podId)
|
|
- $.setAttr(serviceEndpoints, $.serviceEndpoints)
|
|
|
|
|
|
_findUnusedPort:
|
|
Arguments:
|
|
- initial:
|
|
Contract: $.int().notNull()
|
|
- protocol:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- If: $initial != 22 and $._checkIfPortIsNotUsed($initial, $protocol)
|
|
Then:
|
|
Return: $initial
|
|
|
|
- $port: 1025
|
|
- While: not $._checkIfPortIsNotUsed($port, $protocol)
|
|
Do:
|
|
$port: $port + 1
|
|
- Return: $port
|
|
|
|
|
|
_checkIfPortIsNotUsed:
|
|
Arguments:
|
|
- port:
|
|
Contract: $.int().notNull()
|
|
- protocol:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- Return: len(list($.serviceEndpoints.where($.port = $port).where($.protocol = $protocol))) = 0
|
|
|
|
|
|
scaleNodesUp:
|
|
Usage: Action
|
|
Body:
|
|
- If: $.nodeCount < len($.minionNodes)
|
|
Then:
|
|
- $._environment.reporter.report($this, 'Scaling up Kubernetes cluster')
|
|
- $.nodeCount: $.nodeCount + 1
|
|
- $.deploy()
|
|
Else:
|
|
- $._environment.reporter.report($this, 'The maximum number of nodes has been reached')
|
|
|
|
|
|
scaleNodesDown:
|
|
Usage: Action
|
|
Body:
|
|
- If: $.nodeCount > 1
|
|
Then:
|
|
- $._environment.reporter.report($this, 'Scaling Kubernetes cluster down')
|
|
- $.nodeCount: $.nodeCount - 1
|
|
- $.deploy()
|
|
Else:
|
|
- $._environment.reporter.report($this, 'At least one node must be in cluster')
|
|
|
|
|
|
scaleGatewaysUp:
|
|
Usage: Action
|
|
Body:
|
|
- If: $.gatewayCount < len($.gatewayNodes)
|
|
Then:
|
|
- $._environment.reporter.report($this, 'Adding new gateway node')
|
|
- $.gatewayCount: $.gatewayCount + 1
|
|
- $.deploy()
|
|
Else:
|
|
- $._environment.reporter.report($this, 'The maximum number of nodes has been reached')
|
|
|
|
|
|
scaleGatewaysDown:
|
|
Usage: Action
|
|
Body:
|
|
- If: $.gatewayCount > 1
|
|
Then:
|
|
- $._environment.reporter.report($this, 'Removing gateway node')
|
|
- $.gatewayCount: $.gatewayCount - 1
|
|
- $.deploy()
|
|
Else:
|
|
- $._environment.reporter.report($this, 'No gateway nodes that can be removed')
|
|
|
|
|
|
|
|
scaleRc:
|
|
Arguments:
|
|
- rcName:
|
|
Contract: $.string().notNull()
|
|
- newSize:
|
|
Contract: $.int().notNull()
|
|
Body:
|
|
- $resources: new(sys:Resources)
|
|
- $template: $resources.yaml('ScaleRc.template').bind(dict(
|
|
rcName => $rcName,
|
|
newSize => $newSize
|
|
))
|
|
- $.masterNode.instance.agent.call($template, $resources)
|
|
|
|
|
|
restartContainers:
|
|
Arguments:
|
|
- podName:
|
|
Contract: $.string().notNull()
|
|
|
|
Body:
|
|
- $.minionNodes.take($.nodeCount).pselect($.restartContainers(podName => $podName))
|