六、控制平面高可用(VIP 管理)部署

6.1 部署前环境检查

# 1. 检查集群状态
echo "=== 检查集群状态 ==="
kubectl get nodes

# 2. 检查API Server端口监听
echo "=== 检查API Server端口监听 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 检查节点 $node ==="
  ssh $node "netstat -tuln | grep :6443 || echo '6443端口未监听'"
done

# 3. 检查VIP 192.168.30.100 (此时应不可达,因为还未部署)
echo "=== 检查VIP 192.168.30.100 (部署前) ==="
ping -c 3 192.168.30.100 || echo "VIP 192.168.30.100 当前不可达 (正常)"

# 4. 检查系统资源
echo "=== 检查系统资源 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 节点 $node ==="
  ssh $node "free -h | head -2"
  ssh $node "df -h | head -2"
done

# 5. 检查网络连通性
echo "=== 检查网络连通性 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 从 k8s-master-1 到 $node ==="
  ssh k8s-master-1 "ping -c 3 $node"
done

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.2 安装Keepalived(所有Master节点执行)

# 1. 安装Keepalived
echo "=== 安装Keepalived ==="
yum install -y keepalived

# 2. 验证安装
echo "=== 验证安装 ==="
keepalived --version

在这里插入图片描述

6.3 配置Keepalived(各Master节点分别执行)

说明: 使用 Keepalived 的 vrrp_instance 实现 VIP 的高可用(故障转移)。

6.3.1 在k8s-master-1配置Keepalived(MASTER节点)
# 1. 备份原始Keepalived配置
echo "=== 备份原始Keepalived配置 ==="
cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

# 2. 创建Keepalived配置(MASTER节点)- **仅使用 VRRP 实现高可用**
echo "=== 创建Keepalived配置(MASTER节点 - VRRP Only) ==="
cat > /etc/keepalived/keepalived.conf << 'EOF'
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL # 保持原有名称,但实际不使用 LVS
}

# VRRP 实例,用于管理 VIP
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.30.100
    }
}
EOF

# 3. 启动Keepalived服务
echo "=== 启动Keepalived服务 ==="
systemctl start keepalived
systemctl enable keepalived

# 4. 验证Keepalived启动
echo "=== 验证Keepalived启动 ==="
systemctl status keepalived --no-pager | head -10

# 5. 验证VIP绑定 (此时 VIP 应该在 k8s-master-1 上)
echo "=== 验证VIP绑定 ==="
ip addr show | grep 192.168.30.100

在这里插入图片描述

6.3.2 在k8s-master-2配置Keepalived(BACKUP节点)
# 1. 备份原始Keepalived配置
echo "=== 备份原始Keepalived配置 ==="
cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

# 2. 创建Keepalived配置(BACKUP节点)- **仅使用 VRRP 实现高可用**
echo "=== 创建Keepalived配置(BACKUP节点 - VRRP Only) ==="
cat > /etc/keepalived/keepalived.conf << 'EOF'
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

# VRRP 实例,用于管理 VIP
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.30.100
    }
}
EOF

# 3. 启动Keepalived服务
echo "=== 启动Keepalived服务 ==="
systemctl start keepalived
systemctl enable keepalived

# 4. 验证Keepalived启动
echo "=== 验证Keepalived启动 ==="
systemctl status keepalived --no-pager | head -10

# 5. 验证VIP绑定(此时应该没有VIP,因为 k8s-master-1 是 MASTER)
echo "=== 验证VIP绑定(此时应该没有VIP) ==="
ip addr show | grep 192.168.30.100 || echo "VIP未绑定(正常)"

在这里插入图片描述

6.3.3 在k8s-master-3配置Keepalived(BACKUP节点)
# 1. 备份原始Keepalived配置
echo "=== 备份原始Keepalived配置 ==="
cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

# 2. 创建Keepalived配置(BACKUP节点)- **仅使用 VRRP 实现高可用**
echo "=== 创建Keepalived配置(BACKUP节点 - VRRP Only) ==="
cat > /etc/keepalived/keepalived.conf << 'EOF'
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

# VRRP 实例,用于管理 VIP
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.30.100
    }
}
EOF

# 3. 启动Keepalived服务
echo "=== 启动Keepalived服务 ==="
systemctl start keepalived
systemctl enable keepalived

# 4. 验证Keepalived启动
echo "=== 验证Keepalived启动 ==="
systemctl status keepalived --no-pager | head -10

# 5. 验证VIP绑定(此时应该没有VIP,因为 k8s-master-1 是 MASTER)
echo "=== 验证VIP绑定(此时应该没有VIP) ==="
ip addr show | grep 192.168.30.100 || echo "VIP未绑定(正常)"

在这里插入图片描述

6.4 更新API Server证书(在所有Master节点执行)

重要: 在 VIP 高可用部署完成后,必须更新所有 API Server 的证书,使其包含 VIP 192.168.30.100,否则 kubectl 无法通过 VIP 连接。

# 1. 确保 kubeadm-config.yaml 文件包含 certSANs
echo "=== 检查 kubeadm-config.yaml certSANs ==="
grep -A 10 -B 5 certSANs /root/kubeadm-config.yaml

# 2. 备份现有 PKI
echo "=== 备份现有 PKI ==="
sudo cp -r /etc/kubernetes/pki /etc/kubernetes/pki.backup.$(date +%Y%m%d_%H%M%S)

# 3. 在 k8s-master-1 上更新证书
echo "=== 在 k8s-master-1 上更新证书 ==="
sudo kubeadm certs renew apiserver --config=/root/kubeadm-config.yaml

# 4. 在 k8s-master-1 上重启 kubelet
echo "=== 在 k8s-master-1 上重启 kubelet ==="
sudo systemctl restart kubelet

# 5. 在 k8s-master-1 上强制重建 API Server Pod
echo "=== 在 k8s-master-1 上重建 API Server Pod ==="
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
sleep 10
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/

# 6. 将 kubeadm-config.yaml 文件复制到 k8s-master-2 和 k8s-master-3
echo "=== 复制 kubeadm-config.yaml 到其他节点 ==="
scp /root/kubeadm-config.yaml k8s-master-2:/root/
scp /root/kubeadm-config.yaml k8s-master-3:/root/

# 7. 在 k8s-master-2 上更新证书和重建 API Server Pod
echo "=== 在 k8s-master-2 上更新证书和重建 API Server Pod ==="
ssh k8s-master-2 "sudo kubeadm certs renew apiserver --config=/root/kubeadm-config.yaml && sudo systemctl restart kubelet && sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/ && sleep 10 && sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/"

# 8. 在 k8s-master-3 上更新证书和重建 API Server Pod
echo "=== 在 k8s-master-3 上更新证书和重建 API Server Pod ==="
ssh k8s-master-3 "sudo kubeadm certs renew apiserver --config=/root/kubeadm-config.yaml && sudo systemctl restart kubelet && sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/ && sleep 10 && sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/"

# 9. 验证证书是否包含 VIP (在 k8s-master-1 上执行)
echo "=== 验证证书是否包含 VIP ==="
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep -A 1 "Subject Alternative Name"

在这里插入图片描述
在这里插入图片描述

6.5 验证高可用部署

# 1. 检查VIP绑定状态
echo "=== 检查VIP绑定状态 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 节点 $node ==="
  ssh $node "ip addr show | grep 192.168.30.100 || echo 'VIP未绑定'"
done

# 2. 测试VIP连通性
echo "=== 测试VIP连通性 ==="
ping -c 3 192.168.30.100

# 3. 测试API Server健康检查 (通过VIP)
echo "=== 测试API Server健康检查 (通过VIP) ==="
curl -k https://192.168.30.100:6443/healthz --connect-timeout 5

# 4. 检查Keepalived服务状态
echo "=== 检查Keepalived服务状态 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 节点 $node ==="
  ssh $node "systemctl status keepalived --no-pager | head -5"
done

# 5. 验证Kubernetes集群连接 (使用VIP)
echo "=== 验证Kubernetes集群连接 (使用VIP) ==="
kubectl cluster-info
kubectl get nodes
kubectl get pods -n kube-system # 多次执行,观察稳定性

在这里插入图片描述
在这里插入图片描述

6.6 VIP漂移测试

# 1. 查看当前VIP绑定节点
echo "=== 查看当前VIP绑定节点 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  if ssh $node "ip addr show | grep 192.168.30.100" > /dev/null 2>&1; then
    echo "VIP当前绑定在: $node"
  fi
done

# 2. 停止当前VIP绑定节点的Keepalived服务 (例如 k8s-master-1)
echo "=== 停止当前VIP绑定节点的Keepalived服务 ==="
# 假设VIP当前绑定在k8s-master-1
ssh k8s-master-1 "systemctl stop keepalived"

# 3. 等待VIP漂移 (VRRP心跳周期 x 3)
echo "=== 等待VIP漂移(约3秒) ==="
sleep 5

# 4. 查看VIP漂移后的绑定节点
echo "=== 查看VIP漂移后的绑定节点 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  if ssh $node "ip addr show | grep 192.168.30.100" > /dev/null 2>&1; then
    echo "VIP漂移到: $node"
  fi
done

# 5. 测试VIP连通性
echo "=== 测试VIP连通性 ==="
ping -c 3 192.168.30.100

# 6. 测试API Server健康检查 (通过漂移后的VIP)
echo "=== 测试API Server健康检查 (通过漂移后的VIP) ==="
curl -k https://192.168.30.100:6443/healthz --connect-timeout 5

# 7. 验证Kubernetes集群连接 (通过漂移后的VIP)
echo "=== 验证Kubernetes集群连接 (通过漂移后的VIP) ==="
kubectl cluster-info
kubectl get nodes
kubectl get pods -n kube-system # 多次执行,观察稳定性

# 8. 恢复k8s-master-1的Keepalived服务
echo "=== 恢复k8s-master-1的Keepalived服务 ==="
ssh k8s-master-1 "systemctl start keepalived"

# 9. 等待VIP恢复 (取决于抢占策略,默认开启)
echo "=== 等待VIP恢复(取决于抢占策略) ==="
sleep 5

# 10. 查看VIP恢复后的绑定节点
echo "=== 查看VIP恢复后的绑定节点 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  if ssh $node "ip addr show | grep 192.168.30.100" > /dev/null 2>&1; then
    echo "VIP恢复到: $node"
  fi
done

可以看到,VIP飘移到了k8s-master-2节点
在这里插入图片描述
在这里插入图片描述
恢复复k8s-master-1的Keepalived服务
在这里插入图片描述

6.7 监控与日志

# 1. 查看Keepalived日志
echo "=== 查看Keepalived日志 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 节点 $node ==="
  ssh $node "journalctl -u keepalived -f"
done

# 2. 查看VIP状态
echo "=== 查看VIP状态 ==="
watch -n 1 'for node in k8s-master-1 k8s-master-2 k8s-master-3; do echo "=== $node ==="; ssh $node "ip addr show | grep 192.168.30.100 || echo VIP未绑定"; done'

# 3. 查看系统资源使用
echo "=== 查看系统资源使用 ==="
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 节点 $node ==="
  ssh $node "top -bn1 | head -20"
done

这个命令可以一直监控VIP状态
在这里插入图片描述
这个命令用于查看系统资源,后面可以搭配监控工具,设置告警规则,避免集群资源耗尽!
在这里插入图片描述

6.8 部署验证总结

# 1. 生成部署状态报告
echo "=== 生成控制平面高可用部署状态报告 ==="
echo "===== 控制平面高可用部署状态报告 =====" > /tmp/ha-status.txt
echo "" >> /tmp/ha-status.txt

echo "===== VIP绑定状态 =====" >> /tmp/ha-status.txt
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 节点 $node ===" >> /tmp/ha-status.txt
  ssh $node "ip addr show | grep 192.168.30.100 || echo 'VIP未绑定'" >> /tmp/ha-status.txt
  echo "" >> /tmp/ha-status.txt
done

echo "===== Keepalived服务状态 =====" >> /tmp/ha-status.txt
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 节点 $node ===" >> /tmp/ha-status.txt
  ssh $node "systemctl status keepalived --no-pager | head -5" >> /tmp/ha-status.txt
  echo "" >> /tmp/ha-status.txt
done

echo "===== 端口监听状态 =====" >> /tmp/ha-status.txt
for node in k8s-master-1 k8s-master-2 k8s-master-3; do
  echo "=== 节点 $node ===" >> /tmp/ha-status.txt
  ssh $node "netstat -tuln | grep :6443" >> /tmp/ha-status.txt
  echo "" >> /tmp/ha-status.txt
done

echo "===== Kubernetes集群状态 =====" >> /tmp/ha-status.txt
kubectl get nodes >> /tmp/ha-status.txt
kubectl get cs >> /tmp/ha-status.txt
echo "" >> /tmp/ha-status.txt

# 2. 显示报告
echo "=== 控制平面高可用部署状态报告 ==="
cat /tmp/ha-status.txt

# 3. 保存报告
echo "=== 部署状态报告已保存到 /tmp/ha-status.txt ==="

# 4. 验证检查清单
echo "=== 控制平面高可用部署验证检查清单 ==="
echo "✓ VIP 192.168.30.100 已绑定到 MASTER 节点"
echo "✓ Keepalived服务在所有Master节点运行"
echo "✓ 端口6443正常监听"
echo "✓ VIP可以正常漂移"
echo "✓ API Server证书包含VIP"
echo "✓ Kubernetes集群可通过VIP连接且稳定"
echo ""
echo "如果以上所有项都正常,恭喜您!控制平面高可用部署成功!"

七、Harbor私有镜像仓库部署(“k8s-master-2”)

7.1 部署前环境检查

# 1. 检查Docker服务状态
echo "=== 检查Docker服务状态 ==="
systemctl status docker --no-pager | head -10
docker version

# 2. 检查Docker Compose版本
echo "=== 检查Docker Compose版本 ==="
docker-compose --version

# 3. 检查系统资源
echo "=== 检查系统资源 ==="
free -h | head -2
df -h | head -2

# 4. 检查端口占用情况
echo "=== 检查端口占用情况 ==="
netstat -tuln | grep -E ':(80|443|8080|8443)' || echo "端口80/443/8080/8443未被占用"

# 5. 检查磁盘空间
echo "=== 检查磁盘空间 ==="
df -h /data
df -h /var/lib/docker

# 6. 检查网络连通性
echo "=== 检查网络连通性 ==="
ping -c 3 192.168.30.11
curl -I https://github.com --connect-timeout 5

7.2 下载Harbor离线安装包

# 1. 创建Harbor安装目录
echo "=== 创建Harbor安装目录 ==="
mkdir -p /data/harbor
cd /data/harbor

# 2. 下载Harbor离线安装包(v2.5.5)
echo "=== 下载Harbor离线安装包 ==="
wget https://github.com/goharbor/harbor/releases/download/v2.5.5/harbor-offline-installer-v2.5.5.tgz

# 3. 验证下载
echo "=== 验证下载 ==="
ls -lh harbor-offline-installer-v2.5.5.tgz

# 4. 解压安装包
echo "=== 解压Harbor安装包 ==="
tar zxvf harbor-offline-installer-v2.5.5.tgz

# 5. 查看解压内容
echo "=== 查看解压内容 ==="
ls -lh

# 6. 进入Harbor目录
cd harbor

7.3 配置Harbor

# 1. 备份原始配置文件
echo "=== 备份原始配置文件 ==="
cp harbor.yml.tmpl harbor.yml.bak

# 2. 创建Harbor配置文件
echo "=== 创建Harbor配置文件 ==="
cat > harbor.yml << EOF
# Harbor配置文件
_version: 2.5.0

hostname: 192.168.30.11

# HTTP/HTTPS协议配置
http:
  port: 80
https:
  port: 443
  certificate: /data/harbor/ssl/192.168.30.11.crt
  private_key: /data/harbor/ssl/192.168.30.11.key

# Harbor管理员密码
harbor_admin_password: Harbor@123456

# 数据库配置(使用内置PostgreSQL)
database:
  password: root123
  max_idle_conns: 100
  max_open_conns: 900

# 数据存储路径
data_volume: /data/harbor/data

# 日志位置 (新增此部分以解决 KeyError: 'log_location')


# 日志配置 (新增此部分以解决 KeyError: 'level')
log:
  level: info
  local:
    location: /data/harbor/data/log # 设置日志存储位置
  # 保留原有的日志轮转配置
  # log_rotation_count 和 log_rotation_size 可以放在这里或保持在顶层
  # 如果放在 log 下,格式通常是:
  # rotate_count: 7
  # rotate_size: 100M # 示例大小

# 日志保留天数 (可以保留在顶层,但通常在 log 下配置)
log_rotation_count: 7
# log_rotation_size: 100M # 可选,设置单个日志文件大小上限

# 外部URL(可选)
external_url: https://192.168.30.11

# 邮件配置(可选)
email:
  host: smtp.example.com
  port: 465
  username: admin@example.com
  password: password
  from: admin <admin@example.com>
  ssl: true
  insecure_skip_verify: false

# 仓库配置
storage_quota_enabled: true
per_project_repo_quota: -1
per_project_registry_quota: -1

# 安全配置
security_mode: storagepolicy
compliance_mode: generate

# 作业服务配置 (解决上一个错误添加的)
jobservice:
  # 最大作业工作者数量
  max_job_workers: 10
  # 作业日志记录方式
  job_logger: file
  # Uncomment following lines to configure different logger
  # options are: "file", "stdout" and "redis"
  # job_logger: redis
  # redis_host: redis
  # redis_port: 6379
  # redis_password:
  # redis_db_index: 10
  # redis_tls: false
  # redis_sentinel_master_set:
  # redis_cluster_endpoints:

# 作业配置 (原有的日志配置)
job_log_max_backup: 168
job_log_retention_days: 7

# 通知配置
notification:
  webhook_job_max_retry: 3
  webhook_job_ping_interval: 5s
EOF

# 3. 验证配置文件
echo "=== 验证Harbor配置文件 ==="
cat harbor.yml

7.4 生成SSL证书

# 1. 创建SSL证书目录
echo "=== 创建SSL证书目录 ==="
mkdir -p /data/harbor/ssl
cd /data/harbor/ssl

# 2. 生成自签名SSL证书
echo "=== 生成自签名SSL证书 ==="
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout 192.168.30.11.key \
  -out 192.168.30.11.crt \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=Harbor/OU=IT/CN=192.168.30.11"

# 3. 生成证书签名请求(CSR)
echo "=== 生成证书签名请求 ==="
openssl req -new -nodes -newkey rsa:2048 \
  -keyout 192.168.30.11.csr \
  -out 192.168.30.11.csr \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=Harbor/OU=IT/CN=192.168.30.11"

# 4. 验证证书生成
echo "=== 验证证书生成 ==="
ls -lh

# 5. 设置证书权限
echo "=== 设置证书权限 ==="
chmod 600 192.168.30.11.key
chmod 644 192.168.30.11.crt

# 6. 查看证书信息
echo "=== 查看证书信息 ==="
openssl x509 -in 192.168.30.11.crt -noout -text | grep -A 2 "Subject"

7.5 部署Harbor

# 1. 执行Harbor安装脚本
echo "=== 执行Harbor安装脚本 ==="
cd /data/harbor/harbor
./install.sh

# 2. 等待Harbor启动
echo "=== 等待Harbor启动(约2-5分钟) ==="
sleep 30

# 3. 检查Harbor容器状态
echo "=== 检查Harbor容器状态 ==="
docker ps -a | grep goharbor

# 4. 检查Harbor服务状态
echo "=== 检查Harbor服务状态 ==="
docker-compose ps

# 5. 查看Harbor日志
echo "=== 查看Harbor日志 ==="
docker-compose logs --tail=50

# 6. 验证Harbor启动
echo "=== 验证Harbor启动 ==="
curl -I https://192.168.30.11 --insecure --connect-timeout 5

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.6 配置Docker信任Harbor

# 1. 创建Docker证书目录
echo "=== 创建Docker证书目录 ==="
mkdir -p /etc/docker/certs.d

# 2. 复制Harbor证书到Docker证书目录
echo "=== 复制Harbor证书到Docker证书目录 ==="
cp /data/harbor/ssl/192.168.30.11.crt /etc/docker/certs.d/192.168.30.11.crt

# 3. 配置Docker daemon信任Harbor
echo "=== 配置Docker daemon信任Harbor ==="
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://biiwlm2v.mirror.aliyuncs.com"
  ],
  "insecure-registries": [
    "192.168.30.11"
  ],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

# 4. 重启Docker服务
echo "=== 重启Docker服务 ==="
systemctl daemon-reload
systemctl restart docker

# 5. 验证Docker配置
echo "=== 验证Docker配置 ==="
docker info | grep -E "Registry Mirrors|Insecure Registries|Cgroup Driver|Storage Driver"

7.7 配置containerd信任Harbor

# 1. 创建containerd证书目录
echo "=== 创建containerd证书目录 ==="
mkdir -p /etc/containerd/certs.d/192.168.30.11

# 2. 复制Harbor证书到containerd证书目录
echo "=== 复制Harbor证书到containerd证书目录 ==="
cp /data/harbor/ssl/192.168.30.11.crt /etc/containerd/certs.d/192.168.30.11/harbor-ca.crt

# 3. 修改containerd配置
echo "=== 修改containerd配置 ==="
vim /etc/containerd/config.toml
# 主要是补充下面的这些,也就是确保存在下面的这些信息!:
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.30.11"]
  endpoint = ["https://192.168.30.11"] # 使用 https
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.30.11".config]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.30.11".config."http"]
      tls = false # 跳过 TLS 验证

# 4. 重启containerd服务
echo "=== 重启containerd服务 ==="
systemctl restart containerd

# 4. 重启containerd服务
echo "=== 重启containerd服务 ==="
systemctl restart containerd

# 5. 验证containerd配置
echo "=== 验证containerd配置 ==="
systemctl status containerd --no-pager | head -10

7.8 验证Harbor部署

# 1. 检查Harbor容器状态
echo "=== 检查Harbor容器状态 ==="
docker ps -a | grep goharbor

# 2. 检查Harbor服务状态
echo "=== 检查Harbor服务状态 ==="
docker-compose ps

# 3. 测试Harbor访问
echo "=== 测试Harbor访问 ==="
curl -I https://192.168.30.11 --insecure --connect-timeout 5

# 4. 查看Harbor日志
echo "=== 查看Harbor日志 ==="
docker-compose logs --tail=50

# 5. 检查Harbor端口监听
echo "=== 检查Harbor端口监听 ==="
netstat -tuln | grep -E ':(80|443)'

# 6. 检查Harbor数据目录
echo "=== 检查Harbor数据目录 ==="
ls -lh /data/harbor/data

7.9 登录Harbor并创建项目 (Web 界面方式)

# 1. 访问 Harbor Web 界面
打开浏览器,访问 https://192.168.30.11。由于使用的是自签名证书,浏览器会提示“不安全”,
请忽略警告并继续访问。

# 2. 登录 Harbor
用户名: admin
密码: Harbor@123456 (在 harbor.yml 中配置的 harbor_admin_password)
点击登录按钮。

# 3. 创建新项目
登录成功后,在左侧导航栏中点击 “项目”。
在项目列表页面,点击右上角的 “+ 新建项目” 按钮。
在弹出的对话框中:
项目名称: 输入 k8s (或你希望使用的项目名)。
公开性: 选择 “私有” (默认值)。
(可选)可以设置项目级别的存储配额等高级选项。
点击 “确定” 按钮。
# 4. 验证项目创建
创建成功后,新项目 k8s 会出现在项目列表中。
你可以点击项目名称进入项目详情页,查看其基本信息和权限设置。

在这里插入图片描述

7.10 推送镜像到Harbor

# 1. 拉取测试镜像
echo "=== 拉取测试镜像 ==="
docker pull nginx:1.14

# 2. 标记镜像
echo "=== 标记镜像 ==="
docker tag nginx:1.14 192.168.30.11/k8s/nginx:1.14

# 3. 推送镜像到Harbor
echo "=== 推送镜像到Harbor ==="
docker push 192.168.30.11/k8s/nginx:1.14

# 4. 验证镜像推送
echo "=== 验证镜像推送 ==="
curl -X GET "https://192.168.30.11/api/v2.0/projects/k8s/repositories/nginx/artifacts" \
  -H "Authorization: Basic YWRtaW46SGFyYm9yQDEyMzQ1NTY=" \
  -k

# 5. 查看Harbor镜像列表
echo "=== 查看Harbor镜像列表 ==="
curl -X GET "https://192.168.30.11/api/v2.0/repositories" \
  -H "Authorization: Basic YWRtaW46SGFyYm9yQDEyMzQ1NTY=" \
  -k

推送成功!
在这里插入图片描述
去web界面验证一下
在这里插入图片描述

7.11 配置Kubernetes使用Harbor

# 1. 创建Harbor Secret
echo "=== 创建Harbor Secret ==="
kubectl create secret docker-registry harbor-secret \
  --docker-server=192.168.30.11 \
  --docker-username=admin \
  --docker-password=Harbor@123456 \
  --docker-email=admin@example.com \
  -n default

# 2. 验证Secret创建
echo "=== 验证Secret创建 ==="
kubectl get secret harbor-secret -n default -o yaml

# 3. 这里我选择在k8s-master-1执行,所以需要先登录Harbor账号!
echo "=== 登录账号 ==="
docker login 192.168.30.11 -u admin -p Harbor@123456

# 4. 创建测试Deployment使用Harbor镜像
echo "=== 创建测试Deployment使用Harbor镜像 ==="
cat > harbor-test-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: harbor-test
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: harbor-test
  template:
    metadata:
      labels:
        app: harbor-test
    spec:
      imagePullSecrets:
      - name: harbor-secret
      containers:
      - name: nginx
        image: 192.168.30.11/k8s/nginx:1.14
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: harbor-test-svc
  namespace: default
spec:
  selector:
    app: harbor-test
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
EOF

kubectl apply -f harbor-test-deployment.yaml

# 5. 等待Pod启动
echo "=== 等待Pod启动 ==="
kubectl wait --for=condition=ready pod -l app=harbor-test -n default --timeout=120s

# 6. 查看Pod状态
echo "=== 查看Pod状态 ==="
kubectl get pods -n default -l app=harbor-test
kubectl get svc -n default

# 7. 测试应用访问
echo "=== 测试应用访问 ==="
kubectl run curl-test --image=curlimages/curl:latest --rm -it -- curl http://harbor-test-svc.default

在这里插入图片描述
测试是否能够访问
在这里插入图片描述
再开一个终端,确认是否能够访问,可以看到能够正常访问!
也进一步证明了:
·Harbor 镜像仓库部署成功。
·Kubernetes 配置 Harbor Secret 成功。
·Pod 成功从 Harbor 拉取镜像并运行。
·Service 正确暴露了 Pod。
在这里插入图片描述

7.12 故障排查与修复(这里仅供故障时参考)

7.12.1 Harbor无法启动
# 1. 检查Harbor容器状态
echo "=== 检查Harbor容器状态 ==="
docker ps -a | grep goharbor

# 2. 查看Harbor日志
echo "=== 查看Harbor日志 ==="
docker-compose logs --tail=100

# 3. 检查Harbor配置
echo "=== 检查Harbor配置 ==="
cat /data/harbor/harbor/harbor.yml

# 4. 检查端口占用
echo "=== 检查端口占用 ==="
netstat -tuln | grep -E ':(80|443)'

# 5. 检查磁盘空间
echo "=== 检查磁盘空间 ==="
df -h /data
df -h /var/lib/docker

# 6. 重新部署Harbor
echo "=== 重新部署Harbor ==="
cd /data/harbor/harbor
docker-compose down
./install.sh
7.12.2 无法登录Harbor
# 1. 检查Harbor服务状态
echo "=== 检查Harbor服务状态 ==="
curl -I https://192.168.30.11 --insecure --connect-timeout 5

# 2. 测试Harbor API
echo "=== 测试Harbor API ==="
curl -X GET "https://192.168.30.11/api/v2.0/systeminfo" \
  -H "Authorization: Basic YWRtaW46SGFyYm9yQDEyMzQ1NTY=" \
  -k

# 3. 检查Docker登录配置
echo "=== 检查Docker登录配置 ==="
cat ~/.docker/config.json

# 4. 清除Docker登录缓存
echo "=== 清除Docker登录缓存 ==="
docker logout 192.168.30.11

# 5. 重新登录Harbor
echo "=== 重新登录Harbor ==="
docker login 192.168.30.11 -u admin -p Harbor@123456
7.12.3 镜像推送失败
# 1. 检查Harbor项目是否存在
echo "=== 检查Harbor项目是否存在 ==="
curl -X GET "https://192.168.30.11/api/v2.0/projects" \
  -H "Authorization: Basic YWRtaW46SGFyYm9yQDEyMzQ1NTY=" \
  -k

# 2. 检查Docker登录状态
echo "=== 检查Docker登录状态 ==="
docker info | grep -A 5 "Registry"

# 3. 查看Docker推送日志
echo "=== 查看Docker推送日志 ==="
journalctl -u docker -n 50 --no-pager

# 4. 检查Harbor存储空间
echo "=== 检查Harbor存储空间 ==="
df -h /data/harbor/data

# 5. 重新推送镜像
echo "=== 重新推送镜像 ==="
docker push 192.168.30.11/k8s/nginx:1.14
7.12.4 Kubernetes无法拉取Harbor镜像
# 1. 检查Secret配置
echo "=== 检查Secret配置 ==="
kubectl get secret harbor-secret -n default -o yaml

# 2. 检查Pod事件
echo "=== 检查Pod事件 ==="
kubectl get events -n default --sort-by='.lastTimestamp'

# 3. 检查Pod镜像拉取日志
echo "=== 检查Pod镜像拉取日志 ==="
kubectl describe pod -l app=harbor-test -n default | grep -A 10 "Events"

# 4. 手动拉取镜像测试
echo "=== 手动拉取镜像测试 ==="
crictl pull 192.168.30.11/k8s/nginx:1.14

# 5. 检查containerd配置
echo "=== 检查containerd配置 ==="
crictl info | grep -A 10 "registry"

7.13 性能优化配置(这个项目主要是架构搭建,性能优化不进行深度修改)

# 1. 优化Harbor配置
echo "=== 优化Harbor配置 ==="
cat > /data/harbor/harbor/harbor.yml << 'EOF'
# Harbor优化配置文件
hostname: 192.168.30.11

# HTTP/HTTPS协议配置
http:
  port: 80
https:
  port: 443
  certificate: /data/harbor/ssl/192.168.30.11.crt
  private_key: /data/harbor/ssl/192.168.30.11.key

# Harbor管理员密码
harbor_admin_password: Harbor@123456

# 数据库配置(使用内置PostgreSQL)
database:
  password: root123
  max_idle_conns: 100
  max_open_conns: 900

# 数据存储路径
data_volume: /data/harbor/data

# 日志级别
log_level: info

# 日志保留天数
log_rotation_count: 7

# 外部URL(可选)
external_url: https://192.168.30.11

# 仓库配置
storage_quota_enabled: true
per_project_repo_quota: -1
per_project_registry_quota: -1

# 安全配置
security_mode: storagepolicy
compliance_mode: generate

# 作业配置
job_log_max_backup: 168
job_log_retention_days: 7

# 通知配置
notification:
  webhook_job_max_retry: 3
  webhook_job_ping_interval: 5s

# 缓存配置
cache:
  enabled: true
  expire_hours: 24

# 垃圾回收配置
gc:
  enabled: true
  interval: 24
  dryrun: false
  delete_untagged: true
  delete_unreferenced: true
EOF

# 2. 重启Harbor应用配置
echo "=== 重启Harbor应用配置 ==="
cd /data/harbor/harbor
docker-compose down
./install.sh

# 3. 等待Harbor重启
echo "=== 等待Harbor重启(约2-5分钟) ==="
sleep 30

# 4. 验证Harbor启动
echo "=== 验证Harbor启动 ==="
docker ps -a | grep goharbor
curl -I https://192.168.30.11 --insecure --connect-timeout 5

7.14 监控与日志

# 1. 查看Harbor容器日志
echo "=== 查看Harbor容器日志 ==="
docker-compose logs -f

# 2. 查看特定服务日志
echo "=== 查看特定服务日志 ==="
docker-compose logs -f core
docker-compose logs -f registry
docker-compose logs -f jobservice

# 3. 查看Harbor资源使用
echo "=== 查看Harbor资源使用 ==="
docker stats --no-stream

# 4. 查看Harbor存储使用
echo "=== 查看Harbor存储使用 ==="
du -sh /data/harbor/data
df -h /data/harbor/data

# 5. 查看Harbor API日志
echo "=== 查看Harbor API日志 ==="
docker-compose logs core | tail -100

7.15 清理测试资源

# 1. 删除测试Deployment
echo "=== 删除测试Deployment ==="
kubectl delete -f harbor-test-deployment.yaml
rm -f harbor-test-deployment.yaml

# 2. 删除Harbor Secret
echo "=== 删除Harbor Secret ==="
kubectl delete secret harbor-secret -n default

# 3. 清理本地测试镜像
echo "=== 清理本地测试镜像 ==="
docker rmi 192.168.30.11/k8s/nginx:1.14
docker rmi nginx:1.14

# 4. 验证清理
echo "=== 验证清理 ==="
kubectl get pods -n default
kubectl get secrets -n default
docker images | grep -E "nginx|harbor"

7.16 部署验证总结

# 1. 生成Harbor部署状态报告
echo "=== 生成Harbor部署状态报告 ==="
echo "===== Harbor部署状态报告 =====" > /tmp/harbor-status.txt
echo "" >> /tmp/harbor-status.txt

echo "===== Harbor容器状态 =====" >> /tmp/harbor-status.txt
docker ps -a | grep goharbor >> /tmp/harbor-status.txt
echo "" >> /tmp/harbor-status.txt

echo "===== Harbor服务状态 =====" >> /tmp/harbor-status.txt
docker-compose ps >> /tmp/harbor-status.txt
echo "" >> /tmp/harbor-status.txt

echo "===== Harbor端口监听 =====" >> /tmp/harbor-status.txt
netstat -tuln | grep -E ':(80|443)' >> /tmp/harbor-status.txt
echo "" >> /tmp/harbor-status.txt

echo "===== Harbor存储使用 =====" >> /tmp/harbor-status.txt
df -h /data/harbor/data >> /tmp/harbor-status.txt
du -sh /data/harbor/data >> /tmp/harbor-status.txt
echo "" >> /tmp/harbor-status.txt

echo "===== Harbor项目列表 =====" >> /tmp/harbor-status.txt
curl -X GET "https://192.168.30.11/api/v2.0/projects" \
  -H "Authorization: Basic YWRtaW46SGFyYm9yQDEyMzQ1NTY=" \
  -k >> /tmp/harbor-status.txt
echo "" >> /tmp/harbor-status.txt

echo "===== Harbor镜像列表 =====" >> /tmp/harbor-status.txt
curl -X GET "https://192.168.30.11/api/v2.0/repositories" \
  -H "Authorization: Basic YWRtaW46SGFyYm9yQDEyMzQ1NTY=" \
  -k >> /tmp/harbor-status.txt
echo "" >> /tmp/harbor-status.txt

# 2. 显示报告
echo "=== Harbor部署状态报告 ==="
cat /tmp/harbor-status.txt

# 3. 保存报告
echo "=== 部署状态报告已保存到 /tmp/harbor-status.txt ==="

# 4. 验证检查清单
echo "=== Harbor部署验证检查清单 ==="
echo "✓ Harbor容器全部Running"
echo "✓ Harbor服务全部Up"
echo "✓ 端口80/443正常监听"
echo "✓ Harbor可以正常访问"
echo "✓ Harbor项目创建成功"
echo "✓ 镜像推送成功"
echo "✓ Kubernetes可以拉取Harbor镜像"
echo "✓ Docker信任Harbor"
echo "✓ containerd信任Harbor"
echo ""
echo "如果以上所有项都正常,恭喜您!Harbor私有镜像仓库部署成功!"

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐