def _create_datadog_container(self, app_spec, besteffort_qos_is_required): if besteffort_qos_is_required: resource_requirements = ResourceRequirements() else: resource_requirements = ResourceRequirements(limits={ "cpu": "400m", "memory": "2Gi" }, requests={ "cpu": "200m", "memory": "2Gi" }) tags = app_spec.datadog.tags tags["app"] = app_spec.name tags["k8s_namespace"] = app_spec.namespace # Use an alphabetical order based on keys to ensure that the # output is predictable dd_tags = ",".join("{}:{}".format(k, tags[k]) for k in sorted(tags)) return Container( name=self.DATADOG_CONTAINER_NAME, image=self._datadog_container_image, imagePullPolicy="IfNotPresent", env=[ EnvVar(name="DD_TAGS", value=dd_tags), EnvVar(name="DD_API_KEY", valueFrom=EnvVarSource(secretKeyRef=SecretKeySelector( name="datadog", key="apikey"))), EnvVar(name="NON_LOCAL_TRAFFIC", value="false"), EnvVar(name="DD_LOGS_STDOUT", value="yes"), EnvVar(name="DD_EXPVAR_PORT", value="42622"), EnvVar(name="DD_CMD_PORT", value="42623"), ], resources=resource_requirements)
def _create_default_deployment(): labels = {"test": "true"} object_meta = ObjectMeta(name=NAME, namespace=NAMESPACE, labels=labels) container_port = ContainerPort(name="http5000", containerPort=5000) http = HTTPGetAction(path="/", port="http5000") liveness = Probe(httpGet=http) tcp = TCPSocketAction(port=5000) readiness = Probe(tcpSocket=tcp) container = Container(name="container", image="dummy_image", ports=[container_port], livenessProbe=liveness, readinessProbe=readiness) image_pull_secret = LocalObjectReference(name="image_pull_secret") pod_spec = PodSpec(containers=[container], imagePullSecrets=[image_pull_secret], serviceAccountName="default") pod_template_spec = PodTemplateSpec(metadata=object_meta, spec=pod_spec) deployer_spec = DeploymentSpec(replicas=2, selector=LabelSelector(matchLabels=labels), template=pod_template_spec, revisionHistoryLimit=5) deployment = Deployment(metadata=object_meta, spec=deployer_spec) return deployment
def _create_pod(): object_meta = ObjectMeta(name=NAME, namespace=NAMESPACE, labels={ "test": "true", "app": NAME }) container_port = ContainerPort(name="http5000", containerPort=5000) secrets_volume_mounts = [ VolumeMount( name=NAME, readOnly=True, mountPath="/var/run/secrets/kubernetes.io/kubernetes-secrets") ] secret_volumes = [ Volume(name=NAME, secret=SecretVolumeSource(secretName=NAME)) ] container = Container(name="container", image="dummy_image", ports=[container_port], volumeMounts=secrets_volume_mounts) image_pull_secret = LocalObjectReference(name="image_pull_secret") pod_spec = PodSpec(containers=[container], imagePullSecrets=[image_pull_secret], volumes=secret_volumes, serviceAccountName="default") first = Pod(metadata=object_meta, spec=pod_spec) return first
def test_lifecycle(self, logger): object_meta = ObjectMeta(name=NAME, namespace=NAMESPACE, labels={"test": "true"}) container_port = ContainerPort(name="http5000", containerPort=5000) http = HTTPGetAction(path="/", port="http5000") liveness = Probe(httpGet=http) tcp = TCPSocketAction(port=5000) readiness = Probe(tcpSocket=tcp) container = Container(name="container", image="dummy_image", ports=[container_port], livenessProbe=liveness, readinessProbe=readiness) image_pull_secret = LocalObjectReference(name="image_pull_secret") pod_spec = PodSpec(containers=[container], imagePullSecrets=[image_pull_secret], serviceAccountName="default") pod_template_spec = PodTemplateSpec(metadata=object_meta, spec=pod_spec) rc_spec = ReplicationControllerSpec(replicas=2, selector={"test": "true"}, template=pod_template_spec) first = ReplicationController(metadata=object_meta, spec=rc_spec) logger.debug(pformat(first.as_dict())) first.save() second = ReplicationController.get(NAME, NAMESPACE) assert first.metadata.name == second.metadata.name assert first.metadata.namespace == second.metadata.namespace
def deployment(): main_container = Container( env=[EnvVar(name=CANARY_NAME, value=CANARY_VALUE)]) pod_spec = PodSpec(containers=[main_container]) pod_metadata = ObjectMeta(annotations={CANARY_NAME: CANARY_VALUE}) pod_template_spec = PodTemplateSpec(spec=pod_spec, metadata=pod_metadata) deployment_spec = DeploymentSpec(template=pod_template_spec) return Deployment(spec=deployment_spec)
def _create_deployment(available_replicas, namespace, image): container = Container(image=image) pod_spec = PodSpec(containers=[container]) pod_template_spec = PodTemplateSpec(spec=pod_spec) spec = DeploymentSpec(replicas=1, template=pod_template_spec) status = DeploymentStatus(availableReplicas=available_replicas) metadata = ObjectMeta(name=NAME, namespace=namespace) return Deployment(metadata=metadata, spec=spec, status=status)
def _create_pod_spec(args, channel, namespace, spec_config): container = Container(name="fiaas-deploy-daemon-bootstrap", image=channel.metadata['image'], command=["fiaas-deploy-daemon-bootstrap"] + args, resources=_create_resource_requirements( namespace, spec_config)) pod_spec = PodSpec(containers=[container], serviceAccountName="default", restartPolicy="Never") return pod_spec
def _create_default_job(): labels = {"test": "true"} object_meta = ObjectMeta(name=NAME, namespace=NAMESPACE, labels=labels) container = Container(name="container", image="dummy_image") image_pull_secret = LocalObjectReference(name="image_pull_secret") pod_spec = PodSpec(containers=[container], imagePullSecrets=[image_pull_secret], serviceAccountName="default", restartPolicy="Never") pod_template_spec = PodTemplateSpec(metadata=object_meta, spec=pod_spec) job_spec = JobSpec(template=pod_template_spec) job = Job(metadata=object_meta, spec=job_spec) return job
def _make_secrets_init_container(self, app_spec, image, env_vars=None): if env_vars is None: env_vars = {} env_vars.update({"K8S_DEPLOYMENT": app_spec.name}) environment = [EnvVar(name=k, value=v) for k, v in env_vars.items()] container = Container(name=self.SECRETS_INIT_CONTAINER_NAME, image=image, imagePullPolicy="IfNotPresent", env=environment, envFrom=[ EnvFromSource(configMapRef=ConfigMapEnvSource(name=self.SECRETS_INIT_CONTAINER_NAME, optional=True)) ], volumeMounts=self._make_volume_mounts(app_spec, is_init_container=True)) return container
def test_lifecycle(self, logger): object_meta = ObjectMeta(name=NAME, namespace=NAMESPACE, labels={"test": "true", "app": NAME}) container_port = ContainerPort(name="http5000", containerPort=5000) secrets_volume_mounts = [VolumeMount(name=NAME, readOnly=True, mountPath="/var/run/secrets/kubernetes.io/kubernetes-secrets")] secret_volumes = [Volume(name=NAME, secret=SecretVolumeSource(secretName=NAME))] container = Container(name="container", image="dummy_image", ports=[container_port], volumeMounts=secrets_volume_mounts) image_pull_secret = LocalObjectReference(name="image_pull_secret") pod_spec = PodSpec(containers=[container], imagePullSecrets=[image_pull_secret], volumes=secret_volumes, serviceAccountName="default") first = Pod(metadata=object_meta, spec=pod_spec) logger.debug(pformat(first.as_dict())) first.save() pods = Pod.find(NAME, NAMESPACE) assert len(pods) == 1 second = pods[0] assert first.metadata.name == second.metadata.name assert first.metadata.namespace == second.metadata.namespace
def _create_default_cronjob(): object_meta = ObjectMeta(name=NAME, namespace=NAMESPACE) container = Container(name="container", image="dummy_image") pod_spec = PodSpec(containers=[container], serviceAccountName="default", restartPolicy="OnFailure") pod_template_spec = PodTemplateSpec(metadata=object_meta, spec=pod_spec) job_spec = JobSpec(template=pod_template_spec) job_template_spec = JobTemplateSpec(metadata=object_meta, spec=job_spec) cronjob_spec = CronJobSpec(concurencyPolicy="Allow", failedJobsHistoryLimit=0, jobTemplate=job_template_spec, schedule="*/1 * * * *", startingDeadlineSeconds=5, successfulJobsHistoryLimit=100, suspend=True) cronjob = CronJob(metadata=object_meta, spec=cronjob_spec) return cronjob
def _create_datadog_container(self, app_spec, besteffort_qos_is_required): if besteffort_qos_is_required: resource_requirements = ResourceRequirements() else: resource_requirements = ResourceRequirements(limits={"cpu": "400m", "memory": "2Gi"}, requests={"cpu": "200m", "memory": "2Gi"}) return Container( name=self.DATADOG_CONTAINER_NAME, image=self._datadog_container_image, imagePullPolicy="IfNotPresent", env=[ EnvVar(name="DD_TAGS", value="app:{},k8s_namespace:{}".format(app_spec.name, app_spec.namespace)), EnvVar(name="API_KEY", valueFrom=EnvVarSource(secretKeyRef=SecretKeySelector(name="datadog", key="apikey"))), EnvVar(name="NON_LOCAL_TRAFFIC", value="false"), EnvVar(name="DD_LOGS_STDOUT", value="yes"), EnvVar(name="DD_EXPVAR_PORT", value="42622"), EnvVar(name="DD_CMD_PORT", value="42623"), ], resources=resource_requirements )
def deployment(self): main_container = Container(env=[EnvVar(name="DUMMY", value="CANARY")]) pod_spec = PodSpec(containers=[main_container]) pod_template_spec = PodTemplateSpec(spec=pod_spec) deployment_spec = DeploymentSpec(template=pod_template_spec) return Deployment(spec=deployment_spec)
def deploy(self, app_spec, selector, labels, besteffort_qos_is_required): LOG.info("Creating new deployment for %s", app_spec.name) deployment_labels = merge_dicts(app_spec.labels.deployment, labels) metadata = ObjectMeta(name=app_spec.name, namespace=app_spec.namespace, labels=deployment_labels, annotations=app_spec.annotations.deployment) container_ports = [ ContainerPort(name=port_spec.name, containerPort=port_spec.target_port) for port_spec in app_spec.ports ] env = self._make_env(app_spec) pull_policy = "IfNotPresent" if (":" in app_spec.image and ":latest" not in app_spec.image) else "Always" env_from = [ EnvFromSource(configMapRef=ConfigMapEnvSource(name=app_spec.name, optional=True)) ] containers = [ Container( name=app_spec.name, image=app_spec.image, ports=container_ports, env=env, envFrom=env_from, lifecycle=self._lifecycle, livenessProbe=_make_probe(app_spec.health_checks.liveness), readinessProbe=_make_probe(app_spec.health_checks.readiness), imagePullPolicy=pull_policy, volumeMounts=self._make_volume_mounts(app_spec), resources=_make_resource_requirements(app_spec.resources)) ] automount_service_account_token = app_spec.admin_access init_containers = [] service_account_name = "default" pod_spec = PodSpec( containers=containers, initContainers=init_containers, volumes=self._make_volumes(app_spec), serviceAccountName=service_account_name, automountServiceAccountToken=automount_service_account_token, terminationGracePeriodSeconds=self._grace_period) pod_labels = merge_dicts(app_spec.labels.pod, _add_status_label(labels)) pod_metadata = ObjectMeta(name=app_spec.name, namespace=app_spec.namespace, labels=pod_labels, annotations=app_spec.annotations.pod) pod_template_spec = PodTemplateSpec(metadata=pod_metadata, spec=pod_spec) replicas = app_spec.replicas # we must avoid that the deployment scales up to app_spec.replicas if autoscaler has set another value if should_have_autoscaler(app_spec): try: deployment = Deployment.get(app_spec.name, app_spec.namespace) replicas = deployment.spec.replicas except NotFound: pass deployment_strategy = DeploymentStrategy( rollingUpdate=RollingUpdateDeployment( maxUnavailable=self._max_unavailable, maxSurge=self._max_surge)) if app_spec.replicas == 1 and app_spec.singleton: deployment_strategy = DeploymentStrategy( rollingUpdate=RollingUpdateDeployment(maxUnavailable=1, maxSurge=0)) spec = DeploymentSpec(replicas=replicas, selector=LabelSelector(matchLabels=selector), template=pod_template_spec, revisionHistoryLimit=5, strategy=deployment_strategy) deployment = Deployment.get_or_create(metadata=metadata, spec=spec) _clear_pod_init_container_annotations(deployment) self._datadog.apply(deployment, app_spec, besteffort_qos_is_required) self._prometheus.apply(deployment, app_spec) self._secrets.apply(deployment, app_spec) deployment.save()