add action for k8s deploy
Some checks failed
Build NGINX on Ubuntu / build-nginx (push) Has been cancelled
Some checks failed
Build NGINX on Ubuntu / build-nginx (push) Has been cancelled
This commit is contained in:
parent
2c9b9cd223
commit
5c7293be88
121
.gitea/workflows/README.md
Normal file
121
.gitea/workflows/README.md
Normal file
@ -0,0 +1,121 @@
|
||||
# NGINX CI/CD 配置说明
|
||||
|
||||
本目录包含了为 NGINX 项目定制的 Git Action 工作流配置文件。
|
||||
|
||||
## 工作流文件说明
|
||||
|
||||
### 1. `build-ubuntu.yaml` - 主要构建流程
|
||||
这是主要的构建和部署流水线,适用于生产环境:
|
||||
|
||||
- **触发条件**: 代码推送和 Pull Request
|
||||
- **功能**:
|
||||
- 在 Ubuntu 22.04 上编译 NGINX
|
||||
- 包含完整的模块配置(SSL、流处理、图像处理等)
|
||||
- 创建 Docker 镜像并推送到 Harbor 仓库
|
||||
- 进行基本的功能测试
|
||||
- 上传构建产物
|
||||
|
||||
### 2. `build-multi-platform.yaml` - 多平台构建
|
||||
用于发布版本的完整构建流程:
|
||||
|
||||
- **触发条件**: 标签推送、工作流手动触发
|
||||
- **功能**:
|
||||
- 多 Ubuntu 版本支持(20.04、22.04)
|
||||
- 配置验证和编译测试
|
||||
- 安全漏洞扫描
|
||||
- 完整的 Docker 镜像构建和发布
|
||||
|
||||
### 3. `build-dev.yaml` - 开发测试流程
|
||||
用于日常开发的快速验证:
|
||||
|
||||
- **触发条件**: develop 分支和 feature 分支推送
|
||||
- **功能**:
|
||||
- 快速构建(最小配置)
|
||||
- 代码质量检查
|
||||
- 多编译器兼容性测试(GCC、Clang)
|
||||
- 构建缓存优化
|
||||
|
||||
## 配置要点
|
||||
|
||||
### 依赖库安装
|
||||
根据 NGINX 官方文档,安装了以下依赖:
|
||||
- `libpcre3-dev` - 正则表达式支持
|
||||
- `zlib1g-dev` - 压缩支持
|
||||
- `libssl-dev` - SSL/TLS 支持
|
||||
- `libxslt1-dev` - XSLT 模块
|
||||
- `libgd-dev` - 图像处理模块
|
||||
- `libgeoip-dev` - GeoIP 模块
|
||||
|
||||
### 编译配置
|
||||
使用 `./auto/configure` 脚本进行配置,主要特性:
|
||||
- HTTP/2 支持
|
||||
- SSL/TLS 加密
|
||||
- 流处理模块
|
||||
- 图像过滤器
|
||||
- 地理位置模块
|
||||
- 负载均衡功能
|
||||
|
||||
### Docker 镜像
|
||||
- 基于 Ubuntu 22.04
|
||||
- 运行时优化(仅包含必要的运行时库)
|
||||
- 健康检查配置
|
||||
- 非 root 用户运行
|
||||
|
||||
## 环境变量配置
|
||||
|
||||
需要在仓库设置中配置以下 Secrets:
|
||||
|
||||
```
|
||||
HARBOR_REGISTRY # Harbor 仓库地址
|
||||
HARBOR_USERNAME # Harbor 用户名
|
||||
HARBOR_PASSWORD # Harbor 密码
|
||||
```
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 开发流程
|
||||
1. 在 `develop` 或 `feature/*` 分支上工作
|
||||
2. 推送代码会触发 `build-dev.yaml`,进行快速验证
|
||||
3. 创建 Pull Request 到 `main` 分支
|
||||
4. 会触发完整的构建测试
|
||||
|
||||
### 发布流程
|
||||
1. 合并到 `main` 分支后,创建版本标签
|
||||
2. 推送标签会触发 `build-multi-platform.yaml`
|
||||
3. 执行完整的多平台构建和安全扫描
|
||||
4. 自动构建并推送 Docker 镜像
|
||||
|
||||
### 手动触发
|
||||
可以在 Actions 页面手动触发 `build-multi-platform.yaml` 工作流。
|
||||
|
||||
## 构建产物
|
||||
|
||||
- **二进制文件**: 上传到 GitHub Actions Artifacts
|
||||
- **Docker 镜像**: 推送到配置的 Harbor 仓库
|
||||
- **版本标记**: 支持语义化版本标签
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
1. **依赖安装失败**: 检查 Ubuntu 版本和包名称
|
||||
2. **编译错误**: 查看具体的编译器错误信息
|
||||
3. **Docker 推送失败**: 检查 Harbor 凭据配置
|
||||
4. **测试失败**: 检查 NGINX 配置文件语法
|
||||
|
||||
### 调试建议
|
||||
- 查看 Actions 日志中的详细输出
|
||||
- 本地使用相同的命令进行测试
|
||||
- 检查依赖库版本兼容性
|
||||
|
||||
## 性能优化
|
||||
|
||||
- 使用 `make -j$(nproc)` 进行并行编译
|
||||
- 配置构建缓存减少重复下载
|
||||
- 分阶段构建减少单次运行时间
|
||||
|
||||
## 安全考虑
|
||||
|
||||
- 定期更新基础镜像
|
||||
- 运行 Trivy 安全扫描
|
||||
- 使用非 root 用户运行容器
|
||||
- 及时更新依赖库版本
|
@ -174,3 +174,42 @@ jobs:
|
||||
docker rmi ${{ secrets.HARBOR_REGISTRY }}/test/nginx:${{ github.sha }} || true
|
||||
docker rmi ${{ secrets.HARBOR_REGISTRY }}/test/nginx:latest || true
|
||||
|
||||
- name: 部署到 Kubernetes (可选)
|
||||
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
||||
run: |
|
||||
echo "开始部署到 Kubernetes..."
|
||||
|
||||
# 检查是否配置了 Kubernetes 部署
|
||||
if [[ -n "${{ secrets.KUBE_CONFIG }}" ]]; then
|
||||
# 安装 kubectl
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
chmod +x kubectl
|
||||
sudo mv kubectl /usr/local/bin/
|
||||
|
||||
# 配置 kubectl
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
# 验证 kubectl 连接
|
||||
kubectl cluster-info --short || (echo "Kubernetes 连接失败" && exit 1)
|
||||
|
||||
# 设置环境变量
|
||||
export HARBOR_REGISTRY="${{ secrets.HARBOR_REGISTRY }}"
|
||||
export HARBOR_USERNAME="${{ secrets.HARBOR_USERNAME }}"
|
||||
export HARBOR_PASSWORD="${{ secrets.HARBOR_PASSWORD }}"
|
||||
export NGINX_IMAGE_TAG="${{ github.sha }}"
|
||||
export NAMESPACE="${{ secrets.K8S_NAMESPACE || 'default' }}"
|
||||
|
||||
# 进入 k8s 目录
|
||||
cd k8s
|
||||
|
||||
# 运行部署脚本
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
|
||||
echo "Kubernetes 部署完成"
|
||||
else
|
||||
echo "跳过 Kubernetes 部署 - 未配置 KUBE_CONFIG"
|
||||
fi
|
||||
|
||||
|
17
k8s/.env.template
Normal file
17
k8s/.env.template
Normal file
@ -0,0 +1,17 @@
|
||||
# 环境变量配置文件模板
|
||||
# 复制此文件为 .env 并填入实际值
|
||||
|
||||
# Harbor 仓库配置
|
||||
HARBOR_REGISTRY=harbor.example.com
|
||||
HARBOR_USERNAME=your-username
|
||||
HARBOR_PASSWORD=your-password
|
||||
|
||||
# 镜像配置
|
||||
NGINX_IMAGE_TAG=latest
|
||||
|
||||
# Kubernetes 配置
|
||||
NAMESPACE=default
|
||||
DEPLOYMENT_FILE=./nginx-deployment.yaml
|
||||
|
||||
# 可选配置
|
||||
# KUBECONFIG=/path/to/kubeconfig # 如果不使用默认的 kubectl 配置
|
152
k8s/Makefile
Normal file
152
k8s/Makefile
Normal file
@ -0,0 +1,152 @@
|
||||
# NGINX Kubernetes 部署 Makefile
|
||||
# 简化部署操作和管理
|
||||
|
||||
# 默认配置
|
||||
HARBOR_REGISTRY ?= harbor.example.com
|
||||
HARBOR_USERNAME ?= your-username
|
||||
HARBOR_PASSWORD ?= your-password
|
||||
NGINX_IMAGE_TAG ?= latest
|
||||
NAMESPACE ?= default
|
||||
DEPLOYMENT_FILE ?= ./nginx-deployment.yaml
|
||||
|
||||
# 颜色输出
|
||||
RED := \033[0;31m
|
||||
GREEN := \033[0;32m
|
||||
YELLOW := \033[1;33m
|
||||
BLUE := \033[0;34m
|
||||
NC := \033[0m # No Color
|
||||
|
||||
.PHONY: help deploy clean status logs port-forward scale update rollback check-env install-deps
|
||||
|
||||
# 默认目标
|
||||
help: ## 显示帮助信息
|
||||
@echo "$(BLUE)NGINX Kubernetes 部署工具$(NC)"
|
||||
@echo ""
|
||||
@echo "$(YELLOW)可用命令:$(NC)"
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " $(GREEN)%-15s$(NC) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||
@echo ""
|
||||
@echo "$(YELLOW)环境变量:$(NC)"
|
||||
@echo " HARBOR_REGISTRY Harbor 仓库地址 (当前: $(HARBOR_REGISTRY))"
|
||||
@echo " HARBOR_USERNAME Harbor 用户名 (当前: $(HARBOR_USERNAME))"
|
||||
@echo " HARBOR_PASSWORD Harbor 密码 (已设置: $(if $(HARBOR_PASSWORD),是,否))"
|
||||
@echo " NGINX_IMAGE_TAG 镜像标签 (当前: $(NGINX_IMAGE_TAG))"
|
||||
@echo " NAMESPACE 命名空间 (当前: $(NAMESPACE))"
|
||||
|
||||
check-env: ## 检查环境变量
|
||||
@echo "$(BLUE)[INFO]$(NC) 检查必要的环境变量..."
|
||||
@if [ -z "$(HARBOR_REGISTRY)" ]; then echo "$(RED)[ERROR]$(NC) HARBOR_REGISTRY 未设置"; exit 1; fi
|
||||
@if [ -z "$(HARBOR_USERNAME)" ]; then echo "$(RED)[ERROR]$(NC) HARBOR_USERNAME 未设置"; exit 1; fi
|
||||
@if [ -z "$(HARBOR_PASSWORD)" ]; then echo "$(RED)[ERROR]$(NC) HARBOR_PASSWORD 未设置"; exit 1; fi
|
||||
@if [ -z "$(NGINX_IMAGE_TAG)" ]; then echo "$(RED)[ERROR]$(NC) NGINX_IMAGE_TAG 未设置"; exit 1; fi
|
||||
@echo "$(GREEN)[SUCCESS]$(NC) 环境变量检查通过"
|
||||
|
||||
install-deps: ## 安装必要的依赖工具
|
||||
@echo "$(BLUE)[INFO]$(NC) 检查并安装必要的工具..."
|
||||
@which kubectl > /dev/null || (echo "$(RED)[ERROR]$(NC) kubectl 未安装" && exit 1)
|
||||
@echo "$(GREEN)[SUCCESS]$(NC) 所有必要工具已安装"
|
||||
|
||||
deploy: check-env install-deps ## 部署 NGINX 到 Kubernetes
|
||||
@echo "$(BLUE)[INFO]$(NC) 开始部署 NGINX 到 Kubernetes..."
|
||||
@cd k8s && chmod +x deploy.sh && \
|
||||
HARBOR_REGISTRY=$(HARBOR_REGISTRY) \
|
||||
HARBOR_USERNAME=$(HARBOR_USERNAME) \
|
||||
HARBOR_PASSWORD=$(HARBOR_PASSWORD) \
|
||||
NGINX_IMAGE_TAG=$(NGINX_IMAGE_TAG) \
|
||||
NAMESPACE=$(NAMESPACE) \
|
||||
./deploy.sh
|
||||
|
||||
status: ## 查看部署状态
|
||||
@echo "$(BLUE)[INFO]$(NC) 查看 NGINX 部署状态..."
|
||||
@echo ""
|
||||
@echo "$(YELLOW)=== Pods ===$(NC)"
|
||||
@kubectl get pods -l app=nginx -n $(NAMESPACE) -o wide || true
|
||||
@echo ""
|
||||
@echo "$(YELLOW)=== Services ===$(NC)"
|
||||
@kubectl get services -l app=nginx -n $(NAMESPACE) || true
|
||||
@echo ""
|
||||
@echo "$(YELLOW)=== Deployments ===$(NC)"
|
||||
@kubectl get deployments -l app=nginx -n $(NAMESPACE) || true
|
||||
@echo ""
|
||||
@echo "$(YELLOW)=== HPA ===$(NC)"
|
||||
@kubectl get hpa -l app=nginx -n $(NAMESPACE) 2>/dev/null || echo "HPA 未启用"
|
||||
|
||||
logs: ## 查看 NGINX Pod 日志
|
||||
@echo "$(BLUE)[INFO]$(NC) 查看 NGINX Pod 日志..."
|
||||
@kubectl logs -l app=nginx -n $(NAMESPACE) -f --all-containers=true
|
||||
|
||||
port-forward: ## 设置端口转发以便本地访问
|
||||
@echo "$(BLUE)[INFO]$(NC) 设置端口转发 localhost:8080 -> nginx-service:80"
|
||||
@echo "$(YELLOW)访问 http://localhost:8080 来测试 NGINX$(NC)"
|
||||
@kubectl port-forward service/nginx-service 8080:80 -n $(NAMESPACE)
|
||||
|
||||
scale: ## 扩缩容 NGINX 部署 (用法: make scale REPLICAS=5)
|
||||
@if [ -z "$(REPLICAS)" ]; then echo "$(RED)[ERROR]$(NC) 请指定副本数: make scale REPLICAS=5"; exit 1; fi
|
||||
@echo "$(BLUE)[INFO]$(NC) 扩缩容 NGINX 到 $(REPLICAS) 个副本..."
|
||||
@kubectl scale deployment nginx-deployment --replicas=$(REPLICAS) -n $(NAMESPACE)
|
||||
@kubectl rollout status deployment/nginx-deployment -n $(NAMESPACE)
|
||||
|
||||
update: check-env ## 更新 NGINX 镜像版本
|
||||
@echo "$(BLUE)[INFO]$(NC) 更新 NGINX 镜像到 $(NGINX_IMAGE_TAG)..."
|
||||
@kubectl set image deployment/nginx-deployment nginx=$(HARBOR_REGISTRY)/test/nginx:$(NGINX_IMAGE_TAG) -n $(NAMESPACE)
|
||||
@kubectl rollout status deployment/nginx-deployment -n $(NAMESPACE)
|
||||
@echo "$(GREEN)[SUCCESS]$(NC) 镜像更新完成"
|
||||
|
||||
rollback: ## 回滚到上一个版本
|
||||
@echo "$(BLUE)[INFO]$(NC) 回滚 NGINX 部署到上一个版本..."
|
||||
@kubectl rollout undo deployment/nginx-deployment -n $(NAMESPACE)
|
||||
@kubectl rollout status deployment/nginx-deployment -n $(NAMESPACE)
|
||||
@echo "$(GREEN)[SUCCESS]$(NC) 回滚完成"
|
||||
|
||||
restart: ## 重启 NGINX 部署
|
||||
@echo "$(BLUE)[INFO]$(NC) 重启 NGINX 部署..."
|
||||
@kubectl rollout restart deployment/nginx-deployment -n $(NAMESPACE)
|
||||
@kubectl rollout status deployment/nginx-deployment -n $(NAMESPACE)
|
||||
@echo "$(GREEN)[SUCCESS]$(NC) 重启完成"
|
||||
|
||||
clean: ## 清理 NGINX 部署
|
||||
@echo "$(BLUE)[INFO]$(NC) 清理 NGINX 部署..."
|
||||
@kubectl delete -f k8s/nginx-deployment.yaml -n $(NAMESPACE) --ignore-not-found=true
|
||||
@kubectl delete secret harbor-registry-secret -n $(NAMESPACE) --ignore-not-found=true
|
||||
@echo "$(GREEN)[SUCCESS]$(NC) 清理完成"
|
||||
|
||||
config: ## 显示当前配置
|
||||
@echo "$(BLUE)[INFO]$(NC) 当前配置:"
|
||||
@echo " Harbor 仓库: $(HARBOR_REGISTRY)"
|
||||
@echo " Harbor 用户: $(HARBOR_USERNAME)"
|
||||
@echo " 镜像标签: $(NGINX_IMAGE_TAG)"
|
||||
@echo " 命名空间: $(NAMESPACE)"
|
||||
@echo " 部署文件: $(DEPLOYMENT_FILE)"
|
||||
|
||||
test: ## 测试 NGINX 服务连接
|
||||
@echo "$(BLUE)[INFO]$(NC) 测试 NGINX 服务连接..."
|
||||
@POD_NAME=$$(kubectl get pods -l app=nginx -n $(NAMESPACE) -o jsonpath='{.items[0].metadata.name}'); \
|
||||
if [ -n "$$POD_NAME" ]; then \
|
||||
echo "测试 Pod: $$POD_NAME"; \
|
||||
kubectl exec $$POD_NAME -n $(NAMESPACE) -- curl -s -o /dev/null -w "HTTP状态码: %{http_code}\n" http://localhost/; \
|
||||
else \
|
||||
echo "$(RED)[ERROR]$(NC) 未找到运行中的 NGINX Pod"; \
|
||||
fi
|
||||
|
||||
debug: ## 调试部署问题
|
||||
@echo "$(BLUE)[INFO]$(NC) 调试 NGINX 部署..."
|
||||
@echo ""
|
||||
@echo "$(YELLOW)=== 检查 Secrets ===$(NC)"
|
||||
@kubectl get secret harbor-registry-secret -n $(NAMESPACE) -o yaml 2>/dev/null || echo "Secret 不存在"
|
||||
@echo ""
|
||||
@echo "$(YELLOW)=== 检查事件 ===$(NC)"
|
||||
@kubectl get events --sort-by=.metadata.creationTimestamp -n $(NAMESPACE) | grep nginx | tail -10
|
||||
@echo ""
|
||||
@echo "$(YELLOW)=== Pod 详细信息 ===$(NC)"
|
||||
@POD_NAME=$$(kubectl get pods -l app=nginx -n $(NAMESPACE) -o jsonpath='{.items[0].metadata.name}' 2>/dev/null); \
|
||||
if [ -n "$$POD_NAME" ]; then \
|
||||
kubectl describe pod $$POD_NAME -n $(NAMESPACE); \
|
||||
else \
|
||||
echo "未找到 NGINX Pod"; \
|
||||
fi
|
||||
|
||||
# 为方便使用,创建一些简短的别名
|
||||
s: status ## 别名: status
|
||||
l: logs ## 别名: logs
|
||||
d: deploy ## 别名: deploy
|
||||
c: clean ## 别名: clean
|
||||
u: update ## 别名: update
|
308
k8s/README.md
Normal file
308
k8s/README.md
Normal file
@ -0,0 +1,308 @@
|
||||
# Kubernetes 部署指南
|
||||
|
||||
本指南详细说明了如何将构建好的 NGINX Docker 镜像从私有 Harbor 仓库部署到 Kubernetes 集群。
|
||||
|
||||
## 📋 目录结构
|
||||
|
||||
```
|
||||
k8s/
|
||||
├── deploy.sh # Linux/macOS 自动部署脚本
|
||||
├── deploy.bat # Windows 自动部署脚本
|
||||
├── nginx-deployment.yaml # Kubernetes 部署配置
|
||||
├── .env.template # 环境变量模板
|
||||
└── README.md # 本文档
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 方法一:使用自动部署脚本(推荐)
|
||||
|
||||
1. **设置环境变量**
|
||||
```bash
|
||||
# Linux/macOS
|
||||
export HARBOR_REGISTRY=harbor.example.com
|
||||
export HARBOR_USERNAME=your-username
|
||||
export HARBOR_PASSWORD=your-password
|
||||
export NGINX_IMAGE_TAG=latest # 或使用 ${GITHUB_SHA}
|
||||
```
|
||||
|
||||
```cmd
|
||||
REM Windows
|
||||
set HARBOR_REGISTRY=harbor.example.com
|
||||
set HARBOR_USERNAME=your-username
|
||||
set HARBOR_PASSWORD=your-password
|
||||
set NGINX_IMAGE_TAG=latest
|
||||
```
|
||||
|
||||
2. **运行部署脚本**
|
||||
```bash
|
||||
# Linux/macOS
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
|
||||
# Windows
|
||||
deploy.bat
|
||||
```
|
||||
|
||||
### 方法二:使用环境变量文件
|
||||
|
||||
1. **创建环境变量文件**
|
||||
```bash
|
||||
cp .env.template .env
|
||||
# 编辑 .env 文件,填入实际的配置值
|
||||
```
|
||||
|
||||
2. **运行部署脚本**
|
||||
```bash
|
||||
# 脚本会自动加载 .env 文件
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### 方法三:手动部署
|
||||
|
||||
1. **创建 Harbor 仓库访问凭据**
|
||||
```bash
|
||||
kubectl create secret docker-registry harbor-registry-secret \
|
||||
--docker-server=harbor.example.com \
|
||||
--docker-username=your-username \
|
||||
--docker-password=your-password \
|
||||
--namespace=default
|
||||
```
|
||||
|
||||
2. **更新部署文件中的镜像标签**
|
||||
```bash
|
||||
# 编辑 nginx-deployment.yaml,替换镜像标签
|
||||
# 将 harbor.example.com/test/nginx:latest 替换为实际的镜像地址
|
||||
```
|
||||
|
||||
3. **应用 Kubernetes 配置**
|
||||
```bash
|
||||
kubectl apply -f nginx-deployment.yaml
|
||||
```
|
||||
|
||||
4. **检查部署状态**
|
||||
```bash
|
||||
kubectl get pods -l app=nginx
|
||||
kubectl get services -l app=nginx
|
||||
```
|
||||
|
||||
## 🔧 配置说明
|
||||
|
||||
### 环境变量
|
||||
|
||||
| 变量名 | 描述 | 必需 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| `HARBOR_REGISTRY` | Harbor 仓库地址 | 是 | - |
|
||||
| `HARBOR_USERNAME` | Harbor 用户名 | 是 | - |
|
||||
| `HARBOR_PASSWORD` | Harbor 密码 | 是 | - |
|
||||
| `NGINX_IMAGE_TAG` | NGINX 镜像标签 | 是 | - |
|
||||
| `NAMESPACE` | Kubernetes 命名空间 | 否 | `default` |
|
||||
| `DEPLOYMENT_FILE` | 部署配置文件路径 | 否 | `./nginx-deployment.yaml` |
|
||||
|
||||
### Kubernetes 资源
|
||||
|
||||
部署文件包含以下 Kubernetes 资源:
|
||||
|
||||
1. **ConfigMap** (`nginx-config`)
|
||||
- 包含 NGINX 配置文件
|
||||
- 自定义日志格式和访问控制
|
||||
|
||||
2. **Deployment** (`nginx-deployment`)
|
||||
- 3 个副本的 NGINX Pod
|
||||
- 从私有 Harbor 仓库拉取镜像
|
||||
- 包含健康检查和资源限制
|
||||
|
||||
3. **Service** (`nginx-service`)
|
||||
- NodePort 类型(端口 30080)
|
||||
- 可以改为 LoadBalancer 或 ClusterIP
|
||||
|
||||
4. **HPA** (`nginx-hpa`)
|
||||
- 水平自动伸缩
|
||||
- 基于 CPU 使用率(目标 70%)
|
||||
- 副本数范围:3-10
|
||||
|
||||
5. **PodDisruptionBudget** (`nginx-pdb`)
|
||||
- 确保更新期间的可用性
|
||||
- 最小可用副本数:2
|
||||
|
||||
## 🔍 验证部署
|
||||
|
||||
### 检查 Pod 状态
|
||||
```bash
|
||||
kubectl get pods -l app=nginx -o wide
|
||||
```
|
||||
|
||||
### 检查服务状态
|
||||
```bash
|
||||
kubectl get services -l app=nginx
|
||||
```
|
||||
|
||||
### 查看日志
|
||||
```bash
|
||||
# 查看特定 Pod 的日志
|
||||
kubectl logs -l app=nginx -f
|
||||
|
||||
# 查看所有 NGINX Pod 的日志
|
||||
kubectl logs -l app=nginx --all-containers=true -f
|
||||
```
|
||||
|
||||
### 访问应用
|
||||
|
||||
根据服务类型不同,访问方式如下:
|
||||
|
||||
1. **NodePort**(默认)
|
||||
```bash
|
||||
# 获取节点 IP 和端口
|
||||
kubectl get nodes -o wide
|
||||
kubectl get service nginx-service
|
||||
# 访问 http://<node-ip>:30080
|
||||
```
|
||||
|
||||
2. **LoadBalancer**
|
||||
```bash
|
||||
# 等待外部 IP 分配
|
||||
kubectl get service nginx-service -w
|
||||
# 访问 http://<external-ip>
|
||||
```
|
||||
|
||||
3. **ClusterIP**
|
||||
```bash
|
||||
# 使用端口转发进行测试
|
||||
kubectl port-forward service/nginx-service 8080:80
|
||||
# 访问 http://localhost:8080
|
||||
```
|
||||
|
||||
## 🔧 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **镜像拉取失败**
|
||||
```bash
|
||||
# 检查 Secret 是否正确创建
|
||||
kubectl get secret harbor-registry-secret -o yaml
|
||||
|
||||
# 检查镜像地址是否正确
|
||||
kubectl describe pod <pod-name>
|
||||
```
|
||||
|
||||
2. **Pod 启动失败**
|
||||
```bash
|
||||
# 查看 Pod 详细信息
|
||||
kubectl describe pod <pod-name>
|
||||
|
||||
# 查看 Pod 日志
|
||||
kubectl logs <pod-name>
|
||||
```
|
||||
|
||||
3. **服务无法访问**
|
||||
```bash
|
||||
# 检查服务端点
|
||||
kubectl get endpoints nginx-service
|
||||
|
||||
# 检查网络策略(如果启用)
|
||||
kubectl get networkpolicy
|
||||
```
|
||||
|
||||
### 日志查看
|
||||
|
||||
```bash
|
||||
# 查看部署事件
|
||||
kubectl get events --sort-by=.metadata.creationTimestamp
|
||||
|
||||
# 查看特定资源的事件
|
||||
kubectl describe deployment nginx-deployment
|
||||
kubectl describe service nginx-service
|
||||
```
|
||||
|
||||
## 🔄 更新部署
|
||||
|
||||
### 更新镜像版本
|
||||
|
||||
1. **使用脚本更新**
|
||||
```bash
|
||||
export NGINX_IMAGE_TAG=new-version
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
2. **手动更新**
|
||||
```bash
|
||||
kubectl set image deployment/nginx-deployment \
|
||||
nginx=harbor.example.com/test/nginx:new-version
|
||||
```
|
||||
|
||||
3. **滚动更新策略**
|
||||
```bash
|
||||
# 查看滚动更新状态
|
||||
kubectl rollout status deployment/nginx-deployment
|
||||
|
||||
# 回滚到上一个版本
|
||||
kubectl rollout undo deployment/nginx-deployment
|
||||
```
|
||||
|
||||
## 🗑️ 清理资源
|
||||
|
||||
### 删除部署
|
||||
```bash
|
||||
kubectl delete -f nginx-deployment.yaml
|
||||
kubectl delete secret harbor-registry-secret
|
||||
```
|
||||
|
||||
### 删除命名空间(如果使用专用命名空间)
|
||||
```bash
|
||||
kubectl delete namespace <namespace-name>
|
||||
```
|
||||
|
||||
## 🔐 安全注意事项
|
||||
|
||||
1. **敏感信息管理**
|
||||
- 不要将 Harbor 凭据提交到代码仓库
|
||||
- 使用 Kubernetes Secrets 存储敏感信息
|
||||
- 考虑使用外部密钥管理系统
|
||||
|
||||
2. **网络安全**
|
||||
- 配置网络策略限制 Pod 间通信
|
||||
- 使用 HTTPS 和 TLS 证书
|
||||
- 配置防火墙规则
|
||||
|
||||
3. **镜像安全**
|
||||
- 定期扫描镜像漏洞
|
||||
- 使用最小权限运行容器
|
||||
- 启用镜像签名验证
|
||||
|
||||
## 📚 参考资料
|
||||
|
||||
- [Kubernetes 官方文档](https://kubernetes.io/docs/)
|
||||
- [Harbor 官方文档](https://goharbor.io/docs/)
|
||||
- [NGINX 官方文档](https://nginx.org/en/docs/)
|
||||
- [Docker 私有仓库配置](https://docs.docker.com/registry/deploying/)
|
||||
|
||||
## 💡 提示
|
||||
|
||||
1. **性能优化**
|
||||
- 根据实际负载调整副本数和资源限制
|
||||
- 配置 NGINX 缓存策略
|
||||
- 使用持久化存储保存日志
|
||||
|
||||
2. **监控配置**
|
||||
- 集成 Prometheus 监控
|
||||
- 配置 Grafana 仪表板
|
||||
- 设置告警规则
|
||||
|
||||
3. **自动化**
|
||||
- 集成到 CI/CD 流水线
|
||||
- 使用 Helm 管理复杂部署
|
||||
- 配置自动化测试
|
||||
|
||||
## `${{ github.sha }}` 变量说明
|
||||
|
||||
`${{ github.sha }}` 是 GitHub Actions 中的一个内置环境变量,代表:
|
||||
|
||||
- **含义**: 当前提交的完整 SHA-1 哈希值(40 字符)
|
||||
- **格式**: 例如 `a1b2c3d4e5f6789012345678901234567890abcd`
|
||||
- **用途**: 作为 Docker 镜像的唯一标签,确保每次构建的镜像都有唯一标识
|
||||
- **优势**:
|
||||
- 可追溯性:能够准确对应到具体的代码提交
|
||||
- 唯一性:避免镜像标签冲突
|
||||
- 版本控制:便于回滚和版本管理
|
||||
|
||||
在 CI/CD 中使用 `${{ github.sha }}` 作为镜像标签是最佳实践,可以实现精确的版本控制和部署追踪。
|
295
k8s/deploy.bat
Normal file
295
k8s/deploy.bat
Normal file
@ -0,0 +1,295 @@
|
||||
@echo off
|
||||
REM Kubernetes 自动部署脚本 (Windows 版本)
|
||||
REM 用于从私有 Harbor 仓库拉取 NGINX 镜像并部署到 K8s 集群
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
REM 设置颜色代码(Windows 10/11 支持 ANSI 转义序列)
|
||||
set "RED=[91m"
|
||||
set "GREEN=[92m"
|
||||
set "YELLOW=[93m"
|
||||
set "BLUE=[94m"
|
||||
set "NC=[0m"
|
||||
|
||||
REM 打印带颜色的信息
|
||||
:print_info
|
||||
echo %BLUE%[INFO]%NC% %~1
|
||||
goto :eof
|
||||
|
||||
:print_success
|
||||
echo %GREEN%[SUCCESS]%NC% %~1
|
||||
goto :eof
|
||||
|
||||
:print_warning
|
||||
echo %YELLOW%[WARNING]%NC% %~1
|
||||
goto :eof
|
||||
|
||||
:print_error
|
||||
echo %RED%[ERROR]%NC% %~1
|
||||
goto :eof
|
||||
|
||||
REM 检查必要的环境变量
|
||||
:check_env_vars
|
||||
call :print_info "检查环境变量..."
|
||||
|
||||
set "missing_vars="
|
||||
if "%HARBOR_REGISTRY%"=="" set "missing_vars=%missing_vars% HARBOR_REGISTRY"
|
||||
if "%HARBOR_USERNAME%"=="" set "missing_vars=%missing_vars% HARBOR_USERNAME"
|
||||
if "%HARBOR_PASSWORD%"=="" set "missing_vars=%missing_vars% HARBOR_PASSWORD"
|
||||
if "%NGINX_IMAGE_TAG%"=="" set "missing_vars=%missing_vars% NGINX_IMAGE_TAG"
|
||||
|
||||
if not "%missing_vars%"=="" (
|
||||
call :print_error "缺少必要的环境变量: %missing_vars%"
|
||||
echo.
|
||||
echo 请设置以下环境变量:
|
||||
echo set HARBOR_REGISTRY=^<你的Harbor仓库地址^>
|
||||
echo set HARBOR_USERNAME=^<Harbor用户名^>
|
||||
echo set HARBOR_PASSWORD=^<Harbor密码^>
|
||||
echo set NGINX_IMAGE_TAG=^<镜像标签,如: %%GITHUB_SHA%% 或 latest^>
|
||||
echo.
|
||||
echo 或者创建 .env 文件包含这些变量
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call :print_success "环境变量检查通过"
|
||||
goto :eof
|
||||
|
||||
REM 检查 kubectl 连接
|
||||
:check_kubectl
|
||||
call :print_info "检查 kubectl 连接..."
|
||||
|
||||
kubectl version --client >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
call :print_error "kubectl 未安装或不在 PATH 中"
|
||||
echo 请从 https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/ 安装 kubectl
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
kubectl cluster-info >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
call :print_error "无法连接到 Kubernetes 集群"
|
||||
echo 请确保:
|
||||
echo 1. kubectl 已正确配置
|
||||
echo 2. 能够访问 Kubernetes 集群
|
||||
echo 3. 当前用户有适当的权限
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call :print_success "kubectl 连接正常"
|
||||
kubectl cluster-info --short
|
||||
goto :eof
|
||||
|
||||
REM 创建命名空间(如果不存在)
|
||||
:create_namespace
|
||||
set "namespace=%~1"
|
||||
if "%namespace%"=="" set "namespace=default"
|
||||
|
||||
call :print_info "检查命名空间: %namespace%"
|
||||
|
||||
kubectl get namespace %namespace% >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
call :print_info "创建命名空间: %namespace%"
|
||||
kubectl create namespace %namespace%
|
||||
if errorlevel 1 (
|
||||
call :print_error "创建命名空间失败"
|
||||
exit /b 1
|
||||
)
|
||||
call :print_success "命名空间 '%namespace%' 创建成功"
|
||||
) else (
|
||||
call :print_success "命名空间 '%namespace%' 已存在"
|
||||
)
|
||||
goto :eof
|
||||
|
||||
REM 创建或更新 Harbor 仓库访问凭据
|
||||
:create_harbor_secret
|
||||
set "namespace=%~1"
|
||||
if "%namespace%"=="" set "namespace=default"
|
||||
|
||||
call :print_info "创建/更新 Harbor 仓库访问凭据..."
|
||||
|
||||
REM 删除已存在的 secret(如果存在)
|
||||
kubectl delete secret harbor-registry-secret -n %namespace% --ignore-not-found=true >nul 2>&1
|
||||
|
||||
REM 创建新的 secret
|
||||
kubectl create secret docker-registry harbor-registry-secret --docker-server=%HARBOR_REGISTRY% --docker-username=%HARBOR_USERNAME% --docker-password=%HARBOR_PASSWORD% --namespace=%namespace%
|
||||
if errorlevel 1 (
|
||||
call :print_error "创建 Harbor 仓库访问凭据失败"
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call :print_success "Harbor 仓库访问凭据创建成功"
|
||||
goto :eof
|
||||
|
||||
REM 更新部署文件中的镜像标签
|
||||
:update_deployment_image
|
||||
set "deployment_file=%~1"
|
||||
set "image_tag=%~2"
|
||||
|
||||
call :print_info "更新部署文件中的镜像标签: %image_tag%"
|
||||
|
||||
set "full_image=%HARBOR_REGISTRY%/test/nginx:%image_tag%"
|
||||
|
||||
REM 备份原文件
|
||||
copy "%deployment_file%" "%deployment_file%.bak" >nul
|
||||
|
||||
REM 使用 PowerShell 替换镜像标签
|
||||
powershell -Command "(Get-Content '%deployment_file%') -replace '%HARBOR_REGISTRY%/test/nginx:[^\s]*', '%full_image%' | Set-Content '%deployment_file%'"
|
||||
if errorlevel 1 (
|
||||
call :print_error "更新镜像标签失败"
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call :print_success "镜像标签更新为: %full_image%"
|
||||
goto :eof
|
||||
|
||||
REM 应用 Kubernetes 配置
|
||||
:apply_k8s_config
|
||||
set "deployment_file=%~1"
|
||||
call :print_info "应用 Kubernetes 配置..."
|
||||
|
||||
if not exist "%deployment_file%" (
|
||||
call :print_error "部署文件不存在: %deployment_file%"
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
kubectl apply -f "%deployment_file%"
|
||||
if errorlevel 1 (
|
||||
call :print_error "应用 Kubernetes 配置失败"
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call :print_success "Kubernetes 配置应用成功"
|
||||
goto :eof
|
||||
|
||||
REM 等待部署就绪
|
||||
:wait_for_deployment
|
||||
set "deployment_name=nginx-deployment"
|
||||
set "namespace=%~1"
|
||||
set "timeout=%~2"
|
||||
if "%namespace%"=="" set "namespace=default"
|
||||
if "%timeout%"=="" set "timeout=300"
|
||||
|
||||
call :print_info "等待部署就绪..."
|
||||
|
||||
kubectl wait --for=condition=available deployment/%deployment_name% --namespace=%namespace% --timeout=%timeout%s
|
||||
if errorlevel 1 (
|
||||
call :print_error "部署超时,请检查部署状态"
|
||||
kubectl describe deployment %deployment_name% -n %namespace%
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call :print_success "部署已就绪"
|
||||
goto :eof
|
||||
|
||||
REM 显示部署状态
|
||||
:show_deployment_status
|
||||
set "namespace=%~1"
|
||||
if "%namespace%"=="" set "namespace=default"
|
||||
|
||||
call :print_info "部署状态:"
|
||||
|
||||
echo.
|
||||
echo === Pods ===
|
||||
kubectl get pods -l app=nginx -n %namespace% -o wide
|
||||
|
||||
echo.
|
||||
echo === Services ===
|
||||
kubectl get services -l app=nginx -n %namespace%
|
||||
|
||||
echo.
|
||||
echo === Deployments ===
|
||||
kubectl get deployments -l app=nginx -n %namespace%
|
||||
|
||||
echo.
|
||||
echo === HPA ===
|
||||
kubectl get hpa -l app=nginx -n %namespace% 2>nul || echo HPA 未启用
|
||||
|
||||
echo.
|
||||
echo === Events ===
|
||||
kubectl get events --sort-by=.metadata.creationTimestamp -n %namespace% | findstr /C:"nginx"
|
||||
goto :eof
|
||||
|
||||
REM 获取访问信息
|
||||
:get_access_info
|
||||
set "namespace=%~1"
|
||||
if "%namespace%"=="" set "namespace=default"
|
||||
|
||||
call :print_info "获取访问信息..."
|
||||
|
||||
for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.type}"') do set "service_type=%%i"
|
||||
|
||||
if "%service_type%"=="NodePort" (
|
||||
for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.ports[0].nodePort}"') do set "node_port=%%i"
|
||||
for /f "tokens=*" %%i in ('kubectl get nodes -o jsonpath^="{.items[0].status.addresses[?(@.type==\"InternalIP\")].address}"') do set "node_ip=%%i"
|
||||
call :print_success "NodePort 访问地址: http://!node_ip!:!node_port!"
|
||||
) else if "%service_type%"=="LoadBalancer" (
|
||||
call :print_info "等待 LoadBalancer 外部 IP..."
|
||||
for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.status.loadBalancer.ingress[0].ip}" 2^>nul') do set "external_ip=%%i"
|
||||
if not "!external_ip!"=="" (
|
||||
call :print_success "LoadBalancer 访问地址: http://!external_ip!"
|
||||
) else (
|
||||
call :print_warning "LoadBalancer 外部 IP 仍在分配中"
|
||||
)
|
||||
) else if "%service_type%"=="ClusterIP" (
|
||||
for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.clusterIP}"') do set "cluster_ip=%%i"
|
||||
call :print_success "ClusterIP 访问地址: http://!cluster_ip!"
|
||||
call :print_info "注意: ClusterIP 只能在集群内部访问"
|
||||
)
|
||||
goto :eof
|
||||
|
||||
REM 清理函数
|
||||
:cleanup
|
||||
call :print_info "执行清理操作..."
|
||||
if exist ".\nginx-deployment.yaml.bak" (
|
||||
move ".\nginx-deployment.yaml.bak" ".\nginx-deployment.yaml" >nul
|
||||
)
|
||||
goto :eof
|
||||
|
||||
REM 主函数
|
||||
:main
|
||||
call :print_info "开始 NGINX Kubernetes 自动部署..."
|
||||
|
||||
REM 设置默认值
|
||||
if "%NAMESPACE%"=="" set "NAMESPACE=default"
|
||||
if "%DEPLOYMENT_FILE%"=="" set "DEPLOYMENT_FILE=.\nginx-deployment.yaml"
|
||||
if "%NGINX_IMAGE_TAG%"=="" set "NGINX_IMAGE_TAG=latest"
|
||||
|
||||
REM 检查是否有 .env 文件
|
||||
if exist ".env" (
|
||||
call :print_info "加载 .env 文件..."
|
||||
for /f "usebackq tokens=1,2 delims==" %%a in (".env") do (
|
||||
set "%%a=%%b"
|
||||
)
|
||||
)
|
||||
|
||||
REM 执行部署步骤
|
||||
call :check_env_vars
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
call :check_kubectl
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
call :create_namespace "%NAMESPACE%"
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
call :create_harbor_secret "%NAMESPACE%"
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
call :update_deployment_image "%DEPLOYMENT_FILE%" "%NGINX_IMAGE_TAG%"
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
call :apply_k8s_config "%DEPLOYMENT_FILE%"
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
call :wait_for_deployment "%NAMESPACE%"
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
call :show_deployment_status "%NAMESPACE%"
|
||||
call :get_access_info "%NAMESPACE%"
|
||||
|
||||
call :print_success "🎉 NGINX 部署完成!"
|
||||
goto :eof
|
||||
|
||||
REM 如果直接运行此脚本,执行主函数
|
||||
call :main
|
||||
call :cleanup
|
263
k8s/deploy.sh
Normal file
263
k8s/deploy.sh
Normal file
@ -0,0 +1,263 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Kubernetes 自动部署脚本
|
||||
# 用于从私有 Harbor 仓库拉取 NGINX 镜像并部署到 K8s 集群
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 打印带颜色的信息
|
||||
print_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 检查必要的环境变量
|
||||
check_env_vars() {
|
||||
print_info "检查环境变量..."
|
||||
|
||||
required_vars=("HARBOR_REGISTRY" "HARBOR_USERNAME" "HARBOR_PASSWORD" "NGINX_IMAGE_TAG")
|
||||
missing_vars=()
|
||||
|
||||
for var in "${required_vars[@]}"; do
|
||||
if [[ -z "${!var}" ]]; then
|
||||
missing_vars+=("$var")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#missing_vars[@]} -gt 0 ]]; then
|
||||
print_error "缺少必要的环境变量:"
|
||||
for var in "${missing_vars[@]}"; do
|
||||
echo " - $var"
|
||||
done
|
||||
print_info "请设置以下环境变量:"
|
||||
echo " export HARBOR_REGISTRY=<你的Harbor仓库地址>"
|
||||
echo " export HARBOR_USERNAME=<Harbor用户名>"
|
||||
echo " export HARBOR_PASSWORD=<Harbor密码>"
|
||||
echo " export NGINX_IMAGE_TAG=<镜像标签,如: \${GITHUB_SHA} 或 latest>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "环境变量检查通过"
|
||||
}
|
||||
|
||||
# 检查 kubectl 连接
|
||||
check_kubectl() {
|
||||
print_info "检查 kubectl 连接..."
|
||||
|
||||
if ! command -v kubectl &> /dev/null; then
|
||||
print_error "kubectl 未安装或不在 PATH 中"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! kubectl cluster-info &> /dev/null; then
|
||||
print_error "无法连接到 Kubernetes 集群"
|
||||
print_info "请确保:"
|
||||
echo " 1. kubectl 已正确配置"
|
||||
echo " 2. 能够访问 Kubernetes 集群"
|
||||
echo " 3. 当前用户有适当的权限"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "kubectl 连接正常"
|
||||
kubectl cluster-info --short
|
||||
}
|
||||
|
||||
# 创建命名空间(如果不存在)
|
||||
create_namespace() {
|
||||
local namespace=${1:-default}
|
||||
print_info "检查命名空间: $namespace"
|
||||
|
||||
if kubectl get namespace "$namespace" &> /dev/null; then
|
||||
print_success "命名空间 '$namespace' 已存在"
|
||||
else
|
||||
print_info "创建命名空间: $namespace"
|
||||
kubectl create namespace "$namespace"
|
||||
print_success "命名空间 '$namespace' 创建成功"
|
||||
fi
|
||||
}
|
||||
|
||||
# 创建或更新 Harbor 仓库访问凭据
|
||||
create_harbor_secret() {
|
||||
local namespace=${1:-default}
|
||||
print_info "创建/更新 Harbor 仓库访问凭据..."
|
||||
|
||||
# 删除已存在的 secret(如果存在)
|
||||
kubectl delete secret harbor-registry-secret -n "$namespace" --ignore-not-found=true
|
||||
|
||||
# 创建新的 secret
|
||||
kubectl create secret docker-registry harbor-registry-secret \
|
||||
--docker-server="$HARBOR_REGISTRY" \
|
||||
--docker-username="$HARBOR_USERNAME" \
|
||||
--docker-password="$HARBOR_PASSWORD" \
|
||||
--namespace="$namespace"
|
||||
|
||||
print_success "Harbor 仓库访问凭据创建成功"
|
||||
}
|
||||
|
||||
# 更新部署文件中的镜像标签
|
||||
update_deployment_image() {
|
||||
local deployment_file="$1"
|
||||
local image_tag="$2"
|
||||
|
||||
print_info "更新部署文件中的镜像标签: $image_tag"
|
||||
|
||||
# 使用 sed 替换镜像标签
|
||||
local full_image="${HARBOR_REGISTRY}/test/nginx:${image_tag}"
|
||||
|
||||
# 备份原文件
|
||||
cp "$deployment_file" "${deployment_file}.bak"
|
||||
|
||||
# 替换镜像标签 (假设镜像行包含 harbor-registry/test/nginx)
|
||||
sed -i.tmp "s|${HARBOR_REGISTRY}/test/nginx:[^[:space:]]*|${full_image}|g" "$deployment_file"
|
||||
|
||||
print_success "镜像标签更新为: $full_image"
|
||||
}
|
||||
|
||||
# 应用 Kubernetes 配置
|
||||
apply_k8s_config() {
|
||||
local deployment_file="$1"
|
||||
print_info "应用 Kubernetes 配置..."
|
||||
|
||||
if [[ ! -f "$deployment_file" ]]; then
|
||||
print_error "部署文件不存在: $deployment_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kubectl apply -f "$deployment_file"
|
||||
print_success "Kubernetes 配置应用成功"
|
||||
}
|
||||
|
||||
# 等待部署就绪
|
||||
wait_for_deployment() {
|
||||
local deployment_name="nginx-deployment"
|
||||
local namespace=${1:-default}
|
||||
local timeout=${2:-300}
|
||||
|
||||
print_info "等待部署就绪..."
|
||||
|
||||
if kubectl wait --for=condition=available deployment/"$deployment_name" \
|
||||
--namespace="$namespace" --timeout="${timeout}s"; then
|
||||
print_success "部署已就绪"
|
||||
else
|
||||
print_error "部署超时,请检查部署状态"
|
||||
kubectl describe deployment "$deployment_name" -n "$namespace"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 显示部署状态
|
||||
show_deployment_status() {
|
||||
local namespace=${1:-default}
|
||||
print_info "部署状态:"
|
||||
|
||||
echo
|
||||
echo "=== Pods ==="
|
||||
kubectl get pods -l app=nginx -n "$namespace" -o wide
|
||||
|
||||
echo
|
||||
echo "=== Services ==="
|
||||
kubectl get services -l app=nginx -n "$namespace"
|
||||
|
||||
echo
|
||||
echo "=== Deployments ==="
|
||||
kubectl get deployments -l app=nginx -n "$namespace"
|
||||
|
||||
echo
|
||||
echo "=== HPA ==="
|
||||
kubectl get hpa -l app=nginx -n "$namespace" 2>/dev/null || echo "HPA 未启用"
|
||||
|
||||
echo
|
||||
echo "=== Events ==="
|
||||
kubectl get events --sort-by=.metadata.creationTimestamp -n "$namespace" | tail -10
|
||||
}
|
||||
|
||||
# 获取访问信息
|
||||
get_access_info() {
|
||||
local namespace=${1:-default}
|
||||
print_info "获取访问信息..."
|
||||
|
||||
local service_type=$(kubectl get service nginx-service -n "$namespace" -o jsonpath='{.spec.type}')
|
||||
|
||||
case "$service_type" in
|
||||
"NodePort")
|
||||
local node_port=$(kubectl get service nginx-service -n "$namespace" -o jsonpath='{.spec.ports[0].nodePort}')
|
||||
local node_ip=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}')
|
||||
if [[ -z "$node_ip" ]]; then
|
||||
node_ip=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
|
||||
fi
|
||||
print_success "NodePort 访问地址: http://${node_ip}:${node_port}"
|
||||
;;
|
||||
"LoadBalancer")
|
||||
print_info "等待 LoadBalancer 外部 IP..."
|
||||
local external_ip=$(kubectl get service nginx-service -n "$namespace" -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
|
||||
if [[ -n "$external_ip" ]]; then
|
||||
print_success "LoadBalancer 访问地址: http://${external_ip}"
|
||||
else
|
||||
print_warning "LoadBalancer 外部 IP 仍在分配中"
|
||||
fi
|
||||
;;
|
||||
"ClusterIP")
|
||||
local cluster_ip=$(kubectl get service nginx-service -n "$namespace" -o jsonpath='{.spec.clusterIP}')
|
||||
print_success "ClusterIP 访问地址: http://${cluster_ip}"
|
||||
print_info "注意: ClusterIP 只能在集群内部访问"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
print_info "开始 NGINX Kubernetes 自动部署..."
|
||||
|
||||
# 设置默认值
|
||||
local namespace=${NAMESPACE:-default}
|
||||
local deployment_file=${DEPLOYMENT_FILE:-./nginx-deployment.yaml}
|
||||
local image_tag=${NGINX_IMAGE_TAG:-latest}
|
||||
|
||||
# 执行部署步骤
|
||||
check_env_vars
|
||||
check_kubectl
|
||||
create_namespace "$namespace"
|
||||
create_harbor_secret "$namespace"
|
||||
update_deployment_image "$deployment_file" "$image_tag"
|
||||
apply_k8s_config "$deployment_file"
|
||||
wait_for_deployment "$namespace"
|
||||
show_deployment_status "$namespace"
|
||||
get_access_info "$namespace"
|
||||
|
||||
print_success "🎉 NGINX 部署完成!"
|
||||
}
|
||||
|
||||
# 清理函数
|
||||
cleanup() {
|
||||
print_info "执行清理操作..."
|
||||
# 恢复备份文件
|
||||
if [[ -f "./nginx-deployment.yaml.bak" ]]; then
|
||||
mv "./nginx-deployment.yaml.bak" "./nginx-deployment.yaml"
|
||||
fi
|
||||
}
|
||||
|
||||
# 设置清理陷阱
|
||||
trap cleanup EXIT
|
||||
|
||||
# 如果直接运行此脚本
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
308
k8s/nginx-deployment.yaml
Normal file
308
k8s/nginx-deployment.yaml
Normal file
@ -0,0 +1,308 @@
|
||||
# Kubernetes 部署配置文件
|
||||
# 用于从私有 Harbor 仓库拉取 NGINX 镜像并部署
|
||||
#
|
||||
# 使用方法:
|
||||
# 1. 设置环境变量:
|
||||
# export HARBOR_REGISTRY=<你的Harbor仓库地址>
|
||||
# export HARBOR_USERNAME=<Harbor用户名>
|
||||
# export HARBOR_PASSWORD=<Harbor密码>
|
||||
# export NGINX_IMAGE_TAG=<镜像标签>
|
||||
#
|
||||
# 2. 运行部署脚本:
|
||||
# ./deploy.sh
|
||||
#
|
||||
# 或者手动执行:
|
||||
# 1. kubectl create secret docker-registry harbor-registry-secret \
|
||||
# --docker-server=$HARBOR_REGISTRY \
|
||||
# --docker-username=$HARBOR_USERNAME \
|
||||
# --docker-password=$HARBOR_PASSWORD
|
||||
# 2. kubectl apply -f nginx-deployment.yaml
|
||||
|
||||
---
|
||||
# 1. 私有仓库访问凭据 Secret (通过脚本自动创建)
|
||||
# 如果需要手动创建,请使用以下命令:
|
||||
# kubectl create secret docker-registry harbor-registry-secret \
|
||||
# --docker-server=<HARBOR_REGISTRY> \
|
||||
# --docker-username=<HARBOR_USERNAME> \
|
||||
# --docker-password=<HARBOR_PASSWORD>
|
||||
|
||||
---
|
||||
# 1. ConfigMap - NGINX 配置
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nginx-config
|
||||
namespace: default
|
||||
data:
|
||||
nginx.conf: |
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
|
||||
# 基本安全头
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
|
||||
# Gzip 压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
# 健康检查端点
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# 状态监控端点
|
||||
location /nginx_status {
|
||||
stub_status on;
|
||||
access_log off;
|
||||
allow 127.0.0.1;
|
||||
allow 10.0.0.0/8;
|
||||
allow 172.16.0.0/12;
|
||||
allow 192.168.0.0/16;
|
||||
deny all;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
# 错误页面
|
||||
error_page 404 /404.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
# 3. Deployment - NGINX 应用部署
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
namespace: default
|
||||
labels:
|
||||
app: nginx
|
||||
version: v1
|
||||
spec:
|
||||
replicas: 3
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
version: v1
|
||||
spec:
|
||||
# 使用私有仓库凭据
|
||||
imagePullSecrets:
|
||||
- name: harbor-registry-secret
|
||||
|
||||
# 安全上下文
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 65534
|
||||
fsGroup: 65534
|
||||
|
||||
containers:
|
||||
- name: nginx
|
||||
# 使用私有仓库中的镜像(需要根据实际情况修改)
|
||||
image: ${HARBOR_REGISTRY}/test/nginx:latest
|
||||
imagePullPolicy: Always
|
||||
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
|
||||
# 环境变量
|
||||
env:
|
||||
- name: TZ
|
||||
value: "Asia/Shanghai"
|
||||
|
||||
# 资源限制
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "50m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "200m"
|
||||
|
||||
# 健康检查
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 80
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 80
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
|
||||
# 启动探针
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 80
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
|
||||
# 挂载配置文件
|
||||
volumeMounts:
|
||||
- name: nginx-config-volume
|
||||
mountPath: /etc/nginx/nginx.conf
|
||||
subPath: nginx.conf
|
||||
readOnly: true
|
||||
- name: nginx-cache
|
||||
mountPath: /var/cache/nginx
|
||||
- name: nginx-run
|
||||
mountPath: /var/run
|
||||
|
||||
volumes:
|
||||
- name: nginx-config-volume
|
||||
configMap:
|
||||
name: nginx-config
|
||||
defaultMode: 0644
|
||||
- name: nginx-cache
|
||||
emptyDir: {}
|
||||
- name: nginx-run
|
||||
emptyDir: {}
|
||||
|
||||
# 节点选择器(可选)
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
|
||||
# 容忍度(可选)
|
||||
tolerations:
|
||||
- key: "node.kubernetes.io/not-ready"
|
||||
operator: "Exists"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 300
|
||||
- key: "node.kubernetes.io/unreachable"
|
||||
operator: "Exists"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 300
|
||||
|
||||
---
|
||||
# 4. Service - 服务暴露
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx-service
|
||||
namespace: default
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: nginx
|
||||
|
||||
---
|
||||
# 5. HorizontalPodAutoscaler - 自动扩缩容
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: nginx-hpa
|
||||
namespace: default
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: nginx-deployment
|
||||
minReplicas: 2
|
||||
maxReplicas: 10
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 80
|
||||
behavior:
|
||||
scaleDown:
|
||||
stabilizationWindowSeconds: 300
|
||||
policies:
|
||||
- type: Percent
|
||||
value: 50
|
||||
periodSeconds: 60
|
||||
scaleUp:
|
||||
stabilizationWindowSeconds: 60
|
||||
policies:
|
||||
- type: Percent
|
||||
value: 100
|
||||
periodSeconds: 15
|
||||
|
||||
---
|
||||
# 6. PodDisruptionBudget - Pod 中断预算
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: nginx-pdb
|
||||
namespace: default
|
||||
spec:
|
||||
minAvailable: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
257
k8s/quickstart.sh
Normal file
257
k8s/quickstart.sh
Normal file
@ -0,0 +1,257 @@
|
||||
#!/bin/bash
|
||||
|
||||
# NGINX Kubernetes 快速启动脚本
|
||||
# 用于快速设置和部署 NGINX 到 Kubernetes
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_banner() {
|
||||
echo -e "${BLUE}"
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ NGINX Kubernetes 部署工具 ║"
|
||||
echo "║ 快速启动和配置向导 ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 交互式配置收集
|
||||
collect_config() {
|
||||
print_info "开始收集配置信息..."
|
||||
echo
|
||||
|
||||
# Harbor 配置
|
||||
read -p "$(echo -e ${BLUE}请输入 Harbor 仓库地址${NC} (例: harbor.example.com): " HARBOR_REGISTRY
|
||||
read -p "$(echo -e ${BLUE}请输入 Harbor 用户名${NC}: " HARBOR_USERNAME
|
||||
read -s -p "$(echo -e ${BLUE}请输入 Harbor 密码${NC}: " HARBOR_PASSWORD
|
||||
echo
|
||||
|
||||
# 镜像配置
|
||||
read -p "$(echo -e ${BLUE}请输入镜像标签${NC} (默认: latest): " NGINX_IMAGE_TAG
|
||||
NGINX_IMAGE_TAG=${NGINX_IMAGE_TAG:-latest}
|
||||
|
||||
# Kubernetes 配置
|
||||
read -p "$(echo -e ${BLUE}请输入 Kubernetes 命名空间${NC} (默认: default): " NAMESPACE
|
||||
NAMESPACE=${NAMESPACE:-default}
|
||||
|
||||
echo
|
||||
print_success "配置收集完成"
|
||||
}
|
||||
|
||||
# 验证配置
|
||||
validate_config() {
|
||||
print_info "验证配置..."
|
||||
|
||||
if [[ -z "$HARBOR_REGISTRY" ]]; then
|
||||
print_error "Harbor 仓库地址不能为空"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -z "$HARBOR_USERNAME" ]]; then
|
||||
print_error "Harbor 用户名不能为空"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -z "$HARBOR_PASSWORD" ]]; then
|
||||
print_error "Harbor 密码不能为空"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_success "配置验证通过"
|
||||
}
|
||||
|
||||
# 保存配置到环境文件
|
||||
save_config() {
|
||||
print_info "保存配置到 .env 文件..."
|
||||
|
||||
cat > .env << EOF
|
||||
# NGINX Kubernetes 部署配置
|
||||
# 由快速启动脚本生成于 $(date)
|
||||
|
||||
# Harbor 仓库配置
|
||||
HARBOR_REGISTRY=$HARBOR_REGISTRY
|
||||
HARBOR_USERNAME=$HARBOR_USERNAME
|
||||
HARBOR_PASSWORD=$HARBOR_PASSWORD
|
||||
|
||||
# 镜像配置
|
||||
NGINX_IMAGE_TAG=$NGINX_IMAGE_TAG
|
||||
|
||||
# Kubernetes 配置
|
||||
NAMESPACE=$NAMESPACE
|
||||
DEPLOYMENT_FILE=./nginx-deployment.yaml
|
||||
EOF
|
||||
|
||||
print_success "配置已保存到 .env 文件"
|
||||
}
|
||||
|
||||
# 显示配置摘要
|
||||
show_config_summary() {
|
||||
echo
|
||||
print_info "配置摘要:"
|
||||
echo " Harbor 仓库: $HARBOR_REGISTRY"
|
||||
echo " Harbor 用户: $HARBOR_USERNAME"
|
||||
echo " 镜像标签: $NGINX_IMAGE_TAG"
|
||||
echo " 命名空间: $NAMESPACE"
|
||||
echo " 完整镜像地址: $HARBOR_REGISTRY/test/nginx:$NGINX_IMAGE_TAG"
|
||||
echo
|
||||
}
|
||||
|
||||
# 检查先决条件
|
||||
check_prerequisites() {
|
||||
print_info "检查先决条件..."
|
||||
|
||||
local missing_tools=()
|
||||
|
||||
# 检查 kubectl
|
||||
if ! command -v kubectl &> /dev/null; then
|
||||
missing_tools+=("kubectl")
|
||||
fi
|
||||
|
||||
# 检查 docker (可选)
|
||||
if ! command -v docker &> /dev/null; then
|
||||
print_warning "Docker 未安装 (可选)"
|
||||
fi
|
||||
|
||||
if [[ ${#missing_tools[@]} -gt 0 ]]; then
|
||||
print_error "缺少必要工具: ${missing_tools[*]}"
|
||||
echo "请安装缺少的工具后重试"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 检查 kubectl 连接
|
||||
if ! kubectl cluster-info &> /dev/null; then
|
||||
print_error "无法连接到 Kubernetes 集群"
|
||||
echo "请确保 kubectl 已正确配置并能访问集群"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_success "先决条件检查通过"
|
||||
}
|
||||
|
||||
# 测试 Harbor 连接
|
||||
test_harbor_connection() {
|
||||
print_info "测试 Harbor 连接..."
|
||||
|
||||
if command -v docker &> /dev/null; then
|
||||
if echo "$HARBOR_PASSWORD" | docker login "$HARBOR_REGISTRY" -u "$HARBOR_USERNAME" --password-stdin &> /dev/null; then
|
||||
print_success "Harbor 连接测试通过"
|
||||
docker logout "$HARBOR_REGISTRY" &> /dev/null
|
||||
else
|
||||
print_warning "Harbor 连接测试失败,请检查凭据"
|
||||
fi
|
||||
else
|
||||
print_warning "Docker 未安装,跳过 Harbor 连接测试"
|
||||
fi
|
||||
}
|
||||
|
||||
# 运行部署
|
||||
run_deployment() {
|
||||
print_info "开始部署..."
|
||||
|
||||
# 导出环境变量
|
||||
export HARBOR_REGISTRY
|
||||
export HARBOR_USERNAME
|
||||
export HARBOR_PASSWORD
|
||||
export NGINX_IMAGE_TAG
|
||||
export NAMESPACE
|
||||
|
||||
# 运行部署脚本
|
||||
if [[ -f "deploy.sh" ]]; then
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
else
|
||||
print_error "部署脚本 deploy.sh 不存在"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 提供后续操作建议
|
||||
show_next_steps() {
|
||||
echo
|
||||
print_success "🎉 部署完成!"
|
||||
echo
|
||||
print_info "后续操作建议:"
|
||||
echo " 1. 查看部署状态: make status"
|
||||
echo " 2. 查看日志: make logs"
|
||||
echo " 3. 设置端口转发: make port-forward"
|
||||
echo " 4. 扩缩容: make scale REPLICAS=5"
|
||||
echo " 5. 更新镜像: make update NGINX_IMAGE_TAG=new-version"
|
||||
echo " 6. 清理部署: make clean"
|
||||
echo
|
||||
print_info "配置文件已保存到 .env,下次可以直接运行 ./deploy.sh"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
print_banner
|
||||
|
||||
# 检查是否已有配置文件
|
||||
if [[ -f ".env" ]]; then
|
||||
read -p "$(echo -e ${YELLOW}发现已存在配置文件 .env,是否重新配置?${NC} (y/N): " RECONFIGURE
|
||||
if [[ "$RECONFIGURE" =~ ^[Yy]$ ]]; then
|
||||
collect_config
|
||||
else
|
||||
print_info "使用现有配置文件..."
|
||||
source .env
|
||||
fi
|
||||
else
|
||||
collect_config
|
||||
fi
|
||||
|
||||
validate_config || exit 1
|
||||
show_config_summary
|
||||
|
||||
# 询问是否继续
|
||||
read -p "$(echo -e ${YELLOW}是否继续部署?${NC} (Y/n): " CONTINUE
|
||||
if [[ "$CONTINUE" =~ ^[Nn]$ ]]; then
|
||||
print_info "部署已取消"
|
||||
save_config
|
||||
echo "配置已保存,可以稍后运行 ./deploy.sh 进行部署"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check_prerequisites || exit 1
|
||||
test_harbor_connection
|
||||
save_config
|
||||
run_deployment
|
||||
show_next_steps
|
||||
}
|
||||
|
||||
# 清理函数
|
||||
cleanup() {
|
||||
# 恢复终端状态
|
||||
stty echo 2>/dev/null || true
|
||||
}
|
||||
|
||||
# 设置清理陷阱
|
||||
trap cleanup EXIT
|
||||
|
||||
# 处理中断信号
|
||||
trap 'print_warning "操作被中断"; exit 130' INT
|
||||
|
||||
# 如果直接运行此脚本
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
Loading…
x
Reference in New Issue
Block a user