如何check k8s集群中所有pod背后的镜像的jre/jdk证书库中是否导入了CFCA根证书?
#!/bin/bash
# 检查命名空间参数
NAMESPACE="${1:-test}"
if ! kubectl get ns "$NAMESPACE" &> /dev/null; then
echo "错误: 命名空间 $NAMESPACE 不存在或无法访问"
exit 1
fi
# 获取所有镜像并去重
echo "正在获取 $NAMESPACE 命名空间中的镜像..."
IMAGES=$(kubectl get pods -n "$NAMESPACE" -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u)
if [ -z "$IMAGES" ]; then
echo "未找到任何镜像"
exit 2
fi
echo -e "\n发现以下镜像:"
echo "$IMAGES"
echo "========================================"
# 拉取所有镜像
echo "开始拉取镜像..."
for IMAGE in $IMAGES; do
echo "拉取: $IMAGE"
if ! docker pull -q "$IMAGE" > /dev/null; then
echo "警告: 拉取 $IMAGE 失败"
fi
done
echo "========================================"
echo
# 检查CFCA证书的函数
check_cfca() {
local IMAGE=$1
echo "检查镜像: $IMAGE"
# 使用临时容器执行检查
docker run --rm -i --entrypoint=/bin/sh "$IMAGE" <<'EOF'
#!/bin/sh
set -e
# 获取Java路径
find_java() {
# 检查JAVA_HOME环境变量
if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then
echo "$JAVA_HOME"
return 0
fi
# 检查PATH中的java命令
if command -v java >/dev/null 2>&1; then
JAVA_PATH=$(command -v java)
# 解析符号链接
while [ -L "$JAVA_PATH" ]; do
LINK=$(ls -l "$JAVA_PATH" | awk '{print $NF}')
if [ "${LINK:0:1}" = "/" ]; then
JAVA_PATH="$LINK"
else
JAVA_PATH="$(dirname "$JAVA_PATH")/$LINK"
fi
done
JAVA_HOME=$(dirname "$(dirname "$JAVA_PATH")")
echo "$JAVA_HOME"
return 0
fi
# 尝试常见路径
for path in /usr/lib/jvm/* /usr/java/*; do
if [ -x "$path/bin/java" ]; then
echo "$path"
return 0
fi
done
echo "未找到Java环境" >&2
return 1
}
# 查找证书库
find_keystore() {
local JAVA_HOME=$1
# 尝试常见位置(不使用数组)
for path in \
"$JAVA_HOME/lib/security/cacerts" \
"$JAVA_HOME/jre/lib/security/cacerts" \
"/etc/ssl/certs/java/cacerts" \
"/etc/pki/java/cacerts"; do
if [ -f "$path" ]; then
echo "$path"
return 0
fi
done
echo "未找到证书库" >&2
return 2
}
# 主检查逻辑
JAVA_HOME=$(find_java)
if [ $? -ne 0 ]; then
exit 1
fi
echo "发现JAVA_HOME: $JAVA_HOME"
KEYSTORE=$(find_keystore "$JAVA_HOME")
if [ $? -ne 0 ]; then
exit 2
fi
echo "使用证书库: $KEYSTORE"
# 检查CFCA证书
if "$JAVA_HOME/bin/keytool" -list -keystore "$KEYSTORE" -storepass changeit 2>/dev/null | grep -q -i "cfca"; then
exit 0
else
exit 3
fi
EOF
# 处理检查结果
EXIT_CODE=$?
case $EXIT_CODE in
0) echo "✅ 结果: CFCA证书存在" ;;
1) echo "⚠️ 结果: 未找到Java环境" ;;
2) echo "⚠️ 结果: 未找到证书库" ;;
3) echo "⚠️ 结果: CFCA证书不存在" ;;
*) echo "⚠️ 结果: 检查失败 (错误码: $EXIT_CODE)" ;;
esac
echo "----------------------------------------"
}
# 检查所有镜像的CFCA证书
echo "开始检查CFCA证书..."
for IMAGE in $IMAGES; do
check_cfca "$IMAGE"
done
echo "所有操作完成!!!"
注意事项:
- 符号链接解析:
- 脚本现在使用更兼容的方法解析符号链接,适用于各种基础镜像
- 如果遇到多层符号链接,脚本会递归解析直到找到真实路径
- 路径检查:
- 脚本会尝试多个可能的证书库位置,即使
JAVA_HOME设置正确 - 包含系统级证书库路径作为备选
- 错误处理:
- 每个可能失败的点都有明确的退出代码
- 输出会显示具体的失败原因和位置
这个修复版脚本应该能够避免之前的语法错误,并在各种环境下正确运行,同时保持原有的功能:获取镜像、拉取镜像、检查Java证书库中的CFCA证书。
如何check k8s集群中所有pod的jre/jdk证书库中是否导入了CFCA根根证书?
#!/bin/bash
namespace="test"
log_file="check_cfca_certs.log"
# 清空或创建日志文件
> "$log_file"
# 获取所有 Pod 名称
pods=$(kubectl get pods -n $namespace -o jsonpath='{.items[*].metadata.name}')
# 存储没有 CFCA 证书的 Pod
no_cfca_pods=()
{
for pod in $pods; do
pod_has_cfca=false
echo "===== 检查 Pod: $pod ====="
# 获取容器列表(支持多容器 Pod)
containers=$(kubectl get pod $pod -n $namespace -o jsonpath='{.spec.containers[*].name}')
for container in $containers; do
echo "--- 容器: $container ---"
# 1. 获取 JAVA_HOME 环境变量
java_home=$(kubectl exec $pod -n $namespace -c $container -- sh -c 'echo $JAVA_HOME' 2>/dev/null)
# 2. 如果未设置 JAVA_HOME,尝试通过 which java 推导
if [ -z "$java_home" ]; then
java_home=$(kubectl exec $pod -n $namespace -c $container -- sh -c \
'which java >/dev/null 2>&1 && dirname $(dirname $(readlink -f $(which java)))' 2>/dev/null)
fi
# 检查是否找到 JAVA_HOME
if [ -z "$java_home" ]; then
echo "未找到 JAVA_HOME,跳过检查"
continue
fi
echo "检测到 JAVA_HOME: $java_home"
# 3. 检查证书库
certstore_paths=(
"$java_home/jre/lib/security/cacerts" # JDK 8 及更早版本
"$java_home/lib/security/cacerts" # JDK 9 及以上版本
)
for certstore in "${certstore_paths[@]}"; do
# 检查证书文件是否存在
kubectl exec $pod -n $namespace -c $container -- test -f "$certstore" >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "证书库不存在: $certstore"
continue
fi
# 执行证书检查
echo "检查证书库: $certstore"
result=$(kubectl exec $pod -n $namespace -c $container -- \
sh -c "keytool -list -keystore '$certstore' -storepass changeit 2>&1 | grep -i 'cfca'" 2>/dev/null)
if [ -n "$result" ]; then
echo "发现 CFCA 证书"
pod_has_cfca=true
else
echo "未找到 CFCA 证书"
fi
done
done
# 记录没有 CFCA 证书的 Pod
if ! $pod_has_cfca; then
no_cfca_pods+=("$pod")
fi
done
# 输出没有 CFCA 证书的 Pod 列表
echo "===== 没有 CFCA 证书的 Pod ====="
if [ ${#no_cfca_pods[@]} -eq 0 ]; then
echo "所有 Pod 都包含 CFCA 证书"
else
for pod in "${no_cfca_pods[@]}"; do
echo "$pod"
done
fi
} | tee -a "$log_file"
echo "检查完成,结果已保存到: $log_file !!!"
参考
全球顶级商业CA机构(市场主导者)
https://blog.51cto.com/u_16555391/14188944