def _create_deployment(self): REPLICAS = 1 container_port = k8s.V1ContainerPort(name=self.uid[-14:], container_port=os.getenv( "OPENVAS_OMP_PORT", 9390)) resources = k8s.V1ResourceRequirements( limits={ "cpu": KubernetesDeployer.CONTAINER_USE_CPU_LIMIT, "memory": KubernetesDeployer.CONTAINER_USE_MEMORY_LIMIT, }) readiness_probe = k8s.V1Probe( _exec=k8s.V1ExecAction( command=KubernetesDeployer.OPENVAS_HEALTHCHECK_COMMAND), initial_delay_seconds=300, period_seconds=30, ) liveness_probe = k8s.V1Probe( tcp_socket=k8s.V1TCPSocketAction( port=container_port.container_port), initial_delay_seconds=180, period_seconds=30, failure_threshold=3, timeout_seconds=5, ) container = k8s.V1Container( image=KubernetesDeployer.OPENVAS_CONTAINER_IMAGE, name=self.uid, image_pull_policy="IfNotPresent", ports=[container_port], resources=resources, readiness_probe=readiness_probe, liveness_probe=liveness_probe, ) toleration = k8s.V1Toleration(effect="NoSchedule", key="Scanners", operator="Exists") pod_spec = k8s.V1PodSpec(containers=[container], tolerations=[toleration]) pod_metadata = k8s.V1ObjectMeta( name=self.uid, labels={"app.kubernetes.io/name": self.uid}, annotations={ "cluster-autoscaler.kubernetes.io/safe-to-evict": "false" }, ) pod_template = k8s.V1PodTemplateSpec(spec=pod_spec, metadata=pod_metadata) selector = k8s.V1LabelSelector( match_labels={"app.kubernetes.io/name": self.uid}) deployment_spec = k8s.V1DeploymentSpec(replicas=REPLICAS, selector=selector, template=pod_template) deployment_metadata = k8s.V1ObjectMeta( name=self.uid, labels={"app.kubernetes.io/name": self.uid}) deployment = k8s.V1Deployment(spec=deployment_spec, metadata=deployment_metadata) return k8s.AppsV1Api(self.client).create_namespaced_deployment( self.namespace, deployment)
def create_sts_spec(node_name, workload_type): sts_name = STS_PREFIX + node_name cmd = get_workload_command(workload_type, sts_name) container = client.V1Container( name=sts_name, image=IMAGE, command=["/bin/bash"], args=["-c", cmd], liveness_probe=client.V1Probe( _exec=client.V1ExecAction(command=["ls", "/mnt/" + sts_name]), initial_delay_seconds=5, period_seconds=5), volume_mounts=[ client.V1VolumeMount(name=sts_name, mount_path="/mnt/" + sts_name) ]) template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels={"app": sts_name}), spec=client.V1PodSpec( node_name=node_name, restart_policy="Always", termination_grace_period_seconds=10, containers=[container], )) spec = client.V1StatefulSetSpec( replicas=0, service_name=sts_name, selector=client.V1LabelSelector(match_labels={"app": sts_name}), template=template, volume_claim_templates=[ client.V1PersistentVolumeClaim( metadata=client.V1ObjectMeta(name=sts_name), spec=client.V1PersistentVolumeClaimSpec( access_modes=["ReadWriteOnce"], storage_class_name="longhorn", resources=client.V1ResourceRequirements( requests={"storage": "4Gi"}))) ]) statefulset = client.V1StatefulSet( api_version="apps/v1", kind="StatefulSet", metadata=client.V1ObjectMeta(name=sts_name), spec=spec) statefulset.spec.replicas return statefulset
def main(): # Fetching and loading Kubernetes Information config.load_kube_config() # For incluster details # config.incluster_kube_config() extension = client.ExtensionsV1beta1Api() # Container container = client.V1Container( name="nginx", image="nginx:1.7.9", image_pull_policy="IfNotPresent", ports=[client.V1ContainerPort(container_port=80)], lifecycle=client.V1Lifecycle( pre_stop=client.V1Handler( _exec=client.V1ExecAction( command=[ # Commands to be executed in the prestop hook "touch kube-test.txt" ] ) ) ), ) # Template template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels={"app": "nginx"}), spec=client.V1PodSpec(containers=[container]), ) # Spec spec = client.ExtensionsV1beta1DeploymentSpec(replicas=1, template=template) # Deployment deployment = client.ExtensionsV1beta1Deployment( api_version="extensions/v1beta1", kind="Deployment", metadata=client.V1ObjectMeta(name="nginx-deployment"), spec=spec, ) # Creation of the Deployment in specified namespace extension.create_namespaced_deployment( namespace="kube-client", body=deployment)
def load_liveness_readiness_probe(data): probe = yaml.load(data) httpGet = None if "httpGet" in probe: if "port" in probe['httpGet']: httpGet = client.V1HTTPGetAction( port=int(probe['httpGet']['port']) ) if "path" in probe['httpGet']: httpGet.path = probe['httpGet']['path'] if "host" in probe['httpGet']: httpGet.host = probe['httpGet']['host'] execLiveness = None if "exec" in probe: if probe['exec']['command']: execLiveness = client.V1ExecAction( command=probe['exec']['command'] ) v1Probe = client.V1Probe() if httpGet: v1Probe.http_get = httpGet if execLiveness: v1Probe._exec = execLiveness if "initialDelaySeconds" in probe: v1Probe.initial_delay_seconds = probe["initialDelaySeconds"] if "periodSeconds" in probe: v1Probe.period_seconds = probe["periodSeconds"] if "timeoutSeconds" in probe: v1Probe.timeout_seconds = probe["timeoutSeconds"] return v1Probe
def _create_probe(hc, port): ''' Create a Kubernetes probe based on info in the health check dictionary hc ''' probe_type = hc['type'] probe = None period = _parse_interval(hc.get('interval', PROBE_DEFAULT_PERIOD)) timeout = _parse_interval(hc.get('timeout', PROBE_DEFAULT_TIMEOUT)) if probe_type in ['http', 'https']: probe = client.V1Probe(failure_threshold=1, initial_delay_seconds=5, period_seconds=period, timeout_seconds=timeout, http_get=client.V1HTTPGetAction( path=hc['endpoint'], port=port, scheme=probe_type.upper())) elif probe_type in ['script', 'docker']: probe = client.V1Probe( failure_threshold=1, initial_delay_seconds=5, period_seconds=period, timeout_seconds=timeout, _exec=client.V1ExecAction(command=hc['script'].split())) return probe
def template(context): """ handle yml env """ name = context.get("name") version = context.get("version") labels = { "app": name, "version": "v1" } if not version else { "app": name.strip("-v2"), "version": version } image_tag = context["name"].split('-')[1] image = context["image_namespace"] + image_tag + ":" + context[ "image_branch"] args = [arg for arg in context["args"]] if context.get("args") else None limits, requests = context["resources"]["limits"], context["resources"][ "requests"] replicas = context.get("replicas", 1) workingDir = context["workingDir"] if name == "backend-logproxy": annotations = {"sidecar.istio.io/inject": "false"} else: annotations = {"traffic.sidecar.istio.io/excludeOutboundPorts": "6379"} """ handle cmdb env """ filename = "env_" + name.split("-")[1] + ".yml" env = handle_env("/tmp/{}".format(filename)) """ k8s yaml 组件模块 """ #从svn分支configmap目录中获取相关的目录结构 parentDir, subdir = handle_configmap("configmap") volumemounts = [ client.V1VolumeMount(mount_path="/{}".format(parentDir), name="mainfiles") ] volumes = [ client.V1Volume( name="mainfiles", config_map=client.V1ConfigMapVolumeSource(name="mainfiles")) ] for dir in subdir: volumemounts.append( client.V1VolumeMount(mount_path="/{}/{}".format(parentDir, dir), name=dir)) volumes.append( client.V1Volume( name=dir, config_map=client.V1ConfigMapVolumeSource(name=dir))) if name.startswith("frontend-dispatch"): containers = [ client.V1Container( name=name, image=image, env=env, args=args, volume_mounts=volumemounts, image_pull_policy="Always", lifecycle=client.V1Lifecycle(pre_stop=client.V1Handler( _exec=client.V1ExecAction( command=["nginx", "-s", "quit"]))), readiness_probe=client.V1Probe(_exec=client.V1ExecAction( command=['cat', '/tmp/container_ready']), initial_delay_seconds=10, period_seconds=5), resources=client.V1ResourceRequirements(limits=limits, requests=requests), security_context=client.V1SecurityContext(privileged=True), working_dir=workingDir, ) ] else: containers = [ client.V1Container( name=name, image=image, env=env, args=args, volume_mounts=volumemounts, image_pull_policy="Always", readiness_probe=client.V1Probe(_exec=client.V1ExecAction( command=['cat', '/tmp/container_ready']), initial_delay_seconds=10, period_seconds=5), resources=client.V1ResourceRequirements(limits=limits, requests=requests), security_context=client.V1SecurityContext(privileged=True), working_dir=workingDir, ) ] template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels=labels, annotations=annotations), spec=client.V1PodSpec( containers=containers, dns_policy="ClusterFirst", image_pull_secrets=[ client.V1LocalObjectReference(name="image-pull-secret") ], restart_policy="Always", volumes=volumes)) spec = client.V1DeploymentSpec( replicas=replicas, selector=client.V1LabelSelector(match_labels=labels), template=template, strategy=client.ExtensionsV1beta1DeploymentStrategy( rolling_update=client.ExtensionsV1beta1RollingUpdateDeployment( max_surge=1, max_unavailable='25%'), type="RollingUpdate", ), ) return client.V1Deployment(api_version="apps/v1", kind="Deployment", metadata=client.V1ObjectMeta(name=name, labels=labels), spec=spec)
def _build_definition(machine, config_map): volume_mounts = [] if config_map: # Define volume mounts for hostlab if a ConfigMap is defined. volume_mounts.append( client.V1VolumeMount(name="hostlab", mount_path="/tmp/kathara")) if Setting.get_instance().host_shared: volume_mounts.append( client.V1VolumeMount(name="shared", mount_path="/shared")) # Machine must be executed in privileged mode to run sysctls. security_context = client.V1SecurityContext(privileged=True) ports_info = machine.get_ports() container_ports = None if ports_info: container_ports = [] for (host_port, protocol), guest_port in ports_info.items(): container_ports.append( client.V1ContainerPort(name=str(uuid.uuid4()).replace( '-', '')[0:15], container_port=guest_port, host_port=host_port, protocol=protocol.upper())) resources = None memory = machine.get_mem() cpus = machine.get_cpu(multiplier=1000) if memory or cpus: limits = dict() if memory: limits["memory"] = memory.upper() if cpus: limits["cpu"] = "%dm" % cpus resources = client.V1ResourceRequirements(limits=limits) # postStart lifecycle hook is launched asynchronously by k8s master when the main container is Ready # On Ready state, the pod has volumes and network interfaces up, so this hook is used # to execute custom commands coming from .startup file and "exec" option # Build the final startup commands string sysctl_commands = "; ".join([ "sysctl -w -q %s=%d" % item for item in machine.meta["sysctls"].items() ]) startup_commands_string = "; ".join(STARTUP_COMMANDS) \ .format(machine_name=machine.name, sysctl_commands=sysctl_commands, machine_commands="; ".join(machine.startup_commands) ) post_start = client.V1Handler(_exec=client.V1ExecAction(command=[ Setting.get_instance().device_shell, "-c", startup_commands_string ])) lifecycle = client.V1Lifecycle(post_start=post_start) env = [ client.V1EnvVar( "_MEGALOS_SHELL", machine.meta["shell"] if "shell" in machine.meta else Setting.get_instance().device_shell) ] container_definition = client.V1Container( name=machine.meta['real_name'], image=machine.get_image(), lifecycle=lifecycle, stdin=True, tty=True, image_pull_policy=Setting.get_instance().image_pull_policy, ports=container_ports, resources=resources, volume_mounts=volume_mounts, security_context=security_context, env=env) pod_annotations = {} network_interfaces = [] for (idx, machine_link) in machine.interfaces.items(): network_interfaces.append({ "name": machine_link.api_object["metadata"]["name"], "namespace": machine.lab.folder_hash, "interface": "net%d" % idx }) pod_annotations["k8s.v1.cni.cncf.io/networks"] = json.dumps( network_interfaces) # Create labels (so Deployment can match them) pod_labels = {"name": machine.name, "app": "kathara"} pod_metadata = client.V1ObjectMeta(deletion_grace_period_seconds=0, annotations=pod_annotations, labels=pod_labels) # Add fake DNS just to override k8s one dns_config = client.V1PodDNSConfig(nameservers=["127.0.0.1"]) volumes = [] if config_map: # Hostlab is the lab base64 encoded .tar.gz of the machine files, deployed as a ConfigMap in the cluster # The base64 file is mounted into /tmp and it's extracted by the postStart hook volumes.append( client.V1Volume(name="hostlab", config_map=client.V1ConfigMapVolumeSource( name=config_map.metadata.name))) # Container /shared mounts in /home/shared folder if Setting.get_instance().host_shared: volumes.append( client.V1Volume(name="shared", host_path=client.V1HostPathVolumeSource( path='/home/shared', type='DirectoryOrCreate'))) pod_spec = client.V1PodSpec(containers=[container_definition], hostname=machine.meta['real_name'], dns_policy="None", dns_config=dns_config, volumes=volumes) pod_template = client.V1PodTemplateSpec(metadata=pod_metadata, spec=pod_spec) selector_rules = client.V1LabelSelector(match_labels=pod_labels) deployment_spec = client.V1DeploymentSpec(replicas=1, template=pod_template, selector=selector_rules) deployment_metadata = client.V1ObjectMeta( name=machine.meta['real_name'], labels=pod_labels) return client.V1Deployment(api_version="apps/v1", kind="Deployment", metadata=deployment_metadata, spec=deployment_spec)
def template(context): pod_spec_volumes = [] pod_spec_volume_mounts = [] stateful_set_spec_volume_claim_templates = [] for pvc in context.get("pvc"): stateful_set_spec_volume_claim_templates.append( client.V1PersistentVolumeClaim( metadata=client.V1ObjectMeta( name=pvc["name"], annotations={ "volume.beta.kubernetes.io/storage-class": pvc["class"] }, ), spec=client.V1PersistentVolumeClaimSpec( access_modes=["ReadWriteOnce"], resources=client.V1ResourceRequirements( requests={"storage": pvc["size"]} ), ), ) ) pod_spec_volume_mounts.append( client.V1VolumeMount(name=pvc["name"], mount_path=pvc["mountPath"]) ) if "configmap" in context: volume_name = "{}-config".format(context["name"]) pod_spec_volumes.append( client.V1Volume( name=volume_name, config_map=client.V1ConfigMapVolumeSource(name=context["name"]), ) ) pod_spec_volume_mounts.append( client.V1VolumeMount(name=volume_name, mount_path="/etc/postgresql/") ) labels = {"app": context["name"]} pg_isready_exec = client.V1ExecAction(command=["gosu postgres pg_isready"]) return client.V1StatefulSet( api_version="apps/v1beta1", kind="StatefulSet", metadata=client.V1ObjectMeta(name=context["name"]), spec=client.V1StatefulSetSpec( service_name=context["name"], replicas=context["replicas"], selector=client.V1LabelSelector(match_labels=labels), template=client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels=labels), spec=client.V1PodSpec( containers=[ client.V1Container( name="postgres", image=context["image"], lifecycle=client.V1Lifecycle( pre_stop=client.V1Handler( _exec=client.V1ExecAction( command=[ 'gosu postgres pg_ctl -D "$PGDATA" -m fast -w stop' ] ) ) ), liveness_probe=client.V1Probe( _exec=pg_isready_exec, initial_delay_seconds=120, timeout_seconds=5, failure_threshold=6, ), readiness_probe=client.V1Probe( _exec=pg_isready_exec, initial_delay_seconds=10, timeout_seconds=5, period_seconds=30, failure_threshold=999, ), ports=[client.V1ContainerPort(container_port=5432)], volume_mounts=pod_spec_volume_mounts, resources=client.V1ResourceRequirements( **context["resources"] ) if "resources" in context else None, ) ], volumes=pod_spec_volumes, node_selector=context.get("nodeSelector"), ), ), volume_claim_templates=stateful_set_spec_volume_claim_templates, ), )
from kubernetes import client, config # Fetching and loading Kubernetes Information config.load_kube_config() extension = client.ExtensionsV1beta1Api() # Container container = client.V1Container( name="hooktest", image="nginx:1.7.9", image_pull_policy="IfNotPresent", ports=[client.V1ContainerPort(container_port=80)], lifecycle=client.V1Lifecycle( post_start=client.V1Handler( _exec=client.V1ExecAction(command=["touch kube-test.txt"]) ) ), ) # Template template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels={"app": "hooktest"}), spec=client.V1PodSpec(containers=[container]), ) # Spec spec = client.ExtensionsV1beta1DeploymentSpec(replicas=1, template=template)
def create_deployment_old(config_file): """ Create IBM Spectrum Scale CSI Operator deployment object in operator namespace using deployment_operator_image_for_crd and deployment_driver_image_for_crd parameters from config.json file Args: param1: config_file - configuration json file Returns: None Raises: Raises an exception on kubernetes client api failure and asserts """ deployment_apps_api_instance = client.AppsV1Api() deployment_labels = { "app.kubernetes.io/instance": "ibm-spectrum-scale-csi-operator", "app.kubernetes.io/managed-by": "ibm-spectrum-scale-csi-operator", "app.kubernetes.io/name": "ibm-spectrum-scale-csi-operator", "product": "ibm-spectrum-scale-csi", "release": "ibm-spectrum-scale-csi-operator" } deployment_annotations = { "productID": "ibm-spectrum-scale-csi-operator", "productName": "IBM Spectrum Scale CSI Operator", "productVersion": "2.0.0" } deployment_metadata = client.V1ObjectMeta( name="ibm-spectrum-scale-csi-operator", labels=deployment_labels, namespace=namespace_value) deployment_selector = client.V1LabelSelector( match_labels={ "app.kubernetes.io/name": "ibm-spectrum-scale-csi-operator" }) podtemplate_metadata = client.V1ObjectMeta( labels=deployment_labels, annotations=deployment_annotations) pod_affinity = client.V1Affinity(node_affinity=client.V1NodeAffinity( required_during_scheduling_ignored_during_execution=client. V1NodeSelector(node_selector_terms=[ client.V1NodeSelectorTerm(match_expressions=[ client.V1NodeSelectorRequirement(key="beta.kubernetes.io/arch", operator="Exists") ]) ]))) ansible_pod_container = client.V1Container( image=config_file["deployment_operator_image_for_crd"], command=[ "/usr/local/bin/ao-logs", "/tmp/ansible-operator/runner", "stdout" ], liveness_probe=client.V1Probe( _exec=client.V1ExecAction(command=["/health_check.sh"]), initial_delay_seconds=10, period_seconds=30), readiness_probe=client.V1Probe( _exec=client.V1ExecAction(command=["/health_check.sh"]), initial_delay_seconds=3, period_seconds=1), name="ansible", image_pull_policy="IfNotPresent", security_context=client.V1SecurityContext( capabilities=client.V1Capabilities(drop=["ALL"])), volume_mounts=[ client.V1VolumeMount(mount_path="/tmp/ansible-operator/runner", name="runner", read_only=True) ], env=[ client.V1EnvVar( name="CSI_DRIVER_IMAGE", value=config_file["deployment_driver_image_for_crd"]) ]) operator_pod_container = client.V1Container( image=config_file["deployment_operator_image_for_crd"], name="operator", image_pull_policy="IfNotPresent", liveness_probe=client.V1Probe( _exec=client.V1ExecAction(command=["/health_check.sh"]), initial_delay_seconds=10, period_seconds=30), readiness_probe=client.V1Probe( _exec=client.V1ExecAction(command=["/health_check.sh"]), initial_delay_seconds=3, period_seconds=1), security_context=client.V1SecurityContext( capabilities=client.V1Capabilities(drop=["ALL"])), env=[ client.V1EnvVar(name="WATCH_NAMESPACE", value_from=client.V1EnvVarSource( field_ref=client.V1ObjectFieldSelector( field_path="metadata.namespace"))), client.V1EnvVar(name="POD_NAME", value_from=client.V1EnvVarSource( field_ref=client.V1ObjectFieldSelector( field_path="metadata.name"))), client.V1EnvVar(name="OPERATOR_NAME", value="ibm-spectrum-scale-csi-operator"), client.V1EnvVar( name="CSI_DRIVER_IMAGE", value=config_file["deployment_driver_image_for_crd"]) ], volume_mounts=[ client.V1VolumeMount(mount_path="/tmp/ansible-operator/runner", name="runner") ]) pod_spec = client.V1PodSpec( affinity=pod_affinity, containers=[ansible_pod_container, operator_pod_container], service_account_name="ibm-spectrum-scale-csi-operator", volumes=[ client.V1Volume( empty_dir=client.V1EmptyDirVolumeSource(medium="Memory"), name="runner") ]) podtemplate_spec = client.V1PodTemplateSpec(metadata=podtemplate_metadata, spec=pod_spec) deployment_spec = client.V1DeploymentSpec(replicas=1, selector=deployment_selector, template=podtemplate_spec) body_dep = client.V1Deployment(kind='Deployment', api_version='apps/v1', metadata=deployment_metadata, spec=deployment_spec) try: LOGGER.info("creating deployment for operator") deployment_apps_api_response = deployment_apps_api_instance.create_namespaced_deployment( namespace=namespace_value, body=body_dep) LOGGER.debug(str(deployment_apps_api_response)) except ApiException as e: LOGGER.error( f"Exception when calling RbacAuthorizationV1Api->create_namespaced_deployment: {e}" ) assert False
def specifications(self): """ Set the deployment specifications. :returns: The deployment specifications. :rtype: client.ExtensionsV1beta1Deployment """ #1. Set the ports ports = [client.V1ContainerPort(container_port=port['number'], protocol=port['protocol']) for port in self.definition['ports']] #2. Set the resources #resources = {'cpu':self.definition['cpu'], 'memory': self.definition['memory']} resources = {'cpu':'100m', 'memory': '100Mi'} resources = client.V1ResourceRequirements(limits=resources, requests=resources) #3. Set healthchecks readiness = None liveness = None for health in self.definition['healthchecks']: _exec, tcp_socket, http_get = None, None, None if health['command'] == 'COMMAND': _exec = client.V1ExecAction(command=health['value']) elif health['command'] == 'TCP': tcp_socket = client.V1TCPSocketAction(port=health['port']) else: http_get = client.V1HTTPGetAction(path=health['path'], port=health['port'], scheme=health['command']) probe = client.V1Probe(failure_threshold=self.definition['failure_threshold'], initial_delay_seconds=self.definition['initial_delay_seconds'], period_seconds=self.definition['interval_seconds'], success_threshold=self.definition['success_threshold'], timeout_seconds=self.definition['timeout_seconds'], _exec=_exec, tcp_socket=tcp_socket, http_get=http_get ) if health['type'] == 'readiness': readiness = probe else: liveness = probe #4. Security context security = client.V1SecurityContext(allow_privilege_escalation=False, run_as_non_root=True) #5. Set the container container = client.V1Container( name=self.definition['repo'], image=self.definition['tag'], ports=ports, resources=resources, readiness_probe=readiness, liveness_probe=liveness, security_context=security, env=None)#No need to setup envs : already done in the dockerfile #6. The pod template template = client.V1PodTemplateSpec( client.V1ObjectMeta(labels={"name": self.definition['repo'], "repo": self.definition['repo'], "owner": self.definition['owner'], "branch": self.definition['branch'], "fullname": self.definition['name']}), spec=client.V1PodSpec(containers=[container])) #7. The rolling update strategy strategy = client.ExtensionsV1beta1DeploymentStrategy( type='RollingUpdate', rolling_update=client.ExtensionsV1beta1RollingUpdateDeployment( max_surge=1, max_unavailable=1 ) ) #8. The deployment spec spec = client.ExtensionsV1beta1DeploymentSpec( #replicas=self.definition['instances'], replicas=1, strategy=strategy, template=template) #9. The deployment object deployment = client.ExtensionsV1beta1Deployment( api_version="extensions/v1beta1", kind="Deployment", metadata=client.V1ObjectMeta(name=self.definition['repo'], labels={"uid": self.definition['uid'], "repo": self.definition['repo'], "owner": self.definition['owner'], "branch": self.definition['branch'], "fullname": self.definition['name'], "name": self.definition['repo']}), spec=spec) return deployment
def kubernetes_device_definition(): security_context = client.V1SecurityContext(privileged=True) resources = client.V1ResourceRequirements(limits={ "memory": "64M", "cpu": "2000m" }) sysctl_commands = "sysctl -w -q net.ipv4.conf.all.rp_filter=0; sysctl -w -q net.ipv4.conf.default.rp_filter=0; " \ "sysctl -w -q net.ipv4.conf.lo.rp_filter=0; sysctl -w -q net.ipv4.ip_forward=1; " \ "sysctl -w -q net.ipv4.icmp_ratelimit=0" startup_commands_string = "; ".join(STARTUP_COMMANDS) \ .format(machine_name="test_device", sysctl_commands=sysctl_commands, machine_commands="ls") post_start = client.V1Handler(_exec=client.V1ExecAction( command=["/bin/bash", "-c", startup_commands_string])) container_definition = client.V1Container( name="devprefix-test-device-ec84ad3b", image="kathara/test", lifecycle=client.V1Lifecycle(post_start=post_start), stdin=True, tty=True, image_pull_policy="Always", ports=None, resources=resources, volume_mounts=[], security_context=security_context, env=[client.V1EnvVar("_MEGALOS_SHELL", "/bin/bash")]) pod_metadata = client.V1ObjectMeta( deletion_grace_period_seconds=0, annotations={"k8s.v1.cni.cncf.io/networks": "[]"}, labels={ "name": "test_device", "app": "kathara" }) pod_spec = client.V1PodSpec( containers=[container_definition], hostname="devprefix-test-device-ec84ad3b", dns_policy="None", dns_config=client.V1PodDNSConfig(nameservers=["127.0.0.1"]), volumes=[]) pod_template = client.V1PodTemplateSpec(metadata=pod_metadata, spec=pod_spec) label_selector = client.V1LabelSelector(match_labels={ "name": "test_device", "app": "kathara" }) deployment_spec = client.V1DeploymentSpec(replicas=1, template=pod_template, selector=label_selector) return client.V1Deployment(api_version="apps/v1", kind="Deployment", metadata=client.V1ObjectMeta( name="devprefix-test-device-ec84ad3b", labels={ "name": "test_device", "app": "kathara" }), spec=deployment_spec)
def test_create_ipv6(mock_setting_get_instance, kubernetes_machine, default_device): setting_mock = Mock() setting_mock.configure_mock( **{ 'device_prefix': 'devprefix', 'device_shell': '/bin/bash', 'enable_ipv6': True, 'image_pull_policy': 'Always', 'host_shared': False }) mock_setting_get_instance.return_value = setting_mock security_context = client.V1SecurityContext(privileged=True) resources = client.V1ResourceRequirements(limits={ "memory": "64M", "cpu": "2000m" }) sysctl_commands = "; ".join([ "sysctl -w -q %s=%d" % item for item in { 'net.ipv4.conf.all.rp_filter': 0, 'net.ipv4.conf.default.rp_filter': 0, 'net.ipv4.conf.lo.rp_filter': 0, 'net.ipv4.ip_forward': 1, 'net.ipv4.icmp_ratelimit': 0, 'net.ipv6.conf.all.forwarding': 1, 'net.ipv6.icmp.ratelimit': 0, 'net.ipv6.conf.default.disable_ipv6': 0, 'net.ipv6.conf.all.disable_ipv6': 0 }.items() ]) startup_commands_string = "; ".join(STARTUP_COMMANDS) \ .format(machine_name="test_device", sysctl_commands=sysctl_commands, machine_commands="ls") post_start = client.V1Handler(_exec=client.V1ExecAction( command=["/bin/bash", "-c", startup_commands_string])) container_definition = client.V1Container( name="devprefix-test-device-ec84ad3b", image="kathara/test", lifecycle=client.V1Lifecycle(post_start=post_start), stdin=True, tty=True, image_pull_policy="Always", ports=None, resources=resources, volume_mounts=[], security_context=security_context, env=[client.V1EnvVar("_MEGALOS_SHELL", "/bin/bash")]) pod_metadata = client.V1ObjectMeta( deletion_grace_period_seconds=0, annotations={"k8s.v1.cni.cncf.io/networks": "[]"}, labels={ "name": "test_device", "app": "kathara" }) pod_spec = client.V1PodSpec( containers=[container_definition], hostname="devprefix-test-device-ec84ad3b", dns_policy="None", dns_config=client.V1PodDNSConfig(nameservers=["127.0.0.1"]), volumes=[]) pod_template = client.V1PodTemplateSpec(metadata=pod_metadata, spec=pod_spec) label_selector = client.V1LabelSelector(match_labels={ "name": "test_device", "app": "kathara" }) deployment_spec = client.V1DeploymentSpec(replicas=1, template=pod_template, selector=label_selector) expected_definition = client.V1Deployment( api_version="apps/v1", kind="Deployment", metadata=client.V1ObjectMeta(name="devprefix-test-device-ec84ad3b", labels={ "name": "test_device", "app": "kathara" }), spec=deployment_spec) kubernetes_machine.create(default_device) kubernetes_machine.client.create_namespaced_deployment.assert_called_once_with( body=expected_definition, namespace="FwFaxbiuhvSWb2KpN5zw")
def test_build_definition(mock_setting_get_instance, config_map_mock, default_device, kubernetes_machine): setting_mock = Mock() setting_mock.configure_mock( **{ 'device_prefix': 'devprefix', 'device_shell': '/bin/bash', 'enable_ipv6': False, 'image_pull_policy': 'Always', 'host_shared': False }) mock_setting_get_instance.return_value = setting_mock config_map_mock.metadata.name = "test_device_config_map" security_context = client.V1SecurityContext(privileged=True) resources = client.V1ResourceRequirements(limits={ "memory": "64M", "cpu": "2000m" }) startup_commands_string = "; ".join(STARTUP_COMMANDS) \ .format(machine_name="test_device", sysctl_commands="", machine_commands="ls") post_start = client.V1Handler(_exec=client.V1ExecAction( command=["/bin/bash", "-c", startup_commands_string])) container_definition = client.V1Container( name="devprefix-test-device-ec84ad3b", image="kathara/test", lifecycle=client.V1Lifecycle(post_start=post_start), stdin=True, tty=True, image_pull_policy="Always", ports=None, resources=resources, volume_mounts=[ client.V1VolumeMount(name="hostlab", mount_path="/tmp/kathara") ], security_context=security_context, env=[client.V1EnvVar("_MEGALOS_SHELL", "/bin/bash")]) pod_metadata = client.V1ObjectMeta( deletion_grace_period_seconds=0, annotations={"k8s.v1.cni.cncf.io/networks": "[]"}, labels={ "name": "test_device", "app": "kathara" }) pod_spec = client.V1PodSpec( containers=[container_definition], hostname="devprefix-test-device-ec84ad3b", dns_policy="None", dns_config=client.V1PodDNSConfig(nameservers=["127.0.0.1"]), volumes=[ client.V1Volume(name="hostlab", config_map=client.V1ConfigMapVolumeSource( name="test_device_config_map")) ]) pod_template = client.V1PodTemplateSpec(metadata=pod_metadata, spec=pod_spec) label_selector = client.V1LabelSelector(match_labels={ "name": "test_device", "app": "kathara" }) deployment_spec = client.V1DeploymentSpec(replicas=1, template=pod_template, selector=label_selector) expected_definition = client.V1Deployment( api_version="apps/v1", kind="Deployment", metadata=client.V1ObjectMeta(name="devprefix-test-device-ec84ad3b", labels={ "name": "test_device", "app": "kathara" }), spec=deployment_spec) actual_definition = kubernetes_machine._build_definition( default_device, config_map_mock) assert actual_definition == expected_definition
def createStatefulSet(username, replicas, image, is_host_network=False, ssh_port="22"): statefulset_name = username + "-horovod" statefulset = client.V1StatefulSet() #statefulset.api_version="apps/v1beta2" statefulset.metadata = client.V1ObjectMeta(name=statefulset_name, labels={ "app": "horovod", "user": username, "role": "worker" }) label_selector = client.V1LabelSelector(match_labels={ "app": "horovod", "user": username, "role": "worker" }) # Pod template 정의 pod_template = client.V1PodTemplateSpec() pod_template.metadata = client.V1ObjectMeta(labels={ "app": "horovod", "user": username, "role": "worker" }) container = client.V1Container(name="worker") container.image = image container.image_pull_policy = "IfNotPresent" container.env = [ client.V1EnvVar(name="SSHPORT", value=ssh_port), client.V1EnvVar(name="USESECRETS", value="true"), # TODO: 바꾸기 client.V1EnvVar(name="ENTRY_POINT", value="train.py") ] container.ports = [client.V1ContainerPort(container_port=22)] container.volume_mounts = [ client.V1VolumeMount(name=statefulset_name + "-cm", mount_path="/horovod/generated"), client.V1VolumeMount(name=statefulset_name + "-secret", mount_path="/etc/secret-volume", read_only=True), client.V1VolumeMount(name=statefulset_name + "-data", mount_path="/horovod/data") ] container.command = ["/horovod/generated/run.sh"] container.readiness_probe = client.V1Probe( _exec=client.V1ExecAction(command=["/horovod/generated/check.sh"]), initial_delay_seconds=1, period_seconds=2) pod_spec = client.V1PodSpec(containers=[container]) # Host Network가 설정되있다면 if is_host_network == True: pod_spec.host_network = True pod_spec.dns_policy = "ClusterFirstWithHostNet" pod_spec.volumes = [ client.V1Volume(name=statefulset_name + "-cm", config_map=client.V1ConfigMapVolumeSource( name=statefulset_name, items=[ client.V1KeyToPath(key="hostfile.config", path="hostfile", mode=438), client.V1KeyToPath(key="ssh.readiness", path="check.sh", mode=365), client.V1KeyToPath(key="worker.run", path="run.sh", mode=365) ])), client.V1Volume(name=statefulset_name + "-secret", secret=client.V1SecretVolumeSource( secret_name=statefulset_name, default_mode=448, items=[ client.V1KeyToPath(key="host-key", path="id_rsa"), client.V1KeyToPath(key="host-key-pub", path="authorized_keys") ])), client.V1Volume(name=statefulset_name + "-data", empty_dir=client.V1EmptyDirVolumeSource()) ] pod_spec.subdomain = statefulset_name pod_spec.hostname = statefulset_name pod_spec.init_containers = [ client.V1Container( name="download-data", image=image, image_pull_policy="IfNotPresent", command=["/bin/bash", "-c"], args=[ "curl http://ywj-horovod.s3.ap-northeast-2.amazonaws.com/horovod/" + username + "/train.py > /horovod/data/train.py" ], volume_mounts=[ client.V1VolumeMount(name=statefulset_name + "-data", mount_path="/horovod/data") ]) ] pod_template.spec = pod_spec statefulset.spec = client.V1StatefulSetSpec( selector=label_selector, service_name=statefulset_name + "-worker", # https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-identity pod_management_policy="Parallel", replicas=replicas, template=pod_template) return statefulset
def createStatefulSet(cls, cluster_object: V1MongoClusterConfiguration) -> client.V1beta1StatefulSet: """ Creates a the stateful set configuration for the given cluster. :param cluster_object: The cluster object from the YAML file. :return: The stateful set object. """ # Parse cluster data object. name = cluster_object.metadata.name namespace = cluster_object.metadata.namespace replicas = cluster_object.spec.mongodb.replicas storage_mount_path = cluster_object.spec.mongodb.host_path or cls.DEFAULT_STORAGE_MOUNT_PATH host_path = cluster_object.spec.mongodb.host_path cpu_limit = cluster_object.spec.mongodb.cpu_limit or cls.DEFAULT_CPU_LIMIT memory_limit = cluster_object.spec.mongodb.memory_limit or cls.DEFAULT_MEMORY_LIMIT run_as_user = cluster_object.spec.mongodb.run_as_user or cls.DEFAULT_RUN_AS_USER service_account = cluster_object.spec.mongodb.service_account or cls.DEFAULT_SERVICE_ACCOUNT wired_tiger_cache_size = cluster_object.spec.mongodb.wired_tiger_cache_size or cls.DEFAULT_CACHE_SIZE secret_name = cls.ADMIN_SECRET_NAME_FORMAT.format(name) # create container mongo_container = client.V1Container( name=name, env=[client.V1EnvVar( name="POD_IP", value_from=client.V1EnvVarSource( field_ref = client.V1ObjectFieldSelector( api_version = "v1", field_path = "status.podIP" ) ) ), client.V1EnvVar( name="MONGODB_PASSWORD", value_from=client.V1EnvVarSource( secret_key_ref=client.V1SecretKeySelector( key="database-password", name=secret_name ) ) ), client.V1EnvVar( name="MONGODB_USER", value_from=client.V1EnvVarSource( secret_key_ref=client.V1SecretKeySelector( key="database-user", name=secret_name ) ) ), client.V1EnvVar( name="MONGODB_DATABASE", value_from=client.V1EnvVarSource( secret_key_ref=client.V1SecretKeySelector( key="database-name", name=secret_name ) ) ), client.V1EnvVar( name="MONGODB_ADMIN_PASSWORD", value_from=client.V1EnvVarSource( secret_key_ref=client.V1SecretKeySelector( key="database-admin-password", name=secret_name ) ) ), client.V1EnvVar( name="WIREDTIGER_CACHE_SIZE", value=wired_tiger_cache_size ), client.V1EnvVar( name="MONGODB_REPLICA_NAME", value=name ), client.V1EnvVar( name="MONGODB_SERVICE_NAME", value="svc-" + name + "-internal" ), client.V1EnvVar( name="MONGODB_KEYFILE_VALUE", value="supersecretkeyfile123" )], liveness_probe=client.V1Probe(failure_threshold=3, initial_delay_seconds=30, period_seconds=30, success_threshold=1, tcp_socket=client.V1TCPSocketAction(port=cls.MONGO_PORT), timeout_seconds=1 ), command=cls.MONGO_COMMAND.split(), image=cls.MONGO_IMAGE, image_pull_policy="Always", ports=[client.V1ContainerPort( name="mongodb", container_port=cls.MONGO_PORT, protocol="TCP" )], readiness_probe=client.V1Probe(_exec=client.V1ExecAction(command=["/bin/sh", "-i", "-c", "mongo 127.0.0.1:27017/$MONGODB_DATABASE -u $MONGODB_USER -p $MONGODB_PASSWORD --eval=\"quit()\""]), failure_threshold=3, initial_delay_seconds=10, period_seconds=10, success_threshold=1, timeout_seconds=1 ), security_context=client.V1SecurityContext( run_as_user=int(run_as_user), se_linux_options=client.V1SELinuxOptions( level="s0", type="spc_t" ) ), termination_message_path="/dev/termination-log", volume_mounts=[client.V1VolumeMount( name="mongo-data", read_only=False, mount_path=storage_mount_path )], resources=client.V1ResourceRequirements( limits={"cpu": cpu_limit, "memory": memory_limit}, requests={"cpu": cpu_limit, "memory": memory_limit} ) ) #create affinity rules affinity = client.V1Affinity( pod_anti_affinity=client.V1PodAntiAffinity( required_during_scheduling_ignored_during_execution=[ client.V1PodAffinityTerm(label_selector=client.V1LabelSelector( match_expressions=[client.V1LabelSelectorRequirement( key="app", operator="In", values=[name] )] ), topology_key="kubernetes.io/hostname") ] ) ) volumes = [client.V1Volume( name="mongo-data", host_path=client.V1HostPathVolumeSource(path=host_path) )] # Create stateful set. return client.V1beta1StatefulSet( metadata = client.V1ObjectMeta(annotations={"service.alpha.kubernetes.io/tolerate-unready-endpoints": "true"}, name=name, namespace=namespace, labels=cls.createDefaultLabels(name)), spec = client.V1beta1StatefulSetSpec( replicas = replicas, service_name = "svc-" + name + "-internal", template = client.V1PodTemplateSpec( metadata = client.V1ObjectMeta(labels=cls.createDefaultLabels(name)), spec = client.V1PodSpec(affinity = affinity, containers=[mongo_container], node_selector={"compute":"mongodb"}, service_account=service_account, #restart_policy="Never", volumes=volumes ) ), ), )
def test_sanitize_k8s_container_attribute(self): # test cases for implicit type sanitization(conversion) op = dsl.ContainerOp(name='echo', image='image', command=['sh', '-c'], arguments=['echo test | tee /tmp/message.txt'], file_outputs={'merged': '/tmp/message.txt'}) op.container \ .add_volume_mount(k8s_client.V1VolumeMount( mount_path='/secret/gcp-credentials', name='gcp-credentials')) \ .add_env_variable(k8s_client.V1EnvVar( name=80, value=80)) \ .add_env_variable(k8s_client.V1EnvVar( name=80, value_from=k8s_client.V1EnvVarSource( config_map_key_ref=k8s_client.V1ConfigMapKeySelector(key=80, name=8080, optional='False'), field_ref=k8s_client.V1ObjectFieldSelector(api_version=80, field_path=8080), resource_field_ref=k8s_client.V1ResourceFieldSelector(container_name=80, divisor=8080, resource=8888), secret_key_ref=k8s_client.V1SecretKeySelector(key=80, name=8080, optional='False') ) )) \ .add_env_from(k8s_client.V1EnvFromSource( config_map_ref=k8s_client.V1ConfigMapEnvSource(name=80, optional='True'), prefix=999 )) \ .add_env_from(k8s_client.V1EnvFromSource( secret_ref=k8s_client.V1SecretEnvSource(name=80, optional='True'), prefix=888 )) \ .add_volume_mount(k8s_client.V1VolumeMount( mount_path=111, mount_propagation=222, name=333, read_only='False', sub_path=444, sub_path_expr=555 )) \ .add_volume_devices(k8s_client.V1VolumeDevice( device_path=111, name=222 )) \ .add_port(k8s_client.V1ContainerPort( container_port='8080', host_ip=111, host_port='8888', name=222, protocol=333 )) \ .set_security_context(k8s_client.V1SecurityContext( allow_privilege_escalation='True', capabilities=k8s_client.V1Capabilities(add=[11, 22], drop=[33, 44]), privileged='False', proc_mount=111, read_only_root_filesystem='False', run_as_group='222', run_as_non_root='True', run_as_user='******', se_linux_options=k8s_client.V1SELinuxOptions(level=11, role=22, type=33, user=44), windows_options=k8s_client.V1WindowsSecurityContextOptions( gmsa_credential_spec=11, gmsa_credential_spec_name=22) )) \ .set_stdin(stdin='False') \ .set_stdin_once(stdin_once='False') \ .set_termination_message_path(termination_message_path=111) \ .set_tty(tty='False') \ .set_readiness_probe(readiness_probe=k8s_client.V1Probe( _exec=k8s_client.V1ExecAction(command=[11, 22, 33]), failure_threshold='111', http_get=k8s_client.V1HTTPGetAction( host=11, http_headers=[k8s_client.V1HTTPHeader(name=22, value=33)], path=44, port='55', scheme=66), initial_delay_seconds='222', period_seconds='333', success_threshold='444', tcp_socket=k8s_client.V1TCPSocketAction(host=555, port='666'), timeout_seconds='777' )) \ .set_liveness_probe(liveness_probe=k8s_client.V1Probe( _exec=k8s_client.V1ExecAction(command=[11, 22, 33]), failure_threshold='111', http_get=k8s_client.V1HTTPGetAction( host=11, http_headers=[k8s_client.V1HTTPHeader(name=22, value=33)], path=44, port='55', scheme=66), initial_delay_seconds='222', period_seconds='333', success_threshold='444', tcp_socket=k8s_client.V1TCPSocketAction(host=555, port='666'), timeout_seconds='777' )) \ .set_lifecycle(lifecycle=k8s_client.V1Lifecycle( post_start=k8s_client.V1Handler( _exec=k8s_client.V1ExecAction(command=[11, 22, 33]), http_get=k8s_client.V1HTTPGetAction( host=11, http_headers=[k8s_client.V1HTTPHeader(name=22, value=33)], path=44, port='55', scheme=66), tcp_socket=k8s_client.V1TCPSocketAction(host=555, port='666') ), pre_stop=k8s_client.V1Handler( _exec=k8s_client.V1ExecAction(command=[11, 22, 33]), http_get=k8s_client.V1HTTPGetAction( host=11, http_headers=[k8s_client.V1HTTPHeader(name=22, value=33)], path=44, port='55', scheme=66), tcp_socket=k8s_client.V1TCPSocketAction(host=555, port='666') ) )) sanitize_k8s_object(op.container) for e in op.container.env: self.assertIsInstance(e.name, str) if e.value: self.assertIsInstance(e.value, str) if e.value_from: if e.value_from.config_map_key_ref: self.assertIsInstance(e.value_from.config_map_key_ref.key, str) if e.value_from.config_map_key_ref.name: self.assertIsInstance(e.value_from.config_map_key_ref.name, str) if e.value_from.config_map_key_ref.optional: self.assertIsInstance(e.value_from.config_map_key_ref.optional, bool) if e.value_from.field_ref: self.assertIsInstance(e.value_from.field_ref.field_path, str) if e.value_from.field_ref.api_version: self.assertIsInstance(e.value_from.field_ref.api_version, str) if e.value_from.resource_field_ref: self.assertIsInstance(e.value_from.resource_field_ref.resource, str) if e.value_from.resource_field_ref.container_name: self.assertIsInstance(e.value_from.resource_field_ref.container_name, str) if e.value_from.resource_field_ref.divisor: self.assertIsInstance(e.value_from.resource_field_ref.divisor, str) if e.value_from.secret_key_ref: self.assertIsInstance(e.value_from.secret_key_ref.key, str) if e.value_from.secret_key_ref.name: self.assertIsInstance(e.value_from.secret_key_ref.name, str) if e.value_from.secret_key_ref.optional: self.assertIsInstance(e.value_from.secret_key_ref.optional, bool) for e in op.container.env_from: if e.prefix: self.assertIsInstance(e.prefix, str) if e.config_map_ref: if e.config_map_ref.name: self.assertIsInstance(e.config_map_ref.name, str) if e.config_map_ref.optional: self.assertIsInstance(e.config_map_ref.optional, bool) if e.secret_ref: if e.secret_ref.name: self.assertIsInstance(e.secret_ref.name, str) if e.secret_ref.optional: self.assertIsInstance(e.secret_ref.optional, bool) for e in op.container.volume_mounts: if e.mount_path: self.assertIsInstance(e.mount_path, str) if e.mount_propagation: self.assertIsInstance(e.mount_propagation, str) if e.name: self.assertIsInstance(e.name, str) if e.read_only: self.assertIsInstance(e.read_only, bool) if e.sub_path: self.assertIsInstance(e.sub_path, str) if e.sub_path_expr: self.assertIsInstance(e.sub_path_expr, str) for e in op.container.volume_devices: if e.device_path: self.assertIsInstance(e.device_path, str) if e.name: self.assertIsInstance(e.name, str) for e in op.container.ports: if e.container_port: self.assertIsInstance(e.container_port, int) if e.host_ip: self.assertIsInstance(e.host_ip, str) if e.host_port: self.assertIsInstance(e.host_port, int) if e.name: self.assertIsInstance(e.name, str) if e.protocol: self.assertIsInstance(e.protocol, str) if op.container.security_context: e = op.container.security_context if e.allow_privilege_escalation: self.assertIsInstance(e.allow_privilege_escalation, bool) if e.capabilities: for a in e.capabilities.add: self.assertIsInstance(a, str) for d in e.capabilities.drop: self.assertIsInstance(d, str) if e.privileged: self.assertIsInstance(e.privileged, bool) if e.proc_mount: self.assertIsInstance(e.proc_mount, str) if e.read_only_root_filesystem: self.assertIsInstance(e.read_only_root_filesystem, bool) if e.run_as_group: self.assertIsInstance(e.run_as_group, int) if e.run_as_non_root: self.assertIsInstance(e.run_as_non_root, bool) if e.run_as_user: self.assertIsInstance(e.run_as_user, int) if e.se_linux_options: if e.se_linux_options.level: self.assertIsInstance(e.se_linux_options.level, str) if e.se_linux_options.role: self.assertIsInstance(e.se_linux_options.role, str) if e.se_linux_options.type: self.assertIsInstance(e.se_linux_options.type, str) if e.se_linux_options.user: self.assertIsInstance(e.se_linux_options.user, str) if e.windows_options: if e.windows_options.gmsa_credential_spec: self.assertIsInstance(e.windows_options.gmsa_credential_spec, str) if e.windows_options.gmsa_credential_spec_name: self.assertIsInstance(e.windows_options.gmsa_credential_spec_name, str) if op.container.stdin: self.assertIsInstance(op.container.stdin, bool) if op.container.stdin_once: self.assertIsInstance(op.container.stdin_once, bool) if op.container.termination_message_path: self.assertIsInstance(op.container.termination_message_path, str) if op.container.tty: self.assertIsInstance(op.container.tty, bool) for e in [op.container.readiness_probe, op.container.liveness_probe]: if e: if e._exec: for c in e._exec.command: self.assertIsInstance(c, str) if e.failure_threshold: self.assertIsInstance(e.failure_threshold, int) if e.http_get: if e.http_get.host: self.assertIsInstance(e.http_get.host, str) if e.http_get.http_headers: for h in e.http_get.http_headers: if h.name: self.assertIsInstance(h.name, str) if h.value: self.assertIsInstance(h.value, str) if e.http_get.path: self.assertIsInstance(e.http_get.path, str) if e.http_get.port: self.assertIsInstance(e.http_get.port, (str, int)) if e.http_get.scheme: self.assertIsInstance(e.http_get.scheme, str) if e.initial_delay_seconds: self.assertIsInstance(e.initial_delay_seconds, int) if e.period_seconds: self.assertIsInstance(e.period_seconds, int) if e.success_threshold: self.assertIsInstance(e.success_threshold, int) if e.tcp_socket: if e.tcp_socket.host: self.assertIsInstance(e.tcp_socket.host, str) if e.tcp_socket.port: self.assertIsInstance(e.tcp_socket.port, (str, int)) if e.timeout_seconds: self.assertIsInstance(e.timeout_seconds, int) if op.container.lifecycle: for e in [op.container.lifecycle.post_start, op.container.lifecycle.pre_stop]: if e: if e._exec: for c in e._exec.command: self.assertIsInstance(c, str) if e.http_get: if e.http_get.host: self.assertIsInstance(e.http_get.host, str) if e.http_get.http_headers: for h in e.http_get.http_headers: if h.name: self.assertIsInstance(h.name, str) if h.value: self.assertIsInstance(h.value, str) if e.http_get.path: self.assertIsInstance(e.http_get.path, str) if e.http_get.port: self.assertIsInstance(e.http_get.port, (str, int)) if e.http_get.scheme: self.assertIsInstance(e.http_get.scheme, str) if e.tcp_socket: if e.tcp_socket.host: self.assertIsInstance(e.tcp_socket.host, str) if e.tcp_socket.port: self.assertIsInstance(e.tcp_socket.port, (str, int)) # test cases for checking value after sanitization check_value_op = dsl.ContainerOp(name='echo', image='image', command=['sh', '-c'], arguments=['echo test | tee /tmp/message.txt'], file_outputs={'merged': '/tmp/message.txt'}) check_value_op.container \ .add_env_variable(k8s_client.V1EnvVar( name=80, value=8080)) \ .set_security_context(k8s_client.V1SecurityContext( allow_privilege_escalation='true', capabilities=k8s_client.V1Capabilities(add=[11, 22], drop=[33, 44]), privileged='false', proc_mount=111, read_only_root_filesystem='False', run_as_group='222', run_as_non_root='True', run_as_user='******', se_linux_options=k8s_client.V1SELinuxOptions(level=11, role=22, type=33, user=44), windows_options=k8s_client.V1WindowsSecurityContextOptions( gmsa_credential_spec=11, gmsa_credential_spec_name=22) )) sanitize_k8s_object(check_value_op.container) self.assertEqual(check_value_op.container.env[0].name, '80') self.assertEqual(check_value_op.container.env[0].value, '8080') self.assertEqual(check_value_op.container.security_context.allow_privilege_escalation, True) self.assertEqual(check_value_op.container.security_context.capabilities.add[0], '11') self.assertEqual(check_value_op.container.security_context.capabilities.add[1], '22') self.assertEqual(check_value_op.container.security_context.capabilities.drop[0], '33') self.assertEqual(check_value_op.container.security_context.capabilities.drop[1], '44') self.assertEqual(check_value_op.container.security_context.privileged, False) self.assertEqual(check_value_op.container.security_context.proc_mount, '111') self.assertEqual(check_value_op.container.security_context.read_only_root_filesystem, False) self.assertEqual(check_value_op.container.security_context.run_as_group, 222) self.assertEqual(check_value_op.container.security_context.run_as_non_root, True) self.assertEqual(check_value_op.container.security_context.run_as_user, 333) self.assertEqual(check_value_op.container.security_context.se_linux_options.level, '11') self.assertEqual(check_value_op.container.security_context.se_linux_options.role, '22') self.assertEqual(check_value_op.container.security_context.se_linux_options.type, '33') self.assertEqual(check_value_op.container.security_context.se_linux_options.user, '44') self.assertEqual(check_value_op.container.security_context.windows_options.gmsa_credential_spec, '11') self.assertEqual(check_value_op.container.security_context.windows_options.gmsa_credential_spec_name, '22') # test cases for exception with self.assertRaises(ValueError, msg='Invalid boolean string 2. Should be boolean.'): exception_op = dsl.ContainerOp(name='echo', image='image') exception_op.container \ .set_security_context(k8s_client.V1SecurityContext( allow_privilege_escalation=1 )) sanitize_k8s_object(exception_op.container) with self.assertRaises(ValueError, msg='Invalid boolean string Test. Should be "true" or "false".'): exception_op = dsl.ContainerOp(name='echo', image='image') exception_op.container \ .set_security_context(k8s_client.V1SecurityContext( allow_privilege_escalation='Test' )) sanitize_k8s_object(exception_op.container) with self.assertRaises(ValueError, msg='Invalid test. Should be integer.'): exception_op = dsl.ContainerOp(name='echo', image='image') exception_op.container \ .set_security_context(k8s_client.V1SecurityContext( run_as_group='test', )) sanitize_k8s_object(exception_op.container)
def injectSidecar(deployment, group, port, service, serviceNamespace, revision=0): log.info( "Injecting sidecar process for deployment : {}-{}, group : {}, port : {}, service : {}" .format(deployment.metadata.namespace, deployment.metadata.name, group, port, service)) # Create/Patch config map proxyConfigFilename = "proxy-" + deployment.metadata.name proxyPort = getSideCarPort(deployment) configMapStatus = setProxyConfigMap( name=deployment.metadata.name, namespace=deployment.metadata.namespace, filename=proxyConfigFilename, port=port, proxyPort=proxyPort) if configMapStatus == False: log.error("Unable to make Proxy Config Map") release = os.environ.get("RELEASE") if os.environ.get( "RELEASE") else "latest" container = client.V1Container( name="sidecar", image="medinvention/k8s-sms-sidecar:" + release, ports=[client.V1ContainerPort(container_port=proxyPort)], env=[ client.V1EnvVar(name="POD_NAME", value_from=client.V1EnvVarSource( field_ref=client.V1ObjectFieldSelector( field_path="metadata.name"))), client.V1EnvVar(name="POD_NAMESPACE", value_from=client.V1EnvVarSource( field_ref=client.V1ObjectFieldSelector( field_path="metadata.namespace"))), client.V1EnvVar(name="POD_IP", value_from=client.V1EnvVarSource( field_ref=client.V1ObjectFieldSelector( field_path="status.podIP"))), client.V1EnvVar(name="NODE_GROUP", value=group), client.V1EnvVar(name="NODE_SERVICE", value=service if service != False else deployment.metadata.name), client.V1EnvVar(name="NODE_SERVICE_PORT", value=port) ], lifecycle=client.V1Lifecycle( post_start=client.V1Handler(_exec=client.V1ExecAction( command=["/bin/sh", "/var/register"])), pre_stop=client.V1Handler(_exec=client.V1ExecAction( command=["/bin/sh", "/var/unregister"]))), volume_mounts=[ client.V1VolumeMount(name="sms-volume", sub_path=proxyConfigFilename, mount_path="/etc/nginx/conf.d/default.conf"), client.V1VolumeMount(name="sms-volume", sub_path="register", mount_path="/var/register"), client.V1VolumeMount(name="sms-volume", sub_path="unregister", mount_path="/var/unregister") ]) template = client.V1PodTemplateSpec(spec=client.V1PodSpec( containers=[container], volumes=[ client.V1Volume(name="sms-volume", config_map=client.V1ConfigMapVolumeSource( name="sms-files")) ])) spec = client.V1DeploymentSpec(template=template, selector=deployment.spec.selector) patch = client.V1Deployment(metadata=client.V1ObjectMeta( annotations={ annotations.METADATA: metadata(group=group, port=port, service=service, serviceNamespace=serviceNamespace, revision=int(revision) + 1), annotations.REVISION: str(int(revision) + 1) }), spec=spec) try: response = api_instance.patch_namespaced_deployment( deployment.metadata.name, deployment.metadata.namespace, patch) log.info("Patch deployment to add Sidecar for {}".format( deployment.metadata.name)) return True except ApiException as e: log.error("Exception when patching deployment: {}".format(e)) return False
extension = client.ExtensionsV1beta1Api() # Container container = client.V1Container( name="dep1", image="registry.lti-aiq.in:443/mosaic-ai-logistics/mosaic-ai-templates-ga:Canary-Dep-1", image_pull_policy="Never", ports=[client.V1ContainerPort(container_port=80)], lifecycle=client.V1Lifecycle( pre_stop=client.V1Handler( _exec=client.V1ExecAction( command=[ # Commands to be executed in the prestop hook "echo \"Hello World\"" ] )#closing for V1ExecAction )#closing for V1Handler )#closing for V1Lifecycle ) # Template template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels={"app": "dep1"}), spec=client.V1PodSpec(containers=[container]))
from kubernetes import client, config # Fetching and loading Kubernetes Information config.load_kube_config() extension = client.ExtensionsV1beta1Api() # Container container = client.V1Container( name="hooktest", image="nginx:1.7.9", image_pull_policy="IfNotPresent", ports=[client.V1ContainerPort(container_port=80)], lifecycle=client.V1Lifecycle(post_start=client.V1Handler( _exec=client.V1ExecAction(command=['echo \'Hello World\'' ]) #closing for V1ExecAction ) #closing for V1Handler ) #closing for V1Lifecycle ) # Template template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels={"app": "hook-test"}), spec=client.V1PodSpec(containers=[container])) # Spec spec = client.ExtensionsV1beta1DeploymentSpec(replicas=1, template=template) # Deployment deployment = client.ExtensionsV1beta1Deployment( api_version="extensions/v1beta1",