导航
- 上一步:模块5:构建Docker镜像
- 下一步:模块7:故障排查和优化
- 返回主索引:阿里云ACK部署SOP
模块概述
预计时间:30分钟
本模块目标:
- ✅ 理解Kubernetes核心资源(Namespace、Deployment、Service、Ingress)
- ✅ 创建完整的应用配置文件
- ✅ 部署应用到Kubernetes集群
- ✅ 配置健康检查和资源限制
- ✅ 通过域名访问应用
- ✅ 验证负载均衡和高可用
成本说明:
- 本模块不产生额外费用
- 使用已有的ACK集群和ALB实例
步骤6.1:理解Kubernetes核心资源
🎬 操作说明
在开始部署之前,我们需要先理解Kubernetes的核心资源。这些资源是部署应用的基础,理解它们的作用和关系非常重要。
📍 详细说明
Kubernetes资源层级关系
┌─────────────────────────────────────────┐
│ Ingress(外网访问入口) │
│ - 域名路由 │
│ - SSL证书 │
│ - 七层负载均衡 │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Service(服务发现和负载均衡) │
│ - ClusterIP(集群内部访问) │
│ - 自动负载均衡到多个Pod │
│ - 服务发现(通过DNS) │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Deployment(管理Pod副本) │
│ - 声明期望的副本数 │
│ - 自动创建和管理Pod │
│ - 滚动更新和回滚 │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Pod(最小部署单元) │
│ - 运行一个或多个容器 │
│ - 共享网络和存储 │
│ - 生命周期管理 │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Container(容器) │
│ - 运行Docker镜像 │
│ - 隔离的运行环境 │
└─────────────────────────────────────────┘
核心资源详解
1. Namespace(命名空间)
作用:
- 资源隔离:不同的应用或环境使用不同的Namespace
- 权限控制:可以为不同的Namespace设置不同的权限
- 资源配额:可以限制每个Namespace的资源使用量
示例场景:
dev:开发环境test:测试环境prod:生产环境
2. Deployment(部署)
作用:
- 管理Pod副本:声明期望的副本数,Kubernetes自动维护
- 滚动更新:更新应用时,逐步替换旧版本,不中断服务
- 自动恢复:Pod故障时,自动创建新的Pod替换
关键配置:
replicas:副本数(建议至少2个,实现高可用)image:Docker镜像地址resources:资源限制(CPU、内存)livenessProbe:存活探针(检测应用是否健康)readinessProbe:就绪探针(检测应用是否准备好接收流量)
3. Service(服务)
作用:
- 服务发现:为Pod提供稳定的访问地址(Pod的IP会变化)
- 负载均衡:自动将流量分发到多个Pod
- 端口映射:将Service端口映射到Pod端口
Service类型:
ClusterIP:集群内部访问(默认,最常用)NodePort:通过节点IP+端口访问(不推荐)LoadBalancer:通过云厂商的负载均衡器访问(成本高)
4. Ingress(入口)
作用:
- 七层路由:基于域名和路径路由到不同的Service
- SSL终止:在Ingress层处理HTTPS,后端使用HTTP
- 统一入口:一个Ingress可以管理多个域名和服务
关键配置:
host:域名path:路径规则backend:后端Servicetls:SSL证书配置
5. ConfigMap和Secret
作用:
ConfigMap:存储配置文件(明文)Secret:存储敏感信息(Base64编码)
使用场景:
- 数据库连接字符串
- API密钥
- 配置文件
✅ 验证点
- 理解Namespace的作用
- 理解Deployment管理Pod的方式
- 理解Service提供稳定访问的原理
- 理解Ingress的路由功能
⚠️ 常见问题
问题1:为什么需要Service?直接访问Pod不行吗?
- 答:Pod的IP会变化
- Pod重启后,IP会改变
- Service提供稳定的ClusterIP
- Service自动更新后端Pod列表
问题2:Deployment和Pod有什么区别?
- 答:Deployment是管理者,Pod是被管理者
- 不要直接创建Pod,应该通过Deployment创建
- Deployment可以自动恢复故障的Pod
- Deployment支持滚动更新和回滚
问题3:为什么要配置资源限制?
- 答:防止资源耗尽
- 一个Pod占用过多资源,会影响其他Pod
- 资源限制可以保证集群稳定性
- Kubernetes根据资源限制进行调度
问题4:健康检查有什么用?
- 答:自动检测应用状态
- livenessProbe:应用不健康时,自动重启Pod
- readinessProbe:应用未就绪时,不转发流量
- 提高应用的可用性
💡 小贴士
- 🎯 建议先理解资源关系,再开始配置
- 📚 Kubernetes官方文档是最好的学习资源
- 🔍 使用
kubectl explain命令查看资源字段说明
步骤6.2:创建项目目录结构
🎬 操作说明
现在我们创建一个项目目录,用于存放所有的Kubernetes配置文件。良好的目录结构可以让配置文件更易于管理。
📍 详细步骤
第1步:创建项目目录
- 在本地电脑上,创建项目目录:
mkdir -p ~/my-app-k8s cd ~/my-app-k8s
第2步:创建子目录
- 创建不同类型资源的子目录:
mkdir -p base mkdir -p overlays/dev mkdir -p overlays/prod - 目录说明:
base/:基础配置(所有环境共用)overlays/dev/:开发环境特定配置overlays/prod/:生产环境特定配置
第3步:查看目录结构
- 运行命令:
tree . - 应该看到:
. ├── base └── overlays ├── dev └── prod
✅ 验证点
- 项目目录已创建
- 子目录结构清晰
⚠️ 常见问题
问题1:为什么要分base和overlays?
- 答:这是Kustomize的目录结构
- base存放通用配置
- overlays存放环境特定配置
- 可以避免配置重复
问题2:不使用Kustomize可以吗?
- 答:可以
- 可以直接在base目录创建所有配置文件
- 但使用Kustomize可以更好地管理多环境配置
💡 小贴士
- 📁 良好的目录结构是项目管理的基础
- 🔄 后续可以使用Git管理这些配置文件
步骤6.3:创建Namespace配置
🎬 操作说明
首先创建Namespace配置文件。Namespace用于隔离不同的应用或环境,是Kubernetes资源管理的基础。
📍 详细步骤
第1步:创建namespace.yaml文件
- 在base目录创建文件:
cat > base/namespace.yaml << 'EOF' apiVersion: v1 kind: Namespace metadata: name: my-app labels: name: my-app env: production EOF
第2步:理解配置内容
apiVersion: v1 # API版本
kind: Namespace # 资源类型
metadata: # 元数据
name: my-app # Namespace名称(必须唯一)
labels: # 标签(用于筛选和管理)
name: my-app # 应用名称标签
env: production # 环境标签
第3步:验证YAML语法
- 运行命令检查语法:
kubectl apply --dry-run=client -f base/namespace.yaml - 如果没有错误,说明语法正确
✅ 验证点
- namespace.yaml文件已创建
- YAML语法正确
- 文件内容符合预期
⚠️ 常见问题
问题1:Namespace名称有什么限制?
- 答:必须符合DNS规范
- 只能包含小写字母、数字、连字符
- 不能以连字符开头或结尾
- 长度不超过63个字符
问题2:可以不创建Namespace吗?
- 答:可以使用default命名空间
- 但不推荐,生产环境应该创建独立的Namespace
- 便于资源隔离和权限管理
问题3:标签有什么用?
- 答:用于筛选和管理资源
- 可以通过标签查询资源
- 可以基于标签设置权限
- 可以基于标签统计成本
💡 小贴士
- 🏷️ 建议为所有资源添加统一的标签
- 📝 标签命名要有意义,便于理解
步骤6.4:创建Deployment配置
🎬 操作说明
现在创建Deployment配置文件。这是最核心的配置,定义了应用如何运行,包括镜像、副本数、资源限制、健康检查等。
📍 详细步骤
第1步:创建deployment.yaml文件
- 在base目录创建文件:
cat > base/deployment.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: name: my-app namespace: my-app labels: app: my-app spec: # 副本数:2个Pod实现高可用 replicas: 2 # 选择器:匹配哪些Pod属于这个Deployment selector: matchLabels: app: my-app # Pod模板 template: metadata: labels: app: my-app version: v1.0.0 spec: # 容器列表 containers: - name: my-app # 镜像地址(替换为你的镜像) image: registry.cn-hangzhou.aliyuncs.com/my-namespace/my-app:v1.0.0 # 镜像拉取策略 imagePullPolicy: Always # 容器端口 ports: - name: http containerPort: 8080 protocol: TCP # 环境变量 env: - name: PORT value: "8080" - name: ENV value: "production" # 资源限制 resources: # 请求资源(调度时保证的资源) requests: cpu: 100m # 0.1核CPU memory: 128Mi # 128MB内存 # 限制资源(最大可使用的资源) limits: cpu: 500m # 0.5核CPU memory: 512Mi # 512MB内存 # 存活探针(检测应用是否健康) livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 # 启动后30秒开始检测 periodSeconds: 10 # 每10秒检测一次 timeoutSeconds: 5 # 超时时间5秒 failureThreshold: 3 # 连续失败3次认为不健康 # 就绪探针(检测应用是否准备好接收流量) readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 10 # 启动后10秒开始检测 periodSeconds: 5 # 每5秒检测一次 timeoutSeconds: 3 # 超时时间3秒 failureThreshold: 3 # 连续失败3次认为未就绪 # 镜像拉取密钥 imagePullSecrets: - name: acr-secret EOF
第2步:理解关键配置
副本数配置:
replicas: 2
- 2个副本可以实现基本的高可用
- 一个Pod故障时,另一个Pod继续服务
- 生产环境建议至少2个副本
资源限制配置:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
requests:调度时保证的资源,Kubernetes会找有足够资源的节点limits:最大可使用的资源,超过会被限制或杀死- CPU单位:
m表示毫核,1000m = 1核 - 内存单位:
Mi表示MiB,Gi表示GiB
健康检查配置:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:存活探针,失败会重启PodreadinessProbe:就绪探针,失败会从Service移除initialDelaySeconds:启动后多久开始检测(给应用启动时间)periodSeconds:检测间隔
第3步:修改镜像地址
- 将镜像地址替换为你的镜像:
# 使用sed命令替换 sed -i '' 's|registry.cn-hangzhou.aliyuncs.com/my-namespace/my-app:v1.0.0|你的镜像地址|g' base/deployment.yaml - 或者手动编辑文件
第4步:验证YAML语法
- 运行命令:
kubectl apply --dry-run=client -f base/deployment.yaml
✅ 验证点
- deployment.yaml文件已创建
- 镜像地址已修改为你的镜像
- YAML语法正确
- 理解每个配置项的作用
⚠️ 常见问题
问题1:requests和limits有什么区别?
- 答:requests是保证,limits是限制
- requests:调度时使用,保证Pod能分配到这么多资源
- limits:运行时使用,超过会被限制
- 建议:requests设置为正常使用量,limits设置为峰值
问题2:如何确定资源限制的值?
- 答:先设置一个合理的值,然后观察
- 可以先设置较大的值,运行一段时间后查看实际使用量
- 使用
kubectl top pod查看资源使用情况 - 根据实际使用量调整
问题3:livenessProbe和readinessProbe有什么区别?
- 答:作用不同
- livenessProbe:检测应用是否健康,失败会重启Pod
- readinessProbe:检测应用是否就绪,失败会从Service移除
- 通常两者配置相同,但initialDelaySeconds不同
问题4:为什么要设置imagePullPolicy为Always?
- 答:确保使用最新的镜像
- 如果使用latest标签,建议设置为Always
- 如果使用明确的版本号,可以设置为IfNotPresent
问题5:健康检查失败会怎样?
- 答:取决于探针类型
- livenessProbe失败:Pod会被重启
- readinessProbe失败:Pod会从Service移除,不接收流量
- 连续失败failureThreshold次才会触发
💡 小贴士
- 🎯 资源限制很重要,防止单个Pod耗尽节点资源
- 🏥 健康检查是高可用的关键,务必配置
- 📊 建议先运行一段时间,根据实际情况调整资源限制
- 🔄 使用明确的版本号,不要使用latest标签
步骤6.5:创建Service配置
🎬 操作说明
现在创建Service配置文件。Service为Pod提供稳定的访问地址和负载均衡功能,是应用对外提供服务的基础。
📍 详细步骤
第1步:创建service.yaml文件
- 在base目录创建文件:
cat > base/service.yaml << 'EOF' apiVersion: v1 kind: Service metadata: name: my-app namespace: my-app labels: app: my-app spec: # Service类型:ClusterIP(集群内部访问) type: ClusterIP # 选择器:匹配哪些Pod selector: app: my-app # 端口配置 ports: - name: http protocol: TCP port: 80 # Service端口 targetPort: 8080 # Pod端口 EOF
第2步:理解配置内容
apiVersion: v1
kind: Service
metadata:
name: my-app # Service名称
namespace: my-app # 所属命名空间
spec:
type: ClusterIP # Service类型
selector: # 选择器(匹配Pod的标签)
app: my-app
ports:
- port: 80 # Service端口(其他服务访问这个端口)
targetPort: 8080 # Pod端口(流量转发到Pod的这个端口)
Service工作原理:
- Service创建后,会分配一个ClusterIP(如:10.96.1.100)
- 其他Pod可以通过ClusterIP或Service名称访问
- Service会自动负载均衡到所有匹配selector的Pod
- Pod增加或减少时,Service自动更新后端列表
第3步:验证YAML语法
- 运行命令:
kubectl apply --dry-run=client -f base/service.yaml
✅ 验证点
- service.yaml文件已创建
- selector标签和Deployment的Pod标签一致
- 端口映射配置正确
⚠️ 常见问题
问题1:为什么选择ClusterIP类型?
- 答:ClusterIP是最常用的类型
- 只在集群内部访问,安全性高
- 外部访问通过Ingress,更灵活
- NodePort和LoadBalancer类型成本高或不安全
问题2:selector如何匹配Pod?
- 答:通过标签匹配
- Service的selector必须和Deployment的Pod标签一致
- 本例中都是
app: my-app - 如果标签不匹配,Service无法找到Pod
问题3:port和targetPort有什么区别?
- 答:port是Service端口,targetPort是Pod端口
- 其他服务访问Service的port
- Service将流量转发到Pod的targetPort
- 可以不同,比如Service用80,Pod用8080
问题4:如何测试Service是否工作?
- 答:在集群内部测试
- 创建一个临时Pod:
kubectl run test --image=busybox -it --rm -- sh - 在Pod内访问Service:
wget -O- http://my-app.my-app.svc.cluster.local
💡 小贴士
- 🎯 Service名称会自动注册到DNS
- 🔍 完整域名格式:
<service-name>.<namespace>.svc.cluster.local - 📝 同一命名空间内可以直接使用Service名称访问
步骤6.6:创建Ingress配置
🎬 操作说明
现在创建Ingress配置文件。Ingress是应用对外提供服务的入口,配置域名、SSL证书和路由规则。
📍 详细步骤
第1步:创建ingress.yaml文件
- 在base目录创建文件:
cat > base/ingress.yaml << 'EOF' apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app namespace: my-app annotations: # 使用ALB Ingress Controller kubernetes.io/ingress.class: alb # 自动签发SSL证书 cert-manager.io/cluster-issuer: letsencrypt-prod # 监听端口:HTTP 80 和 HTTPS 443 alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]' # HTTP自动重定向到HTTPS alb.ingress.kubernetes.io/ssl-redirect: "true" # 健康检查配置 alb.ingress.kubernetes.io/healthcheck-enabled: "true" alb.ingress.kubernetes.io/healthcheck-path: "/health" alb.ingress.kubernetes.io/healthcheck-protocol: "HTTP" alb.ingress.kubernetes.io/healthcheck-interval-seconds: "10" alb.ingress.kubernetes.io/healthcheck-timeout-seconds: "5" alb.ingress.kubernetes.io/healthy-threshold-count: "2" alb.ingress.kubernetes.io/unhealthy-threshold-count: "3" spec: # TLS配置 tls: - hosts: - www.example.com # 替换为你的域名 secretName: my-app-tls # 路由规则 rules: - host: www.example.com # 替换为你的域名 http: paths: - path: / pathType: Prefix backend: service: name: my-app port: number: 80 EOF
第2步:修改域名
- 将域名替换为你的域名:
sed -i '' 's/www.example.com/你的域名/g' base/ingress.yaml
第3步:理解关键配置
Ingress注解(Annotations):
annotations:
kubernetes.io/ingress.class: alb
cert-manager.io/cluster-issuer: letsencrypt-prod
alb.ingress.kubernetes.io/ssl-redirect: "true"
ingress.class:指定使用ALB Ingress Controllercluster-issuer:自动签发SSL证书ssl-redirect:HTTP自动跳转到HTTPS
TLS配置:
tls:
- hosts:
- www.example.com
secretName: my-app-tls
hosts:需要SSL证书的域名secretName:证书存储的Secret名称(cert-manager自动创建)
路由规则:
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
host:域名path:路径(/表示所有路径)pathType:路径匹配类型(Prefix表示前缀匹配)backend:后端Service
第4步:验证YAML语法
- 运行命令:
kubectl apply --dry-run=client -f base/ingress.yaml
✅ 验证点
- ingress.yaml文件已创建
- 域名已修改为你的域名
- YAML语法正确
⚠️ 常见问题
问题1:pathType有哪些选项?
- 答:三种类型
Prefix:前缀匹配(最常用)Exact:精确匹配ImplementationSpecific:由Ingress Controller决定
问题2:如何配置多个域名?
- 答:在rules中添加多个host
rules: - host: www.example.com http: paths: - path: / backend: service: name: web-service - host: api.example.com http: paths: - path: / backend: service: name: api-service
问题3:如何配置路径路由?
- 答:在paths中添加多个路径
paths: - path: /api backend: service: name: api-service - path: /web backend: service: name: web-service
问题4:SSL证书多久签发?
- 答:通常2-3分钟
- cert-manager会自动向Let’s Encrypt申请证书
- 可以查看Certificate资源的状态
- 证书会自动续期,不用担心过期
💡 小贴士
- 🔒 SSL证书完全自动化,无需手动管理
- 🌐 一个Ingress可以管理多个域名
- 📝 健康检查配置很重要,确保流量只转发到健康的Pod
步骤6.7:应用所有配置
🎬 操作说明
现在所有配置文件都准备好了,我们将它们应用到Kubernetes集群。这一步会创建所有资源,启动应用。
📍 详细步骤
第1步:查看所有配置文件
- 运行命令:
ls -lh base/ - 应该看到:
deployment.yaml ingress.yaml namespace.yaml service.yaml
第2步:应用Namespace
- 先创建Namespace:
kubectl apply -f base/namespace.yaml - 应该看到:
namespace/my-app created
第3步:创建镜像拉取密钥
- 如果还没有创建,现在创建:
kubectl create secret docker-registry acr-secret \ --docker-server=registry.cn-hangzhou.aliyuncs.com \ --docker-username=your-username \ --docker-password=your-password \ --docker-email=your-email@example.com \ -n my-app - 替换为你的ACR凭证
第4步:应用Deployment
- 创建Deployment:
kubectl apply -f base/deployment.yaml - 应该看到:
deployment.apps/my-app created
第5步:应用Service
- 创建Service:
kubectl apply -f base/service.yaml - 应该看到:
service/my-app created
第6步:应用Ingress
- 创建Ingress:
kubectl apply -f base/ingress.yaml - 应该看到:
ingress.networking.k8s.io/my-app created
第7步:一次性应用所有配置(可选)
- 也可以一次性应用所有配置:
kubectl apply -f base/ - 这会应用base目录下的所有YAML文件
✅ 验证点
- 所有资源都已创建
- 没有报错信息
⚠️ 常见问题
问题1:apply和create有什么区别?
- 答:apply是声明式,create是命令式
- apply:如果资源存在就更新,不存在就创建
- create:如果资源存在会报错
- 建议使用apply
问题2:可以修改配置后重新apply吗?
- 答:可以
- 修改YAML文件后,重新运行kubectl apply
- Kubernetes会自动更新资源
- Deployment会滚动更新Pod
问题3:如何查看apply的详细过程?
- 答:使用–v参数
kubectl apply -f base/ --v=8 - 数字越大,输出越详细
💡 小贴士
- 🔄 建议使用Git管理配置文件
- 📝 每次修改后都要apply才能生效
- 🎯 可以使用kubectl diff查看变更
步骤6.8:查看Pod状态
🎬 操作说明
应用已经部署了,现在我们查看Pod的状态,确认Pod是否正常启动。这是验证部署是否成功的第一步。
📍 详细步骤
第1步:查看Pod列表
- 运行命令:
kubectl get pods -n my-app - 初始状态可能是:
NAME READY STATUS RESTARTS AGE my-app-7d9f8c6b5d-abc12 0/1 ContainerCreating 0 10s my-app-7d9f8c6b5d-def34 0/1 ContainerCreating 0 10s
第2步:等待Pod启动
- 等待约30-60秒,再次查看:
kubectl get pods -n my-app - 最终应该看到:
NAME READY STATUS RESTARTS AGE my-app-7d9f8c6b5d-abc12 1/1 Running 0 1m my-app-7d9f8c6b5d-def34 1/1 Running 0 1m
第3步:持续监控Pod状态
- 使用watch命令持续监控:
kubectl get pods -n my-app -w - 按Ctrl+C停止监控
第4步:查看Pod详情
- 选择一个Pod,查看详情:
kubectl describe pod <Pod名称> -n my-app - 可以看到:
- Pod的事件(Events)
- 容器状态
- 资源使用情况
- 健康检查结果
第5步:查看Pod日志
- 查看Pod的日志:
kubectl logs <Pod名称> -n my-app - 应该看到应用的启动日志:
2026/01/29 03:00:00 Server starting on port 8080
第6步:查看所有Pod的日志
- 查看所有Pod的日志:
kubectl logs -l app=my-app -n my-app -l app=my-app:通过标签选择Pod
第7步:实时查看日志
- 实时查看日志(类似tail -f):
kubectl logs -f <Pod名称> -n my-app - 按Ctrl+C停止
✅ 验证点
- 2个Pod都在运行(STATUS为Running)
- READY显示为1/1
- RESTARTS为0(没有重启)
- 日志显示应用正常启动
⚠️ 常见问题
问题1:Pod一直是ContainerCreating状态?
- 答:可能是镜像拉取慢
- 查看Pod详情:
kubectl describe pod <Pod名称> -n my-app - 在Events部分查看进度
- 如果超过5分钟,可能是镜像拉取失败
问题2:Pod状态是ImagePullBackOff?
- 答:镜像拉取失败
- 常见原因:
- 镜像地址错误
- 镜像拉取密钥错误
- 镜像不存在
- 查看详细错误:
kubectl describe pod <Pod名称> -n my-app | grep -A 10 Events
问题3:Pod状态是CrashLoopBackOff?
- 答:应用启动失败
- 查看日志:
kubectl logs <Pod名称> -n my-app - 常见原因:
- 应用代码错误
- 端口配置错误
- 环境变量缺失
问题4:Pod状态是Pending?
- 答:无法调度
- 查看详情:
kubectl describe pod <Pod名称> -n my-app - 常见原因:
- 资源不足(CPU或内存)
- 节点不可用
- 镜像拉取密钥不存在
问题5:如何查看之前的日志?
- 答:使用–previous参数
kubectl logs <Pod名称> -n my-app --previous - 查看Pod重启前的日志
💡 小贴士
- 🔍 describe命令是排查问题的利器
- 📝 日志是了解应用状态的最佳方式
- ⏰ 给应用足够的启动时间(30-60秒)
- 🎯 如果Pod一直不正常,参考模块7的故障排查
步骤6.9:查看Service和Ingress状态
🎬 操作说明
Pod已经正常运行了,现在我们查看Service和Ingress的状态,确认网络配置是否正确。
📍 详细步骤
第1步:查看Service
- 运行命令:
kubectl get svc -n my-app - 应该看到:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-app ClusterIP 10.96.123.456 <none> 80/TCP 5m - 记下CLUSTER-IP
第2步:查看Service详情
- 运行命令:
kubectl describe svc my-app -n my-app - 可以看到:
- Endpoints:后端Pod的IP列表
- Selector:标签选择器
- Port:端口映射
第3步:验证Service的Endpoints
- 运行命令:
kubectl get endpoints my-app -n my-app - 应该看到2个Pod的IP:
NAME ENDPOINTS AGE my-app 192.168.1.10:8080,192.168.1.11:8080 5m - 如果Endpoints为空,说明Service没有找到Pod
第4步:查看Ingress
- 运行命令:
kubectl get ingress -n my-app - 应该看到:
NAME CLASS HOSTS ADDRESS PORTS AGE my-app alb www.example.com 47.98.123.456 80, 443 5m - ADDRESS列显示ALB的公网IP
第5步:查看Ingress详情
- 运行命令:
kubectl describe ingress my-app -n my-app - 可以看到:
- Rules:路由规则
- Backend:后端Service
- Events:创建过程的事件
第6步:查看SSL证书状态
- 运行命令:
kubectl get certificate -n my-app - 应该看到:
NAME READY SECRET AGE my-app-tls True my-app-tls 5m - READY为True表示证书已签发
第7步:查看证书详情
- 如果证书未就绪,查看详情:
kubectl describe certificate my-app-tls -n my-app - 在Events部分查看签发进度
✅ 验证点
- Service的CLUSTER-IP已分配
- Service的Endpoints包含2个Pod的IP
- Ingress的ADDRESS显示ALB的IP
- Certificate的READY状态为True
⚠️ 常见问题
问题1:Service的Endpoints为空?
- 答:Service没有找到Pod
- 检查selector是否正确:
kubectl get svc my-app -n my-app -o yaml | grep -A 2 selector kubectl get pods -n my-app --show-labels - 确保Service的selector和Pod的labels一致
问题2:Ingress没有ADDRESS?
- 答:ALB Ingress Controller可能有问题
- 查看Controller日志:
kubectl logs -n kube-system -l app=alb-ingress-controller - 检查是否有错误信息
问题3:Certificate一直是False?
- 答:证书签发失败
- 查看Certificate详情:
kubectl describe certificate my-app-tls -n my-app - 常见原因:
- DNS未生效
- 域名无法访问
- Let’s Encrypt限流
问题4:如何测试Service连通性?
- 答:在集群内部测试
- 创建临时Pod:
kubectl run test --image=busybox -it --rm -n my-app -- sh - 在Pod内测试:
wget -O- http://my-app
💡 小贴士
- 🔍 Endpoints是Service和Pod之间的桥梁
- 📝 如果Endpoints为空,Service无法工作
- ⏰ 证书签发需要2-3分钟,请耐心等待
步骤6.10:通过域名访问应用
🎬 操作说明
现在所有资源都已就绪,我们通过域名访问应用,验证整个部署是否成功。这是最终的验证步骤。
📍 详细步骤
第1步:确认DNS已生效
- 运行命令:
nslookup www.example.com - 应该返回ALB的公网IP
- 如果没有,等待DNS生效(5-10分钟)
第2步:使用curl测试HTTP访问
- 运行命令:
curl -I http://www.example.com - 应该看到301重定向:
HTTP/1.1 301 Moved Permanently Location: https://www.example.com/
第3步:使用curl测试HTTPS访问
- 运行命令:
curl -I https://www.example.com - 应该看到200成功响应:
HTTP/2 200 server: nginx
第4步:获取完整响应
- 运行命令:
curl https://www.example.com - 应该看到应用的响应:
Hello from Kubernetes! Version: 1.0.0 Hostname: my-app-7d9f8c6b5d-abc12
第5步:多次请求验证负载均衡
- 运行命令多次:
for i in {1..10}; do curl -s https://www.example.com | grep Hostname; done - 应该看到不同的Hostname(2个Pod轮流响应):
Hostname: my-app-7d9f8c6b5d-abc12 Hostname: my-app-7d9f8c6b5d-def34 Hostname: my-app-7d9f8c6b5d-abc12 Hostname: my-app-7d9f8c6b5d-def34 ...
第6步:使用浏览器访问
- 在浏览器中访问:https://www.example.com
- 应该看到应用页面
- 浏览器地址栏显示小锁图标(HTTPS安全连接)
第7步:检查SSL证书
- 在浏览器中,点击地址栏的小锁图标
- 点击"证书"查看详情
- 确认:
- 颁发者:Let’s Encrypt
- 有效期:90天
- 域名:www.example.com
第8步:测试健康检查接口
- 运行命令:
curl https://www.example.com/health - 应该看到:
OK
✅ 验证点
- HTTP自动重定向到HTTPS
- HTTPS访问返回200状态码
- 浏览器显示安全连接
- 负载均衡正常工作(请求分发到不同的Pod)
- SSL证书有效
⚠️ 常见问题
问题1:浏览器显示"无法访问此网站"?
- 答:检查以下几点
- DNS是否生效:
nslookup www.example.com - Ingress是否有ADDRESS:
kubectl get ingress -n my-app - ALB安全组是否允许80和443端口
问题2:浏览器显示"证书错误"?
- 答:证书可能还没签发
- 检查Certificate状态:
kubectl get certificate -n my-app - 如果READY是False,等待几分钟
- 如果长时间False,查看Certificate的Events
问题3:访问超时?
- 答:可能是网络问题
- 检查Pod是否正常:
kubectl get pods -n my-app - 检查Service的Endpoints:
kubectl get endpoints my-app -n my-app - 检查Ingress配置:
kubectl describe ingress my-app -n my-app
问题4:负载均衡不工作?
- 答:可能是Pod数量不够
- 检查Pod数量:
kubectl get pods -n my-app - 应该有2个Pod都在Running状态
- 如果只有1个Pod,检查Deployment配置
问题5:看到的是ALB的默认页面?
- 答:Ingress配置可能有问题
- 检查Ingress的host是否和访问的域名一致
- 检查Ingress的backend是否指向正确的Service
💡 小贴士
- 🔒 HTTPS访问说明SSL证书配置成功
- 🔄 负载均衡说明高可用配置成功
- 🎉 如果所有验证都通过,恭喜你成功部署了应用!
模块总结
🎉 恭喜!你已经成功将应用部署到Kubernetes
在这个模块中,我们完成了以下工作:
✅ 理解了Kubernetes核心资源
- Namespace:资源隔离
- Deployment:管理Pod副本
- Service:服务发现和负载均衡
- Ingress:外网访问入口
✅ 创建了完整的配置文件
- namespace.yaml:命名空间配置
- deployment.yaml:应用部署配置(副本、资源限制、健康检查)
- service.yaml:服务配置
- ingress.yaml:入口配置(域名、SSL、路由)
✅ 部署了应用
- 应用所有配置文件
- 创建了2个Pod副本
- 配置了资源限制和健康检查
✅ 验证了部署
- Pod正常运行
- Service正常工作
- Ingress正常路由
- SSL证书自动签发
- 负载均衡正常工作
📊 资源清单
| 资源类型 | 资源名称 | 数量 | 说明 |
|---|---|---|---|
| Namespace | my-app | 1 | 资源隔离 |
| Deployment | my-app | 1 | 管理2个Pod副本 |
| Pod | my-app-xxx | 2 | 运行应用容器 |
| Service | my-app | 1 | ClusterIP类型 |
| Ingress | my-app | 1 | ALB入口 |
| Certificate | my-app-tls | 1 | SSL证书 |
| Secret | acr-secret | 1 | 镜像拉取密钥 |
🎯 下一步
现在应用已经成功部署并可以访问了。但在生产环境中,我们还需要:
- 监控应用的运行状态
- 排查可能出现的问题
- 优化资源使用和成本
- 学会回滚和恢复
在下一个模块中,我们将学习:
- 常见问题的排查方法
- 日志查看和分析
- 应用回滚操作
- 成本优化建议
- 如何彻底清理资源
继续学习:模块7:故障排查和优化
💡 重要提示
- 🎯 配置管理:建议使用Git管理所有配置文件
- 🔒 安全建议:不要在配置文件中硬编码敏感信息,使用Secret
- 📊 监控建议:配置监控告警,及时发现问题
- 💰 成本建议:定期检查资源使用情况,优化配置
📖 配置文件完整示例
完整的目录结构:
my-app-k8s/
├── base/
│ ├── namespace.yaml
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ingress.yaml
└── README.md
一键部署命令:
# 创建所有资源
kubectl apply -f base/
# 查看部署状态
kubectl get all -n my-app
# 查看Ingress
kubectl get ingress -n my-app
# 查看证书
kubectl get certificate -n my-app
# 查看日志
kubectl logs -l app=my-app -n my-app
# 删除所有资源
kubectl delete -f base/
🔧 常用运维命令
# 扩容/缩容
kubectl scale deployment my-app --replicas=3 -n my-app
# 更新镜像
kubectl set image deployment/my-app my-app=新镜像地址 -n my-app
# 查看滚动更新状态
kubectl rollout status deployment/my-app -n my-app
# 回滚到上一个版本
kubectl rollout undo deployment/my-app -n my-app
# 查看资源使用情况
kubectl top pods -n my-app
# 进入Pod调试
kubectl exec -it <Pod名称> -n my-app -- sh
# 端口转发(本地调试)
kubectl port-forward svc/my-app 8080:80 -n my-app
导航:
- 上一步:模块5:构建Docker镜像
- 下一步:模块7:故障排查和优化
- 返回主索引:阿里云ACK部署SOP