@@ -28,33 +28,293 @@ import (
2828const containerdTemplate = `
2929: ${CONTAINERD_VERSION:={{.Version}}}
3030
31+ # Check system requirements
32+ echo "Checking system requirements..."
33+
34+ # Check for systemd
35+ if ! command -v systemctl &> /dev/null; then
36+ echo "Error: systemd is required but not installed"
37+ exit 1
38+ fi
39+
40+ # Check and load required kernel modules
41+ echo "Checking and loading required kernel modules..."
42+ REQUIRED_MODULES="overlay br_netfilter"
43+ for module in $REQUIRED_MODULES; do
44+ if ! lsmod | grep -q "^${module}"; then
45+ echo "Loading ${module} module..."
46+ if ! sudo modprobe ${module}; then
47+ echo "Error: Failed to load ${module} module"
48+ exit 1
49+ fi
50+ fi
51+ done
52+
53+ # Ensure modules are loaded at boot
54+ for module in $REQUIRED_MODULES; do
55+ if [ ! -f "/etc/modules-load.d/${module}.conf" ]; then
56+ echo "${module}" | sudo tee "/etc/modules-load.d/${module}.conf" > /dev/null
57+ fi
58+ done
59+
60+ # Check and configure sysctl settings
61+ echo "Configuring sysctl settings..."
62+ SYSCTL_SETTINGS=(
63+ "net.bridge.bridge-nf-call-iptables=1"
64+ "net.bridge.bridge-nf-call-ip6tables=1"
65+ "net.ipv4.ip_forward=1"
66+ )
67+
68+ for setting in "${SYSCTL_SETTINGS[@]}"; do
69+ key=$(echo $setting | cut -d= -f1)
70+ value=$(echo $setting | cut -d= -f2)
71+ if [ "$(sudo sysctl -n $key)" != "$value" ]; then
72+ echo "Setting $key to $value"
73+ sudo sysctl -w $key=$value
74+ echo "$key=$value" | sudo tee -a /etc/sysctl.conf > /dev/null
75+ fi
76+ done
77+
78+ # Apply sysctl settings
79+ sudo sysctl --system
80+
81+ # Check for required commands
82+ REQUIRED_COMMANDS="curl tar systemctl"
83+ for cmd in $REQUIRED_COMMANDS; do
84+ if ! command -v $cmd &> /dev/null; then
85+ echo "Error: Required command '$cmd' not found"
86+ exit 1
87+ fi
88+ done
89+
3190# Install required packages
91+ echo "Installing required packages..."
3292with_retry 3 10s sudo apt-get update
3393install_packages_with_retry ca-certificates curl gnupg -y
3494sudo install -m 0755 -d /etc/apt/keyrings
35- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
36- sudo chmod a+r /etc/apt/keyrings/docker.gpg
37-
38- # Add the repository to Apt sources:
39- echo \
40- "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
41- "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
42- sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
43- with_retry 3 10s sudo apt-get update
44-
45- # Install containerd
46- install_packages_with_retry containerd.io=${CONTAINERD_VERSION}-1
47-
48- # Configure containerd and start service
49- mkdir -p /etc/containerd
50- containerd config default | sudo tee /etc/containerd/config.toml
51- # Set systemd as the cgroup driver
52- # see https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd
53- sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
54-
55- # restart containerd
56- sudo systemctl restart containerd
57- sudo systemctl enable containerd
95+
96+ # Check if CONTAINERD_VERSION is empty, if so fetch the latest stable version
97+ if [ -z "$CONTAINERD_VERSION" ]; then
98+ echo "Fetching latest stable containerd version..."
99+ CONTAINERD_VERSION=$(curl -fsSL https://api.github.com/repos/containerd/containerd/releases/latest | grep '"tag_name":' | cut -d '"' -f 4 | sed 's/v//')
100+
101+ if [ -z "$CONTAINERD_VERSION" ]; then
102+ echo "Failed to fetch latest Containerd version. Exiting."
103+ exit 1
104+ fi
105+ fi
106+ echo "Using containerd version: $CONTAINERD_VERSION"
107+
108+ # Determine major version for configuration
109+ MAJOR_VERSION=$(echo $CONTAINERD_VERSION | cut -d. -f1)
110+
111+ # Check architecture
112+ ARCH=$(uname -m)
113+ if [[ "$ARCH" == "x86_64" ]]; then
114+ ARCH="amd64"
115+ elif [[ "$ARCH" == "aarch64" ]]; then
116+ ARCH="arm64"
117+ else
118+ echo "Error: Unsupported architecture: $ARCH"
119+ exit 1
120+ fi
121+
122+ CONTAINERD_TAR="containerd-${CONTAINERD_VERSION}-linux-${ARCH}.tar.gz"
123+ CONTAINERD_URL="https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/${CONTAINERD_TAR}"
124+ CONTAINERD_SHA256_URL="${CONTAINERD_URL}.sha256sum"
125+
126+ echo "Downloading and extracting containerd ${CONTAINERD_VERSION} from: $CONTAINERD_URL"
127+
128+ # Create temporary directory for downloads
129+ TMP_DIR=$(mktemp -d)
130+ cd $TMP_DIR
131+
132+ # Download containerd tarball and checksum
133+ if ! curl -fsSL -o ${CONTAINERD_TAR} ${CONTAINERD_URL}; then
134+ echo "Error: Failed to download containerd tarball"
135+ exit 1
136+ fi
137+
138+ if ! curl -fsSL -o containerd_SHA256SUMS ${CONTAINERD_SHA256_URL}; then
139+ echo "Error: Failed to download containerd checksum"
140+ exit 1
141+ fi
142+
143+ # Verify SHA256 checksum
144+ EXPECTED_CHECKSUM=$(cat containerd_SHA256SUMS | awk '{print $1}')
145+ ACTUAL_CHECKSUM=$(sha256sum ${CONTAINERD_TAR} | awk '{print $1}')
146+
147+ if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then
148+ echo "Error: Checksum verification failed for containerd"
149+ echo "Expected: $EXPECTED_CHECKSUM"
150+ echo "Actual: $ACTUAL_CHECKSUM"
151+ exit 1
152+ fi
153+
154+ # Stream directly into tar to avoid saving the archive
155+ if ! cat ${CONTAINERD_TAR} | sudo tar Cxzvf /usr/local -; then
156+ echo "Error: Failed to extract containerd tarball"
157+ exit 1
158+ fi
159+
160+ # Cleanup
161+ cd - > /dev/null
162+ rm -rf $TMP_DIR
163+
164+ echo "Containerd ${CONTAINERD_VERSION} installed successfully."
165+
166+ # Fetch latest stable RUNC version from GitHub
167+ echo "Fetching latest stable runc version..."
168+ RUNC_VERSION=$(curl -fsSL https://api.github.com/repos/opencontainers/runc/releases/latest | grep '"tag_name":' | cut -d '"' -f 4 | sed 's/v//')
169+
170+ if [ -z "$RUNC_VERSION" ]; then
171+ echo "Failed to fetch latest RUNC version. Using default version."
172+ RUNC_VERSION="1.2.6"
173+ fi
174+
175+ RUNC_URL="https://github.com/opencontainers/runc/releases/download/v${RUNC_VERSION}/runc.${ARCH}"
176+
177+ echo "Downloading runc ${RUNC_VERSION} from: $RUNC_URL"
178+
179+ # Download runc binary and checksum
180+ curl -fsSL -o runc.${ARCH} ${RUNC_URL}
181+
182+ sudo install -m 755 runc.${ARCH} /usr/local/sbin/runc
183+
184+ echo "Runc ${RUNC_VERSION} installed successfully."
185+
186+ # Install CNI plugins
187+ CNI_VERSION="1.1.1"
188+ CNI_TAR="cni-plugins-linux-${ARCH}-v${CNI_VERSION}.tgz"
189+ CNI_URL="https://github.com/containernetworking/plugins/releases/download/v${CNI_VERSION}/${CNI_TAR}"
190+
191+ echo "Downloading CNI plugins from: $CNI_URL"
192+
193+ # Download CNI tarball and checksum
194+ curl -fsSL -o ${CNI_TAR} ${CNI_URL}
195+
196+ sudo mkdir -p /opt/cni/bin
197+ sudo tar Cxzvf /opt/cni/bin ${CNI_TAR}
198+
199+ # Configure containerd
200+ sudo mkdir -p /etc/containerd
201+
202+ # Generate base configuration
203+ sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
204+
205+ # Configure based on version
206+ if [ "$MAJOR_VERSION" = "2" ]; then
207+ # Containerd 2.x configuration
208+ cat <<EOF | sudo tee /etc/containerd/config.toml > /dev/null
209+ version = 2
210+ root = "/var/lib/containerd"
211+ state = "/run/containerd"
212+
213+ [grpc]
214+ address = "/run/containerd/containerd.sock"
215+ uid = 0
216+ gid = 0
217+
218+ [plugins]
219+ [plugins."io.containerd.grpc.v1.cri"]
220+ sandbox_image = "registry.k8s.io/pause:3.9"
221+ systemd_cgroup = true
222+ [plugins."io.containerd.grpc.v1.cri".containerd]
223+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
224+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
225+ runtime_type = "io.containerd.runc.v2"
226+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
227+ SystemdCgroup = true
228+ [plugins."io.containerd.grpc.v1.cri".registry]
229+ [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
230+ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
231+ endpoint = ["https://registry-1.docker.io"]
232+ EOF
233+ else
234+ # Containerd 1.x configuration
235+ cat <<EOF | sudo tee /etc/containerd/config.toml > /dev/null
236+ version = 1
237+ root = "/var/lib/containerd"
238+ state = "/run/containerd"
239+
240+ [grpc]
241+ address = "/run/containerd/containerd.sock"
242+ uid = 0
243+ gid = 0
244+
245+ [plugins]
246+ [plugins."io.containerd.grpc.v1.cri"]
247+ sandbox_image = "registry.k8s.io/pause:3.9"
248+ systemd_cgroup = true
249+ [plugins."io.containerd.grpc.v1.cri".containerd]
250+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
251+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
252+ runtime_type = "io.containerd.runtime.v1.linux"
253+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
254+ SystemdCgroup = true
255+ [plugins."io.containerd.grpc.v1.cri".registry]
256+ [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
257+ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
258+ endpoint = ["https://registry-1.docker.io"]
259+ EOF
260+ fi
261+
262+ # Set up systemd service for containerd
263+ sudo curl -fsSL "https://raw.githubusercontent.com/containerd/containerd/main/containerd.service" -o /etc/systemd/system/containerd.service
264+
265+ # Create containerd service directory
266+ sudo mkdir -p /etc/systemd/system/containerd.service.d
267+
268+ # Add custom service configuration
269+ cat <<EOF | sudo tee /etc/systemd/system/containerd.service.d/override.conf > /dev/null
270+ [Service]
271+ ExecStart=
272+ ExecStart=/usr/local/bin/containerd
273+ Restart=always
274+ RestartSec=5
275+ Delegate=yes
276+ KillMode=process
277+ OOMScoreAdjust=-999
278+ LimitNOFILE=1048576
279+ LimitNPROC=infinity
280+ LimitCORE=infinity
281+ TasksMax=infinity
282+ # Ensure socket directory exists with correct permissions
283+ ExecStartPre=/bin/mkdir -p /run/containerd
284+ ExecStartPre=/bin/chmod 711 /run/containerd
285+ EOF
286+
287+ # Reload systemd and start containerd
288+ sudo systemctl daemon-reload
289+ sudo systemctl enable --now containerd
290+
291+ # Wait for containerd to be ready
292+ echo "Waiting for containerd to be ready..."
293+ timeout=60
294+ while ! sudo ctr version &>/dev/null; do
295+ if [ $timeout -le 0 ]; then
296+ echo "Timeout waiting for containerd to be ready"
297+ exit 1
298+ fi
299+ sleep 1
300+ timeout=$((timeout-1))
301+ done
302+
303+ # Ensure socket permissions are correct
304+ sudo chmod 666 /run/containerd/containerd.sock
305+
306+ # Verify installation
307+ echo "Verifying installation..."
308+ containerd --version
309+ runc --version
310+ sudo ctr version
311+
312+ # Test containerd functionality
313+ echo "Testing containerd functionality..."
314+ sudo ctr images pull docker.io/library/hello-world:latest
315+ sudo ctr run --rm docker.io/library/hello-world:latest test
316+
317+ echo "Containerd installation completed successfully!"
58318`
59319
60320type Containerd struct {
0 commit comments