summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--k8s/ChangeLog.md5
-rw-r--r--k8s/k8s-node-type.yaml2
-rw-r--r--k8s/k8sclient/k8sclient.py23
-rw-r--r--k8s/k8splugin/tasks.py26
-rw-r--r--k8s/setup.py2
-rw-r--r--k8s/tests/test_tasks.py4
6 files changed, 43 insertions, 19 deletions
diff --git a/k8s/ChangeLog.md b/k8s/ChangeLog.md
index 3402581..a59a016 100644
--- a/k8s/ChangeLog.md
+++ b/k8s/ChangeLog.md
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [1.4.9]
+* Support for liveness probes (https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
+* fix the readiness probe to run script such as "/opt/app/snmptrap/bin/snmptrapd.sh status"
+* change "ports" and the "mode" of volume to be optional instead of mandatory
+
## [1.4.8]
* If an installation step times out because a component does not become ready within the maximum wait time,
delete the Kubernetes artifacts associated with the component. Previously, an installation step might time
diff --git a/k8s/k8s-node-type.yaml b/k8s/k8s-node-type.yaml
index 13798f4..c803b81 100644
--- a/k8s/k8s-node-type.yaml
+++ b/k8s/k8s-node-type.yaml
@@ -25,7 +25,7 @@ plugins:
k8s:
executor: 'central_deployment_agent'
package_name: k8splugin
- package_version: 1.4.8
+ package_version: 1.4.9
data_types:
diff --git a/k8s/k8sclient/k8sclient.py b/k8s/k8sclient/k8sclient.py
index 31631ad..d3417a7 100644
--- a/k8s/k8sclient/k8sclient.py
+++ b/k8s/k8sclient/k8sclient.py
@@ -116,7 +116,7 @@ def _create_probe(hc, port, use_tls=False):
period_seconds = period,
timeout_seconds = timeout,
_exec = client.V1ExecAction(
- command = [hc['script']]
+ command = hc['script'].split( )
)
)
return probe
@@ -131,7 +131,7 @@ def _create_resources(resources=None):
else:
return None
-def _create_container_object(name, image, always_pull, use_tls=False, env={}, container_ports=[], volume_mounts = [], resources = None, readiness = None):
+def _create_container_object(name, image, always_pull, use_tls=False, env={}, container_ports=[], volume_mounts = [], resources = None, readiness = None, liveness = None):
# Set up environment variables
# Copy any passed in environment variables
env_vars = [client.V1EnvVar(name=k, value=env[k]) for k in env.keys()]
@@ -139,15 +139,21 @@ def _create_container_object(name, image, always_pull, use_tls=False, env={}, co
pod_ip = client.V1EnvVarSource(field_ref = client.V1ObjectFieldSelector(field_path="status.podIP"))
env_vars.append(client.V1EnvVar(name="POD_IP",value_from=pod_ip))
- # If a health check is specified, create a readiness probe
+ # If a health check is specified, create a readiness/liveness probe
# (For an HTTP-based check, we assume it's at the first container port)
probe = None
+ live_probe = None
if readiness:
hc_port = None
if len(container_ports) > 0:
(hc_port, proto) = container_ports[0]
probe = _create_probe(readiness, hc_port, use_tls)
+ if liveness:
+ hc_port = None
+ if len(container_ports) > 0:
+ (hc_port, proto) = container_ports[0]
+ live_probe = _create_probe(liveness, hc_port, use_tls)
if resources:
resources_obj = _create_resources(resources)
@@ -162,7 +168,8 @@ def _create_container_object(name, image, always_pull, use_tls=False, env={}, co
ports=[client.V1ContainerPort(container_port=p, protocol=proto) for (p, proto) in container_ports],
volume_mounts = volume_mounts,
resources = resources_obj,
- readiness_probe = probe
+ readiness_probe = probe,
+ liveness_probe = live_probe
)
def _create_deployment_object(component_name,
@@ -386,6 +393,12 @@ def deploy(namespace, component_name, image, replicas, always_pull, k8sconfig, r
- timeout: time (in seconds) to allow a probe to complete
- endpoint: the path portion of the URL that points to the readiness endpoint for "http" and "https" types
- path: the full path to the script to be executed in the container for "script" and "docker" types
+ - liveness: dict with health check info; if present, used to create a liveness probe for the main container. Includes:
+ - type: check is done by making http(s) request to an endpoint ("http", "https") or by exec'ing a script in the container ("script", "docker")
+ - interval: period (in seconds) between probes
+ - timeout: time (in seconds) to allow a probe to complete
+ - endpoint: the path portion of the URL that points to the liveness endpoint for "http" and "https" types
+ - path: the full path to the script to be executed in the container for "script" and "docker" types
'''
@@ -460,7 +473,7 @@ def deploy(namespace, component_name, image, replicas, always_pull, k8sconfig, r
# Create the container for the component
# Make it the first container in the pod
- containers.insert(0, _create_container_object(component_name, image, always_pull, use_tls, kwargs.get("env", {}), container_ports, volume_mounts, resources, kwargs["readiness"]))
+ containers.insert(0, _create_container_object(component_name, image, always_pull, use_tls, kwargs.get("env", {}), container_ports, volume_mounts, resources, kwargs["readiness"], kwargs.get("liveness")))
# Build the k8s Deployment object
labels = kwargs.get("labels", {})
diff --git a/k8s/k8splugin/tasks.py b/k8s/k8splugin/tasks.py
index 727be78..399bc9f 100644
--- a/k8s/k8splugin/tasks.py
+++ b/k8s/k8splugin/tasks.py
@@ -286,6 +286,7 @@ def _create_and_start_container(container_name, image, **kwargs):
{"log_directory": "/path/to/container/log/directory", "alternate_fb_path" : "/alternate/sidecar/log/path"}"
- replicas: number of replicas to be launched initially
- readiness: object with information needed to create a readiness check
+ - liveness: object with information needed to create a liveness check
'''
env = { "CONSUL_HOST": CONSUL_INTERNAL_NAME,
"CONFIG_BINDING_SERVICE": "config-binding-service" }
@@ -308,7 +309,8 @@ def _create_and_start_container(container_name, image, **kwargs):
env = env,
labels = kwargs.get("labels", {}),
log_info=kwargs.get("log_info"),
- readiness=kwargs.get("readiness"))
+ readiness=kwargs.get("readiness"),
+ liveness=kwargs.get("liveness"))
# Capture the result of deployment for future use
ctx.instance.runtime_properties[K8S_DEPLOYMENT] = dep
@@ -327,8 +329,8 @@ def _parse_cloudify_context(**kwargs):
# Set some labels for the Kubernetes pods
kwargs["labels"] = {
"cfydeployment" : ctx.deployment.id,
- "cfynode": ctx.node.name,
- "cfynodeinstance": ctx.instance.id
+ "cfynode": ctx.node.name[:63],
+ "cfynodeinstance": ctx.instance.id[:63]
}
# Pick up the centralized logging info
@@ -349,14 +351,16 @@ def _parse_cloudify_context(**kwargs):
def _enhance_docker_params(**kwargs):
'''
- Set up Docker environment variables and readiness check info
+ Set up Docker environment variables and readiness/liveness check info
and inject into kwargs.
'''
- # Get info for setting up readiness probe, if present
+ # Get info for setting up readiness/liveness probe, if present
docker_config = kwargs.get("docker_config", {})
if "healthcheck" in docker_config:
kwargs["readiness"] = docker_config["healthcheck"]
+ if "livehealthcheck" in docker_config:
+ kwargs["liveness"] = docker_config["livehealthcheck"]
envs = kwargs.get("envs", {})
@@ -371,8 +375,7 @@ def _enhance_docker_params(**kwargs):
def combine_params(key, docker_config, kwargs):
v = docker_config.get(key, []) + kwargs.get(key, [])
- if v:
- kwargs[key] = v
+ kwargs[key] = v
return kwargs
# Add the lists of ports and volumes unintelligently - meaning just add the
@@ -398,7 +401,8 @@ def _create_and_start_component(**kwargs):
"tls_info": kwargs.get("tls_info", {}),
"labels": kwargs.get("labels", {}),
"resource_config": kwargs.get("resource_config",{}),
- "readiness": kwargs.get("readiness",{})}
+ "readiness": kwargs.get("readiness",{}),
+ "liveness": kwargs.get("liveness",{})}
returned_args = _create_and_start_container(service_component_name, image, **sub_kwargs)
kwargs[K8S_DEPLOYMENT] = returned_args[K8S_DEPLOYMENT]
@@ -518,6 +522,8 @@ def create_and_start_container_for_platforms(**kwargs):
kwargs["resource_config"] = resource_config
if "healthcheck" in docker_config:
kwargs["readiness"] = docker_config["healthcheck"]
+ if "livehealthcheck" in docker_config:
+ kwargs["liveness"] = docker_config["livehealthcheck"]
if "dns_name" in ctx.node.properties:
service_component_name = ctx.node.properties["dns_name"]
else:
@@ -526,8 +532,8 @@ def create_and_start_container_for_platforms(**kwargs):
# Set some labels for the Kubernetes pods
kwargs["labels"] = {
"cfydeployment" : ctx.deployment.id,
- "cfynode": ctx.node.name,
- "cfynodeinstance": ctx.instance.id
+ "cfynode": ctx.node.name[:63],
+ "cfynodeinstance": ctx.instance.id[:63]
}
host_port = ctx.node.properties["host_port"]
diff --git a/k8s/setup.py b/k8s/setup.py
index 3d94c96..a64efc8 100644
--- a/k8s/setup.py
+++ b/k8s/setup.py
@@ -23,7 +23,7 @@ from setuptools import setup
setup(
name='k8splugin',
description='Cloudify plugin for containerized components deployed using Kubernetes',
- version="1.4.8",
+ version="1.4.9",
author='J. F. Lucas, Michael Hwang, Tommy Carpenter',
packages=['k8splugin','k8sclient','msb','configure'],
zip_safe=False,
diff --git a/k8s/tests/test_tasks.py b/k8s/tests/test_tasks.py
index 948489a..cf78860 100644
--- a/k8s/tests/test_tasks.py
+++ b/k8s/tests/test_tasks.py
@@ -247,7 +247,7 @@ def test_enhance_docker_params(mockconfig):
test_kwargs = { "docker_config": {}, "service_id": None }
actual = tasks._enhance_docker_params(**test_kwargs)
- assert actual == {'envs': {"SERVICE_TAGS": ""}, 'docker_config': {}, "service_id": None }
+ assert actual == {'envs': {"SERVICE_TAGS": ""}, 'docker_config': {}, 'ports': [], 'volumes': [], "service_id": None }
# Good - Test just docker config ports and volumes
@@ -289,4 +289,4 @@ def test_notify_container(mockconfig):
from k8splugin import tasks
test_input = { "docker_config": { "policy": { "trigger_type": "unknown" } } }
- assert [] == tasks._notify_container(**test_input) \ No newline at end of file
+ assert [] == tasks._notify_container(**test_input)