27、容器安全加固

容器平台等保三级安全加固(Docker/Kubernetes/Harbor):Docker 远程 API TLS 双向认证与 2375 明文收敛、daemon.json 基线(live-restore、log-driver max-size/max-file、userns-remap 用户命名空间重映射与 dockremap)、容器非 root 运行与 –privileged/capabilities/seccomp/AppArmor 收敛、镜像来源治理与 DOCKER_CONTENT_TRUST;Kubernetes 控制面 –anonymous-auth=false 与 RBAC cluster-admin 收敛、Pod Security Admission 分级、NodeRestriction、审计策略 –audit-log-maxage、etcd 静态加密 secretbox、NetworkPolicy;Harbor HTTPS 强制、harbor_admin_password 首启读取机制、Trivy 扫描阻断策略、机器人账号与垃圾回收;每节附核查命令、加固操作与 CIS/Docker Bench 对照。

定位:容器技术栈(Docker / Kubernetes / Harbor)等保三级安全加固手册:按 00~10 编号分节覆盖基线自查、Docker 守护进程与远程 API、镜像治理、运行时隔离、用户命名空间、日志审计、Kubernetes 控制面与数据面、Harbor 私有仓库、备份恢复与版本生命周期,每节附核查命令、加固操作与官方依据。

适用版本:Docker Engine 24.x/25.x(daemon.json 配置参考以 docs.docker.com 现行版为准)、Kubernetes v1.28~v1.33(kubeadm 与二进制部署)、Harbor 2.x(v2.10+)。 配套测评:Docker 容器运行平台测评Kubernetes 容器编排平台测评Harbor 容器镜像仓库测评

使用说明:

  • 本文为加固操作手册systemctl restart docker、修改 kube-apiserver 静态 Pod 参数(需重启控制面 Pod)、docker restart 均会造成业务中断,实施前必须完成变更审批、确认业务窗口、备份 daemon.json//etc/kubernetes//Harbor 数据目录,并准备可执行的回滚预案
  • 先在测试集群或单节点灰度验证,确认业务容器与 Pod 正常后再推广;每完成一项立即用文中「核查方法」复核——daemon.json 修改后未重启守护进程不生效、userns-remap 启用后既有镜像与容器会被隔离到新的属主目录(官方建议在新装环境启用而非存量环境)。
  • 示例中的地址、账户、口令、路径均为演示值(如 192.168.10.5registry.demo.local),现场须替换为真实值并脱敏;严禁直接沿用示例口令
  • 命令回显与本文不一致时,先确认版本与部署形态(包管理器/二进制/kubeadm/Helm),再查阅对应版本文档换用等效命令;版本差异不得直接作为「无法整改」的结论,须给出替代措施并评估其实际效果。
  • 涉及远程 API、TLS、RBAC、准入的变更存在锁死自身风险:务必保留一条已验证的恢复通道(本机 root SSH、控制台访问、另一个 cluster-admin kubeconfig 或 bootstrap token)后再实施。
  • 加固完成后按「16、安全评估加固记录表3.0」逐项留痕,并纳入复测;测评判定口径以 GB/T 28448-2019 与《高风险判定指引》为准。

不适用标识说明:

  • 使用 【不适用】 明确标记现场可判定为不适用的控制点,并写明判定依据与承载该能力的上位组件。
  • 依据 GB/T 28448-2019「按测评对象实际承载功能与数据处理范围判定」原则:能力由云托管容器平台(ACK/GKE/EKS 等)、镜像仓库 SaaS、统一日志平台承载时,应注明测评单元边界后判定不适用或转由上位组件核查。
  • 产品版本确实不提供该能力时,须核查替代措施并按实际效果定档,不得直接判不适用。

测评项对照表

控制点(GB/T 22239-2019 安全计算环境-容器平台)对应章节
入侵防范:暴露面收敛、最小安装、漏洞修补00、01、02
身份鉴别:管理入口鉴别、防窃听01、06、08
访问控制:权限最小化、默认账户治理03、06、08
安全审计:日志与留存05
数据保密性:etcd 加密、TLS07
数据备份恢复09
剩余信息保护:镜像与凭据清理10

00 官方安全基线与自查

对应控制点:GB/T 22239-2019 8.1.4.4 入侵防范 a)~f)

加固要点:以官方文档与社区基线为整改标尺并定期自查:Docker 官方安全文档与守护进程攻击面说明(docs.docker.com/engine/security/)、CIS Docker Benchmark 与配套自查脚本 Docker Bench for Security(docker/docker-bench-security)、CIS Kubernetes Benchmark(cisecurity.org 入口)、Harbor 官方管理文档(goharbor.io/docs)。测评现场高频引用的容器逃逸与暴露面判定口径即来自这两套基准。

验证方法:Docker Bench for Security 输出报告(WARN 项整改台账)、CIS 自查记录、版本台账。

核查方法

# Docker Bench for Security(只读自查脚本,容器化运行)
docker run --rm --net none --pid host --userns host --cap-drop ALL \
  -v /var/lib:/var/lib:ro -v /var/run/docker.sock:/var/run/docker.sock:ro \
  -v /etc:/etc:ro --label docker_bench_security docker/docker-bench-security
docker version --format '{{.Server.Version}}'
kubectl version
docker compose version        # Harbor 2.x 部署侧
  • 预期现象:自查报告 WARN 项有整改记录;三平台版本均在官方支持窗口内。

01 Docker 守护进程与远程 API 收敛(核心)

对应控制点:GB/T 22239-2019 8.1.4.1 身份鉴别 c)、8.1.4.4 入侵防范 b) c)

加固要点:Docker 守护进程默认仅监听本机 Unix socket(/var/run/docker.sock),凡将 -H tcp://0.0.0.0:2375 明文开放远程 API,等同向网络开放 root 级主机控制通道(官方安全文档明确要求守护进程仅可达于受信方)。确需远程管理时:仅绑定运维网段地址、强制 --tlsverify 双向证书认证(ca/server/client 三套证书)、防火墙仅放行堡垒机来源;docker.sock 不得挂载进业务容器;宿主机侧对 docker 组成员按最小化收敛(docker 组等价 root)。

验证方法ss -lntp 无 2375 明文监听、docker context ls 管理通道清单、TLS 证书连接实测、docker inspect 无 sock 挂载抽查。

核查方法

ss -lntp | grep -E "2375|2376"
ps -ef | grep [d]ockerd
docker context ls
grep -R "hosts\|tls" /etc/docker/daemon.json
docker ps -q | xargs -I{} docker inspect {} --format '{{.Name}} {{json .Mounts}}' | grep docker.sock
示例输出(节选)
$ ss -lntp | grep 237
LISTEN 0 128 192.168.10.5:2376 users:(("dockerd",pid=1122,fd=7))    # 仅运维网段且 TLS
(无 0.0.0.0:2375 明文监听)
$ ps -ef | grep [d]ockerd
root  1122  /usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/ca.pem \
  --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem \
  -H=fd:// -H=tcp://192.168.10.5:2376

加固操作/etc/docker/daemon.json + 重启;证书生成走内部 CA,客户端配置 docker context create 分发)

# 生成服务端/客户端证书(官方 Protect the Docker daemon socket 章节流程,CA 为内部根)
systemctl stop docker
# 编辑 /etc/docker/daemon.json:见下方 JSON
systemctl start docker
docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
  -H=tcp://192.168.10.5:2376 version    # 验证 TLS 通道
{
  "hosts": ["unix:///var/run/docker.sock", "tcp://192.168.10.5:2376"],
  "tls": true,
  "tlsverify": true,
  "tlscacert": "/etc/docker/ca.pem",
  "tlscert": "/etc/docker/server-cert.pem",
  "tlskey": "/etc/docker/server-key.pem",
  "live-restore": true,
  "log-driver": "json-file",
  "log-opts": { "max-size": "50m", "max-file": "5" }
}
  • 预期现象:明文 API 关闭;无证书客户端连接被拒;live-restore 生效(守护进程重启不中断容器,docker info 显示 Live Restore Enabled: true)。

02 镜像治理与内容信任

对应控制点:GB/T 22239-2019 8.1.4.4 入侵防范 a) d)(最小安装、数据有效性检验)

加固要点:镜像来源白名单(仅内部 Harbor 或官方认证仓库,杜绝公网随手 docker run);基础镜像定期重建扫描(配合 Harbor Trivy,见 08 节);启用内容信任(Content Trust)验证镜像签名——环境变量 DOCKER_CONTENT_TRUST=1 后 pull 未签名镜像被拒(官方 Content trust in Docker 章节);生产镜像使用 digest 固定(nginx@sha256:...)而非可变 tag;镜像构建走 CI 流水线留痕,禁止在生产宿主机现场构建。

验证方法DOCKER_CONTENT_TRUST=1 docker pull 拒绝未签名镜像实测、镜像清单 digest 抽查、CI 构建记录。

核查方法

docker images --digests
DOCKER_CONTENT_TRUST=1 docker pull demo.local/app:v1.2.3
grep -R "DOCKER_CONTENT_TRUST" /etc/profile.d/ /root/.bashrc 2>/dev/null
示例输出(节选)
$ DOCKER_CONTENT_TRUST=1 docker pull demo.local/app:v1.2.3
Pull (1 of 1): demo.local/app@sha256:9c7f...
docker.io/demo.local/app:v1.2.3 未启用签名的公共仓库:
Error: remote does not have trusted data    # 无签名镜像被拒

加固操作

# 对运维账户默认启用内容信任(按需,注意对既有脚本的影响——未签名仓库 pull 会失败)
echo 'export DOCKER_CONTENT_TRUST=1' > /etc/profile.d/docker-trust.sh
  • 预期现象:签名验证开启;镜像台账中每条来源可追溯(仓库、digest、构建流水线编号)。

03 容器运行时隔离:非 root、去特权与能力收敛

对应控制点:GB/T 22239-2019 8.1.4.2 访问控制 a)~f)、8.1.4.4 入侵防范

加固要点:官方安全文档的优先级顺序:容器内应用以非特权用户运行是防提权的第一道防线docker run --user 或镜像内 USER 指令);禁止无业务必要的 --privileged(官方明确其给予几乎所有主机能力);按需 --cap-drop ALL 后仅 --cap-add 单项能力;只读根文件系统 --read-only;资源限额(--memory/--cpus)防资源耗尽;seccomp 默认 profile 已启用(Docker 默认阻断数十个高危系统调用,自定义见官方 Seccomp security profiles 章节);Ubuntu 宿主机确认 AppArmor profile 加载(官方 AppArmor security profiles for Docker 章节)。挂载最小化:不挂载 /etc/var/run/root 等宿主敏感目录,必需挂载尽量 :ro

验证方法docker inspect 的 Privileged/CapAdd/User/ReadonlyRootfs 字段抽查、docker info 的 Security Options(seccomp/apparmor)、特权容器清单为空或有例外审批。

核查方法

docker ps -q | xargs -I{} docker inspect {} --format \
  '{{.Name}} Priv={{.HostConfig.Privileged}} Caps={{.HostConfig.CapAdd}} User={{.Config.User}} RO={{.HostConfig.ReadonlyRootfs}}'
docker info --format '{{json .SecurityOptions}}'
docker ps -q | xargs -I{} docker inspect {} --format '{{.Name}} {{json .HostConfig.Binds}}'
示例输出(节选)
/demo-web Priv=false Caps=[] User=appuser RO=true
/demo-redis Priv=false Caps=[] User=999 RO=false
docker info --format '{{json .SecurityOptions}}'
["name=seccomp,profile=builtin","name=apparmor,profile=docker-default"]

加固操作(以运行命令与 Dockerfile 两条路径落地,变更需重启容器窗口)

# 运行命令侧:非 root + 全量去能力 + 按需加回 + 只读根 + 资源限额
docker run -d --name demo-web \
  --user 1000:1000 --cap-drop ALL --cap-add NET_BIND_SERVICE \
  --read-only --tmpfs /tmp --memory 512m --cpus 1.0 \
  --restart unless-stopped demo.local/app:v1.2.3
# Dockerfile 侧:镜像固化非 root 用户与最小内容
FROM registry.demo.local/base/nginx:1.24-alpine
RUN adduser -D -u 1000 appuser
USER appuser
  • 预期现象:特权容器清单为空;CapAdd 均有业务依据;业务回归正常。

04 用户命名空间重映射(userns-remap)与 rootless

对应控制点:GB/T 22239-2019 8.1.4.2 访问控制、8.1.4.4 入侵防范(提权防护)

加固要点:官方 userns-remap 机制:把容器内 root 重映射为宿主机无特权的高位 UID 区间(经 /etc/subuid/etc/subgid 管理,如 dockremap:231072:65536——容器内 UID 0 对应宿主 UID 231072,对宿主无任何特权)。daemon.json{"userns-remap": "default"} 由 Docker 自动创建 dockremap 用户(也可指定既有用户)。官方注意事项:启用后既有镜像与容器会被隔离(对象移入 /var/lib/docker/<uid>.<gid>/ 子目录,建议在新装环境启用);与 --privileged--pid=host--network=host 不兼容(需 --userns=host 显式豁免,豁免须审批)。更彻底的隔离用 Rootless 模式(守护进程与容器均无 root,见官方 Rootless mode 章节),适配场景有限时保留 sock 权限收敛补偿。

验证方法docker info 出现 userns 安全选项、grep dockremap /etc/subuid、宿主 /var/lib/docker/<uid>.<gid>/ 目录属主、容器内 root 对宿主文件无写入实测。

核查方法

docker info | grep -i -A2 "security"
grep dockremap /etc/subuid /etc/subgid
id dockremap
ls -ld /var/lib/docker/[0-9]*.[0-9]*/ 2>/dev/null
示例输出(节选)
$ grep dockremap /etc/subuid /etc/subgid
/etc/subuid:dockremap:231072:65536
/etc/subgid:dockremap:231072:65536
$ ls -ld /var/lib/docker/231072.231072/
drwx------ 11 231072 231072 4096 Jun 21 21:19 /var/lib/docker/231072.231072/

加固操作(新装环境优先;存量环境须先导出容器清单并安排重建窗口)

{ "userns-remap": "default" }
  • 预期现象:重启后 docker info Security options 含 userns;既有镜像列表为空(对象已隔离)属正常现象;容器内 cat /proc/self/uid_map 显示映射区间。

05 日志与审计

对应控制点:GB/T 22239-2019 8.1.4.3 安全审计 a)~d)

加固要点:容器日志三路汇聚并留存不少于 6 个月:容器 stdout 日志(daemon.json 的 log-driver+max-size+max-file,防磁盘占满即防日志丢失)、守护进程日志(journalctl -u docker,外送 rsyslog)、宿主机 auditd 对 Docker 关键路径的审计规则(docker.sock、daemon.json、/var/lib/docker 的变更)。容器内应用日志沿用宿主日志通道或独立采集器,不留在容器可写层。日志外送至日志审计系统(《网络安全法》第 21 条留存口径)。

验证方法docker info 日志驱动与轮转参数回显、auditd 规则 auditctl -l、日志平台中容器日志最早时间戳。

核查方法

docker info --format '{{.LoggingDriver}}'
grep -A4 "log-driver" /etc/docker/daemon.json
journalctl -u docker --no-pager | tail -n 5
auditctl -l | grep docker
示例输出(节选)
$ grep -A4 "log-driver" /etc/docker/daemon.json
"log-driver": "json-file",
"log-opts": { "max-size": "50m", "max-file": "5" }
$ auditctl -l | grep docker
-w /etc/docker/daemon.json -p wa -k docker_config
-w /var/run/docker.sock -p wa -k docker_sock

加固操作

# auditd 规则(/etc/audit/rules.d/docker.rules,载入后 auditctl -R 或重启 auditd)
cat > /etc/audit/rules.d/docker.rules <<'EOF'
-w /etc/docker/daemon.json -p wa -k docker_config
-w /etc/docker -p wa -k docker_dir
-w /var/run/docker.sock -p wa -k docker_sock
EOF
augenrules --load
  • 预期现象:规则加载成功;日志平台可检索 6 个月以上容器事件;docker inspect 日志路径在轮转目录内。

06 Kubernetes 控制面加固

对应控制点:GB/T 22239-2019 8.1.4.1 身份鉴别、8.1.4.2 访问控制、8.1.4.3 安全审计

加固要点:kube-apiserver 收敛:--anonymous-auth=false(默认 true,匿名请求映射 system:anonymous,关闭后未认证请求被拒)、--insecure-port 已废弃不得出现;RBAC 治理:cluster-admin ClusterRoleBinding 仅保留必要主体(审计 kubectl get clusterrolebindings cluster-admin -o wide),不为普通用户/组授予;准入链启用 NodeRestriction(kubelet 仅能修改自身 Node/Pod)与 Pod Security Admission(命名空间打 pod-security.kubernetes.io/enforce 标签,baseline/restricted 分级,v1.25 起稳定);审计策略 --audit-policy-file 全量覆盖(至少 metadata 级,认证失败与特权操作升 Request 级),--audit-log-maxage ≥180 满足 6 个月留存(现行默认 366);管理入口仅经堡垒机/运维网段访问 6443。ServiceAccount 治理:默认 token 自 v1.24 不再自动投影长期令牌,automountServiceAccountToken: false 按业务显式关闭。

验证方法:apiserver 启动参数核查(静态 Pod YAML/kubectl get --raw='/readyz?verbose')、无凭据 curl 6443 返回 401 实测、cluster-admin 绑定清单、审计日志样例(含 user/verb/resource/时间)、namespace PSA 标签清单。

核查方法

kubectl get pods -n kube-system -l component=kube-apiserver -o yaml | grep -E "anonymous-auth|audit-policy|authorization-mode|admission"
kubectl get clusterrolebindings cluster-admin -o wide
kubectl get ns -L pod-security.kubernetes.io/enforce
curl -sk https://192.168.10.5:6443/version    # 预期 401 Unauthorized
kubectl auth can-i --list --as=system:anonymous
示例输出(节选)
$ grep -E "anonymous-auth|authorization-mode" <apiserver.yaml>
- --anonymous-auth=false
- --authorization-mode=Node,RBAC
$ curl -sk https://192.168.10.5:6443/version
{
  "kind": "Status",
  "code": 401, ...
}
$ kubectl get clusterrolebindings cluster-admin -o wide
NAME          ROLE                        SUBJECTS
cluster-admin ClusterRole/cluster-admin   Group/system:masters      # 仅控制面组

加固操作(修改 /etc/kubernetes/manifests/kube-apiserver.yaml 后静态 Pod 自动重启,须维护窗口)

- command:
  - kube-apiserver
  - --anonymous-auth=false
  - --authorization-mode=Node,RBAC
  - --enable-admission-plugins=NodeRestriction
  - --audit-policy-file=/etc/kubernetes/audit-policy.yaml
  - --audit-log-path=/var/log/kubernetes/audit.log
  - --audit-log-maxage=365
  - --audit-log-maxbackup=10
  - --audit-log-maxsize=100
  • 预期现象:匿名请求 401;审计日志持续落盘且含认证失败事件;PSA enforce 标签覆盖全部业务命名空间。

07 Kubernetes 数据面与 etcd 加密

对应控制点:GB/T 22239-2019 8.1.4.7 数据完整性、8.1.4.8 数据保密性

加固要点:etcd 是集群全量状态库,三级要求落地三件事:静态加密——kube-apiserver 启用 --encryption-provider-config(EncryptionConfiguration,官方现行推荐 secretbox 加密 Secret;kms v2 自 v1.29 稳定,对接外部 KMS 更佳),并以 k8s:enc: 前缀验证实际落密;传输加密——apiserver 与 etcd 间 --etcd-cafile/--etcd-certfile/--etcd-keyfile 证书双向认证,etcd 2379 仅监听管理网/本机(ss -lntp | grep 2379);访问控制——etcd 证书与 key 文件权限 600,仅控制面节点可达。数据面:Pod 出网按 NetworkPolicy 白名单化(默认全通须整改);Secret 不落明文(避免 env 明文注入,优先 volume 挂载或外部密钥管理);镜像来源与签名策略经准入(Gatekeeper/Kyverno 或仓库侧策略)管控。

验证方法kubectl get secret -o jsonpath 数据带 k8s:enc: 前缀、etcdctl 直读为密文、2379 监听地址与防火墙策略、NetworkPolicy 覆盖清单。

核查方法

kubectl get secret demo-secret -n demo-ns -o jsonpath='{.data.password}' | base64 -d | head -c 40
grep -R "encryption-provider-config\|etcd-cafile" /etc/kubernetes/
ss -lntp | grep 2379
kubectl get networkpolicy -A
ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key \
  get /kubernetes/secrets/demo-ns/demo-secret --print-value-only | head -c 60
示例输出(节选)
$ kubectl get secret demo-secret -o jsonpath='{.data.password}' | base64 -d | head -c 40
k8s:enc:aescbc:v1:key1:fi��...            # k8s:enc: 前缀=已静态加密
$ etcdctl get ... --print-value-only | head -c 60
k8s:enc:aescbc:v1:key1:��}...            # etcd 侧同为密文
$ ss -lntp | grep 2379
LISTEN 0 128 192.168.10.5:2379 users:(("etcd",pid=990,fd=6))   # 未绑 0.0.0.0

加固操作(先创建 EncryptionConfiguration,再改 apiserver 参数重启;旧 Secret 须重写一遍才会被加密——官方文档以 kubectl get secrets --all-namespaces -o json | kubectl replace -f - 触发重写)

# /etc/kubernetes/enc-config.yaml(官方 Encrypting Secret Data at Rest 章节示例结构)
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources: ["secrets"]
  providers:
  - secretbox:
      keys:
      - name: key1
        secret: <32字节随机base64>
  - identity: {}
  • 预期现象:新写入 Secret 带 k8s:enc: 前缀;etcd 直读密文;2379 不对业务网段开放。

08 Harbor 私有仓库加固

对应控制点:GB/T 22239-2019 8.1.4.1~8.1.4.4(仓库作为镜像供应链核心组件)

加固要点harbor.yml 强制 HTTPS(自签证书须向 docker daemon 与 k8c节点分发 CA;HTTP-only 对外即高风险);harbor_admin_password首次启动从配置文件读取(改口令须登录控制台,不能只改 yml——官方 Reconfigure 文档口径),初始 Harbor12345 必改;认证模式按需接 OIDC/LDAP(db_auth 本地账户配强口令策略);关闭 self_registration 自助注册(按需);项目公开性默认私有、按最小可见开放;机器人账号(robot account)替代人员共享凭据拉取,设有效期与最小项目权限;Trivy 漏洞扫描开启并配置「高危阻断拉取」策略(Prevent images with vulnerability severity of High or higher from pulling);部署后启用审计日志留存与日志外送;定期垃圾回收(GC)清理无引用镜像层。

验证方法:HTTPS 访问与证书有效期、admin 口令登录实测、GET /api/v2.0/configurations 的 self_registration/scan 策略回显、机器人账号清单与到期时间、GC 计划任务截图。

核查方法

grep -E "^hostname|^https|admin_password" /path/to/harbor/harbor.yml | sed 's/password.*/password: ***/'
curl -s -o /dev/null -w "%{http_code}\n" https://registry.demo.local/api/v2.0/health
curl -su admin:*** https://registry.demo.local/api/v2.0/configurations | jq '.self_registration, .scan_all_policy'
docker compose ps        # Harbor 安装目录(v2 语法)
示例输出(节选)
$ curl -s https://registry.demo.local/api/v2.0/health
{"status":"healthy","components":[]}
$ curl -su admin:*** .../api/v2.0/configurations | jq '.self_registration'
false        # 自助注册已关闭

加固操作harbor.yml 修改后执行 ./preparedocker compose down && docker compose up -d,须窗口)

# harbor.yml 关键项
hostname: registry.demo.local
https:
  certificate: /data/cert/registry.crt
  private_key: /data/cert/registry.key
harbor_admin_password: <首次部署时的强口令,之后经控制台修改>
  • 预期现象:HTTP 跳转 HTTPS;扫描策略生效(高危镜像 pull 被拒实测);机器人账号按项目最小授权。

09 备份恢复

对应控制点:GB/T 22239-2019 8.1.4.9 数据备份恢复 a)~c)

加固要点:三平台各自的恢复面:Docker——daemon.json、证书、自定义 systemd 单元与命名数据卷纳入配置管理,容器重建以编排(compose 文件/K8s 清单)为准而非手工 docker run 复现;Kubernetes——etcd 定期快照(etcdctl snapshot save;v3.5+ 校验用 etcdutl snapshot status)异地存放,Velero 备份工作负载与 PV,恢复演练每半年至少一次并留痕;Harbor——按官方升级/备份章节导出 /data/database、registry 存储、harbor.yml 与 secrets 归档。集群多副本(etcd 3 节点、控制面 HA)作为冗余不替代备份。

验证方法:快照清单与 snapshot status 输出、Velero 备份清单(velero backup get)、Harbor 归档清单、最近一次恢复演练记录。

核查方法

ls -l /backup/etcd-snapshots/ | tail -n 3
ETCDCTL_API=3 etcdutl snapshot status /backup/etcd-snapshots/snap-latest.db -w table 2>/dev/null \
  || ETCDCTL_API=3 etcdctl snapshot status /backup/etdb-snapshots/snap-latest.db -w table
velero backup get
docker run --rm -v /backup:/backup -v /var/lib/docker/volumes:/volumes alpine ls /backup
示例输出(节选)
$ etcdutl snapshot status /backup/etcd-snapshots/snap-latest.db -w table
+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 0x1a2b3c |  8941234 |       2011 |      29 MB |
+----------+----------+------------+------------+

加固操作(快照属运维变更,按计划任务窗口执行)

# etcd 定期快照(cron 示例)
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  snapshot save /backup/etcd-snapshots/snap-$(date +%F).db
  • 预期现象:快照按期生成且 snapshot status 校验通过;恢复演练记录在案。

10 剩余信息保护与版本生命周期

对应控制点:GB/T 22239-2019 8.1.4.10 剩余信息保护、8.1.4.4 入侵防范(补丁管理)

核查方法

docker ps -a --filter "status=exited" --format "{{.Names}} {{.RunningFor}}"
docker images --format "{{.Repository}}:{{.Tag}} {{.CreatedSince}}" | sort -k2 | head
docker ps -q | xargs -I{} docker inspect {} --format '{{.Name}}' | wc -l
kubectl get secrets -A | wc -l
  • 加固要点:停用容器、超过留存期的旧镜像、失效 ServiceAccount 令牌与机器人凭据定期清理并留处置记录(docker container prune/docker image prune 属变更类,走审批);环境变量中的明文口令改用 secret 机制(Docker secrets/K8s Secret 加密/外部 KMS)。
  • 版本生命周期:Kubernetes 官方仅维护最近三个小版本(升级滚动计划);Docker Engine 跟随发行版/官方源补丁;Harbor 跟随 goharbor releases;三平台升级台账与窗口记录纳入测评证据。
  • 预期现象:无长期 Exited 容器与半年以上未引用镜像;凭据无明文残留;升级记录完整。

参考依据

关联文章