mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-21 01:59:07 +00:00
Merge pull request #73 from justincormack/docker
Add an output format for running images with Docker
This commit is contained in:
commit
d906292096
@ -35,7 +35,37 @@ func (o *outputList) Set(value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var streamable = map[string]bool{
|
var streamable = map[string]bool{
|
||||||
"tar": true,
|
"docker": true,
|
||||||
|
"tar": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
type addFun func(*tar.Writer) error
|
||||||
|
|
||||||
|
const dockerfile = `
|
||||||
|
FROM scratch
|
||||||
|
|
||||||
|
COPY . ./
|
||||||
|
RUN rm -f Dockerfile
|
||||||
|
|
||||||
|
ENTRYPOINT ["/sbin/tini", "--", "/bin/rc.init"]
|
||||||
|
`
|
||||||
|
|
||||||
|
var additions = map[string]addFun{
|
||||||
|
"docker": func(tw *tar.Writer) error {
|
||||||
|
log.Infof(" Adding Dockerfile")
|
||||||
|
hdr := &tar.Header{
|
||||||
|
Name: "Dockerfile",
|
||||||
|
Mode: 0644,
|
||||||
|
Size: int64(len(dockerfile)),
|
||||||
|
}
|
||||||
|
if err := tw.WriteHeader(hdr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := tw.Write([]byte(dockerfile)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the build arguments and execute build
|
// Process the build arguments and execute build
|
||||||
@ -127,6 +157,7 @@ func build(args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var outputFile *os.File
|
var outputFile *os.File
|
||||||
|
var addition addFun
|
||||||
if *buildOutputFile != "" {
|
if *buildOutputFile != "" {
|
||||||
if len(buildOut) > 1 {
|
if len(buildOut) > 1 {
|
||||||
log.Fatal("The -output option can only be specified when generating a single output format")
|
log.Fatal("The -output option can only be specified when generating a single output format")
|
||||||
@ -150,6 +181,7 @@ func build(args []string) {
|
|||||||
}
|
}
|
||||||
defer outputFile.Close()
|
defer outputFile.Close()
|
||||||
}
|
}
|
||||||
|
addition = additions[buildOut[0]]
|
||||||
}
|
}
|
||||||
|
|
||||||
size, err := getDiskSizeMB(*buildSize)
|
size, err := getDiskSizeMB(*buildSize)
|
||||||
@ -194,7 +226,7 @@ func build(args []string) {
|
|||||||
buf = new(bytes.Buffer)
|
buf = new(bytes.Buffer)
|
||||||
w = buf
|
w = buf
|
||||||
}
|
}
|
||||||
buildInternal(moby, w, *buildPull)
|
buildInternal(moby, w, *buildPull, addition)
|
||||||
|
|
||||||
if outputFile == nil {
|
if outputFile == nil {
|
||||||
image := buf.Bytes()
|
image := buf.Bytes()
|
||||||
@ -272,7 +304,7 @@ func enforceContentTrust(fullImageName string, config *TrustConfig) bool {
|
|||||||
|
|
||||||
// Perform the actual build process
|
// Perform the actual build process
|
||||||
// TODO return error not panic
|
// TODO return error not panic
|
||||||
func buildInternal(m Moby, w io.Writer, pull bool) {
|
func buildInternal(m Moby, w io.Writer, pull bool, addition addFun) {
|
||||||
iw := tar.NewWriter(w)
|
iw := tar.NewWriter(w)
|
||||||
|
|
||||||
if m.Kernel.Image != "" {
|
if m.Kernel.Image != "" {
|
||||||
@ -341,6 +373,15 @@ func buildInternal(m Moby, w io.Writer, pull bool) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to add filesystem parts: %v", err)
|
log.Fatalf("failed to add filesystem parts: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add anything additional for this output type
|
||||||
|
if addition != nil {
|
||||||
|
err = addition(iw)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to add additional files")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = iw.Close()
|
err = iw.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("initrd close error: %v", err)
|
log.Fatalf("initrd close error: %v", err)
|
||||||
|
@ -60,7 +60,7 @@ func ensureLinuxkitImage(name string) error {
|
|||||||
}
|
}
|
||||||
// TODO pass through --pull to here
|
// TODO pass through --pull to here
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
buildInternal(m, buf, false)
|
buildInternal(m, buf, false, nil)
|
||||||
image := buf.Bytes()
|
image := buf.Bytes()
|
||||||
kernel, initrd, cmdline, err := tarToInitrd(image)
|
kernel, initrd, cmdline, err := tarToInitrd(image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
23
examples/README.md
Normal file
23
examples/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
Examples of building an image to run on LinuxKit or on a host
|
||||||
|
|
||||||
|
Currently the `moby` tool can output formats suitable for LinuxKit to boot on
|
||||||
|
a VM, and also some formats for running natively.
|
||||||
|
|
||||||
|
The `docker` format adds a `Dockerfile` to the tarball and expects a similar
|
||||||
|
file structure to `LinuxKit` but with the low level system setup pieces removed
|
||||||
|
as this will already be set up in a container.
|
||||||
|
|
||||||
|
The `mobytest/init-container` image in this repository has an example setup that
|
||||||
|
initialises `containerd` in exactly the same way as it runs in LinuxKit, which will
|
||||||
|
then start the `onboot` and `service` containers. The example below shows how you
|
||||||
|
can run `nginx` on either of these base configs.
|
||||||
|
|
||||||
|
```
|
||||||
|
moby build -output docker -o - docker.yml nginx.yml | docker build -t dockertest -
|
||||||
|
docker run -d -p 80:80 --privileged dockertest
|
||||||
|
|
||||||
|
moby build -output kernel+initrd linuxkit.yml nginx.yml
|
||||||
|
linuxkit run nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
Both of these will run the same `nginx` either in a VM or a container.
|
9
examples/docker.yml
Normal file
9
examples/docker.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
init:
|
||||||
|
- mobytest/init-container:b5de246b2790d74d53bae583a95c87869ca003e6
|
||||||
|
- linuxkit/runc:3a4e6cbf15470f62501b019b55e1caac5ee7689f
|
||||||
|
- linuxkit/containerd:5749f2e9e65395cc6635229e8da0e0d484320ddf
|
||||||
|
- linuxkit/ca-certificates:75cf419fb58770884c3464eb687ec8dfc704169d
|
||||||
|
trust:
|
||||||
|
org:
|
||||||
|
- linuxkit
|
||||||
|
- mobytest
|
18
examples/linuxkit.yml
Normal file
18
examples/linuxkit.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
kernel:
|
||||||
|
image: "linuxkit/kernel:4.9.x"
|
||||||
|
cmdline: "console=ttyS0"
|
||||||
|
init:
|
||||||
|
- linuxkit/init:1b8a7e394d2ec2f1fdb4d67645829d1b5bdca037
|
||||||
|
- linuxkit/runc:3a4e6cbf15470f62501b019b55e1caac5ee7689f
|
||||||
|
- linuxkit/containerd:5749f2e9e65395cc6635229e8da0e0d484320ddf
|
||||||
|
- linuxkit/ca-certificates:75cf419fb58770884c3464eb687ec8dfc704169d
|
||||||
|
onboot:
|
||||||
|
- name: dhcpcd
|
||||||
|
image: "linuxkit/dhcpcd:7d2b8aaaf20c24ad7d11a5ea2ea5b4a80dc966f1"
|
||||||
|
command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
|
||||||
|
services:
|
||||||
|
- name: rngd
|
||||||
|
image: "linuxkit/rngd:1fa4de44c961bb5075647181891a3e7e7ba51c31"
|
||||||
|
trust:
|
||||||
|
org:
|
||||||
|
- linuxkit
|
12
examples/nginx.yml
Normal file
12
examples/nginx.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
services:
|
||||||
|
- name: nginx
|
||||||
|
image: "nginx:alpine"
|
||||||
|
capabilities:
|
||||||
|
- CAP_NET_BIND_SERVICE
|
||||||
|
- CAP_CHOWN
|
||||||
|
- CAP_SETUID
|
||||||
|
- CAP_SETGID
|
||||||
|
- CAP_DAC_OVERRIDE
|
||||||
|
trust:
|
||||||
|
org:
|
||||||
|
- library
|
14
pkg/init-container/Dockerfile
Normal file
14
pkg/init-container/Dockerfile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
FROM linuxkit/alpine:630ee558e4869672fae230c78364e367b8ea67a9 AS mirror
|
||||||
|
RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/
|
||||||
|
RUN apk add --no-cache --initdb -p /out alpine-baselayout busybox musl tini
|
||||||
|
|
||||||
|
# Remove apk residuals. We have a read-only rootfs, so apk is of no use.
|
||||||
|
RUN rm -rf /out/etc/apk /out/lib/apk /out/var/cache
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
ENTRYPOINT []
|
||||||
|
CMD []
|
||||||
|
WORKDIR /
|
||||||
|
COPY --from=mirror /out/ /
|
||||||
|
COPY etc etc/
|
||||||
|
COPY bin bin/
|
15
pkg/init-container/Makefile
Normal file
15
pkg/init-container/Makefile
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.PHONY: tag push
|
||||||
|
default: push
|
||||||
|
|
||||||
|
ORG?=mobytest
|
||||||
|
IMAGE=init-container
|
||||||
|
DEPS=Dockerfile $(wildcard etc/init.d/*) $(wildcard bin/*)
|
||||||
|
|
||||||
|
HASH?=$(shell git ls-tree HEAD -- ../$(notdir $(CURDIR)) | awk '{print $$3}')
|
||||||
|
|
||||||
|
tag: $(DEPS)
|
||||||
|
docker build --no-cache --network=none -t $(ORG)/$(IMAGE):$(HASH) .
|
||||||
|
|
||||||
|
push: tag
|
||||||
|
DOCKER_CONTENT_TRUST=1 docker pull $(ORG)/$(IMAGE):$(HASH) || \
|
||||||
|
DOCKER_CONTENT_TRUST=1 docker push $(ORG)/$(IMAGE):$(HASH)
|
10
pkg/init-container/bin/rc.init
Executable file
10
pkg/init-container/bin/rc.init
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# execute other init processes
|
||||||
|
INITS="$(find /etc/init.d -type f | sort)"
|
||||||
|
for f in $INITS
|
||||||
|
do
|
||||||
|
$f &
|
||||||
|
done
|
||||||
|
|
||||||
|
wait
|
46
pkg/init-container/etc/init.d/010-containerd
Executable file
46
pkg/init-container/etc/init.d/010-containerd
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# set global ulimits TODO move to /etc/limits.conf
|
||||||
|
ulimit -n 1048576
|
||||||
|
ulimit -p unlimited
|
||||||
|
|
||||||
|
# bring up containerd
|
||||||
|
printf "\nStarting containerd\n"
|
||||||
|
/usr/bin/containerd &
|
||||||
|
|
||||||
|
# wait for socket to be there
|
||||||
|
while [ ! -S /run/containerd/containerd.sock ]
|
||||||
|
do
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
|
||||||
|
# start onboot containers, run to completion
|
||||||
|
|
||||||
|
if [ -d /containers/onboot ]
|
||||||
|
then
|
||||||
|
for f in $(find /containers/onboot -mindepth 1 -maxdepth 1 | sort)
|
||||||
|
do
|
||||||
|
base="$(basename $f)"
|
||||||
|
#/bin/mount --bind "$f/rootfs" "$f/rootfs"
|
||||||
|
#mount -o remount,rw "$f/rootfs"
|
||||||
|
/usr/bin/runc run --bundle "$f" "$(basename $f)"
|
||||||
|
printf " - $base\n"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# start service containers
|
||||||
|
|
||||||
|
if [ -d /containers/services ]
|
||||||
|
then
|
||||||
|
for f in $(find /containers/services -mindepth 1 -maxdepth 1 | sort)
|
||||||
|
do
|
||||||
|
base="$(basename $f)"
|
||||||
|
#/bin/mount --bind "$f/rootfs" "$f/rootfs"
|
||||||
|
#mount -o remount,rw "$f/rootfs"
|
||||||
|
log="/var/log/$base.log"
|
||||||
|
ctr run --runtime-config "$f/config.json" --rootfs "$f/rootfs" --id "$(basename $f)" </dev/null 2>$log >$log &
|
||||||
|
printf " - $base\n"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
wait
|
Loading…
Reference in New Issue
Block a user