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

Enable image distribution on IPFS #505

Merged
merged 1 commit into from
Nov 17, 2021
Merged

Conversation

ktock
Copy link
Member

@ktock ktock commented Nov 9, 2021

#465

This commit enables image distribution on IPFS when ipfs:// prefix is specified before the image name.
(ipfs daemon needs running)

push: pushes the specified image to IPFS

The following example pushes ubuntu:20.04 (pulled from DockerHub with nerdctl pull ubuntu:20.04 in advance) to IPFS

# nerdctl push ipfs://ubuntu:20.04
INFO[0000] pushing image "ubuntu:20.04" to IPFS         
INFO[0000] ensuring image contents                      
INFO[0005] converted "application/vnd.docker.image.rootfs.diff.tar.gzip" to sha256:3645595d053b17b1910effafdcc6d924ff0f915b25ce81a07f76a7b0bb22c964 
bafkreigrkfhzm5bt5xbb7tvrnwzrkvulgipwupc4w24kwudysexmwzyske

pull: pulls the specified image from IFPS

# nerdctl pull ipfs://bafkreigrkfhzm5bt5xbb7tvrnwzrkvulgipwupc4w24kwudysexmwzyske
bafkreigrkfhzm5bt5xbb7tvrnwzrkvulgipwupc4w24kwudysexmwzyske:                      resolved       |++++++++++++++++++++++++++++++++++++++| 
index-sha256:cfbf2274a7499e2ccf1738793396cce136576786415d4f3da20e500491c21e95:    done           |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:78ef4cff96127a9c9302508ab8116d692e68f863f43598c00aa202ed216d961c: done           |++++++++++++++++++++++++++++++++++++++| 
config-sha256:92978473846792f54f088079a8be7b26ab384e08271a3c6b2ca699f75c6a0b25:   done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:3645595d053b17b1910effafdcc6d924ff0f915b25ce81a07f76a7b0bb22c964:    done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 1.2 s                                                                    total:  29.0 M (24.2 MiB/s)                                      

run:

# nerdctl run --rm -it ipfs://bafkreigrkfhzm5bt5xbb7tvrnwzrkvulgipwupc4w24kwudysexmwzyske echo hello
hello

compose:

# mkdir /tmp/proj
# cat <<EOF > /tmp/proj/docker-compose.yml
version: "3.4"
services:
  ubuntu:
    image: ipfs://bafkreigrkfhzm5bt5xbb7tvrnwzrkvulgipwupc4w24kwudysexmwzyske
    command: echo hello
EOF
# nerdctl compose up -f /tmp/proj/docker-compose.yml
INFO[0001] Creating container proj_ubuntu_1             
INFO[0000] No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: [nameserver 8.8.8.8 nameserver 8.8.4.4] 
INFO[0000] IPv6 enabled; Adding default IPv6 external servers: [nameserver 2001:4860:4860::8888 nameserver 2001:4860:4860::8844] 
INFO[0001] Attaching to logs                            
ubuntu_1 |hello
INFO[0001] Container "proj_ubuntu_1" exited             
INFO[0001] All the containers have exited               
INFO[0001] Stopping containers (forcibly)               
INFO[0001] Stopping container proj_ubuntu_1             

encryption (needs to disable estargz conversoin):

# nerdctl pull ghcr.io/stargz-containers/ubuntu:20.04-org
# nerdctl image encrypt --recipient=jwe:/tmp/mypubkey.pem --platform=linux/amd64 ghcr.io/stargz-containers/ubuntu:20.04-org ghcr.io/stargz-containers/ubuntu:20.04-org-enc
sha256:524694948a388c3116478bbbe86c2934a158f51a1d9b6d28459ac9a5fa573e91
# nerdctl push --ipfs-no-estargz ipfs://ghcr.io/stargz-containers/ubuntu:20.04-org-enc
INFO[0000] pushing image "ghcr.io/stargz-containers/ubuntu:20.04-org-enc" to IPFS 
INFO[0000] ensuring image contents                      
bafkreid4rpdokddpdxkjplmbgijyilmdneqzl3vpxzgpsq4764d5rrm4qq
# nerdctl run --rm -it ipfs://bafkreid4rpdokddpdxkjplmbgijyilmdneqzl3vpxzgpsq4764d5rrm4qq echo hello
FATA[0000] failed to extract layer sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439: failed to get stream processor for application/vnd.oci.image.layer.v1.tar+gzip+encrypted: exec: "ctd-decoder": executable file not found in $PATH: unknown 
# nerdctl pull --unpack=false ipfs://bafkreid4rpdokddpdxkjplmbgijyilmdneqzl3vpxzgpsq4764d5rrm4qq echo hello
# nerdctl image decrypt --key=/tmp/mykey.pem ipfs://bafkreid4rpdokddpdxkjplmbgijyilmdneqzl3vpxzgpsq4764d5rrm4qq ubuntu:decrypted
sha256:2aa04b1e79ab1ca8af57a5bf67649871cb5fb6118e9cb07660cd6f1f435c5f80
# nerdctl run --rm -it ubuntu:decrypted echo hello
INFO[0000] No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: [nameserver 8.8.8.8 nameserver 8.8.4.4] 
INFO[0000] IPv6 enabled; Adding default IPv6 external servers: [nameserver 2001:4860:4860::8888 nameserver 2001:4860:4860::8844] 
hello

This commit also adds nerdctl ipfs push and nerdctl ipfs pull subcommands as the low-level CLI can be used for debugging.

Lazy pulling with stagz snapshotter (doc) is enabled when --snapshotter=stargz is specified.

@AkihiroSuda AkihiroSuda added this to the v0.14.0 milestone Nov 9, 2021
@AkihiroSuda AkihiroSuda added enhancement New feature or request impact/major labels Nov 9, 2021
ipfsPullCommand.PersistentFlags().Bool("all-platforms", false, "Pull content for all platforms")
// #endregion

ipfsPullCommand.PersistentFlags().String("scheme", "ipfs", "Scheme to pull the CID (\"ipfs\" or \"ipns\")")
Copy link
Member

Choose a reason for hiding this comment

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

nit: register flag completion func


func newIPFSPullCommand() *cobra.Command {
var ipfsPullCommand = &cobra.Command{
Use: "pull",
Copy link
Member

Choose a reason for hiding this comment

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

Explain argument

ipfsPushCommand.PersistentFlags().Bool("all-platforms", false, "Push content for all platforms")
// #endregion

ipfsPushCommand.PersistentFlags().Bool("estargz", true, "Convert the image into eStargz")
Copy link
Member

Choose a reason for hiding this comment

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

If we want --estargz flag here, we should add that to the regular nerdctl image push too, and deduplicate the code across nerdctl image push and nerdctl ipfs push.
(But do we really need nerdctl ipfs * commands?)

echo "ipfs = true" > ${HOME}/.config/containerd-stargz-grpc/config.toml
systemctl --user restart stargz-snapshotter.service
sleep 3
fi
Copy link
Member

Choose a reason for hiding this comment

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

The logic looks too much complicated.

Maybe we should just run IPFS as a systemd service?

Copy link
Member Author

Choose a reason for hiding this comment

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

Rootless nerdctl (inside rootlesskit network namespace) can't access to IPFS daemon API (127.0.0.1:5001) on the host?

Copy link
Member

Choose a reason for hiding this comment

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

Right. I thought we could just use a public IP.

Copy link
Member

Choose a reason for hiding this comment

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

Wondering we should have containerd-rootless-setuptool.sh install-ipfs to run IPFS daemon in the netns

usage() {
echo "Usage: ${ARG0} [OPTIONS] COMMAND"
echo
echo "A setup tool for Rootless containerd (${CONTAINERD_ROOTLESS_SH})."
echo
echo "Commands:"
echo " check Check prerequisites"
echo " nsenter Enter into RootlessKit namespaces (mostly for debugging)"
echo " install Install systemd unit and show how to manage the service"
echo " uninstall Uninstall systemd unit"
echo
echo "Add-on commands (BuildKit):"
echo " install-buildkit Install the systemd unit for BuildKit"
echo " uninstall-buildkit Uninstall the systemd unit for BuildKit"
echo
echo "Add-on commands (fuse-overlayfs):"
echo " install-fuse-overlayfs Install the systemd unit for fuse-overlayfs snapshotter"
echo " uninstall-fuse-overlayfs Uninstall the systemd unit for fuse-overlayfs snapshotter"
echo
echo "Add-on commands (stargz):"
echo " install-stargz Install the systemd unit for stargz snapshotter"
echo " uninstall-stargz Uninstall the systemd unit for stargz snapshotter"
}

Copy link
Member Author

Choose a reason for hiding this comment

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

SGTM

testutil.DockerIncompatible(t)
base := testutil.NewBase(t)
requiresStargz(base)
base.Env = append(os.Environ(), "CONTAINERD_SNAPSHOTTER=stargz")
Copy link
Member

Choose a reason for hiding this comment

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

We should test this for overlayfs as well

@@ -47,6 +58,11 @@ func newPushCommand() *cobra.Command {
pushCommand.Flags().Bool("all-platforms", false, "Push content for all platforms")
// #endregion

pushCommand.PersistentFlags().Bool("estargz", false, "Convert the image into eStargz (always true in IPFS mode)")
Copy link
Member

Choose a reason for hiding this comment

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

Not sure why this has to be always true in IPFS mode.

pushCommand.PersistentFlags().Bool("estargz", false, "Convert the image into eStargz (always true in IPFS mode)")

pushCommand.PersistentFlags().Bool("ipfs-no-estargz", false, "Disable conversion of the image into eStargz in IPFS mode")
pushCommand.PersistentFlags().Bool("ipfs-ensure-image", true, "Ensure the IPFS image is fully pulled to containerd")
Copy link
Member

Choose a reason for hiding this comment

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

s/pulled/pushed/ (?)

@ktock ktock force-pushed the ipfs branch 2 times, most recently from e83b542 to 5dee562 Compare November 16, 2021 05:35
@ktock
Copy link
Member Author

ktock commented Nov 16, 2021

CI seems to be cancelled?

Error: The operation was canceled.

@ktock ktock force-pushed the ipfs branch 2 times, most recently from e2d5a58 to 5eacb67 Compare November 16, 2021 09:30
@ktock ktock marked this pull request as ready for review November 16, 2021 09:30
go.mod Outdated
github.com/mattn/go-isatty v0.0.14
github.com/moby/sys/mount v0.2.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.2-0.20211102003311-9a7a9876500e
github.com/opencontainers/runtime-spec v1.0.3-0.20211101234015-a3c33d663ebc
github.com/pkg/errors v0.9.1
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't be needed

docs/ipfs.md Outdated
bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4
```

You can pull the encrypted image from IPFS using `ipfs://` prefix and can decrypt it in the same way as described in [`/docs/ocycrypt.md`](/docs/ocicrypt.md).
Copy link
Member

Choose a reason for hiding this comment

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

/docs/ -> ./

docs/ipfs.md Outdated
hello
```

:information_source: Note that though the IPFS-enabled image is OCI compatible, some runtimes including [containerd](https://github.com/containerd/containerd/pull/6221) and [podman](https://github.com/containers/image/pull/1403)) had bugs and failed to pull that image. Containerd has already fixed this.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
:information_source: Note that though the IPFS-enabled image is OCI compatible, some runtimes including [containerd](https://github.com/containerd/containerd/pull/6221) and [podman](https://github.com/containers/image/pull/1403)) had bugs and failed to pull that image. Containerd has already fixed this.
:information_source: Note that though the IPFS-enabled image is OCI compatible, some runtimes including [containerd](https://github.com/containerd/containerd/pull/6221) and [podman](https://github.com/containers/image/pull/1403) had bugs and failed to pull that image. Containerd has already fixed this.

@AkihiroSuda
Copy link
Member

Looks good but a couple of nits.
This is awesome 👍

@AkihiroSuda
Copy link
Member

Probably now we have to increase the CI timeout

timeout-minutes: 20

@ktock
Copy link
Member Author

ktock commented Nov 16, 2021

Probably now we have to increase the CI timeout

I'll fix it in this PR.

@ktock ktock force-pushed the ipfs branch 2 times, most recently from e085893 to fdc5335 Compare November 17, 2021 01:05
docs/ipfs.md Outdated Show resolved Hide resolved
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

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

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/ipfs IPFS enhancement New feature or request impact/major
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants