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 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 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, ), )
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])) # Spec
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
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)
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",