apt / apt-get / dpkg —— Debian / Ubuntu 包管理
一句话定义
apt / apt-get / dpkg 是 Debian 系(Debian / Ubuntu)的包管理工具,三个层级:
dpkg—— 直接操作.deb文件(不解决依赖)apt-get—— 经典命令,脚本里推荐用(稳定输出)apt—— 现代封装,人交互推荐用(输出更友好)
典型场景
训练营文档里 apt 出场 44 次,主要在:
- Day0 装基线工具:
apt install -y curl jq tmux ... - 装 K8s:
apt install -y kubeadm kubectl kubelet apt-mark holdK8s 包不被自动升级- 装 docker / containerd / chrony 等
apt vs apt-get —— 该用哪个
apt | apt-get | |
|---|---|---|
| 适用 | 人交互 | 脚本 |
| 输出 | 彩色、进度条、警告漂亮 | 稳定、可解析 |
| 版本 | Ubuntu 16+ / Debian 8+ | 一直都有 |
| 增量功能 | apt list, apt search(更好用) | 没 |
# 脚本里
apt-get install -y curl
# 命令行手敲
apt install curl
apt 在脚本里偶尔给警告:
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
—— 所以脚本用 apt-get。
核心 5 个动作
apt-get update # 更新包列表(不装包)
apt-get install <pkg> # 装
apt-get remove <pkg> # 卸(保留配置)
apt-get purge <pkg> # 卸 + 删配置
apt-get upgrade # 升所有可升级的
apt-get autoremove # 删除不再需要的依赖(之前别的包带进来的)
apt search <keyword> # 搜(apt 比 apt-get 友好)
apt list --installed # 列已装
apt list --upgradable # 列可升级的
apt show <pkg> # 看包详情
apt-get update 和 upgrade 的区别
| 命令 | 作用 |
|---|---|
apt-get update | 只刷新本地的包目录("知道有哪些包、什么版本");不装任何东西 |
apt-get upgrade | 升级所有已装包到新版(不删旧包、不解决冲突) |
apt-get dist-upgrade | 升级 + 允许加删依赖 |
apt full-upgrade | 等价 dist-upgrade |
装包前必跑 apt-get update:
apt-get update && apt-get install -y curl
否则可能拿不到最新版 / 报"E: Unable to locate package"。
实用 flag
apt-get install -y curl # -y 自动 yes
apt-get install -y --no-install-recommends curl # 不装"建议"依赖(更精简)
apt-get install -y -q curl # quiet(适合脚本)
apt-get install -y -qq curl # 更安静
apt-get install -y --only-upgrade curl # 只升级(不装新的)
apt-get install -y curl=7.81.0-* # 指定版本
apt-get install -y -f # fix 依赖问题
--no-install-recommends —— K8s 节点必加
很多包除了"必需依赖"还有"推荐包"(recommends)。默认 apt 把推荐包也装上 —— 服务器场景多数没用。
apt-get install -y --no-install-recommends \
curl wget vim jq tmux htop
少装一堆没用的(图形库、字体、文档),节点更精简。
阻止 apt 提问
DEBIAN_FRONTEND=noninteractive apt-get install -y postfix
某些包(postfix / tzdata / iptables-persistent)会交互式问配置。脚本里必须设 DEBIAN_FRONTEND=noninteractive,否则卡住。
apt-mark hold —— K8s 必学
K8s 集群里 kubeadm / kubelet / kubectl 版本必须精确一致。普通 apt upgrade 会自动升它们 → 集群挂。
apt-mark hold kubeadm kubectl kubelet # 锁版本,apt upgrade 跳过它们
apt-mark unhold kubeadm kubectl kubelet # 解锁
apt-mark showhold # 看现在被 hold 的包
装完 K8s 第一件事:hold。
升级 K8s 时:
apt-mark unhold kubeadm
apt-get update
apt-get install -y kubeadm=1.29.3-1.1
apt-mark hold kubeadm
源管理:/etc/apt/sources.list + sources.list.d/
# 主源
cat /etc/apt/sources.list
# deb http://archive.ubuntu.com/ubuntu/ jammy main restricted
# 第三方源(K8s / Docker / Helm 等)
ls /etc/apt/sources.list.d/
# docker.list
# kubernetes.list
# helm.list
加 K8s 官方源
# 1. 加 GPG key(验证包签名)
mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key \
| gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# 2. 加源
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" \
> /etc/apt/sources.list.d/kubernetes.list
# 3. 刷新
apt-get update
# 4. 装
apt-get install -y kubeadm kubectl kubelet
apt-mark hold kubeadm kubectl kubelet
国内源(加速)
Ubuntu 默认源在国外、国内慢。换清华 / 阿里源:
# 备份
cp /etc/apt/sources.list /etc/apt/sources.list.bak
# 写清华源
cat > /etc/apt/sources.list <<'EOF'
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
EOF
apt-get update
dpkg —— 直接操作 .deb 文件
dpkg -i package.deb # 装 .deb(不解决依赖)
dpkg -r package # 卸(同 apt remove)
dpkg -P package # 卸 + 删配置
dpkg -l # 列已装包(同 apt list --installed)
dpkg -l | grep kube # 找已装的 K8s 包
dpkg -L package # 看包装了哪些文件
dpkg -S /usr/bin/curl # 反查这个文件属于哪个包
# curl: /usr/bin/curl
dpkg --configure -a # 修复中断的安装
装本地 .deb(带依赖)
dpkg -i package.deb # 报缺依赖
apt-get install -f # 修复依赖
# 或者一步到位
apt-get install -y ./package.deb # apt 装本地文件(带依赖)
看包依赖 / 反向依赖
apt-cache depends curl # curl 依赖哪些包
apt-cache rdepends curl # 哪些包依赖 curl
apt list --installed --no-recommends | wc -l # 已装非"推荐"的包数
排查"卸不掉某包":
apt-cache rdepends --installed <pkg>
# 看哪些已装包依赖它
升级整个系统
apt-get update
apt-get upgrade -y # 保守升级(不动依赖)
# 或
apt-get full-upgrade -y # 允许加删依赖
K8s 节点上跑
apt upgrade之前一定先apt-mark holdK8s 包,否则 kubelet / kubeadm 版本被升、集群挂。
不让某些升级触发交互
apt-get upgrade -y \
-o Dpkg::Options::="--force-confold" \
-o Dpkg::Options::="--force-confdef"
升级时遇到 conf 文件冲突:
--force-confold—— 保留本地修改(生产推荐)--force-confnew—— 用新版本覆盖--force-confdef—— 用包默认 / 询问
Day0 装机脚本里防 sshd_config 被覆盖:
apt-get upgrade -y -o Dpkg::Options::="--force-confold"
清理
apt-get autoremove -y # 删不再需要的依赖
apt-get autoclean # 清掉过期的下载缓存
apt-get clean # 清掉所有下载缓存(更彻底)
# 看缓存占用
du -sh /var/cache/apt/archives/
K8s 节点磁盘紧张时清一下能省几百 MB。
实战:Day0 装机基线
ssh root@$ip 'bash -s' <<'EOF'
export DEBIAN_FRONTEND=noninteractive
# 1. 更新包列表
apt-get update -qq
# 2. 装基线工具(不装推荐包)
apt-get install -y --no-install-recommends \
curl wget ca-certificates apt-transport-https gnupg lsb-release \
vim jq tmux htop iotop \
tcpdump dnsutils iperf3 mtr-tiny net-tools \
chrony \
git unzip zip rsync less \
bash-completion \
ipset conntrack \
python3-pip
# 3. 升级(保留本地 conf)
apt-get upgrade -y -o Dpkg::Options::="--force-confold"
# 4. 清理
apt-get autoremove -y
apt-get autoclean
EOF
常见踩坑
坑 1:apt-get install 不带 -y、脚本卡住
apt-get install curl # 默认问 Y/N
# 脚本里就卡了
脚本一定加 -y。
坑 2:postfix / tzdata 配置卡住
apt-get install -y postfix
# 弹出全屏配置界面
加:
DEBIAN_FRONTEND=noninteractive apt-get install -y postfix
或者 export DEBIAN_FRONTEND=noninteractive 整段脚本前面。
坑 3:K8s 集群升级、忘了 unhold
apt-get install -y kubeadm=1.29.3-1.1
# E: Unable to install kubeadm. kubeadm is held.
apt-mark unhold kubeadm 之后再升、升完再 hold。
坑 4:误升 K8s 包
apt-get upgrade -y # 没 hold
# kubeadm 1.28 → 1.29 自动升、集群乱
装完 K8s 立刻 hold:
apt-mark hold kubeadm kubectl kubelet docker.io containerd.io
坑 5:apt-key 已经废弃
apt-key add some.gpg # 在 Ubuntu 22+ 警告 / 不推荐
新做法:/etc/apt/keyrings/*.gpg + sources.list 里 [signed-by=...]:
mkdir -p /etc/apt/keyrings
curl -fsSL https://example.com/key.gpg | gpg --dearmor -o /etc/apt/keyrings/example.gpg
echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://example.com/repo stable main" \
> /etc/apt/sources.list.d/example.list
坑 6:sources.list 多个 URL 同时刷新慢
apt-get update
# 卡在某个国外源
每个源失败要等超时(默认 120 秒)。临时跳过:
apt-get update -o Acquire::http::Timeout=10
或者注释掉 sources.list 里慢的源。
坑 7:dpkg 中断之后 apt 报错
apt-get install foo
# E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.
dpkg --configure -a
修复中断的安装状态,然后继续。
坑 8:找包但忘了 apt-get update
apt-get install -y new-package
# E: Unable to locate package new-package
源最近加了但没刷:
apt-get update
apt-get install -y new-package
坑 9:装包失败 / "Could not get lock"
apt-get install -y curl
# E: Could not get lock /var/lib/dpkg/lock-frontend
另一个 apt / dpkg 进程在跑(cloud-init / unattended-upgrades / 别的 ssh 会话):
ps aux | grep -E 'apt|dpkg' | grep -v grep
# 等它跑完,或者 kill(小心)
云镜像启动时 cloud-init 经常先跑 apt 操作,首次 ssh 进去等几分钟再操作。
坑 10:apt 装的版本是不是想要的版本
apt-cache policy curl
# curl:
# Installed: 7.81.0-1ubuntu1.10
# Candidate: 7.81.0-1ubuntu1.12
# Version table:
# *** 7.81.0-1ubuntu1.10 100
# ...
Installed 是当前装的,Candidate 是下次 apt install 会装的版本。
要装特定版本:
apt-get install -y curl=7.81.0-1ubuntu1.10
yum / dnf(CentOS / RHEL 系)速查对照
| apt | yum / dnf |
|---|---|
apt-get update | yum check-update / dnf check-update |
apt-get install -y pkg | yum install -y pkg / dnf install -y pkg |
apt-get remove pkg | yum remove pkg |
apt-get upgrade -y | yum update -y |
apt list --installed | yum list installed |
dpkg -L pkg | rpm -ql pkg |
dpkg -S /path/file | rpm -qf /path/file |
apt-mark hold | yum versionlock (要装 plugin) |
CentOS 8+ 用 dnf(yum 的下一代)。命令几乎一样。
关联命令
- systemctl —— 装完包通常 systemctl enable
- journalctl —— 看包安装日志
update-alternatives—— 多版本管理(java / python 等)snap—— Ubuntu 的容器化包管理(K8s 节点上慎用)pip/npm—— 语言级包管理- curl —— 下载 apt key