home / skills / chaterm / terminal-skills / service-ingress
npx playbooks add skill chaterm/terminal-skills --skill service-ingressReview the files below or copy the command above to add this skill to your agents.
---
name: service-ingress
description: Kubernetes Service 与 Ingress
version: 1.0.0
author: terminal-skills
tags: [kubernetes, service, ingress, k8s, networking]
---
# Service 与 Ingress
## 概述
服务暴露、Ingress 配置、TLS 终止等技能。
## Service 类型
### ClusterIP(默认)
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 8080
```
### NodePort
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 30000-32767
```
### LoadBalancer
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 8080
```
### ExternalName
```yaml
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.example.com
```
### Headless Service
```yaml
apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
clusterIP: None
selector:
app: nginx
ports:
- port: 80
```
## Service 操作
```bash
# 查看 Service
kubectl get svc
kubectl get svc -o wide
kubectl describe svc service-name
# 创建 Service
kubectl expose deploy deployment-name --port=80 --target-port=8080
kubectl expose deploy deployment-name --type=NodePort --port=80
# 删除 Service
kubectl delete svc service-name
# 测试 Service
kubectl run test --rm -it --image=busybox -- wget -qO- http://service-name
```
## Ingress 配置
### 基础 Ingress
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
```
### 多路径 Ingress
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-path-ingress
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
```
### 多域名 Ingress
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
```
## TLS 配置
### 创建 TLS Secret
```bash
# 从证书文件创建
kubectl create secret tls tls-secret --cert=cert.pem --key=key.pem
# 查看 Secret
kubectl get secret tls-secret -o yaml
```
### Ingress TLS
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
secretName: tls-secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
```
### cert-manager 自动证书
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auto-tls-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
secretName: example-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
```
## Ingress 注解
### Nginx Ingress 常用注解
```yaml
metadata:
annotations:
# 重写路径
nginx.ingress.kubernetes.io/rewrite-target: /$2
# SSL 重定向
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# 代理超时
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
# 请求体大小
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
# 限流
nginx.ingress.kubernetes.io/limit-rps: "10"
# WebSocket
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"
# 跨域
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
```
## Ingress 操作
```bash
# 查看 Ingress
kubectl get ingress
kubectl get ing -o wide
kubectl describe ing ingress-name
# 查看 Ingress Controller
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
# 测试 Ingress
curl -H "Host: example.com" http://ingress-ip/
```
## 常见场景
### 场景 1:路径重写
```yaml
# /api/v1/users -> /users
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
```
### 场景 2:会话保持
```yaml
metadata:
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
```
### 场景 3:基础认证
```bash
# 创建认证 Secret
htpasswd -c auth admin
kubectl create secret generic basic-auth --from-file=auth
```
```yaml
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
```
### 场景 4:调试 Service 连通性
```bash
# 检查 Endpoints
kubectl get endpoints service-name
# 测试 Pod 到 Service
kubectl run test --rm -it --image=busybox -- sh
wget -qO- http://service-name:port
# 检查 DNS
kubectl run test --rm -it --image=busybox -- nslookup service-name
```
## 故障排查
| 问题 | 排查方法 |
|------|----------|
| Service 无法访问 | 检查 Endpoints、Pod 标签 |
| Ingress 404 | 检查路径配置、后端 Service |
| TLS 错误 | 检查证书 Secret、域名匹配 |
| 502 Bad Gateway | 检查后端 Pod 状态、健康检查 |
```bash
# 检查 Service Endpoints
kubectl get endpoints service-name
# 检查 Ingress Controller 日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=100
# 测试后端连通性
kubectl port-forward svc/service-name 8080:80
curl localhost:8080
```