summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Luo <cl4531@att.com>2019-03-10 00:36:25 +0000
committerJason Luo <cl4531@att.com>2019-03-12 14:46:19 +0000
commitecc38094077da21c7cb7c84597710945fbc01788 (patch)
treecc32b27d44ea8c740711a4c0f4b3928b2b9e4623
parentf024f8e353847f5a59aeeb3b011e5502ee89d253 (diff)
add liveness probe, fix readiness prob exec
liveness and readiness probes may run script with arguments, ports and volumes are optional instead of mandatory, test_tasks.py accept ports[] and volumes[] fix the issue of labels which are logner than 63 Issue-ID: DCAEGEN2-1126 Change-Id: Id2f893adc300bf508c0512a51b3665872d36f674 Signed-off-by: Jason Luo <cl4531@att.com>
-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)