安裝 nerdctl
使用 k3s / k8s 內建使用ctr ,雖然可以透過Docker build 創建容器,但無法使用 需要另外匯出類似這樣,但最後建構完再匯出到ctr 時間太久。
此時可以考慮使用nerdctl,文末提供一鍵安裝腳本會自動偵測cpu架構下載相對應檔案。
#!/bin/bash
set -e
set -o pipefail
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
$CONTAINER_IMAGE=test
docker build -t $CONTAINER_IMAGE
docker save $CONTAINER_IMAGE -o $DIR/test.tar
k3s ctr images import $DIR/test.tar
而nerdctl 在Github 分為兩個版本 精簡/全量主要差異在於如果要建構容器時,建議使用full 版本支持度會更高 ,不用再去安裝其他擴展。

一鍵安裝shell指令
#!/bin/bash
# nerdctl-full 自動安裝腳本
# 自動檢測系統架構並下載對應版本
set -e
# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日誌函數
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 檢測系統架構
detect_arch() {
local arch=$(uname -m)
case $arch in
x86_64)
echo "amd64"
;;
aarch64|arm64)
echo "arm64"
;;
armv7l)
echo "arm-v7"
;;
*)
log_error "不支持的架構: $arch"
exit 1
;;
esac
}
# 檢測操作系統
detect_os() {
local os=$(uname -s | tr '[:upper:]' '[:lower:]')
case $os in
linux)
echo "linux"
;;
darwin)
log_error "macOS 不支持 nerdctl-full,請使用 brew 或其他方式安裝"
exit 1
;;
*)
log_error "不支持的操作系統: $os"
exit 1
;;
esac
}
# 獲取最新版本號
get_latest_version() {
log_info "獲取最新版本信息..."
local version=$(curl -s https://api.github.com/repos/containerd/nerdctl/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
if [ -z "$version" ]; then
log_error "無法獲取最新版本信息"
exit 1
fi
echo $version
}
# 下載文件
download_file() {
local url=$1
local filename=$2
log_info "下載 $filename..."
# 檢查是否有 wget 或 curl
if command -v wget >/dev/null 2>&1; then
wget -O "$filename" "$url"
elif command -v curl >/dev/null 2>&1; then
curl -L -o "$filename" "$url"
else
log_error "需要 wget 或 curl 來下載文件"
exit 1
fi
}
# 驗證下載的文件
verify_download() {
local filename=$1
if [ ! -f "$filename" ]; then
log_error "下載失敗: $filename 不存在"
exit 1
fi
local size=$(stat -c%s "$filename" 2>/dev/null || stat -f%z "$filename" 2>/dev/null)
if [ "$size" -lt 1000000 ]; then # 小於 1MB 可能是錯誤文件
log_error "下載的文件可能有問題,大小只有 $size bytes"
exit 1
fi
log_success "文件下載完成,大小: $size bytes"
}
# 安裝 nerdctl-full
install_nerdctl() {
local filename=$1
local install_path=${2:-/usr/local}
log_info "解壓並安裝到 $install_path..."
# 檢查是否需要 sudo
if [ ! -w "$install_path" ]; then
local sudo_cmd="sudo"
log_warning "需要 sudo 權限安裝到 $install_path"
else
local sudo_cmd=""
fi
# 解壓安裝
$sudo_cmd tar Cxzvf "$install_path" "$filename"
# 驗證安裝
if [ -f "$install_path/bin/nerdctl" ]; then
log_success "nerdctl 安裝成功!"
log_info "版本信息:"
"$install_path/bin/nerdctl" version || true
else
log_error "安裝驗證失敗"
exit 1
fi
}
# 設置 systemd 服務(可選)
setup_services() {
local install_path=${1:-/usr/local}
read -p "是否要啟動 containerd 和 buildkit 服務? (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "啟動服務..."
if command -v systemctl >/dev/null 2>&1; then
sudo systemctl daemon-reload
sudo systemctl enable containerd || log_warning "無法啟用 containerd 服務"
sudo systemctl start containerd || log_warning "無法啟動 containerd 服務"
sudo systemctl enable buildkit || log_warning "無法啟用 buildkit 服務"
sudo systemctl start buildkit || log_warning "無法啟動 buildkit 服務"
log_success "服務設置完成"
else
log_warning "systemctl 不可用,請手動啟動服務"
fi
fi
}
# 主函數
main() {
log_info "nerdctl-full 自動安裝腳本"
log_info "=============================="
# 檢測系統信息
local os=$(detect_os)
local arch=$(detect_arch)
local version=${1:-$(get_latest_version)}
local install_path=${2:-/usr/local}
log_info "檢測到的系統信息:"
log_info " 操作系統: $os"
log_info " 架構: $arch"
log_info " 版本: $version"
log_info " 安裝路徑: $install_path"
# 構造下載 URL 和文件名
local filename="nerdctl-full-${version}-${os}-${arch}.tar.gz"
local download_url="https://github.com/containerd/nerdctl/releases/download/${version}/${filename}"
log_info "下載 URL: $download_url"
# 確認下載
read -p "是否繼續下載並安裝? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
log_info "安裝已取消"
exit 0
fi
# 清理舊文件
[ -f "$filename" ] && rm -f "$filename"
# 下載文件
download_file "$download_url" "$filename"
# 驗證下載
verify_download "$filename"
# 安裝
install_nerdctl "$filename" "$install_path"
# 設置服務
setup_services "$install_path"
# 清理下載文件
read -p "是否刪除下載的安裝包? (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -f "$filename"
log_info "安裝包已刪除"
fi
# 完成信息
log_success "==============================================="
log_success "nerdctl-full 安裝完成!"
log_success "==============================================="
log_info "使用方法:"
log_info " sudo $install_path/bin/nerdctl version"
log_info " sudo $install_path/bin/nerdctl run hello-world"
log_info ""
log_info "如果要使用 rootless 模式:"
log_info " $install_path/bin/containerd-rootless-setuptool.sh install"
log_info ""
log_info "更多信息請查看: https://github.com/containerd/nerdctl"
}
# 顯示幫助信息
show_help() {
echo "用法: $0 [版本] [安裝路徑]"
echo ""
echo "參數:"
echo " 版本 指定要安裝的版本 (默認: 最新版本)"
echo " 安裝路徑 指定安裝目錄 (默認: /usr/local)"
echo ""
echo "示例:"
echo " $0 # 安裝最新版本到 /usr/local"
echo " $0 v2.1.3 # 安裝指定版本"
echo " $0 v2.1.3 /opt # 安裝到指定目錄"
echo ""
echo "支持的架構: amd64, arm64, arm-v7"
echo "支持的系統: Linux"
}
# 檢查參數
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
show_help
exit 0
fi
# 運行主函數
main "$@"