Kubernetes Service

The Kubernetes service: resources in the platform’s Kubernetes cluster.

Kubernetes does not depend on a cloud: only the cluster’s credentials do. So KubernetesService is implemented once, by KubectlKubernetesService, with kubectl, and the cloud provider contributes only the kubeconfig, with update_kubeconfig(), e.g. aws eks update-kubeconfig for AWS EKS.

The platform uses it through smarter.apps.infrastructure.services.infrastructure .kubernetes. Tests replace it with configure_kubernetes().

from smarter.apps.infrastructure.services import infrastructure

infrastructure.kubernetes.apply_manifest(manifest)
class smarter.apps.infrastructure.services.kubernetes.KubectlKubernetesService(provider=None, allow_in_tests=False, **kwargs)[source]

Bases: KubernetesService

The platform’s Kubernetes cluster, through kubectl.

The cluster is ready once kubectl is configured, with the provider’s update_kubeconfig(), and the environment’s namespace, smarter_settings.environment_namespace, exists.

Parameters:
  • provider (Optional[CloudProvider]) – The cloud provider that writes the kubeconfig. None for a cluster whose kubeconfig is already in place.

  • allow_in_tests (bool) – Allow kubectl in the unit tests, e.g. when subprocess is mocked.

__init__(provider=None, allow_in_tests=False, **kwargs)[source]
apply_manifest(manifest)[source]

Create or update the resources of a manifest, with kubectl apply.

Resources that provision billable cloud resources, see billable_resources(), are announced with the billable resource signals. Nothing is applied if the cluster is not ready.

Parameters:

manifest (str) – The manifest, which may have several YAML documents.

Raises:

KubernetesServiceError – If the cluster rejects it.

Return type:

None

property configured: bool

Whether kubectl is configured for the cluster.

delete_resource(kind, name, namespace)[source]

Delete a resource by name.

A resource that does not exist counts as deleted.

Return type:

bool

delete_resources(kinds, namespace, selector)[source]

Delete the resources of several kinds that match a label selector.

Idempotent. A selector is required, so that a namespace is never emptied by mistake.

Return type:

bool

get_pod_logs(namespace, selector, container=None, tail=200)[source]

Return the most recent log lines of the pods that match a label selector.

Return type:

Optional[str]

get_resource(kind, name, namespace)[source]

Return a resource, or None if it does not exist or the cluster is unavailable.

Return type:

Optional[dict]

property kubeconfig: dict

The platform’s kubeconfig file.

property kubeconfig_path: str

The path of the platform’s kubeconfig file.

list_resources(kind, namespace, selector=None)[source]

Return the resources of a kind, optionally those that match a label selector.

Return type:

list[dict]

property namespace_verified: bool

Whether the environment’s namespace exists.

property ready: bool

Whether the service is authenticated and connected, i.e. it can be used.

verify_namespace(namespace)[source]

Whether a namespace exists.

Return type:

bool

class smarter.apps.infrastructure.services.kubernetes.KubernetesService(provider_name, *args, **kwargs)[source]

Bases: InfrastructureService

The platform’s Kubernetes cluster.

Implementations provide the primitives: apply_manifest(), get_resource(), list_resources(), delete_resource(), delete_resources() and get_pod_logs(). The ingress operations that LLMClient deployments use are built on them.

abstractmethod apply_manifest(manifest)[source]

Create or update the resources of a manifest.

Raises:

KubernetesServiceError – If the cluster rejects them.

Return type:

None

certificate_wait_seconds: float = 60

Seconds between the checks of a cert-manager certificate, in verify_ingress_resources().

delete_certificate(name, namespace)[source]

Delete a cert-manager Certificate.

Return type:

bool

delete_ingress(name, namespace)[source]

Delete an Ingress.

Return type:

bool

delete_ingress_resources(hostname, namespace)[source]

Delete a host’s Ingress, its cert-manager Certificate, and its TLS Secret.

Return type:

tuple[bool, bool, bool]

Returns:

Whether the Ingress, the Certificate, and the Secret were deleted.

abstractmethod delete_resource(kind, name, namespace)[source]

Delete a resource by name.

A resource that does not exist counts as deleted.

Return type:

bool

abstractmethod delete_resources(kinds, namespace, selector)[source]

Delete the resources of several kinds that match a label selector.

Idempotent. A selector is required, so that a namespace is never emptied by mistake.

Return type:

bool

delete_secret(name, namespace)[source]

Delete a Secret.

Return type:

bool

error_class

alias of KubernetesServiceError

abstractmethod get_pod_logs(namespace, selector, container=None, tail=200)[source]

Return the most recent log lines of the pods that match a label selector.

Return type:

Optional[str]

abstractmethod get_resource(kind, name, namespace)[source]

Return a resource, or None if it does not exist or the cluster is unavailable.

Return type:

Optional[dict]

abstractmethod list_resources(kind, namespace, selector=None)[source]

Return the resources of a kind, optionally those that match a label selector.

Return type:

list[dict]

service_name: str = 'kubernetes'

The name of the service in signals and logs, see InfrastructureServiceNames.

verify_certificate(name, namespace)[source]

Whether a cert-manager Certificate exists, and is Ready, i.e. issued.

Parameters:
  • name (str) – The Certificate’s name.

  • namespace (str) – The Certificate’s namespace.

Return type:

bool

verify_ingress(name, namespace)[source]

Whether an Ingress exists.

Return type:

bool

verify_ingress_resources(hostname, namespace, max_attempts=30)[source]

Verify that a host’s Ingress, its cert-manager Certificate, and its TLS Secret exist.

The Ingress is named after the host, and the Certificate and Secret <host>-tls.

Parameters:
  • hostname (str) – The host, e.g. example.3141-5926-5359.api.example.com.

  • namespace (str) – The namespace.

  • max_attempts (int) – How many times to check the Certificate, a minute apart. A Celery task passes 1, and checks again later, so that it does not block its worker.

Return type:

tuple[bool, bool, bool]

Returns:

Whether the Ingress, the Certificate, and the Secret are verified.

verify_secret(name, namespace)[source]

Whether a Secret exists.

Return type:

bool

smarter.apps.infrastructure.services.kubernetes.billable_resources(manifest)[source]

Return the resources of a manifest that provision billable cloud resources.

  • a PersistentVolumeClaim provisions a block storage volume.

  • a StatefulSet’s volumeClaimTemplates provision one volume per replica.

  • a Service of type LoadBalancer provisions a cloud load balancer.

Parameters:

manifest (str) – A Kubernetes manifest, which may have several YAML documents.

Return type:

list[tuple[str, str]]

Returns:

The (kind, name) of each, e.g. ("persistentvolumeclaim", "data").

smarter.apps.infrastructure.services.kubernetes.configure_kubernetes(factory)[source]

Set the factory of the Kubernetes service that get_kubernetes() returns.

Parameters:

factory (Optional[Callable[[], KubernetesService]]) – Returns the service, or None to restore the default, KubectlKubernetesService with the configured cloud provider.

Return type:

None

smarter.apps.infrastructure.services.kubernetes.get_kubernetes()[source]

Return the Kubernetes service.

It is created once, and again if the cloud provider is reconfigured, so that it keeps its readiness, rather than configuring kubectl for each call.

Return type:

KubernetesService

smarter.apps.infrastructure.services.kubernetes.manifest_kinds(manifest)[source]

Return the kinds of a manifest’s resources, e.g. ["Ingress"].

Return type:

list[str]