---
# System prepended metadata

title: Docker and K3S in RISCV

---

# Docker and K3S in RISCV

This texts explains the necessary steps to install docker in devices using the RISC-V architecture. The texts is based in the tutorial from the following [link](https://github.com/carlosedp/riscv-bringup/blob/master/build-docker-env.md).

# Installing golang
You can compile your own version of golang, however I have provided an already tarball with the latest version of go 1.20

With the tarball run the following

```bash
# Extract files
tar -xjf go-linux-riscv64-bootstrap.tbz
# Copy files to /usr/local
cp -r go-linux-riscv64-bootstrap /usr/local/go
# Add golang binaries to PATH
echo "export PATH=/usr/local/go/bin:$PATH" >> ~/.bashrc
echo "export PATH=/root/go/bin/:$PATH" >> ~/.bashrc
echo "export GOPATH=$HOME/go" >> ~/.bashrc
# Source bash so you now have access to golang
source ~/.bashrc
```
# Recommended dependencies
To install docker you may need the following dependencies.
```bash
sudo apt sudo libdevmapper-dev install git python3 yamllint python3-dev pkgconf libtool libsystemd-dev libcap-dev libyajl-dev libselinux1-dev go-md2man libtool gperf make pkg-config libseccomp2 libseccomp-dev cmake
```

# Installing Docker requirements
As following the tutorial create a directory to clone and compile all the dependencies
```bash
mkdir -p $HOME/riscv-docker
cd $HOME/riscv-docker
mkdir -p $HOME/riscv-docker/debs
```

## libsecccomp

If your distro does not have the libseccomp package in their respositories you can install it from source as follows:
```bash
git clone git://github.com/seccomp/libseccomp
pushd libseccomp
./autogen.sh && ./configure
make
sudo make install
popd
```

## crun
In my case I did not managed to install runc so I opted for the version crun which is a pure C based runtime that is OCI compliant.
```bash
git clone https://github.com/giuseppe/crun
pushd crun
./autogen.sh
./configure
make
make install
 ln -s /usr/local/bin/crun /usr/local/bin/runc
popd
```

## containerd
```bash
git clone https://github.com/containerd/containerd
pushd containerd
make BUILDTAGS="no_btrfs"
make install
popd
```

## docker-cli
To install docker-cli, I have modified some of the steps since I was having some trouble setting up the go docker directory.
```bash
mkdir -p $GOPATH/src/github.com/docker/
git clone https://github.com/docker/cli
ln -s /root/riscv-docker/debs/cli/ /root/go/src/github.com/docker/cli
pushd cli
DISABLE_WARN_OUTSIDE_CONTAINER=1 GO111MODULE=off make
sudo cp ./build/docker-linux-riscv64 /usr/local/bin
sudo ln -sf /usr/local/bin/docker-linux-riscv64 /usr/local/bin/docker
popd
```

## docker-init
```bash
git clone https://github.com/krallin/tini
pushd tini
export CFLAGS="-DPR_SET_CHILD_SUBREAPER=36 -DPR_GET_CHILD_SUBREAPER=37"
cmake . && make
sudo cp tini-static /usr/local/bin/docker-init
popd
```

## docker-proxy and dockerd
Moby repo already creates the dockerd and docker-proxy binaries which are handled in different steps in the original tutorial.
```bash
git clone https://github.com/moby/moby
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
mkdir -p $HOME/go/src/github.com/ishidawataru/ && cd $HOME/go/src/github.com/ishidawataru/ && git clone https://github.com/ishidawataru/sctp
ln -s $HOME/riscv-docker/debs/moby $HOME/go/src/github.com/docker/docker
pushd moby
sudo cp ./contrib/dockerd-rootless.sh /usr/local/bin
./hack/make.sh binary
sudo cp bundles/binary-daemon/dockerd /usr/local/bin/.
sudo cp bundles/binary-daemon/docker-proxy /usr/local/bin/.
end moby
```

## rootlesskit
```bash
git clone https://github.com/rootless-containers/rootlesskit.git
pushd rootlesskit
make
make install
popd rootlesskit
```

# Enabling docker services

## Containerd service
To create the service
```bash
cat << EOF | sudo tee -a /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd
KillMode=process
Delegate=yes
LimitNOFILE=1048576
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity

[Install]
WantedBy=multi-user.target
EOF
```

To launch and enable the service
```bash
sudo systemctl start containerd
sudo systemctl enable containerd
# If you want to check the logs
sudo journalct -u containerd -f
```
## Docker service
To create the service. There is a modification from the original tutorial, since the containerd socket didn't work in my case.
```bash
cat << EOF | sudo tee -a /etc/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service containerd.service
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/local/bin/dockerd -H unix:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3

# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s

# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this option.
TasksMax=infinity

# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes

# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target
EOF
```
To launch and enable the service
```bash
sudo systemctl start docker
sudo systemctl enable docker
# If you want to check the logs
sudo journalct -u docker -f
```

## Running docker
To check that docker is already running you can run the following command ```sudo docker run hello-world``` which should return something like:

