Skip to content

Commit 962aff3

Browse files
committed
doc: Rootless lazy pulling with Podman, nerdctl and BuildKit
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
1 parent 6844dbb commit 962aff3

9 files changed

+232
-0
lines changed

.github/workflows/tests.yml

+10
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ jobs:
166166
METADATA_STORE: ${{ matrix.metadata-store }}
167167
run: make test-cri-o
168168

169+
test-podman:
170+
runs-on: ubuntu-18.04
171+
name: PodmanRootless
172+
steps:
173+
- uses: actions/checkout@v3
174+
- name: Test Podman (rootless)
175+
env:
176+
DOCKER_BUILD_ARGS: "--build-arg=RUNC_VERSION=v1.0.3"
177+
run: make test-podman
178+
169179
test-k3s:
170180
runs-on: ubuntu-22.04
171181
name: K3S

Dockerfile

+33
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ ARG CONMON_VERSION=v2.1.5
2323
ARG COMMON_VERSION=v0.49.2
2424
ARG CRIO_TEST_PAUSE_IMAGE_NAME=registry.k8s.io/pause:3.6
2525

26+
ARG CONTAINERIZED_SYSTEMD_VERSION=v0.1.1
27+
ARG SLIRP4NETNS_VERSION=v1.1.12
28+
2629
# Used in CI
2730
ARG CRI_TOOLS_VERSION=v1.25.0
2831

@@ -183,6 +186,36 @@ COPY --from=conmon-dev /out/bin/* /usr/local/bin/
183186
COPY --from=containers-common-dev /out/seccomp.json /usr/share/containers/
184187
COPY --from=stargz-store-dev /out/* /usr/local/bin/
185188

189+
# Image for testing rootless Podman with Stargz Store.
190+
# This takes the same approach as nerdctl CI: https://github.com/containerd/nerdctl/blob/6341c8320984f7148b92dd33472d8eaca6dba756/Dockerfile#L302-L326
191+
FROM podman-base AS podman-rootless
192+
ARG CONTAINERIZED_SYSTEMD_VERSION
193+
ARG SLIRP4NETNS_VERSION
194+
RUN apt-get update -y && apt-get install -y \
195+
systemd systemd-sysv dbus dbus-user-session \
196+
openssh-server openssh-client uidmap
197+
RUN curl -o /usr/local/bin/slirp4netns --fail -L https://github.com/rootless-containers/slirp4netns/releases/download/${SLIRP4NETNS_VERSION}/slirp4netns-$(uname -m) && \
198+
chmod +x /usr/local/bin/slirp4netns && \
199+
curl -L -o /docker-entrypoint.sh https://raw.githubusercontent.com/AkihiroSuda/containerized-systemd/${CONTAINERIZED_SYSTEMD_VERSION}/docker-entrypoint.sh && \
200+
chmod +x /docker-entrypoint.sh && \
201+
curl -L -o /etc/containers/policy.json https://raw.githubusercontent.com/containers/skopeo/master/default-policy.json
202+
# storage.conf plugs Stargz Store into Podman as an Additional Layer Store
203+
COPY ./script/podman/config/storage.conf /home/rootless/.config/containers/storage.conf
204+
# Stargz Store systemd service for rootless Podman
205+
COPY ./script/podman/config/podman-rootless-stargz-store.service /home/rootless/.config/systemd/user/
206+
# test-podman-rootless.sh logins to the user via SSH
207+
COPY ./script/podman/config/test-podman-rootless.sh /test-podman-rootless.sh
208+
RUN ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N '' && \
209+
useradd -m -s /bin/bash rootless && \
210+
mkdir -p -m 0700 /home/rootless/.ssh && \
211+
cp -a /root/.ssh/id_rsa.pub /home/rootless/.ssh/authorized_keys && \
212+
mkdir -p /home/rootless/.local/share /home/rootless/.local/share/stargz-store/store && \
213+
chown -R rootless:rootless /home/rootless
214+
VOLUME /home/rootless/.local/share
215+
216+
ENTRYPOINT ["/docker-entrypoint.sh", "/test-podman-rootless.sh"]
217+
CMD ["/bin/bash", "--login", "-i"]
218+
186219
# Image which can be used for interactive demo environment
187220
FROM containerd-base AS demo
188221
ARG CNI_PLUGINS_VERSION

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ test-cri-containerd:
108108
test-cri-o:
109109
@./script/cri-o/test.sh
110110

111+
test-podman:
112+
@./script/podman/test.sh
113+
111114
test-criauth:
112115
@./script/criauth/test.sh
113116

docs/rootless.md

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Rootless execution of stargz snapshotter
2+
3+
This document lists links and information about how to run Stargz Snapshotter and Stargz Store from the non-root user.
4+
5+
## nerdctl (Stargz Snapshotter)
6+
7+
Rootless Stargz Snapshotter for nerdctl can be installed via `containerd-rootless-setuptool.sh install-stargz` command.
8+
Please see [the doc in nerdctl repo](https://github.com/containerd/nerdctl/blob/v1.1.0/docs/rootless.md#stargz-snapshotter) for details.
9+
10+
## Podman (Stargz Store)
11+
12+
> NOTE: This is an experimental configuration leveraging [`podman unshare`](https://docs.podman.io/en/latest/markdown/podman-unshare.1.html). Limitation: `--uidmap` of `podman run` doesn't work.
13+
14+
First, allow podman using Stargz Store by adding the following store configuration.
15+
Put the configuration file to [`/etc/containers/storage.conf` or `$HOME/.config/containers/storage.conf`](https://github.com/containers/podman/blob/v4.3.1/docs/tutorials/rootless_tutorial.md#storageconf).
16+
17+
> NOTE: Replace `/path/to/home` to the actual home directory.
18+
19+
```
20+
[storage]
21+
driver = "overlay"
22+
23+
[storage.options]
24+
additionallayerstores = ["/path/to/homedir/.local/share/stargz-store/store:ref"]
25+
```
26+
27+
Start Stargz Store in the namespace managed by podman via [`podman unshare`](https://docs.podman.io/en/latest/markdown/podman-unshare.1.html) command.
28+
29+
```
30+
$ podman unshare stargz-store --root $HOME/.local/share/stargz-store/data $HOME/.local/share/stargz-store/store &
31+
```
32+
33+
Podman performs lazy pulling when it pulls eStargz images.
34+
35+
```
36+
$ podman pull ghcr.io/stargz-containers/python:3.9-esgz
37+
```
38+
39+
<details>
40+
<summary>Creating systemd unit file for Stargz Store</summary>
41+
42+
It's possible to create systemd unit file of Stargz Store for easily managing it.
43+
An example systemd unit file can be found [here](../script/podman/config/podman-rootless-stargz-store.service)
44+
45+
After installing that file (e.g. to `$HOME/.config/systemd/user/`), start the service using `systemctl`.
46+
47+
```
48+
$ systemctl --user start podman-rootless-stargz-store
49+
```
50+
51+
</details>
52+
53+
## BuildKit (Stargz Snapshotter)
54+
55+
BuildKit supports running Stargz Snapshotter from the non-root user.
56+
Please see [the doc in BuildKit repo](https://github.com/moby/buildkit/blob/8b132188aa7af944c813d02da63c93308d83cf75/docs/stargz-estargz.md) (unmerged 2023/1/18) for details.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[Unit]
2+
Description=Stargz Store service for Podman
3+
4+
[Service]
5+
# This pipes stargz-store's IO to the shell otherwise they are lost and can't be managed by systemd.
6+
# TODO: fix this and do not use pipe
7+
ExecStart=/bin/bash -c "podman unshare stargz-store --log-level=debug --root %h/.local/share/stargz-store/data %h/.local/share/stargz-store/store 2>&1 | cat"
8+
ExecStopPost=podman unshare umount %h/.local/share/stargz-store/store
9+
10+
[Install]
11+
WantedBy=default.target

script/podman/config/storage.conf

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[storage]
2+
driver = "overlay"
3+
[storage.options]
4+
additionallayerstores = ["/home/rootless/.local/share/stargz-store/store:ref"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
3+
# Copyright The containerd Authors.
4+
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -eux -o pipefail
18+
if [[ "$(id -u)" = "0" ]]; then
19+
# Switch to the rootless user via SSH; This is the same approach as done in nerdctl CI
20+
systemctl start sshd
21+
exec ssh -o StrictHostKeyChecking=no rootless@localhost "$0" "$@"
22+
else
23+
systemctl --user start podman-rootless-stargz-store
24+
exec "$@"
25+
fi

script/podman/run_test.sh

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/bash
2+
3+
# Copyright The containerd Authors.
4+
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -euo pipefail
18+
19+
STARGZ_STORE_SERVICE=podman-rootless-stargz-store
20+
21+
# Lazy pulling and run
22+
podman pull ghcr.io/stargz-containers/alpine:3.10.2-esgz
23+
podman run --rm ghcr.io/stargz-containers/alpine:3.10.2-esgz echo hello
24+
25+
# Run (includes lazy pulling)
26+
podman run --rm ghcr.io/stargz-containers/python:3.9-esgz echo hello
27+
28+
# Print store log to be checked by the host
29+
LOG_REMOTE_SNAPSHOT="remote-snapshot-prepared"
30+
journalctl --user -u "${STARGZ_STORE_SERVICE}" | grep "${LOG_REMOTE_SNAPSHOT}"
31+
32+
# Non-lazy pulling
33+
podman run --rm ghcr.io/stargz-containers/ubuntu:22.04-org echo hello
34+
35+
systemctl --user stop "${STARGZ_STORE_SERVICE}"

script/podman/test.sh

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
3+
# Copyright The containerd Authors.
4+
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -euo pipefail
18+
19+
CONTEXT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/"
20+
REPO="${CONTEXT}../../"
21+
22+
source "${REPO}/script/util/utils.sh"
23+
24+
NODE_IMAGE_NAME_BASE=test-podman-rootless-node-base
25+
NODE_IMAGE_NAME=test-podman-rootless-node
26+
27+
if [ "${PODMAN_NO_RECREATE:-}" != "true" ] ; then
28+
echo "Preparing node image..."
29+
docker build ${DOCKER_BUILD_ARGS:-} --progress=plain -t "${NODE_IMAGE_NAME_BASE}" --target podman-rootless "${REPO}"
30+
fi
31+
32+
TEST_LOG=$(mktemp)
33+
STORE_LOG=$(mktemp)
34+
TMP_CONTEXT=$(mktemp -d)
35+
function cleanup {
36+
local ORG_EXIT_CODE="${1}"
37+
rm -rf "${TMP_CONTEXT}" || true
38+
rm "${TEST_LOG}" || true
39+
rm "${STORE_LOG}" || true
40+
exit "${ORG_EXIT_CODE}"
41+
}
42+
trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM
43+
44+
cp "${CONTEXT}/run_test.sh" "${TMP_CONTEXT}/run_test.sh"
45+
cat <<EOF > "${TMP_CONTEXT}/Dockerfile"
46+
FROM ${NODE_IMAGE_NAME_BASE}
47+
48+
COPY run_test.sh /run_test.sh
49+
CMD ["/bin/bash", "--login", "/run_test.sh"]
50+
EOF
51+
52+
docker build ${DOCKER_BUILD_ARGS:-} --progress=plain -t "${NODE_IMAGE_NAME}" "${TMP_CONTEXT}"
53+
docker run -t --rm --privileged "${NODE_IMAGE_NAME}" | tee "${TEST_LOG}"
54+
cat "${TEST_LOG}" | grep "${LOG_REMOTE_SNAPSHOT}" | sed -E 's/^[^\{]*(\{.*)$/\1/g' > "${STORE_LOG}"
55+
check_remote_snapshots "${STORE_LOG}"

0 commit comments

Comments
 (0)