【无标题】

文章目录

      • [**一、 环境与项目准备**](#一、 环境与项目准备)
        • [**1.1 前提条件**](#1.1 前提条件)
        • [**1.2 项目结构**](#1.2 项目结构)
        • [**1.3 应用配置**](#1.3 应用配置)
      • [**二、 容器化 .NET Core 应用**](#二、 容器化 .NET Core 应用)
      • [**三、 部署 Kubernetes 资源**](#三、 部署 Kubernetes 资源)
        • [**3.1 部署 MySQL**](#3.1 部署 MySQL)
        • [**3.2 部署 Redis**](#3.2 部署 Redis)
        • [**3.3 部署 .NET Core WebAPI**](#3.3 部署 .NET Core WebAPI)
        • [**3.4 部署 Nginx Ingress**](#3.4 部署 Nginx Ingress)
      • [**四、 验证与测试**](#四、 验证与测试)
      • [**五、 核心配置与连接总结**](#五、 核心配置与连接总结)
      • **后续建议**

这里整理了一份将 .NET Core WebAPI 项目(包含 MySQL、Redis、Nginx)部署到 Kubernetes 的全流程指南。教程的核心步骤已在下图中展示,可以通过它快速了解部署流程与各组件间的联系。
开始 准备项目
与 Docker 镜像 配置 Kubernetes 资源 部署核心依赖服务 部署 MySQL 部署 Redis 部署 .NET Core WebAPI 部署 Nginx Ingress 验证与测试 检查 Pod 状态 测试 API 连通性 通过域名访问 部署完成

一、 环境与项目准备

1.1 前提条件

在开始之前,请确保你已准备好以下环境:

  • Kubernetes 集群:可以是一个本地集群(如 Minikube、Kind、Docker Desktop 内置 K8s),或云服务商提供的集群(如 AKS、EKS、GKE)。
  • kubectl:已安装并配置好,可以管理你的集群。
  • .NET SDK:本地开发环境需安装相应版本的 .NET SDK(如 .NET 6/7/8)。
  • Docker:用于构建应用程序的容器镜像。
1.2 项目结构

假设你的 .NET Core WebAPI 项目结构如下:

复制代码
k8s-dotnet-demo/
├── src/
│   └── MyWebApi/                 # .NET Core WebAPI 项目目录
│       ├── Controllers/
│       ├── Program.cs
│       ├── appsettings.json
│       ├── MyWebApi.csproj
│       └── Dockerfile            # 项目Dockerfile
└── k8s-manifests/                # 所有K8s YAML配置文件
    ├── 01-mysql.yaml
    ├── 02-redis.yaml
    ├── 03-webapi.yaml
    └── 04-ingress.yaml
1.3 应用配置

确保你的 appsettings.json 或通过环境变量的配置支持从外部读取数据库和缓存连接字符串。这是云原生应用配置的关键。

json 复制代码
{
  "ConnectionStrings": {
    // 注意:这里的 Server 和 Port 使用的是K8s中Service的名称和端口
    "MySqlConnection": "Server=mysql-service;Port=3306;Database=mydb;User=root;Password=${MYSQL_ROOT_PASSWORD};",
    "RedisConnection": "${REDIS_CONNECTION_STRING}" // 例如: redis://redis-service:6379
  }
}

重要 :连接字符串中的服务器地址(如 mysql-service, redis-service)是后续在 Kubernetes 中创建的 Service 名称。Kubernetes 内置的 DNS 服务会自动将其解析为对应 Pod 的 Cluster IP。

二、 容器化 .NET Core 应用

为你的 WebAPI 项目创建 Dockerfile,推荐使用多阶段构建以减小最终镜像体积。

dockerfile 复制代码
# 构建阶段
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["src/MyWebApi/MyWebApi.csproj", "."]
RUN dotnet restore "MyWebApi.csproj"
COPY src/MyWebApi/ .
RUN dotnet publish "MyWebApi.csproj" -c Release -o /app/publish

# 运行时阶段
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app/publish .
# 暴露应用端口(通常为80或5000)
EXPOSE 80
ENTRYPOINT ["dotnet", "MyWebApi.dll"]

构建并推送镜像到你的镜像仓库(如 Docker Hub、阿里云容器镜像服务等):

bash 复制代码
docker build -t yourusername/mywebapi:1.0.0 ./src/MyWebApi
docker push yourusername/mywebapi:1.0.0

三、 部署 Kubernetes 资源

3.1 部署 MySQL

创建 k8s-manifests/01-mysql.yaml。使用 PersistentVolumeClaim (PVC) 来持久化存储数据库数据,防止 Pod 重启后数据丢失。

yaml 复制代码
# 持久化存储声明
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

# 配置信息 (ConfigMap)
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  database: "mydb"

# 敏感信息 (Secret),务必在生产环境中使用!
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
type: Opaque
stringData:
  root-password: "YourStrongPassword123!"

# 部署 (Deployment)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8.0
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: root-password
            - name: MYSQL_DATABASE
              valueFrom:
                configMapKeyRef:
                  name: mysql-config
                  key: database
          ports:
            - containerPort: 3306
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: mysql-storage
      volumes:
        - name: mysql-storage
          persistentVolumeClaim:
            claimName: mysql-pvc

# 服务 (Service) - 在集群内部暴露MySQL
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
    - port: 3306
      targetPort: 3306
  # ClusterIP类型,只在集群内部可访问
  type: ClusterIP

应用配置:kubectl apply -f k8s-manifests/01-mysql.yaml

3.2 部署 Redis

创建 k8s-manifests/02-redis.yaml。Redis 通常也建议进行数据持久化。

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
spec:
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:7-alpine
          command: ["redis-server"]
          args: ["--appendonly", "yes"] # 启用AOF持久化
          ports:
            - containerPort: 6379
          volumeMounts:
            - name: redis-data
              mountPath: /data
      volumes:
        - name: redis-data
          emptyDir: {} # 简单示例,生产环境建议使用PVC

---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
spec:
  selector:
    app: redis
  ports:
    - port: 6379
      targetPort: 6379
  type: ClusterIP

应用配置:kubectl apply -f k8s-manifests/02-redis.yaml

3.3 部署 .NET Core WebAPI

创建 k8s-manifests/03-webapi.yaml。这是最核心的部分,需要配置环境变量、健康检查探针和资源限制。

yaml 复制代码
# 将数据库连接密码等敏感信息存入Secret
apiVersion: v1
kind: Secret
metadata:
  name: webapi-secret
type: Opaque
stringData:
  mysql-password: "YourStrongPassword123!"
  redis-connection: "redis://redis-service:6379"

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapi-deployment
spec:
  replicas: 2 # 运行两个副本以实现基本的高可用
  selector:
    matchLabels:
      app: webapi
  template:
    metadata:
      labels:
        app: webapi
    spec:
      containers:
        - name: webapi
          image: yourusername/mywebapi:1.0.0 # 替换为你的实际镜像
          ports:
            - containerPort: 80
          env:
            # 从Secret和硬编码(仅为示例,生产环境应全放Secret)注入连接字符串
            - name: ConnectionStrings__MySqlConnection
              value: "Server=mysql-service;Port=3306;Database=mydb;User=root;Password=$(MYSQL_ROOT_PASSWORD);"
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: webapi-secret
                  key: mysql-password
            - name: ConnectionStrings__RedisConnection
              valueFrom:
                secretKeyRef:
                  name: webapi-secret
                  key: redis-connection
          # 健康检查是关键配置,让K8s能管理应用的生命周期
          livenessProbe:
            httpGet:
              path: /healthz  # 你的应用需要实现健康检查端点
              port: 80
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 5
          resources:
            requests:
              memory: "256Mi"
              cpu: "100m"
            limits:
              memory: "512Mi"
              cpu: "500m"

---
# 内部服务,用于Ingress或服务间通信
apiVersion: v1
kind: Service
metadata:
  name: webapi-service
spec:
  selector:
    app: webapi
  ports:
    - port: 80
      targetPort: 80
  type: ClusterIP

应用配置:kubectl apply -f k8s-manifests/03-webapi.yaml

3.4 部署 Nginx Ingress

首先,确保你的 Kubernetes 集群已经安装了 Ingress-NGINX 控制器 。安装方法因集群而异。

创建 k8s-manifests/04-ingress.yaml,定义外部访问规则。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: webapi-ingress
  annotations:
    # 使用nginx-ingress的注解实现HTTP到HTTPS的重定向
    nginx.ingress.kubernetes.io/ssl-redirect: "false" # 假设暂未配置TLS
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
spec:
  ingressClassName: nginx
  rules:
  - host: api.yourdomain.com # 将此处替换为你的域名或Minikube IP
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapi-service
            port:
              number: 80

应用配置:kubectl apply -f k8s-manifests/04-ingress.yaml

四、 验证与测试

  1. 检查所有资源状态

    bash 复制代码
    kubectl get pods,svc,ingress,pvc

    等待所有 Pod 的状态变为 Running

  2. 查看应用日志,排查启动问题:

    bash 复制代码
    kubectl logs -l app=webapi --tail=50
  3. 测试内部连接

    bash 复制代码
    # 进入WebAPI的Pod执行命令
    kubectl exec -it <webapi-pod-name> -- curl -v http://localhost/healthz
    # 测试从WebAPI Pod能否连接MySQL和Redis
    kubectl exec -it <webapi-pod-name> -- bash
    # 在Pod内执行
    apt-get update && apt-get install -y mysql-client redis-tools
    mysql -h mysql-service -uroot -p$MYSQL_ROOT_PASSWORD
    redis-cli -h redis-service ping
  4. 外部访问测试

    • Minikube : minikube service webapi-service --url (如果使用Service类型为NodePort,此教程为ClusterIP,由Ingress暴露)。
    • 通过Ingress : 获取Ingress的外部IP (kubectl get ingress),然后使用 curl -H "Host: api.yourdomain.com" http://<INGRESS_IP> 或配置本地hosts文件后访问。

五、 核心配置与连接总结

为了方便你理解,以下是两个关键的连接与检查配置表:

服务连接配置摘要

组件 在 K8s 中的 Service 名称 端口 在 .NET Core 连接字符串中的地址示例
MySQL mysql-service 3306 Server=mysql-service;Port=3306;...
Redis redis-service 6379 redis-service:6379
WebAPI webapi-service 80 内部服务,供 Ingress 或其他服务调用

.NET Core 健康检查端点配置(示例)

Program.cs 中添加健康检查,这是配置 K8s 探针 (livenessProbe, readinessProbe) 的基础。

csharp 复制代码
var builder = WebApplication.CreateBuilder(args);
// 添加健康检查服务
builder.Services.AddHealthChecks();
// 可以添加针对MySQL、Redis的特定健康检查,例如:
// builder.Services.AddHealthChecks().AddMySql(...).AddRedis(...);

var app = builder.Build();
// 映射健康检查端点
app.MapHealthChecks("/healthz");   // 用于存活探针
app.MapHealthChecks("/ready");     // 用于就绪探针

后续建议

  • 生产环境安全:务必使用更安全的方式管理密码(如 HashiCorp Vault 或云厂商的密钥管理服务),并考虑为 MySQL 和 Redis 配置密码认证。
  • 配置管理 :将更多配置(如数据库名、超时时间)移入 ConfigMap
  • 网络策略 :定义 NetworkPolicy 来限制 Pod 之间的网络流量,实现最小权限访问。
  • 使用 Helm :当应用复杂时,使用 Helm Chart 来打包和管理所有这些 YAML 文件,实现参数化部署。
相关推荐
JY.yuyu8 小时前
ACL访问控制列表
运维·服务器·网络
艾莉丝努力练剑8 小时前
【Python库和代码案例:第一课】Python 标准库与第三方库实战指南:从日期处理到 Excel 操作
java·服务器·开发语言·人工智能·python·pycharm·pip
xinxinhenmeihao8 小时前
长效住宅静态IP有什么好处?是选择动态IP还是静态IP好?
服务器·网络·tcp/ip
CoderJia程序员甲8 小时前
GitHub 热榜项目 - 日榜(2025-12-17)
ai·开源·大模型·github·ai教程
irisart8 小时前
第二章【开源功能】—— HTTP 服务器(上)
服务器·nginx·开源
鼎道开发者联盟8 小时前
鼎道AIGUI元件体系如何让DingOS实现“积木”式交互
人工智能·ui·ai·aigc·交互·gui
qq_455760858 小时前
docker - 虚拟化和容器化
linux·运维·服务器
云和数据.ChenGuang8 小时前
ELK 是一套**开源的日志收集、存储、分析与可视化的技术栈
服务器·数据库·elk·开源·运维技术·数据库运维工程师
艾莉丝努力练剑8 小时前
【Linux进程(二)】Linux进程的诞生、管理与消亡:一份基于内核视角的完整分析
大数据·linux·运维·服务器·c++·安全·centos