Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container support for AWS #205

Merged
merged 74 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
b81d30e
[Feat] Add build base docker image as abstract method.
prajinkhadka May 30, 2024
1aaf601
[Feat] Update aws to build the base docker image.
prajinkhadka May 30, 2024
8b0881a
[Feat] Add Container deployment flag. To Do [Check for the valid prov…
prajinkhadka Jun 5, 2024
014c786
[Feat] Add Container deployment support.
prajinkhadka Jun 6, 2024
1bfc272
[Feat] Addd support of the base docker image AWS (python)
prajinkhadka Jun 6, 2024
abf2724
[Feat] Code Refacotring.
prajinkhadka Jun 6, 2024
ab23f73
[Feat] Added Refactoring to do tasks.
prajinkhadka Jun 6, 2024
dbada8f
[Feat] 1. Return container deployment flag, container URI. 2. Add cre…
prajinkhadka Jun 6, 2024
bdca27e
[Feat] Refactored the code. To Do: Need to add entrrypoint for docker…
prajinkhadka Jun 7, 2024
3b248c6
Add entry point in the Dockerfile
prajinkhadka Jun 11, 2024
b486fcb
Maintain cache for the container deployment.
prajinkhadka Jun 11, 2024
e8e5c58
Add correct entrypoint in dockerfile for lambda
prajinkhadka Jun 11, 2024
5565b8e
Remove Whitespaces
prajinkhadka Jun 18, 2024
33f72b8
Docler client login through user provided credentials, refactor ecr a…
prajinkhadka Jun 19, 2024
4f61e00
Fix Mistyped
prajinkhadka Jun 19, 2024
1f65c2a
Minor fixes: Getting docker username, passwoord from config
prajinkhadka Jun 19, 2024
5a59ff4
Minor fixes: Only show the push image error once
prajinkhadka Jun 19, 2024
2955bd8
Minor fixes: Refactor some print debugging statements.
prajinkhadka Jun 19, 2024
3950429
Get repository name from Config.
prajinkhadka Jun 20, 2024
29fae4e
Get repository name from Config if user has provided else generate ra…
prajinkhadka Jun 20, 2024
2577aa6
Refactoring
prajinkhadka Jun 20, 2024
b7015ad
Refactored the create function with simple if/else
prajinkhadka Jun 23, 2024
ac76bb9
Linter and formatter
prajinkhadka Jun 23, 2024
0679485
Removed the parsing for repository name and Image tag. We can use it …
prajinkhadka Jun 23, 2024
a7bc3e5
Linter and formatter
prajinkhadka Jun 23, 2024
8fd1208
Updating function based on container deployment and sotre the code ha…
prajinkhadka Jun 23, 2024
3d7bef5
Refactored
prajinkhadka Jun 23, 2024
15ed07a
Added container deployment as CLI option and update the docs (usage.md)
prajinkhadka Jun 23, 2024
f3dbd91
Linter and formatter
prajinkhadka Jun 23, 2024
eb78d67
Linter and formatter
prajinkhadka Jun 23, 2024
9c6b693
Linter and formatter
prajinkhadka Jun 23, 2024
1a33221
Add new paramters ( container deployment nad uri) to update_function …
prajinkhadka Jun 23, 2024
8c95a1d
Dockerfile for NodeJs
prajinkhadka Jun 23, 2024
621c6a2
Add Empty requirements
prajinkhadka Jun 23, 2024
dfbaee6
Add Empty requirements
prajinkhadka Jun 23, 2024
a31cbee
Black fomatter
prajinkhadka Jun 23, 2024
33eed6a
Black fomatter
prajinkhadka Jun 23, 2024
7fe3d14
Black fomatter
prajinkhadka Jun 23, 2024
2b4eb74
Black fomatter
prajinkhadka Jun 23, 2024
868bac3
Black fomatter
prajinkhadka Jun 23, 2024
226fe70
Fail early if contianer deployment is set for other than AWS.
prajinkhadka Jun 25, 2024
7dd8bf5
Black fomatter
prajinkhadka Jun 25, 2024
918cb61
Minor Fix.
prajinkhadka Jun 25, 2024
e3ac905
Minor Fix.
prajinkhadka Jun 25, 2024
15ece51
Remove unnecessary spaces
prajinkhadka Jun 28, 2024
9df1aa0
Use resource id instead of randomname for ecr reposiotry
prajinkhadka Jun 29, 2024
ef496e5
[Feat] Linting and rebase errors
mcopik Nov 6, 2024
34a46b6
[aws] Make sure to fail when we cannot log in to ECR
mcopik Nov 6, 2024
5ffe7e2
[aws] Reorganize ECR repository creation
mcopik Nov 6, 2024
b9f5253
[aws] Add improt to rich (nice display) and boto3 stubs for ECR
mcopik Nov 6, 2024
6cbcff7
[aws] Do not cache Docker passwords
mcopik Nov 6, 2024
f3175ff
[aws] Remove unnecessary config
mcopik Nov 6, 2024
5b3717a
[aws] Remove unnecessary Docker login
mcopik Nov 6, 2024
f7961bd
[aws] Customize function name for container deployment
mcopik Nov 6, 2024
8175ab3
[aws] remove debug output
mcopik Nov 6, 2024
8f39932
[aws] [system] Extend cache system to support containers
mcopik Nov 6, 2024
37f167f
[aws] Fix typo in the Docker image
mcopik Nov 6, 2024
32b4646
[aws] Build arm64 Docker images
mcopik Nov 6, 2024
e4a5b26
[system] Supporting proper caching of containers with different archi…
mcopik Nov 6, 2024
8a91679
[aws] Prune pip cache after building the image
mcopik Nov 6, 2024
03561be
[aws] Remove unnecessary package
mcopik Nov 6, 2024
bee420a
[aws] CodeRabbit fixes
mcopik Nov 6, 2024
00c5d59
[aws] Adjust other implementations to a new interface
mcopik Nov 6, 2024
ce64f7d
[aws] Move container implementation to a separate class
mcopik Nov 6, 2024
279c66f
[aws] Fix CodeRabbit issue
mcopik Nov 6, 2024
8e3d1f6
[aws] [whisk] Fuse two container implementations
mcopik Nov 6, 2024
00765dd
[tools] Fix incorrect handling of False values
mcopik Nov 7, 2024
5d1bc6a
[system] Reorient container definition to distinguish between AWS and…
mcopik Nov 7, 2024
eeb365f
[system] Add storage configuration option for benchmark invoke
mcopik Nov 7, 2024
2df6828
[system] Disable rich output for regression
mcopik Nov 7, 2024
df08ad3
[benchmark] Separate directory for concurrent build of code package a…
mcopik Nov 7, 2024
18cc75b
[system] Extend regression to support containers
mcopik Nov 7, 2024
7da8d56
[system] Provide documentation on multi-platform builds
mcopik Nov 7, 2024
ff6359a
[aws] Update docs
mcopik Nov 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
Empty file.
15 changes: 15 additions & 0 deletions benchmarks/wrappers/aws/python/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from distutils.core import setup
from glob import glob
from pkg_resources import parse_requirements

with open('requirements.txt') as f:
requirements = [str(r) for r in parse_requirements(f)]

setup(
mcopik marked this conversation as resolved.
Show resolved Hide resolved
name='function',
install_requires=requirements,
packages=['function'],
package_dir={'function': '.'},
package_data={'function': glob('**', recursive=True)},
)

9 changes: 5 additions & 4 deletions config/example.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"experiments": {
"deployment": "openwhisk",
"deployment": "aws",
"update_code": false,
"update_storage": false,
"download_results": false,
"download_results": false,
"architecture": "arm64",
"container_deployment": true,
mcopik marked this conversation as resolved.
Show resolved Hide resolved
mcopik marked this conversation as resolved.
Show resolved Hide resolved
"runtime": {
"language": "nodejs",
"version": "16"
"language": "python",
"version": "3.8"
},
"type": "invocation-overhead",
"perf-cost": {
Expand Down
29 changes: 22 additions & 7 deletions config/systems.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"general": {
"docker_repository": "spcleth/serverless-benchmarks"
"docker_repository": "spcleth/serverless-benchmarks",
"container_deployment": ["aws"]
},
"local": {
"experiments": {
Expand Down Expand Up @@ -61,25 +62,39 @@
"languages": {
"python": {
"base_images": {
"3.11": "amazon/aws-lambda-python:3.11",
"3.10": "amazon/aws-lambda-python:3.10",
"3.9": "amazon/aws-lambda-python:3.9",
"3.8": "amazon/aws-lambda-python:3.8"
"x64": {
"3.11": "amazon/aws-lambda-python:3.11",
"3.10": "amazon/aws-lambda-python:3.10",
"3.9": "amazon/aws-lambda-python:3.9",
"3.8": "amazon/aws-lambda-python:3.8"
},
"arm64": {
"3.11": "amazon/aws-lambda-python:3.11.2024.05.23.17",
"3.10": "amazon/aws-lambda-python:3.10.2024.06.19.11",
"3.9": "amazon/aws-lambda-python:3.9.2024.05.20.23",
"3.8": "amazon/aws-lambda-python:3.8.2024.09.05.16"
}
mcopik marked this conversation as resolved.
Show resolved Hide resolved
},
"images": [
"build"
],
"deployment": {
"files": [
"handler.py",
"storage.py"
"storage.py",
"setup.py"
],
"packages": []
}
},
"nodejs": {
"base_images": {
"16": "amazon/aws-lambda-nodejs:16"
"x64": {
"16": "amazon/aws-lambda-nodejs:16"
},
"arm64": {
"16": "amazon/aws-lambda-nodejs:16.2024.09.06.13"
}
},
"images": [
"build"
Expand Down
9 changes: 9 additions & 0 deletions dockerfiles/aws/nodejs/Dockerfile.function
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ARG BASE_IMAGE
FROM $BASE_IMAGE
COPY . function/
COPY handler.js .
mcopik marked this conversation as resolved.
Show resolved Hide resolved
RUN cd function \
&& npm install --no-package-lock --production \
&& npm cache clean --force

CMD ["handler.handler"]
22 changes: 22 additions & 0 deletions dockerfiles/aws/python/Dockerfile.function
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ARG BASE_IMAGE
FROM $BASE_IMAGE
ARG VERSION
ENV PYTHON_VERSION=${VERSION}

COPY . function/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize COPY command to reduce image size

The current COPY command includes all files from the build context. Consider using .dockerignore or being more specific about what files to copy to:

  1. Reduce image size
  2. Prevent including sensitive files
  3. Improve build performance
-COPY . function/
+COPY requirements.txt function/
+COPY requirements.txt.* function/ 2>/dev/null || true
+COPY handler.py function/
+COPY __init__.py function/ 2>/dev/null || true

Committable suggestion skipped: line range outside the PR's diff.


RUN touch function/__init__.py
RUN if test -f "function/requirements.txt.${PYTHON_VERSION}"; then \
pip install --no-cache-dir \
-r function/requirements.txt \
-r function/requirements.txt.${PYTHON_VERSION} \
function/ && \
pip cache purge; \
else \
pip install --no-cache-dir \
-r function/requirements.txt \
function/ && \
pip cache purge; \
fi

CMD ["function/handler.handler"]
mcopik marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion docs/modularity.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ This function has been retrieved from the cache and requires refreshing function
In practice, this is often limited to updating logging handlers - see existing implementations for details.

```python
def update_function(self, function: Function, code_package: Benchmark):
def update_function(self, function: Function, code_package: Benchmark, container_deployment: bool, container_uri: str):
```

This function updates the function's code and configuration in the platform.
Expand Down
3 changes: 1 addition & 2 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ For each command you can pass `--verbose` flag to increase the verbosity of the
By default, all scripts will create a cache in the directory `cache` to store code with
dependencies and information on allocated cloud resources.
Benchmarks will be rebuilt after a change in source code is detected.
To enforce redeployment of code and benchmark inputs please use flags `--update-code`
and `--update-storage`, respectively.
To enforce redeployment of code, benchmark inputs, container deployment (supported in AWS) please use flags `--update-code`, `--update-storage` and `--container-deployment` respectively.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Documentation needs expansion for container deployment features.

Based on the PR objectives, please expand the documentation to include:

  1. Container deployment workflow:
    • Building container images locally
    • Pushing images to Amazon ECR
    • Image tagging conventions
  2. Configuration details:
    • Example of container_uri in cache configuration
    • Platform limitations (AWS-only support)
  3. CLI commands for container management:
    • Listing deployed images
    • Deleting images

Consider adding a new section specifically for container deployment, similar to the existing "Local" section.

Would you like me to provide a template for the additional documentation?


**Note:** The cache does not support updating the cloud region. If you want to deploy benchmarks
to a new cloud region, then use a new cache directory.
Expand Down
3 changes: 1 addition & 2 deletions requirements.aws.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ boto3
botocore
flake8-boto3
urllib3
boto3-stubs
boto3-stubs[lambda,s3,apigatewayv2,sts,logs,iam]
boto3-stubs[lambda,s3,apigatewayv2,sts,logs,iam,ecr]
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ scipy
#
pycurl>=7.43
click>=7.1.2
rich

75 changes: 47 additions & 28 deletions sebs.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ def common_params(func):
type=click.Choice(["x64", "arm64"]),
help="Target architecture",
)
@click.option(
"--container-deployment/--no-container-deployment",
default=False,
help="Deploy functions as containers (AWS only). When enabled, functions are packaged as container images and pushed to Amazon ECR."
)
@click.option(
"--resource-prefix",
default=None,
Expand Down Expand Up @@ -125,6 +130,7 @@ def parse_common_params(
language,
language_version,
architecture,
container_deployment,
resource_prefix: Optional[str] = None,
initialize_deployment: bool = True,
ignore_cache: bool = False,
Expand All @@ -148,6 +154,7 @@ def parse_common_params(
update_nested_dict(config_obj, ["experiments", "update_code"], update_code)
update_nested_dict(config_obj, ["experiments", "update_storage"], update_storage)
update_nested_dict(config_obj, ["experiments", "architecture"], architecture)
update_nested_dict(config_obj, ["experiments", "container_deployment"], container_deployment)

# set the path the configuration was loaded from
update_nested_dict(config_obj, ["deployment", "local", "path"], config)
Expand Down Expand Up @@ -238,6 +245,7 @@ def invoke(
sebs_client,
deployment_client,
) = parse_common_params(**kwargs)

if image_tag_prefix is not None:
sebs_client.config.image_tag_prefix = image_tag_prefix

Expand All @@ -249,6 +257,7 @@ def invoke(
experiment_config,
logging_filename=logging_filename,
)

if memory is not None:
benchmark_obj.benchmark_config.memory = memory
if timeout is not None:
Expand All @@ -258,6 +267,7 @@ def invoke(
benchmark_obj,
function_name if function_name else deployment_client.default_function_name(benchmark_obj),
)

storage = deployment_client.get_storage(replace_existing=experiment_config.update_storage)
input_config = benchmark_obj.prepare_input(storage=storage, size=benchmark_input_size)

Expand Down Expand Up @@ -371,7 +381,9 @@ def storage_start(storage, output_json, port):

sebs.utils.global_logging()
storage_type = sebs.SeBS.get_storage_implementation(StorageTypes(storage))
storage_config, storage_resources = sebs.SeBS.get_storage_config_implementation(StorageTypes(storage))
storage_config, storage_resources = sebs.SeBS.get_storage_config_implementation(
StorageTypes(storage)
)
mcopik marked this conversation as resolved.
Show resolved Hide resolved
config = storage_config()
resources = storage_resources()

Expand Down Expand Up @@ -405,7 +417,9 @@ def storage_stop(input_json):
resources = storage_resources()

logging.info(f"Stopping storage deployment of {storage_type}.")
storage = sebs.SeBS.get_storage_implementation(storage_type).deserialize(config, None, resources)
storage = sebs.SeBS.get_storage_implementation(storage_type).deserialize(
config, None, resources
)
storage.stop()
logging.info(f"Stopped storage deployment of {storage_type}.")

Expand All @@ -421,16 +435,28 @@ def local():
@click.argument("output", type=str)
@click.option("--deployments", default=1, type=int, help="Number of deployed containers.")
@click.option("--storage-configuration", type=str, help="JSON configuration of deployed storage.")
@click.option("--measure-interval", type=int, default=-1,
help="Interval duration between memory measurements in ms.")
@click.option(
"--measure-interval",
type=int,
default=-1,
help="Interval duration between memory measurements in ms.",
)
@click.option(
"--remove-containers/--no-remove-containers",
default=True,
help="Remove containers after stopping.",
)
@simplified_common_params
def start(benchmark, benchmark_input_size, output, deployments, storage_configuration,
measure_interval, remove_containers, **kwargs):
def start(
benchmark,
benchmark_input_size,
output,
deployments,
storage_configuration,
measure_interval,
remove_containers,
**kwargs,
):
"""
Start a given number of function instances and a storage instance.
"""
Expand Down Expand Up @@ -540,10 +566,7 @@ def resources():


@resources.command("list")
@click.argument(
"resource",
type=click.Choice(["buckets", "resource-groups"])
)
@click.argument("resource", type=click.Choice(["buckets", "resource-groups"]))
@common_params
def resources_list(resource, **kwargs):

Expand All @@ -568,32 +591,23 @@ def resources_list(resource, **kwargs):
sebs_client.logging.error("Resource groups are only supported on Azure!")
return

groups = deployment_client.config.resources.list_resource_groups(deployment_client.cli_instance)
groups = deployment_client.config.resources.list_resource_groups(
deployment_client.cli_instance
)
sebs_client.logging.info("Resource grup:")
for idx, bucket in enumerate(groups):
sebs_client.logging.info(f"({idx}) {bucket}")


@resources.command("remove")
@click.argument(
"resource",
type=click.Choice(["buckets", "resource-groups"])
)
@click.argument(
"prefix",
type=str
)
@click.option(
"--wait/--no-wait",
type=bool,
default=True,
help="Wait for completion of removal."
)
@click.argument("resource", type=click.Choice(["buckets", "resource-groups"]))
@click.argument("prefix", type=str)
@click.option("--wait/--no-wait", type=bool, default=True, help="Wait for completion of removal.")
@click.option(
"--dry-run/--no-dry-run",
type=bool,
default=False,
help="Simulate run without actual deletions."
help="Simulate run without actual deletions.",
)
@common_params
def resources_remove(resource, prefix, wait, dry_run, **kwargs):
Expand Down Expand Up @@ -626,13 +640,18 @@ def resources_remove(resource, prefix, wait, dry_run, **kwargs):
sebs_client.logging.error("Resource groups are only supported on Azure!")
return

groups = deployment_client.config.resources.list_resource_groups(deployment_client.cli_instance)
groups = deployment_client.config.resources.list_resource_groups(
deployment_client.cli_instance
)
for idx, group in enumerate(groups):
if len(prefix) > 0 and not group.startswith(prefix):
continue

sebs_client.logging.info(f"Removing resource group: {group}")
deployment_client.config.resources.delete_resource_group(deployment_client.cli_instance, group, wait)
deployment_client.config.resources.delete_resource_group(
deployment_client.cli_instance, group, wait
)


if __name__ == "__main__":
cli()
Loading