Merge pull request #2513 from amscanne:website-integrated

PiperOrigin-RevId: 311184385
This commit is contained in:
gVisor bot
2020-05-12 12:55:23 -07:00
150 changed files with 6240 additions and 16 deletions
+39
View File
@@ -1,9 +1,48 @@
load("//tools:defs.bzl", "build_test", "gazelle", "go_path")
load("//website:defs.bzl", "doc")
package(licenses = ["notice"])
exports_files(["LICENSE"])
doc(
name = "contributing",
src = "CONTRIBUTING.md",
category = "Project",
permalink = "/contributing/",
visibility = ["//website:__pkg__"],
weight = "20",
)
doc(
name = "security",
src = "SECURITY.md",
category = "Project",
permalink = "/security/",
visibility = ["//website:__pkg__"],
weight = "30",
)
doc(
name = "governance",
src = "GOVERNANCE.md",
category = "Project",
permalink = "/community/governance/",
subcategory = "Community",
visibility = ["//website:__pkg__"],
weight = "91",
)
doc(
name = "code_of_conduct",
src = "CODE_OF_CONDUCT.md",
category = "Project",
permalink = "/community/code_of_conduct/",
subcategory = "Community",
visibility = ["//website:__pkg__"],
weight = "99",
)
# The sandbox filegroup is used for sandbox-internal dependencies.
package_group(
name = "sandbox",
+2 -3
View File
@@ -87,6 +87,5 @@ harassment or threats to anyone's safety, we may take action without notice.
## Attribution
This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
This Code of Conduct is adapted from the
[Contributor Covenant, version 1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html).
+2 -3
View File
@@ -39,8 +39,8 @@ Dependencies can be added by using `go mod get`. In order to keep the
All Go code should conform to the [Go style guidelines][gostyle]. C++ code
should conform to the [Google C++ Style Guide][cppstyle] and the guidelines
described for [tests][teststyle]. Note that code may be automatically formatted
per the guidelines when merged.
described for tests. Note that code may be automatically formatted per the
guidelines when merged.
As a secure runtime, we need to maintain the safety of all of code included in
gVisor. The following rules help mitigate issues.
@@ -131,4 +131,3 @@ one above, the
[github]: https://github.com/google/gvisor/compare
[gvisor-dev-list]: https://groups.google.com/forum/#!forum/gvisor-dev
[gostyle]: https://github.com/golang/go/wiki/CodeReviewComments
[teststyle]: ./test/
+113
View File
@@ -0,0 +1,113 @@
# Governance
## Projects
A *project* is the primary unit of collaboration. Each project may have its own
repository and contribution process.
All projects are covered by the [Code of Conduct](CODE_OF_CONDUCT.md), and
should include an up-to-date copy in the project repository or a link here.
## Contributors
Anyone can be a *contributor* to a project, provided they have signed relevant
Contributor License Agreements (CLAs) and follow the project's contribution
guidelines. Contributions will be reviewed by a maintainer, and must pass all
applicable tests.
Reviews check for code quality and style, including documentation, and enforce
other policies. Contributions may be rejected for reasons unrelated to the code
in question. For example, a change may be too complex to maintain or duplicate
existing functionality.
Note that contributions are not limited to code alone. Bugs, documentation,
experience reports or public advocacy are all valuable ways to contribute to a
project and build trust in the community.
## Maintainers
Each project has one or more *maintainers*. Maintainers set technical direction,
facilitate contributions and exercise overall stewardship.
Maintainers have write access to the project repository. Maintainers review and
approve changes. They can also assign issues and add additional reviewers.
Note that some repositories may not allow direct commit access, which is
reserved for administrators or automated processes. In this case, maintainers
have approval rights, and a separate process exists for merging a change.
Maintainers are responsible for upholding the code of conduct in interactions
via project communication channels. If comments or exchanges are in violation,
they may remove them at their discretion.
### Repositories requiring synchronization
For some projects initiated by Google, the infrastructure which synchronizes and
merges internal and external changes requires that merges are performed by a
Google employee. In such cases, Google will initiate a rotation to merge changes
once they pass tests and are approved by a maintainer. This does not preclude
non-Google contributors from becoming maintainers, in which case the maintainer
holds approval rights and the merge is an automated process. In some cases,
Google-internal tests may fail and have to be fixed: the Google employee will
work with the submitter to achieve this.
### Becoming a maintainer
The list of maintainers is defined by the list of people with commit access or
approval authority on a repository, typically via a Gerrit group or a GitHub
team.
Existing maintainers may elevate a contributor to maintainer status on evidence
of previous contributions and established trust. This decision is based on lazy
consensus from existing maintainers. While contributors may ask maintainers to
make this decision, existing maintainers will also pro-actively identify
contributors who have demonstrated a sustained track record of technical
leadership and direct contributions.
## Special Interest Groups (SIGs)
From time-to-time, a SIG may be formed in order to solve larger, more complex
problems across one or more projects. There are many avenues for collaboration
outside a SIG, but a SIG can provide structure for collaboration on a single
topic.
Each group will be established by a charter, and governed by the Code of
Conduct. Some resources may be provided to the group, such as mailing lists or
meeting space, and archives will be public.
## Security disclosure
Projects may maintain security mailing lists for vulnerability reports and
internal project audits may occasionally reveal security issues. Access to these
lists and audits will be limited to project *maintainers*; individual
maintainers should opt to participate in these lists based on need and
expertise. Once maintainers become aware of a potential security issue, they
will assess the scope and potential impact. If reported externally, maintainers
will determine a reasonable embargo period with the reporter.
During the embargo period, the maintainers will prioritize a fix for the
security issue. They may choose to disclose the issue to additional trusted
contributors in order to facilitate a fix, subjecting them to the embargo, or
notify affected users in order to give them an advanced opportunity to mitigate
the issue. The inclusion of specific users in this disclosure is left to the
discretion of the maintainers and contributors involved, and depends on the
scale of known project use and exposure.
Once a fix is widely available or the embargo period ends, the maintainers will
make technical details about the vulnerability and associated fixes available.
## Mailing lists
There are four key mailing lists that span projects.
* [gvisor-users](mailto:gvisor-users@googlegroups.com): general purpose user
list.
* [gvisor-dev](mailto:gvisor-dev@googlegroups.com): general purpose
development list.
* [gvisor-security](mailto:gvisor-security@googlegroups.com): private security
list. Access to this list is restricted to maintainers of the core gVisor
project, subject to the security disclosure policy described above.
* [gvisor-syzkaller](mailto:gvisor-syzkaller@googlegroups.com): private
syzkaller bug tracking list. Access to this list is not limited to
maintainers, but will be granted to those who can credibly contribute to
fixes.
+33 -1
View File
@@ -108,7 +108,7 @@ runsc: ## Builds the runsc binary.
.PHONY: runsc
smoke-test: ## Runs a simple smoke test after build runsc.
@$(MAKE) run DOCKER_RUN_OPTIONS="" ARGS="--alsologtostderr --network none --debug --TESTONLY-unsafe-nonroot=true --rootless do true"
@$(MAKE) run DOCKER_PRIVILEGED="" ARGS="--alsologtostderr --network none --debug --TESTONLY-unsafe-nonroot=true --rootless do true"
.PHONY: smoke-tests
unit-tests: ## Runs all unit tests in pkg runsc and tools.
@@ -119,6 +119,38 @@ tests: ## Runs all local ptrace system call tests.
@$(MAKE) test OPTIONS="--test_tag_filter runsc_ptrace test/syscalls/..."
.PHONY: tests
##
## Website & documentation helpers.
##
## The website is built from repository documentation and wrappers, using
## using a locally-defined Docker image (see images/jekyll). The following
## variables may be set when using website-push:
## WEBSITE_IMAGE - The name of the container image.
## WEBSITE_SERVICE - The backend service.
## WEBSITE_PROJECT - The project id to use.
## WEBSITE_REGION - The region to deploy to.
##
WEBSITE_IMAGE := gcr.io/gvisordev/gvisordev
WEBSITE_SERVICE := gvisordev
WEBSITE_PROJECT := gvisordev
WEBSITE_REGION := us-central1
website-build: load-jekyll ## Build the site image locally.
@$(MAKE) run TARGETS="//website:website"
.PHONY: website-build
website-server: website-build ## Run a local server for development.
@docker run -i -p 8080:8080 gvisor.dev/images/website
.PHONY: website-server
website-push: website-build ## Push a new image and update the service.
@docker tag gvisor.dev/images/website $(WEBSITE_IMAGE) && docker push $(WEBSITE_IMAGE)
.PHONY: website-push
website-deploy: website-push ## Deploy a new version of the website.
@gcloud run deploy $(WEBSITE_SERVICE) --platform=managed --region=$(WEBSITE_REGION) --project=$(WEBSITE_PROJECT) --image=$(WEBSITE_IMAGE)
.PHONY: website-push
##
## Development helpers and tooling.
##
+1 -1
View File
@@ -5,7 +5,7 @@ the [gvisor-security mailing list][gvisor-security-list]. You should receive a
prompt response, typically within 48 hours.
Policies for security list access, vulnerability embargo, and vulnerability
disclosure are outlined in the [community][community] repository.
disclosure are outlined in the [governance policy](GOVERNANCE.md).
[community]: https://gvisor.googlesource.com/community
[gvisor-security-list]: https://groups.google.com/forum/#!forum/gvisor-security
+2 -2
View File
@@ -380,15 +380,15 @@ go_repository(
go_repository(
name = "org_uber_go_atomic",
importpath = "go.uber.org/atomic",
version = "v1.6.0",
sum = "h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=",
version = "v1.6.0",
)
go_repository(
name = "org_uber_go_multierr",
importpath = "go.uber.org/multierr",
version = "v1.5.0",
sum = "h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=",
version = "v1.5.0",
)
# BigQuery Dependencies for Benchmarks
+31
View File
@@ -0,0 +1,31 @@
load("//website:defs.bzl", "doc")
package(
default_visibility = ["//website:__pkg__"],
licenses = ["notice"],
)
doc(
name = "index",
src = "README.md",
category = "Project",
permalink = "/docs/",
weight = "0",
)
doc(
name = "roadmap",
src = "roadmap.md",
category = "Project",
permalink = "/roadmap/",
weight = "10",
)
doc(
name = "community",
src = "community.md",
category = "Project",
permalink = "/community/",
subcategory = "Community",
weight = "95",
)
+27 -2
View File
@@ -1,2 +1,27 @@
The gVisor logo files are licensed under CC BY-SA 4.0 (Creative Commons
Attribution-ShareAlike 4.0 International).
# What is gVisor?
gVisor is a user-space kernel, written in Go, that implements a substantial
portion of the [Linux system call interface][linux]. It provides an additional
layer of isolation between running applications and the host operating system.
gVisor includes an [Open Container Initiative (OCI)][oci] runtime called `runsc`
that makes it easy to work with existing container tooling. The `runsc` runtime
integrates with Docker and Kubernetes, making it simple to run sandboxed
containers.
gVisor takes a distinct approach to container sandboxing and makes a different
set of technical trade-offs compared to existing sandbox technologies, thus
providing new tools and ideas for the container security landscape.
gVisor can be used with Docker, Kubernetes, or directly using `runsc`. Use the
links below to see detailed instructions for each of them:
* [Docker](./user_guide/quick_start/docker/): The quickest and easiest way to
get started.
* [Kubernetes](./user_guide/quick_start/kubernetes/): Isolate Pods in your K8s
cluster with gVisor.
* [OCI Quick Start](./user_guide/quick_start/oci/): Expert mode. Customize
gVisor for your environment.
[linux]: https://en.wikipedia.org/wiki/Linux_kernel_interfaces
[oci]: https://www.opencontainers.org
+64
View File
@@ -0,0 +1,64 @@
load("//website:defs.bzl", "doc")
package(
default_visibility = ["//website:__pkg__"],
licenses = ["notice"],
)
doc(
name = "index",
src = "README.md",
category = "Architecture Guide",
data = [
"Layers.png",
"Layers.svg",
"Machine-Virtualization.png",
"Machine-Virtualization.svg",
"Rule-Based-Execution.png",
"Rule-Based-Execution.svg",
"Sentry-Gofer.png",
"Sentry-Gofer.svg",
],
permalink = "/docs/architecture_guide/",
weight = "0",
)
doc(
name = "platforms",
src = "platforms.md",
category = "Architecture Guide",
data = [
"Sentry-Gofer.png",
"Sentry-Gofer.svg",
],
permalink = "/docs/architecture_guide/platforms/",
weight = "40",
)
doc(
name = "resources",
src = "resources.md",
category = "Architecture Guide",
permalink = "/docs/architecture_guide/resources/",
weight = "30",
)
doc(
name = "security",
src = "security.md",
category = "Architecture Guide",
data = [
"Layers.png",
"Layers.svg",
],
permalink = "/docs/architecture_guide/security/",
weight = "10",
)
doc(
name = "performance",
src = "performance.md",
category = "Architecture Guide",
permalink = "/docs/architecture_guide/performance/",
weight = "20",
)
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 70 KiB

+80
View File
@@ -0,0 +1,80 @@
# Overview
gVisor provides a virtualized environment in order to sandbox untrusted
containers. The system interfaces normally implemented by the host kernel are
moved into a distinct, per-sandbox user space kernel in order to minimize the
risk of an exploit. gVisor does not introduce large fixed overheads however, and
still retains a process-like model with respect to resource utilization.
## How is this different?
Two other approaches are commonly taken to provide stronger isolation than
native containers.
**Machine-level virtualization**, such as [KVM][kvm] and [Xen][xen], exposes
virtualized hardware to a guest kernel via a Virtual Machine Monitor (VMM). This
virtualized hardware is generally enlightened (paravirtualized) and additional
mechanisms can be used to improve the visibility between the guest and host
(e.g. balloon drivers, paravirtualized spinlocks). Running containers in
distinct virtual machines can provide great isolation, compatibility and
performance (though nested virtualization may bring challenges in this area),
but for containers it often requires additional proxies and agents, and may
require a larger resource footprint and slower start-up times.
![Machine-level virtualization](Machine-Virtualization.png "Machine-level virtualization")
**Rule-based execution**, such as [seccomp][seccomp], [SELinux][selinux] and
[AppArmor][apparmor], allows the specification of a fine-grained security policy
for an application or container. These schemes typically rely on hooks
implemented inside the host kernel to enforce the rules. If the surface can be
made small enough (i.e. a sufficiently complete policy defined), then this is an
excellent way to sandbox applications and maintain native performance. However,
in practice it can be extremely difficult (if not impossible) to reliably define
a policy for arbitrary, previously unknown applications, making this approach
challenging to apply universally.
![Rule-based execution](Rule-Based-Execution.png "Rule-based execution")
Rule-based execution is often combined with additional layers for
defense-in-depth.
**gVisor** provides a third isolation mechanism, distinct from those above.
gVisor intercepts application system calls and acts as the guest kernel, without
the need for translation through virtualized hardware. gVisor may be thought of
as either a merged guest kernel and VMM, or as seccomp on steroids. This
architecture allows it to provide a flexible resource footprint (i.e. one based
on threads and memory mappings, not fixed guest physical resources) while also
lowering the fixed costs of virtualization. However, this comes at the price of
reduced application compatibility and higher per-system call overhead.
![gVisor](Layers.png "gVisor")
On top of this, gVisor employs rule-based execution to provide defense-in-depth
(details below).
gVisor's approach is similar to [User Mode Linux (UML)][uml], although UML
virtualizes hardware internally and thus provides a fixed resource footprint.
Each of the above approaches may excel in distinct scenarios. For example,
machine-level virtualization will face challenges achieving high density, while
gVisor may provide poor performance for system call heavy workloads.
### Why Go?
gVisor is written in [Go][golang] in order to avoid security pitfalls that can
plague kernels. With Go, there are strong types, built-in bounds checks, no
uninitialized variables, no use-after-free, no stack overflow, and a built-in
race detector. (The use of Go has its challenges too, and isn't free.)
### What about Gofers?
<a name="gofer"></a> <!-- For deep linking. -->
[apparmor]: https://wiki.ubuntu.com/AppArmor
[golang]: https://golang.org
[kvm]: https://www.linux-kvm.org
[seccomp]: https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
[selinux]: https://selinuxproject.org
[uml]: http://user-mode-linux.sourceforge.net/
[xen]: https://www.xenproject.org
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 51 KiB

+274
View File
@@ -0,0 +1,274 @@
# Performance Guide
[TOC]
gVisor is designed to provide a secure, virtualized environment while preserving
key benefits of containerization, such as small fixed overheads and a dynamic
resource footprint. For containerized infrastructure, this can provide a
turn-key solution for sandboxing untrusted workloads: there are no changes to
the fundamental resource model.
gVisor imposes runtime costs over native containers. These costs come in two
forms: additional cycles and memory usage, which may manifest as increased
latency, reduced throughput or density, or not at all. In general, these costs
come from two different sources.
First, the existence of the [Sentry](../) means that additional memory will be
required, and application system calls must traverse additional layers of
software. The design emphasizes [security](../security/) and therefore we chose
to use a language for the Sentry that provides benefits in this domain but may
not yet offer the raw performance of other choices. Costs imposed by these
design choices are **structural costs**.
Second, as gVisor is an independent implementation of the system call surface,
many of the subsystems or specific calls are not as optimized as more mature
implementations. A good example here is the network stack, which is continuing
to evolve but does not support all the advanced recovery mechanisms offered by
other stacks and is less CPU efficient. This is an **implementation cost** and
is distinct from **structural costs**. Improvements here are ongoing and driven
by the workloads that matter to gVisor users and contributors.
This page provides a guide for understanding baseline performance, and calls out
distint **structural costs** and **implementation costs**, highlighting where
improvements are possible and not possible.
While we include a variety of workloads here, its worth emphasizing that gVisor
may not be an appropriate solution for every workload, for reasons other than
performance. For example, a sandbox may provide minimal benefit for a trusted
database, since _user data would already be inside the sandbox_ and there is no
need for an attacker to break out in the first place.
## Methodology
All data below was generated using the [benchmark tools][benchmark-tools]
repository, and the machines under test are uniform [Google Compute Engine][gce]
Virtual Machines (VMs) with the following specifications:
Machine type: n1-standard-4 (broadwell)
Image: Debian GNU/Linux 9 (stretch) 4.19.0-0
BootDisk: 2048GB SSD persistent disk
Through this document, `runsc` is used to indicate the runtime provided by
gVisor. When relevant, we use the name `runsc-platform` to describe a specific
[platform choice](../platforms/).
**Except where specified, all tests below are conducted with the `ptrace`
platform. The `ptrace` platform works everywhere and does not require hardware
virtualization or kernel modifications but suffers from the highest structural
costs by far. This platform is used to provide a clear understanding of the
performance model, but in no way represents an ideal scenario. In the future,
this guide will be extended to bare metal environments and include additional
platforms.**
## Memory access
gVisor does not introduce any additional costs with respect to raw memory
accesses. Page faults and other Operating System (OS) mechanisms are translated
through the Sentry, but once mappings are installed and available to the
application, there is no additional overhead.
{% include graph.html id="sysbench-memory"
url="/performance/sysbench-memory.csv" title="perf.py sysbench.memory
--runtime=runc --runtime=runsc" %}
The above figure demonstrates the memory transfer rate as measured by
`sysbench`.
## Memory usage
The Sentry provides an additional layer of indirection, and it requires memory
in order to store state associated with the application. This memory generally
consists of a fixed component, plus an amount that varies with the usage of
operating system resources (e.g. how many sockets or files are opened).
For many use cases, fixed memory overheads are a primary concern. This may be
because sandboxed containers handle a low volume of requests, and it is
therefore important to achieve high densities for efficiency.
{% include graph.html id="density" url="/performance/density.csv" title="perf.py
density --runtime=runc --runtime=runsc" log="true" y_min="100000" %}
The above figure demonstrates these costs based on three sample applications.
This test is the result of running many instances of a container (50, or 5 in
the case of redis) and calculating available memory on the host before and
afterwards, and dividing the difference by the number of containers. This
technique is used for measuring memory usage over the `usage_in_bytes` value of
the container cgroup because we found that some container runtimes, other than
`runc` and `runsc`, do not use an individual container cgroup.
The first application is an instance of `sleep`: a trivial application that does
nothing. The second application is a synthetic `node` application which imports
a number of modules and listens for requests. The third application is a similar
synthetic `ruby` application which does the same. Finally, we include an
instance of `redis` storing approximately 1GB of data. In all cases, the sandbox
itself is responsible for a small, mostly fixed amount of memory overhead.
## CPU performance
gVisor does not perform emulation or otherwise interfere with the raw execution
of CPU instructions by the application. Therefore, there is no runtime cost
imposed for CPU operations.
{% include graph.html id="sysbench-cpu" url="/performance/sysbench-cpu.csv"
title="perf.py sysbench.cpu --runtime=runc --runtime=runsc" %}
The above figure demonstrates the `sysbench` measurement of CPU events per
second. Events per second is based on a CPU-bound loop that calculates all prime
numbers in a specified range. We note that `runsc` does not impose a performance
penalty, as the code is executing natively in both cases.
This has important consequences for classes of workloads that are often
CPU-bound, such as data processing or machine learning. In these cases, `runsc`
will similarly impose minimal runtime overhead.
{% include graph.html id="tensorflow" url="/performance/tensorflow.csv"
title="perf.py tensorflow --runtime=runc --runtime=runsc" %}
For example, the above figure shows a sample TensorFlow workload, the
[convolutional neural network example][cnn]. The time indicated includes the
full start-up and run time for the workload, which trains a model.
## System calls
Some **structural costs** of gVisor are heavily influenced by the
[platform choice](../platforms/), which implements system call interception.
Today, gVisor supports a variety of platforms. These platforms present distinct
performance, compatibility and security trade-offs. For example, the KVM
platform has low overhead system call interception but runs poorly with nested
virtualization.
{% include graph.html id="syscall" url="/performance/syscall.csv" title="perf.py
syscall --runtime=runc --runtime=runsc-ptrace --runtime=runsc-kvm" y_min="100"
log="true" %}
The above figure demonstrates the time required for a raw system call on various
platforms. The test is implemented by a custom binary which performs a large
number of system calls and calculates the average time required.
This cost will principally impact applications that are system call bound, which
tend to be high-performance data stores and static network services. In general,
the impact of system call interception will be lower the more work an
application does.
{% include graph.html id="redis" url="/performance/redis.csv" title="perf.py
redis --runtime=runc --runtime=runsc" %}
For example, `redis` is an application that performs relatively little work in
userspace: in general it reads from a connected socket, reads or modifies some
data, and writes a result back to the socket. The above figure shows the results
of running [comprehensive set of benchmarks][redis-benchmark]. We can see that
small operations impose a large overhead, while larger operations, such as
`LRANGE`, where more work is done in the application, have a smaller relative
overhead.
Some of these costs above are **structural costs**, and `redis` is likely to
remain a challenging performance scenario. However, optimizing the
[platform](../platforms/) will also have a dramatic impact.
## Start-up time
For many use cases, the ability to spin-up containers quickly and efficiently is
important. A sandbox may be short-lived and perform minimal user work (e.g. a
function invocation).
{% include graph.html id="startup" url="/performance/startup.csv" title="perf.py
startup --runtime=runc --runtime=runsc" %}
The above figure indicates how total time required to start a container through
[Docker][docker]. This benchmark uses three different applications. First, an
alpine Linux-container that executes `true`. Second, a `node` application that
loads a number of modules and binds an HTTP server. The time is measured by a
successful request to the bound port. Finally, a `ruby` application that
similarly loads a number of modules and binds an HTTP server.
> Note: most of the time overhead above is associated Docker itself. This is
> evident with the empty `runc` benchmark. To avoid these costs with `runsc`,
> you may also consider using `runsc do` mode or invoking the
> [OCI runtime](../../user_guide/quick_start/oci/) directly.
## Network
Networking is mostly bound by **implementation costs**, and gVisor's network
stack is improving quickly.
While typically not an important metric in practice for common sandbox use
cases, nevertheless `iperf` is a common microbenchmark used to measure raw
throughput.
{% include graph.html id="iperf" url="/performance/iperf.csv" title="perf.py
iperf --runtime=runc --runtime=runsc" %}
The above figure shows the result of an `iperf` test between two instances. For
the upload case, the specified runtime is used for the `iperf` client, and in
the download case, the specified runtime is the server. A native runtime is
always used for the other endpoint in the test.
{% include graph.html id="applications" metric="requests_per_second"
url="/performance/applications.csv" title="perf.py http.(node|ruby)
--connections=25 --runtime=runc --runtime=runsc" %}
The above figure shows the result of simple `node` and `ruby` web services that
render a template upon receiving a request. Because these synthetic benchmarks
do minimal work per request, must like the `redis` case, they suffer from high
overheads. In practice, the more work an application does the smaller the impact
of **structural costs** become.
## File system
Some aspects of file system performance are also reflective of **implementation
costs**, and an area where gVisor's implementation is improving quickly.
In terms of raw disk I/O, gVisor does not introduce significant fundamental
overhead. For general file operations, gVisor introduces a small fixed overhead
for data that transitions across the sandbox boundary. This manifests as
**structural costs** in some cases, since these operations must be routed
through the [Gofer](../) as a result of our [security model](../security/), but
in most cases are dominated by **implementation costs**, due to an internal
[Virtual File System][vfs] (VFS) implementation that needs improvement.
{% include graph.html id="fio-bw" url="/performance/fio.csv" title="perf.py fio
--engine=sync --runtime=runc --runtime=runsc" log="true" %}
The above figures demonstrate the results of `fio` for reads and writes to and
from the disk. In this case, the disk quickly becomes the bottleneck and
dominates other costs.
{% include graph.html id="fio-tmpfs-bw" url="/performance/fio-tmpfs.csv"
title="perf.py fio --engine=sync --runtime=runc --tmpfs=True --runtime=runsc"
log="true" %}
The above figure shows the raw I/O performance of using a `tmpfs` mount which is
sandbox-internal in the case of `runsc`. Generally these operations are
similarly bound to the cost of copying around data in-memory, and we don't see
the cost of VFS operations.
{% include graph.html id="httpd100k" metric="transfer_rate"
url="/performance/httpd100k.csv" title="perf.py http.httpd --connections=1
--connections=5 --connections=10 --connections=25 --runtime=runc
--runtime=runsc" %}
The high costs of VFS operations can manifest in benchmarks that execute many
such operations in the hot path for serving requests, for example. The above
figure shows the result of using gVisor to serve small pieces of static content
with predictably poor results. This workload represents `apache` serving a
single file sized 100k from the container image to a client running
[ApacheBench][ab] with varying levels of concurrency. The high overhead comes
principally from the VFS implementation that needs improvement, with several
internal serialization points (since all requests are reading the same file).
Note that some of some of network stack performance issues also impact this
benchmark.
{% include graph.html id="ffmpeg" url="/performance/ffmpeg.csv" title="perf.py
media.ffmpeg --runtime=runc --runtime=runsc" %}
For benchmarks that are bound by raw disk I/O and a mix of compute, file system
operations are less of an issue. The above figure shows the total time required
for an `ffmpeg` container to start, load and transcode a 27MB input video.
[ab]: https://en.wikipedia.org/wiki/ApacheBench
[benchmark-tools]: https://github.com/google/gvisor/tree/master/benchmarks
[gce]: https://cloud.google.com/compute/
[cnn]: https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/convolutional_network.py
[docker]: https://docker.io
[redis-benchmark]: https://redis.io/topics/benchmarks
[vfs]: https://en.wikipedia.org/wiki/Virtual_file_system

Some files were not shown because too many files have changed in this diff Show More