ansible-devops/scripts/containerd.sh

289 lines
9.7 KiB
Bash
Raw Normal View History

2025-10-29 12:47:17 +08:00
#!/bin/bash
set -euo pipefail
2025-10-30 12:37:05 +08:00
# Containerd安装脚本Ubuntu专用
# 集成配置默认配置生成、镜像源替换、Cgroup驱动、镜像加速
2025-10-29 12:47:17 +08:00
# 适用Ubuntu 20.04/22.04/24.04 LTS
#######################################
# 配置参数
#######################################
DEFAULT_VERSION="1.7.28-1"
ACTION=""
CONTAINERD_VERSION="$DEFAULT_VERSION"
2025-10-30 12:37:05 +08:00
LOG_FILE="/var/log/containerd_manage.log"
2025-10-29 12:47:17 +08:00
DOCKER_REPO="https://download.docker.com/linux/ubuntu"
GPG_KEY_PATH="/etc/apt/keyrings/docker.gpg"
REPO_LIST_PATH="/etc/apt/sources.list.d/docker.list"
CONFIG_PATH="/etc/containerd/config.toml"
PACKAGE_NAME="containerd.io"
2025-10-30 12:37:05 +08:00
CERTS_D_PATH="/etc/containerd/certs.d"
DOCKER_IO_HOSTS="${CERTS_D_PATH}/docker.io/hosts.toml"
2025-10-29 12:47:17 +08:00
#######################################
2025-10-30 12:37:05 +08:00
# 日志函数
2025-10-29 12:47:17 +08:00
#######################################
log() {
local level=$1
local message=$2
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}
#######################################
# 帮助信息
#######################################
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " --install 安装containerd必填"
echo " --uninstall 卸载containerd必填"
2025-10-30 12:37:05 +08:00
echo " --version VERSION 指定版本如1.7.28-1默认$DEFAULT_VERSION"
2025-10-29 12:47:17 +08:00
echo " --help 显示帮助"
exit 1
}
#######################################
# 解析参数
#######################################
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
--install)
2025-10-30 12:37:05 +08:00
if [[ "$ACTION" == "uninstall" ]]; then log "ERROR" "参数冲突"; usage; fi
2025-10-29 12:47:17 +08:00
ACTION="install"
shift
;;
--uninstall)
2025-10-30 12:37:05 +08:00
if [[ "$ACTION" == "install" ]]; then log "ERROR" "参数冲突"; usage; fi
2025-10-29 12:47:17 +08:00
ACTION="uninstall"
shift
;;
--version)
2025-10-30 12:37:05 +08:00
if [[ $# -lt 2 || "$2" == -* ]]; then log "ERROR" "需指定版本"; usage; fi
2025-10-29 12:47:17 +08:00
CONTAINERD_VERSION="$2"
shift 2
;;
--help)
usage
;;
*)
log "ERROR" "未知参数:$1"
usage
;;
esac
done
2025-10-30 12:37:05 +08:00
if [[ -z "$ACTION" ]]; then log "ERROR" "需指定--install或--uninstall"; usage; fi
2025-10-29 12:47:17 +08:00
}
#######################################
2025-10-30 12:37:05 +08:00
# 前置检查
2025-10-29 12:47:17 +08:00
#######################################
pre_check() {
2025-10-30 12:37:05 +08:00
log "INFO" "前置环境检查"
if [[ "$(id -u)" -ne 0 ]]; then log "ERROR" "需root权限"; exit 1; fi
if ! grep -q "Ubuntu" /etc/os-release; then log "ERROR" "仅支持Ubuntu"; exit 1; fi
2025-10-29 12:47:17 +08:00
local os_version=$(grep VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"')
if ! [[ "$os_version" =~ ^20\.04$ || "$os_version" =~ ^22\.04$ || "$os_version" =~ ^24\.04$ ]]; then
2025-10-30 12:37:05 +08:00
log "ERROR" "仅支持Ubuntu 20.04/22.04/24.04"
2025-10-29 12:47:17 +08:00
exit 1
fi
local required_tools=("apt-get" "curl" "gpg" "lsb_release" "systemctl")
for tool in "${required_tools[@]}"; do
if ! command -v "$tool" &> /dev/null; then
log "INFO" "安装缺失工具:$tool"
apt-get update -qq >/dev/null
apt-get install -qq -y "$tool" >/dev/null
fi
done
log "INFO" "前置检查通过"
}
#######################################
2025-10-30 12:37:05 +08:00
# 配置Docker源
2025-10-29 12:47:17 +08:00
#######################################
configure_repo() {
2025-10-30 12:37:05 +08:00
log "INFO" "配置Docker源"
2025-10-29 12:47:17 +08:00
mkdir -p "$(dirname "$GPG_KEY_PATH")"
if [[ ! -f "$GPG_KEY_PATH" ]]; then
log "INFO" "下载Docker GPG密钥"
2025-10-30 12:37:05 +08:00
curl -fsSL --retry 3 --retry-delay 5 "${DOCKER_REPO}/gpg" | gpg --dearmor -o "$GPG_KEY_PATH" >/dev/null 2>&1 || {
log "ERROR" "GPG密钥下载失败"
2025-10-29 12:47:17 +08:00
exit 1
2025-10-30 12:37:05 +08:00
}
2025-10-29 12:47:17 +08:00
chmod a+r "$GPG_KEY_PATH"
fi
local codename=$(lsb_release -cs)
2025-10-30 12:37:05 +08:00
if [[ "$codename" == "noble" ]]; then codename="jammy"; fi # 兼容24.04
2025-10-29 12:47:17 +08:00
local repo_content="deb [arch=$(dpkg --print-architecture) signed-by=$GPG_KEY_PATH] $DOCKER_REPO $codename stable"
2025-10-30 12:37:05 +08:00
if [[ ! -f "$REPO_LIST_PATH" || "$(cat "$REPO_LIST_PATH")" != "$repo_content" ]]; then
2025-10-29 12:47:17 +08:00
echo "$repo_content" | tee "$REPO_LIST_PATH" >/dev/null
apt-get update -qq >/dev/null
fi
2025-10-30 12:37:05 +08:00
log "INFO" "Docker源配置完成"
2025-10-29 12:47:17 +08:00
}
#######################################
2025-10-30 12:37:05 +08:00
# 验证版本可用性
2025-10-29 12:47:17 +08:00
#######################################
verify_version() {
log "INFO" "验证版本${CONTAINERD_VERSION}可用性"
2025-10-30 12:37:05 +08:00
local available_versions=$(apt-cache madison "$PACKAGE_NAME" | awk '{print $3}' | sed 's/~ubuntu.*//' | sort -u)
2025-10-29 12:47:17 +08:00
if ! echo "$available_versions" | grep -qxF "$CONTAINERD_VERSION"; then
2025-10-30 12:37:05 +08:00
log "ERROR" "版本不可用,可用版本:$available_versions"
2025-10-29 12:47:17 +08:00
exit 1
fi
log "INFO" "版本验证通过"
}
#######################################
# 安装containerd
#######################################
install_containerd() {
2025-10-30 12:37:05 +08:00
log "INFO" "安装containerd"
local full_version=$(apt-cache madison "$PACKAGE_NAME" | grep "$CONTAINERD_VERSION" | awk '{print $3}' | head -n 1)
if [[ -z "$full_version" ]]; then log "ERROR" "未找到完整版本"; exit 1; fi
if dpkg -l "$PACKAGE_NAME" &>/dev/null && [[ "$(dpkg -l "$PACKAGE_NAME" | awk '/ii/ {print $3}')" == "$full_version" ]]; then
log "INFO" "已安装$full_version,跳过"
return
2025-10-29 12:47:17 +08:00
fi
2025-10-30 12:37:05 +08:00
log "INFO" "安装$full_version"
apt-get install -qq -y "${PACKAGE_NAME}=${full_version}" >/dev/null 2>&1 || {
log "ERROR" "安装失败手动执行sudo apt-get install -y ${PACKAGE_NAME}=${full_version}"
exit 1
}
2025-10-29 12:47:17 +08:00
}
#######################################
2025-10-30 12:37:05 +08:00
# 核心配置(严格按你的要求执行)
2025-10-29 12:47:17 +08:00
#######################################
configure_containerd() {
2025-10-30 12:37:05 +08:00
log "INFO" "开始配置containerd"
2025-10-29 12:47:17 +08:00
2025-10-30 12:37:05 +08:00
# 1. 生成默认配置文件
log "INFO" "生成默认配置文件"
containerd config default > "$CONFIG_PATH" 2>/dev/null || {
log "ERROR" "生成默认配置失败"
exit 1
}
# 2. 替换镜像源registry.k8s.io -> 华为云)
log "INFO" "替换镜像源为华为云"
sed -i 's#registry.k8s.io#swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io#' "$CONFIG_PATH" || {
log "ERROR" "镜像源替换失败"
exit 1
}
2025-10-29 12:47:17 +08:00
2025-10-30 12:37:05 +08:00
# 3. 配置Cgroup驱动器SystemdCgroup = true
log "INFO" "配置Cgroup驱动器"
sed -i 's/SystemdCgroup\ =\ false/SystemdCgroup\ =\ true/g' "$CONFIG_PATH" || {
log "ERROR" "Cgroup配置失败"
exit 1
}
# 4. 配置镜像加速
log "INFO" "配置镜像加速"
# 4.1 设置registry.config_path
local registry_block="[plugins.\"io.containerd.grpc.v1.cri\".registry]"
local config_path_line=' config_path = "/etc/containerd/certs.d"'
if ! grep -qxF "$config_path_line" "$CONFIG_PATH"; then
if ! grep -qxF "$registry_block" "$CONFIG_PATH"; then
echo -e "\n$registry_block" >> "$CONFIG_PATH"
fi
sed -i "/$registry_block/a $config_path_line" "$CONFIG_PATH"
2025-10-29 12:47:17 +08:00
fi
2025-10-30 12:37:05 +08:00
# 4.2 创建目录并写入加速配置
mkdir -p "$(dirname "$DOCKER_IO_HOSTS")"
local hosts_content=$(cat << EOF
server = "https://docker.io"
[host."https://o2j0mc5x.mirror.aliyuncs.com"]
capabilities = ["pull", "resolve"]
server = "https://k8s.gcr.io"
[host."https://gcr.mirrors.ustc.edu.cn/google-containers/"]
capabilities = ["pull", "resolve"]
server = "https://quay.io"
[host."https://mirror.ccs.tencentyun.com"]
capabilities = ["pull", "resolve"]
EOF
)
echo "$hosts_content" | tee "$DOCKER_IO_HOSTS" >/dev/null
# 重启服务
2025-10-29 12:47:17 +08:00
systemctl restart containerd >/dev/null 2>&1
2025-10-30 12:37:05 +08:00
log "INFO" "配置完成,已重启服务"
2025-10-29 12:47:17 +08:00
}
#######################################
2025-10-30 12:37:05 +08:00
# 启动服务并设置开机启动
2025-10-29 12:47:17 +08:00
#######################################
start_service() {
2025-10-30 12:37:05 +08:00
log "INFO" "设置开机自启并启动服务"
systemctl enable --now containerd >/dev/null 2>&1 || {
log "ERROR" "服务启动失败"
exit 1
}
2025-10-29 12:47:17 +08:00
}
#######################################
2025-10-30 12:37:05 +08:00
# 验证安装
2025-10-29 12:47:17 +08:00
#######################################
verify_installation() {
log "INFO" "验证安装结果"
2025-10-30 12:37:05 +08:00
if ! systemctl is-active --quiet containerd; then log "ERROR" "服务未运行"; exit 1; fi
if ! grep -q "swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io" "$CONFIG_PATH"; then
log "WARNING" "镜像源替换未生效"
2025-10-29 12:47:17 +08:00
fi
2025-10-30 12:37:05 +08:00
if ! grep -q "SystemdCgroup \= true" "$CONFIG_PATH"; then
log "WARNING" "Cgroup配置未生效"
2025-10-29 12:47:17 +08:00
fi
2025-10-30 12:37:05 +08:00
if [[ ! -f "$DOCKER_IO_HOSTS" ]]; then
log "WARNING" "镜像加速配置不存在"
fi
log "INFO" "验证完成"
2025-10-29 12:47:17 +08:00
}
#######################################
2025-10-30 12:37:05 +08:00
# 卸载containerd
2025-10-29 12:47:17 +08:00
#######################################
uninstall_containerd() {
2025-10-30 12:37:05 +08:00
log "INFO" "卸载containerd"
systemctl stop containerd >/dev/null 2>&1 || true
2025-10-29 12:47:17 +08:00
if dpkg -l "$PACKAGE_NAME" &>/dev/null; then
apt-get purge -qq -y "$PACKAGE_NAME" >/dev/null 2>&1
2025-10-30 12:37:05 +08:00
apt-get autoremove -qq -y >/dev/null 2>&1
2025-10-29 12:47:17 +08:00
fi
2025-10-30 12:37:05 +08:00
rm -rf "$CONFIG_PATH" "$CERTS_D_PATH" /var/lib/containerd /var/log/containerd
2025-10-29 12:47:17 +08:00
systemctl daemon-reload >/dev/null 2>&1
2025-10-30 12:37:05 +08:00
log "INFO" "卸载完成"
2025-10-29 12:47:17 +08:00
}
#######################################
# 主流程
#######################################
main() {
> "$LOG_FILE"
2025-10-30 12:37:05 +08:00
log "INFO" "===== 脚本启动 ====="
2025-10-29 12:47:17 +08:00
parse_args "$@"
pre_check
case "$ACTION" in
install)
configure_repo
verify_version
install_containerd
2025-10-30 12:37:05 +08:00
configure_containerd # 执行你的所有配置步骤
2025-10-29 12:47:17 +08:00
start_service
verify_installation
;;
uninstall)
uninstall_containerd
;;
esac
log "INFO" "===== 操作完成 ====="
2025-10-30 12:37:05 +08:00
log "INFO" "日志:$LOG_FILE"
2025-10-29 12:47:17 +08:00
}
main "$@"