Пример #1
0
    def setup(self):
        """
        Sets up MLStack by pulling Docker images, downloading dependencies,
        and building Docker images
        """
        logger.info(
            """

       _      _           _
 _ __ | |  __| |_ __ _ __| |__
| '  \| | (_-<  _/ _  / _| / /
|_|_|_|_| /__/\__\__,_\__|_\_\


Local Kubernetes cluster for machine learning engineering

        """
        )
        logger.info("Setting up MLStack. This will take a little while. Grab a coffee!")
        dockerclient = DockerClient()

        repositories = [
            "tensorflow/tensorflow:latest-py3-jupyter",
            "openjdk:8-jdk-slim-stretch",
            "localstack/localstack:0.8.6",
        ]

        images = ["tensorflow", "spark"]
        dockerclient.pull_images(repositories=repositories)
        download_spark()
        dockerclient.build_images(images=images)
Пример #2
0
    def pull_images(self, repositories: list):
        """
        Pulls images from Docker repositories

        Args
          repositories: Docker repositories to pull from

        """
        for repository in repositories:
            logger.info("Pulling from %s\n", repository)
            for line in self.pull(repository, stream=True, decode=True):
                if (bool(line.get("status", False))) & ("." not in line.get(
                        "id", "")):
                    sys.stdout.write("\r{id}: {status} {progress}".format(
                        id=line.get("id", ""),
                        status=line.get("status", ""),
                        progress=line.get("progress", ""),
                    ))
            print("\n")
Пример #3
0
    def build_images(self, images: list):
        """
        Builds Docker images from a Dockerfile.

        Args
          images: Images stored in mlstack/build/{image}, where the path
                  is a Docker build context containing a Dockerfile

        """
        for image in images:
            # Returns mlstack/build/{image} (where mlstack is the install directory)
            package_dir = str(
                str(Path(__file__).absolute()).replace(
                    Path(__file__).name, ""))
            context_path = package_dir.replace(
                "mlstack/clients", "build/{image}".format(image=image))
            logger.info("Building %s from %s", image, context_path)

            for line in self.build(
                    path=context_path + "/.",
                    tag="mlstack-{image}:latest".format(image=image),
                    decode=True,
            ):

                if line.get("stream", None):
                    logger.info(line.get("stream"))
                elif line.get("error", None):
                    logger.error(line.get("error"))
                else:
                    logger.warning(line)

            logger.info("Successfully built %s", image)
Пример #4
0
 def __init__(self):
     logger.info("Initializing MLStack")
Пример #5
0
 def close():
     """ Close the MLStack cluster """
     logger.info("Closing the MLStack cluster in Kubernetes")
     KubernetesClient().delete_manifests(["spark", "tensorflow", "localstack"])
Пример #6
0
 def create():
     """ Creates an MLStack local Kubernetes cluster """
     logger.info("Creating an MLStack cluster in Kubernetes")
     KubernetesClient().create_manifests(["spark", "tensorflow", "localstack"])
Пример #7
0
    def create_manifest(self, component: str):
        """
        Creates a manifest from a list of components
        located in mlstack/manifests. Uses a clever
        getattr() trick to avoid hardcoding everything.

        Will create kubernetes apps in the following order:

         - PersistentVolumeClaim
         - PersistentVolume
         - ConfigMap
         - Deployment
         - Secret
         - Service

        Args
          components: A list of mlstack component manifests to create.

        """
        warning_message = "KubeApiException on {kind} `{name}`. \n Exception:\n"

        for file in glob.glob(
                str(Path(self.manifests_dir, component)) + "/*.yaml"):
            generator = read_yaml(file)
            for body in generator:
                if body:

                    kind = body.get("kind")
                    name = body.get("metadata").get("name")
                    method_ext = "_".join(
                        val.lower()
                        for val in re.findall("[A-Z][^A-Z]*", kind))

                    warning_message = "KubeApiException on {kind} `{name}`".format(
                        kind=kind, name=name)

                    if kind in [
                            "PersistentVolumeClaim",
                            "ConfigMap",
                            "Service",
                            "Secret",
                    ]:

                        try:
                            method = "create_namespaced_{ext}".format(
                                ext=method_ext)
                            getattr(self, method)(namespace="mlstack",
                                                  body=body)
                            logger.info("%s `%s` created", kind, name)

                        except KubeApiException as exception:
                            logger.warning(warning_message, exception)

                    if kind in ["PersistentVolume"]:
                        try:
                            getattr(self,
                                    "create_persistent_volume")(body=body)
                            logger.info("%s `%s` created", kind, name)

                        except KubeApiException as exception:
                            logger.warning(warning_message, exception)

                    if kind in ["Deployment"]:
                        try:

                            AppsV1Api().create_namespaced_deployment(
                                namespace="mlstack", body=body)
                            logger.info("%s `%s` created", kind, name)

                        except KubeApiException as exception:
                            logger.warning(warning_message, exception)