diff --git a/docs/platform-hyperkit.md b/docs/platform-hyperkit.md index 3a528b60d..455cfbaf6 100644 --- a/docs/platform-hyperkit.md +++ b/docs/platform-hyperkit.md @@ -72,14 +72,14 @@ docker build -t ssh . docker run --rm -ti -v ~/.ssh:/root/.ssh ssh ssh ``` - ### Forwarding ports to the host -While VPNKit has the general tooling to expose any VMs port on the -localhost (just like it does with containers in Docker for Mac), we -are unlikely to expose this as a general feature in `linuxkit run` as -it is very specific to the macOS. However, you can use a `socat` container to proxy between LinuxKit VMs ports and localhost. For example, to expose the redis port from the [RedisOS example](../examples/redis-os.yml), use this Dockerfile: +Ports can be forwarded to the host using a container with `socat` or with VPNKit which comes with Docker for Mac. +#### Port forwarding with `socat` +A `socat` container can be used to proxy between the LinuxKit VM's ports and +localhost. For example, to expose the redis port from the [RedisOS +example](../examples/redis-os.yml), use this Dockerfile: ``` FROM alpine:edge RUN apk add --no-cache socat @@ -91,6 +91,30 @@ docker build -t socat . docker run --rm -t -d -p 6379:6379 socat tcp-listen:6379,reuseaddr,fork tcp::6379 ``` +#### Port forwarding with VPNKit` + +VPNKit has the general tooling to expose any guest VM port on the host (just +like it does with containers in Docker for Mac). To enable forwarding, a +`vpnkit-forwarder` container must be running in the VM. The VM also has to be +booted with `linuxkit run hyperkit -networking=vpnkit`. + +VPNKit uses a 9P mount in `/port` for coordination between the components. +Port forwarding can be manually set up by creating new directories in `/port` +or by using the `vpnkit-expose-port` tool. More details about the forwarding +mechanism is available in the [VPNKit +documentation](https://github.com/moby/vpnkit/blob/master/docs/ports.md#signalling-from-the-vm-to-the-host). + +To get started, the easiest solution at the moment is to use the +`vpnkit-expose-port` command to tell the forwarder and `vpnkit` which ports to +forward. This process requires fewer privileges than `vpnkit-forwarder` and can +be run in a container without networking. + +A full example with `vpnkit` forwarding of `sshd` is available in [examples/vpnkit-forwarder.yml](/examples/vpnkit-forwarder.yml). + +After building and running the example you should be able to connect to ssh on port 22 on +localhost. The port can also be exposed externally by changing the host IP in +the example to 0.0.0.0. + ## Integration services and Metadata There are no special integration services available for HyperKit, but diff --git a/examples/vpnkit-forwarder.yml b/examples/vpnkit-forwarder.yml new file mode 100644 index 000000000..08bd40055 --- /dev/null +++ b/examples/vpnkit-forwarder.yml @@ -0,0 +1,44 @@ +kernel: + image: "linuxkit/kernel:4.9.x" + cmdline: "console=ttyS0 page_poison=1" +init: + - linuxkit/init:2599bcd5013ce5962aa155ee8929c26160de13bd + - linuxkit/runc:3a4e6cbf15470f62501b019b55e1caac5ee7689f + - linuxkit/containerd:b50181bc6e0084e5fcd6b6ad3cf433c4f66cae5a +onboot: + - name: dhcpcd + image: "linuxkit/dhcpcd:7d2b8aaaf20c24ad7d11a5ea2ea5b4a80dc966f1" + command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"] + - name: mount-vpnkit + image: "alpine:3.6" + binds: + - /var/:/host_var:rbind,rshared + capabilities: + - CAP_SYS_ADMIN + rootfsPropagation: shared + command: ["sh", "-c", "mkdir /host_var/vpnkit && mount -v -t 9p -o trans=virtio,dfltuid=1001,dfltgid=50,version=9p2000 port /host_var/vpnkit"] +services: + - name: sshd + image: "linuxkit/sshd:abc1f5e096982ebc3fb61c506aed3ac9c2ae4d55" + - name: vpnkit-forwarder + image: "linuxkit/vpnkit-forwarder:883de832c2c3cb72cd9b01e3f7bd788649e0f2c2" + binds: + - /var/vpnkit:/port + net: host + command: ["/vpnkit-forwarder"] + - name: vpnkit-expose-port + image: "linuxkit/vpnkit-forwarder:883de832c2c3cb72cd9b01e3f7bd788649e0f2c2" + net: none + binds: + - /var/vpnkit:/port + command: ["/vpnkit-expose-port","-i", + "-host-ip","127.0.0.1","-host-port","22", + "-container-ip","127.0.0.1","-container-port","22","-no-local-ip"] + +files: + - path: root/.ssh/authorized_keys + contents: '#your ssh key here' + +trust: + org: + - linuxkit diff --git a/pkg/vpnkit-forwarder/Dockerfile b/pkg/vpnkit-forwarder/Dockerfile new file mode 100644 index 000000000..e6141e2ac --- /dev/null +++ b/pkg/vpnkit-forwarder/Dockerfile @@ -0,0 +1,16 @@ +FROM linuxkit/alpine:630ee558e4869672fae230c78364e367b8ea67a9 AS mirror + +RUN apk add --no-cache go musl-dev git build-base +ENV GOPATH=/go PATH=$PATH:/go/bin +ENV COMMIT=2d6d82167cf81c665c05d1425a79adfbc1a71177 + +RUN git clone https://github.com/moby/vpnkit.git /go/src/github.com/moby/vpnkit && \ + cd /go/src/github.com/moby/vpnkit && \ + git checkout $COMMIT && \ + cd go && \ + make all + +FROM scratch +COPY --from=mirror /go/src/github.com/moby/vpnkit/go/build/vpnkit-forwarder.linux /vpnkit-forwarder +COPY --from=mirror /go/src/github.com/moby/vpnkit/go/build/vpnkit-expose-port.linux /vpnkit-expose-port +CMD ["/vpnkit-forwarder"] diff --git a/pkg/vpnkit-forwarder/Makefile b/pkg/vpnkit-forwarder/Makefile new file mode 100644 index 000000000..a952a6a53 --- /dev/null +++ b/pkg/vpnkit-forwarder/Makefile @@ -0,0 +1,15 @@ +default: push + +ORG?=linuxkit +IMAGE=vpnkit-forwarder +DEPS=$(wildcard *.go) Makefile Dockerfile + +HASH?=$(shell git ls-tree HEAD -- ../$(notdir $(CURDIR)) | awk '{print $$3}') + +tag: $(DEPS) + docker build --squash --no-cache -t $(ORG)/$(IMAGE):$(HASH) . + +push: tag + DOCKER_CONTENT_TRUST=1 docker pull $(ORG)/$(IMAGE):$(HASH) || \ + DOCKER_CONTENT_TRUST=1 docker push $(ORG)/$(IMAGE):$(HASH) + diff --git a/pkg/vpnkit-forwarder/README.md b/pkg/vpnkit-forwarder/README.md new file mode 100644 index 000000000..e0d1a6b8a --- /dev/null +++ b/pkg/vpnkit-forwarder/README.md @@ -0,0 +1,9 @@ +### vpnkit-forwarder + +This package provides `vpnkit-forwarder` and `vpnkit-expose-port` from [vpnkit](http://github.com/moby/vpnkit.git). + +`vpnkit-forwarder` is a forwarding daemon used by Docker for Desktop to forward ports from Docker containers to the host via VSOCK. + +`vpnkit-expose-port` is a userland proxy that opens ports by demand. + +To coordinate with `vpnkit` both tools require access to the 9P port configuration mount point.