Administrator
发布于 2026-03-16 / 1 阅读
0
0

运维与DevOps面试指南

# 运维与DevOps面试指南

> 🎯 面向后端开发者的运维面试准备  
> 涵盖:Linux、Docker、Kubernetes、Nginx、CI/CD、监控告警

---

## 📚 目录

1. [Linux面试题](#一linux面试题)
2. [Docker面试题](#二docker面试题)
3. [Kubernetes面试题](#三kubernetes面试题)
4. [Nginx面试题](#四nginx面试题)
5. [CI/CD面试题](#五cicd面试题)
6. [监控与故障排查](#六监控与故障排查)

---

# 一、Linux面试题

## 1.1 常用命令

### Q1:常用的Linux命令有哪些?

**答**:

**文件操作**:
```bash
# 查看文件
cat file.txt           # 查看全部内容
head -n 100 file.txt   # 查看前100行
tail -f file.txt       # 实时查看文件末尾(看日志)
less file.txt          # 分页查看
more file.txt          # 分页查看

# 查找文件
find /path -name "*.log"              # 按名称查找
find /path -mtime +7 -name "*.log"    # 查找7天前的日志
find /path -size +100M                # 查找大于100M的文件

# 文件权限
chmod 755 file.sh      # 设置权限 rwxr-xr-x
chown user:group file  # 修改所有者
```

**文本处理**:
```bash
# grep - 文本搜索
grep "ERROR" app.log                # 搜索ERROR
grep -i "error" app.log             # 忽略大小写
grep -C 5 "Exception" app.log       # 显示上下5行
grep -r "keyword" /path             # 递归搜索

# awk - 文本分析
awk '{print $1}' file.txt           # 打印第一列
awk -F: '{print $1}' /etc/passwd    # 指定分隔符
awk '/ERROR/{print}' app.log        # 匹配打印

# sed - 文本替换
sed 's/old/new/g' file.txt          # 替换文本
sed -i 's/old/new/g' file.txt       # 直接修改文件
sed -n '10,20p' file.txt            # 打印10-20行
```

**业务场景**:日志分析
```bash
# 统计ERROR出现次数
grep -c "ERROR" app.log

# 统计每个接口的调用次数
awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -20

# 统计某个时间段的日志
sed -n '/2024-01-19 10:00/,/2024-01-19 11:00/p' app.log

# 查找最耗时的请求(假设最后一列是耗时)
awk '{print $NF, $0}' access.log | sort -rn | head -10
```

---

### Q2:如何查看系统资源使用情况?

**答**:

```bash
# CPU
top                    # 实时查看进程
htop                   # 更友好的top
mpstat 1               # CPU使用率(每秒刷新)

# 内存
free -h                # 查看内存使用
vmstat 1               # 虚拟内存统计

# 磁盘
df -h                  # 磁盘使用情况
du -sh /path/*         # 目录大小
iostat -x 1            # 磁盘IO

# 网络
netstat -tlnp          # 查看监听端口
ss -tlnp               # 更快的netstat
iftop                  # 网络流量监控

# 进程
ps aux                 # 查看所有进程
ps -ef | grep java     # 查找Java进程
lsof -i :8080          # 查看端口占用
```

**业务场景**:排查Java应用问题
```bash
# 1. 找到Java进程
ps -ef | grep java | grep -v grep

# 2. 查看进程资源使用
top -p <pid>

# 3. 查看线程CPU使用(找到高CPU线程)
top -Hp <pid>

# 4. 将线程ID转为16进制
printf "%x\n" <tid>

# 5. 用jstack查看线程堆栈
jstack <pid> | grep -A 30 <tid_hex>

# 6. 查看GC情况
jstat -gc <pid> 1000

# 7. 生成堆转储
jmap -dump:format=b,file=heap.hprof <pid>
```

---

### Q3:Linux的文件权限是怎样的?

**答**:

```
-rwxr-xr-x  1 root root  4096 Jan 19 10:00 file.txt
│├─┤├─┤├─┤
│ │  │  └─ 其他用户权限
│ │  └──── 用户组权限
│ └─────── 所有者权限
└───────── 文件类型(- 普通文件,d 目录,l 链接)

权限数字:
r = 4 (读)
w = 2 (写)
x = 1 (执行)

755 = rwxr-xr-x(所有者全部权限,其他读和执行)
644 = rw-r--r--(所有者读写,其他只读)
```

```bash
# 修改权限
chmod 755 file.sh      # 数字方式
chmod u+x file.sh      # 符号方式(给所有者加执行权限)
chmod -R 755 /path     # 递归修改

# 修改所有者
chown user file.txt
chown user:group file.txt
chown -R user:group /path
```

---

### Q4:如何管理后台进程?

**答**:

```bash
# nohup - 后台运行,不受终端关闭影响
nohup java -jar app.jar > app.log 2>&1 &

# 查看后台任务
jobs

# 把后台任务放到前台
fg %1

# systemd管理服务(推荐)
systemctl start app
systemctl stop app
systemctl restart app
systemctl status app
systemctl enable app   # 开机自启

# 创建systemd服务文件 /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target

[Service]
Type=simple
User=app
ExecStart=/usr/bin/java -jar /opt/app/app.jar
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

---

### Q5:Shell脚本基础?

**答**:

```bash
#!/bin/bash

# 变量
NAME="app"
echo "Application: $NAME"

# 条件判断
if [ -f "/path/to/file" ]; then
    echo "文件存在"
elif [ -d "/path/to/dir" ]; then
    echo "目录存在"
else
    echo "不存在"
fi

# 循环
for i in {1..5}; do
    echo "Number: $i"
done

# 遍历文件
for file in /path/*.log; do
    echo "Processing: $file"
done

# 函数
function deploy() {
    local app_name=$1
    echo "Deploying $app_name..."
}

deploy "my-app"

# 读取文件
while read line; do
    echo "$line"
done < file.txt
```

**业务场景**:部署脚本
```bash
#!/bin/bash

APP_NAME="order-service"
JAR_FILE="/opt/app/${APP_NAME}.jar"
LOG_FILE="/var/log/${APP_NAME}.log"
PID_FILE="/var/run/${APP_NAME}.pid"

start() {
    if [ -f "$PID_FILE" ]; then
        echo "Application already running"
        exit 1
    fi
    
    echo "Starting $APP_NAME..."
    nohup java -jar -Xms512m -Xmx1024m $JAR_FILE > $LOG_FILE 2>&1 &
    echo $! > $PID_FILE
    echo "Started with PID: $(cat $PID_FILE)"
}

stop() {
    if [ ! -f "$PID_FILE" ]; then
        echo "Application not running"
        exit 1
    fi
    
    PID=$(cat $PID_FILE)
    echo "Stopping $APP_NAME (PID: $PID)..."
    kill $PID
    rm -f $PID_FILE
    echo "Stopped"
}

restart() {
    stop
    sleep 2
    start
}

case "$1" in
    start)   start ;;
    stop)    stop ;;
    restart) restart ;;
    *)       echo "Usage: $0 {start|stop|restart}" ;;
esac
```

---

# 二、Docker面试题

### Q6:Docker的核心概念?

**答**:

| 概念 | 说明 |
|------|------|
| **镜像(Image)** | 只读模板,包含运行应用所需的所有内容 |
| **容器(Container)** | 镜像的运行实例,可以启动、停止、删除 |
| **仓库(Registry)** | 存储镜像的地方(Docker Hub、私有仓库) |
| **Dockerfile** | 构建镜像的脚本文件 |
| **数据卷(Volume)** | 持久化存储,容器删除数据不丢失 |
| **网络(Network)** | 容器间通信 |

```
关系图:
Dockerfile → (build) → Image → (run) → Container
                         ↓
                      Registry(push/pull)
```

---

### Q7:Docker常用命令?

**答**:

```bash
# 镜像操作
docker images                        # 查看镜像
docker pull nginx:latest             # 拉取镜像
docker build -t myapp:1.0 .          # 构建镜像
docker push myrepo/myapp:1.0         # 推送镜像
docker rmi image_id                  # 删除镜像

# 容器操作
docker ps                            # 查看运行中容器
docker ps -a                         # 查看所有容器
docker run -d --name myapp -p 8080:8080 myapp:1.0  # 运行容器
docker start/stop/restart container  # 启停容器
docker rm container                  # 删除容器
docker logs -f container             # 查看日志
docker exec -it container /bin/bash  # 进入容器

# 资源清理
docker system prune                  # 清理无用资源
docker image prune                   # 清理无用镜像
```

---

### Q8:Dockerfile最佳实践?

**答**:

```dockerfile
# ========== Java应用Dockerfile ==========

# 1. 使用多阶段构建,减小镜像体积
FROM maven:3.8-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
# 先下载依赖,利用缓存
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# 2. 运行阶段使用精简镜像
FROM openjdk:11-jre-slim
WORKDIR /app

# 3. 创建非root用户运行
RUN groupadd -r app && useradd -r -g app app
USER app

# 4. 复制构建产物
COPY --from=builder /app/target/*.jar app.jar

# 5. 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
    CMD curl -f http://localhost:8080/actuator/health || exit 1

# 6. 暴露端口
EXPOSE 8080

# 7. 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]

# 8. 传入JVM参数
CMD ["-Xms512m", "-Xmx1024m"]
```

**最佳实践要点**:
```
1. 使用多阶段构建 → 减小镜像体积
2. 合理利用缓存 → 先COPY依赖文件,再COPY源码
3. 使用.dockerignore → 排除不需要的文件
4. 最小化层数 → 合并RUN命令
5. 使用非root用户 → 安全
6. 添加健康检查 → 便于监控
7. 指定镜像版本 → 避免使用latest
```

---

### Q9:Docker网络模式有哪些?

**答**:

| 网络模式 | 说明 | 使用场景 |
|---------|------|---------|
| **bridge** | 默认模式,容器有独立网络命名空间 | 大多数场景 |
| **host** | 容器使用宿主机网络 | 需要高性能网络 |
| **none** | 无网络 | 安全隔离 |
| **container** | 共享其他容器网络 | 网络调试 |
| **overlay** | 跨主机网络 | Docker Swarm/K8s |

```bash
# 创建自定义网络
docker network create mynet

# 容器加入网络
docker run -d --name app1 --network mynet myapp:1.0
docker run -d --name app2 --network mynet myapp:1.0

# 同一网络内可以通过容器名通信
# app1可以访问app2: http://app2:8080
```

---

### Q10:Docker Compose是什么?

**答**:
Docker Compose用于定义和运行多容器应用。

```yaml
# docker-compose.yml
version: '3.8'

services:
  # 应用服务
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - MYSQL_HOST=mysql
      - REDIS_HOST=redis
    depends_on:
      - mysql
      - redis
    restart: always
    networks:
      - app-network
  
  # MySQL
  mysql:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=root123
      - MYSQL_DATABASE=myapp
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - app-network
  
  # Redis
  redis:
    image: redis:6.2
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    ports:
      - "6379:6379"
    networks:
      - app-network
  
  # Nginx
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app
    networks:
      - app-network

volumes:
  mysql-data:
  redis-data:

networks:
  app-network:
    driver: bridge
```

```bash
# 常用命令
docker-compose up -d        # 启动所有服务
docker-compose down         # 停止并删除
docker-compose ps           # 查看服务状态
docker-compose logs -f app  # 查看日志
docker-compose restart app  # 重启服务
```

---

# 三、Kubernetes面试题

### Q11:K8s的核心概念?

**答**:

| 概念 | 说明 |
|------|------|
| **Pod** | 最小部署单元,包含一个或多个容器 |
| **Deployment** | 管理Pod副本,支持滚动更新 |
| **Service** | 服务发现和负载均衡 |
| **ConfigMap** | 配置管理(非敏感) |
| **Secret** | 敏感配置(密码、证书) |
| **Namespace** | 资源隔离 |
| **Ingress** | 外部访问入口(HTTP/HTTPS路由) |
| **PV/PVC** | 持久化存储 |

```
架构图:
                    ┌─────────────┐
                    │   Ingress   │ (外部访问)
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │   Service   │ (负载均衡)
                    └──────┬──────┘
           ┌───────────────┼───────────────┐
           │               │               │
     ┌─────▼─────┐   ┌─────▼─────┐   ┌─────▼─────┐
     │    Pod    │   │    Pod    │   │    Pod    │
     │  (app:v1) │   │  (app:v1) │   │  (app:v1) │
     └───────────┘   └───────────┘   └───────────┘
                           │
                    ┌──────▼──────┐
                    │ Deployment  │ (管理Pod)
                    └─────────────┘
```

---

### Q12:常用的kubectl命令?

**答**:

```bash
# 查看资源
kubectl get pods                      # 查看Pod
kubectl get pods -o wide              # 详细信息(含IP、节点)
kubectl get deploy,svc,pods           # 查看多种资源
kubectl get all -n namespace          # 查看命名空间所有资源

# 查看详情
kubectl describe pod <pod-name>       # Pod详情
kubectl logs <pod-name>               # 查看日志
kubectl logs -f <pod-name> -c <container>  # 实时日志

# 进入容器
kubectl exec -it <pod-name> -- /bin/bash

# 应用配置
kubectl apply -f deployment.yaml      # 应用配置
kubectl delete -f deployment.yaml     # 删除资源

# 扩缩容
kubectl scale deployment <name> --replicas=5

# 滚动更新
kubectl set image deployment/<name> <container>=<image>:<tag>
kubectl rollout status deployment/<name>   # 查看更新状态
kubectl rollout undo deployment/<name>     # 回滚

# 调试
kubectl describe pod <pod-name>       # 查看事件
kubectl logs <pod-name> --previous    # 查看上一个容器的日志
kubectl port-forward <pod-name> 8080:8080  # 端口转发
```

---

### Q13:K8s的Deployment配置?

**答**:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  namespace: production
  labels:
    app: order-service
spec:
  replicas: 3                    # 副本数
  selector:
    matchLabels:
      app: order-service
  
  # 滚动更新策略
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1                # 最多多出1个Pod
      maxUnavailable: 0          # 最少保持全部可用
  
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
      - name: order-service
        image: myrepo/order-service:v1.0.0
        ports:
        - containerPort: 8080
        
        # 资源限制
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        
        # 环境变量
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        
        # 配置文件挂载
        volumeMounts:
        - name: config
          mountPath: /app/config
        
        # 健康检查
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
      
      volumes:
      - name: config
        configMap:
          name: order-service-config
```

---

### Q14:K8s的Service类型有哪些?

**答**:

| 类型 | 说明 | 使用场景 |
|------|------|---------|
| **ClusterIP** | 集群内部访问(默认) | 内部服务 |
| **NodePort** | 通过节点端口访问 | 开发测试 |
| **LoadBalancer** | 云厂商负载均衡 | 生产环境 |
| **ExternalName** | DNS别名 | 外部服务 |

```yaml
# ClusterIP(内部服务)
apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  type: ClusterIP
  selector:
    app: order-service
  ports:
  - port: 80
    targetPort: 8080

---
# NodePort(外部访问)
apiVersion: v1
kind: Service
metadata:
  name: order-service-nodeport
spec:
  type: NodePort
  selector:
    app: order-service
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080      # 30000-32767
```

---

### Q15:K8s如何实现滚动更新和回滚?

**答**:

```bash
# 滚动更新(自动)
kubectl set image deployment/order-service order-service=myrepo/order-service:v2.0.0

# 查看更新状态
kubectl rollout status deployment/order-service

# 查看更新历史
kubectl rollout history deployment/order-service

# 回滚到上一个版本
kubectl rollout undo deployment/order-service

# 回滚到指定版本
kubectl rollout undo deployment/order-service --to-revision=2

# 暂停/恢复更新
kubectl rollout pause deployment/order-service
kubectl rollout resume deployment/order-service
```

**滚动更新策略说明**:
```yaml
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 25%         # 最多超出期望副本数的比例
    maxUnavailable: 25%   # 最多不可用副本数的比例

# 示例:3个副本
# maxSurge: 1 → 更新时最多4个Pod
# maxUnavailable: 0 → 更新时至少保持3个Pod可用
# 流程:新建1个v2 → 等待v2就绪 → 删除1个v1 → 重复
```

---

# 四、Nginx面试题

### Q16:Nginx的常用配置?

**答**:

```nginx
# nginx.conf 主配置

# 全局配置
worker_processes auto;              # 工作进程数
error_log /var/log/nginx/error.log;

events {
    worker_connections 1024;        # 每个进程最大连接数
    use epoll;                      # Linux使用epoll
}

http {
    include       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" '
                    'rt=$request_time';
    
    access_log /var/log/nginx/access.log main;
    
    # 性能优化
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout  65;
    
    # Gzip压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
    gzip_min_length 1000;
    
    # 上游服务器(负载均衡)
    upstream backend {
        least_conn;                  # 最少连接策略
        server 192.168.1.10:8080 weight=3;
        server 192.168.1.11:8080 weight=2;
        server 192.168.1.12:8080 backup;  # 备用
        
        keepalive 32;                # 保持连接数
    }
    
    # 虚拟主机
    server {
        listen 80;
        server_name www.example.com;
        
        # 静态文件
        location /static/ {
            root /var/www;
            expires 7d;              # 缓存7天
        }
        
        # API反向代理
        location /api/ {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            
            # 超时设置
            proxy_connect_timeout 60s;
            proxy_read_timeout 60s;
            proxy_send_timeout 60s;
        }
        
        # 健康检查
        location /health {
            return 200 "OK";
        }
    }
}
```

---

### Q17:Nginx负载均衡策略有哪些?

**答**:

| 策略 | 说明 | 配置 |
|------|------|------|
| **轮询** | 默认,依次分配 | 无需配置 |
| **权重** | 按权重分配 | `weight=3` |
| **IP哈希** | 同一IP访问同一后端 | `ip_hash` |
| **最少连接** | 分配给连接最少的服务器 | `least_conn` |
| **URL哈希** | 同一URL访问同一后端 | `hash $request_uri` |

```nginx
# 权重轮询
upstream backend {
    server 192.168.1.10:8080 weight=5;
    server 192.168.1.11:8080 weight=3;
    server 192.168.1.12:8080 weight=2;
}

# IP哈希(会话保持)
upstream backend {
    ip_hash;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

# 最少连接
upstream backend {
    least_conn;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}
```

---

### Q18:Nginx如何配置HTTPS?

**答**:

```nginx
server {
    listen 80;
    server_name www.example.com;
    
    # HTTP重定向到HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.example.com;
    
    # SSL证书
    ssl_certificate     /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    
    # SSL优化
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # 安全协议和加密套件
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    
    # HSTS(强制HTTPS)
    add_header Strict-Transport-Security "max-age=31536000" always;
    
    location / {
        proxy_pass http://backend;
    }
}
```

---

### Q19:Nginx如何限流?

**答**:

```nginx
http {
    # 定义限流区域
    # 按IP限流,10m共享内存,每秒10个请求
    limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=10r/s;
    
    # 按接口限流
    limit_req_zone $uri zone=api_limit:10m rate=100r/s;
    
    server {
        # 应用限流
        location /api/ {
            # burst=20:允许突发20个请求
            # nodelay:不延迟处理
            limit_req zone=ip_limit burst=20 nodelay;
            
            proxy_pass http://backend;
        }
        
        # 限制连接数
        limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
        
        location /download/ {
            limit_conn conn_limit 5;   # 每IP最多5个连接
            limit_rate 100k;           # 限速100KB/s
        }
    }
}
```

---

# 五、CI/CD面试题

### Q20:什么是CI/CD?

**答**:

```
CI(Continuous Integration)持续集成:
- 代码提交后自动构建、测试
- 快速发现问题,减少集成风险

CD(Continuous Delivery/Deployment)持续交付/部署:
- 持续交付:自动构建、测试、准备发布,手动部署
- 持续部署:完全自动化,代码提交后自动部署到生产

流程:
代码提交 → 自动构建 → 单元测试 → 代码扫描 → 构建镜像 → 部署测试环境 → 集成测试 → 部署生产
    ↑                                                                              │
    └──────────────────────────────────────────────────────────────────────────────┘
                                    反馈循环
```

---

### Q21:Jenkins Pipeline配置?

**答**:

```groovy
// Jenkinsfile
pipeline {
    agent any
    
    environment {
        DOCKER_REGISTRY = 'harbor.example.com'
        IMAGE_NAME = 'order-service'
    }
    
    stages {
        // 拉取代码
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/xxx/order-service.git'
            }
        }
        
        // 编译构建
        stage('Build') {
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
        
        // 单元测试
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit '**/target/surefire-reports/*.xml'
                }
            }
        }
        
        // 代码扫描
        stage('SonarQube') {
            steps {
                withSonarQubeEnv('SonarQube') {
                    sh 'mvn sonar:sonar'
                }
            }
        }
        
        // 构建Docker镜像
        stage('Docker Build') {
            steps {
                script {
                    def imageTag = "${env.BUILD_NUMBER}"
                    sh "docker build -t ${DOCKER_REGISTRY}/${IMAGE_NAME}:${imageTag} ."
                    sh "docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${imageTag}"
                }
            }
        }
        
        // 部署测试环境
        stage('Deploy to Test') {
            steps {
                sh """
                    kubectl set image deployment/${IMAGE_NAME} \
                        ${IMAGE_NAME}=${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.BUILD_NUMBER} \
                        -n test
                """
            }
        }
        
        // 人工确认
        stage('Approval') {
            steps {
                input message: '确认部署到生产环境?', ok: '部署'
            }
        }
        
        // 部署生产环境
        stage('Deploy to Production') {
            steps {
                sh """
                    kubectl set image deployment/${IMAGE_NAME} \
                        ${IMAGE_NAME}=${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.BUILD_NUMBER} \
                        -n production
                """
            }
        }
    }
    
    post {
        success {
            dingtalk(
                robot: 'dingding-robot',
                type: 'TEXT',
                text: ["构建成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}"]
            )
        }
        failure {
            dingtalk(
                robot: 'dingding-robot',
                type: 'TEXT',
                text: ["构建失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}"]
            )
        }
    }
}
```

---

### Q22:GitLab CI/CD配置?

**答**:

```yaml
# .gitlab-ci.yml
stages:
  - build
  - test
  - docker
  - deploy

variables:
  DOCKER_REGISTRY: harbor.example.com
  IMAGE_NAME: order-service

# 构建
build:
  stage: build
  image: maven:3.8-openjdk-11
  script:
    - mvn clean package -DskipTests
  artifacts:
    paths:
      - target/*.jar
    expire_in: 1 hour
  only:
    - main
    - develop

# 测试
test:
  stage: test
  image: maven:3.8-openjdk-11
  script:
    - mvn test
  artifacts:
    reports:
      junit: target/surefire-reports/*.xml
  only:
    - main
    - develop

# 构建Docker镜像
docker:
  stage: docker
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $DOCKER_USER -p $DOCKER_PASSWORD $DOCKER_REGISTRY
    - docker build -t $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA .
    - docker push $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
  only:
    - main

# 部署测试环境
deploy_test:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl set image deployment/$IMAGE_NAME $IMAGE_NAME=$DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA -n test
  environment:
    name: test
  only:
    - develop

# 部署生产环境(手动触发)
deploy_prod:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl set image deployment/$IMAGE_NAME $IMAGE_NAME=$DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA -n production
  environment:
    name: production
  when: manual
  only:
    - main
```

---

# 六、监控与故障排查

### Q23:常用的监控方案?

**答**:

| 工具 | 用途 | 特点 |
|------|------|------|
| **Prometheus** | 指标采集 | 时序数据库,Pull模式 |
| **Grafana** | 可视化 | 丰富的Dashboard |
| **ELK** | 日志收集分析 | Elasticsearch+Logstash+Kibana |
| **Jaeger/Zipkin** | 链路追踪 | 分布式追踪 |
| **Alertmanager** | 告警管理 | 配合Prometheus |

**监控体系**:
```
                    ┌─────────────────────────────────────┐
                    │              Grafana                │
                    │          (可视化展示)               │
                    └─────────────────┬───────────────────┘
                                      │
          ┌───────────────────────────┼───────────────────────────┐
          │                           │                           │
    ┌─────▼─────┐              ┌──────▼──────┐             ┌──────▼──────┐
    │Prometheus │              │ Elasticsearch│             │   Jaeger    │
    │  (指标)   │              │   (日志)     │             │ (链路追踪)  │
    └─────┬─────┘              └──────┬──────┘             └──────┬──────┘
          │                           │                           │
    ┌─────▼─────┐              ┌──────▼──────┐             ┌──────▼──────┐
    │  Exporter │              │  Filebeat   │             │   Agent     │
    └───────────┘              └─────────────┘             └─────────────┘
          │                           │                           │
    ┌─────▼──────────────────────────▼───────────────────────────▼─────┐
    │                           应用服务                               │
    └──────────────────────────────────────────────────────────────────┘
```

---

### Q24:如何排查线上问题?

**答**:

**排查流程**:
```
1. 确认问题现象
   └─ 接口慢?报错?服务不可用?

2. 查看监控指标
   ├─ CPU、内存、网络、磁盘
   └─ QPS、响应时间、错误率

3. 查看日志
   ├─ 应用日志(ERROR、WARN)
   ├─ Nginx日志(5xx错误)
   └─ 系统日志(/var/log/messages)

4. 定位问题服务
   └─ 链路追踪(Jaeger/Skywalking)

5. 深入分析
   ├─ JVM问题:jstack、jmap、arthas
   ├─ 数据库问题:慢查询日志
   └─ 网络问题:tcpdump、wireshark
```

**常见问题排查命令**:
```bash
# 1. CPU过高
top -Hp <pid>                    # 找到高CPU线程
printf "%x\n" <tid>              # 转16进制
jstack <pid> | grep -A 30 <tid>  # 查看线程堆栈

# 2. 内存问题
jmap -heap <pid>                 # 查看堆内存
jmap -histo:live <pid>           # 对象统计
jmap -dump:format=b,file=heap.hprof <pid>  # 堆转储

# 3. GC问题
jstat -gc <pid> 1000             # 每秒输出GC信息
jstat -gcutil <pid> 1000         # GC统计百分比

# 4. 线程死锁
jstack <pid> | grep -A 50 "deadlock"

# 5. 使用Arthas(推荐)
# 下载并启动
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

# Arthas常用命令
dashboard                        # 总览
thread -n 3                      # 最忙的3个线程
trace com.xxx.Service method     # 方法耗时追踪
watch com.xxx.Service method returnObj  # 观察方法返回值
```

---

### Q25:如何进行容量规划?

**答**:

**评估公式**:
```
QPS估算:
日均PV / (24 * 3600 * 访问集中比例) = 平均QPS
峰值QPS = 平均QPS * 峰值倍数(通常2-10倍)

机器数量:
机器数 = 峰值QPS / 单机QPS * 冗余系数(1.5-2)

示例:
日均PV = 1000万
集中访问时间 = 8小时(比例=8/24=0.33)
平均QPS = 10000000 / (8 * 3600) ≈ 350
峰值QPS = 350 * 3 = 1050
单机QPS = 500(压测得出)
机器数 = 1050 / 500 * 1.5 ≈ 4台
```

**压测指标**:
```
关注指标:
- QPS/TPS
- 响应时间(P99、P95、P50)
- 错误率
- CPU、内存、网络使用率

压测工具:
- JMeter
- wrk
- ab (Apache Bench)
- Locust
```

---

## 📝 面试速记卡

```
【Linux】
文件搜索:find/grep/awk/sed
进程管理:ps/top/kill/nohup/systemctl
资源监控:top/free/df/iostat/netstat

【Docker】
核心:镜像(Image)、容器(Container)、仓库(Registry)
Dockerfile:多阶段构建、最小化层数、非root用户
网络:bridge(默认)、host、overlay(跨主机)

【Kubernetes】
核心对象:Pod、Deployment、Service、ConfigMap、Secret
Service类型:ClusterIP(内部)、NodePort、LoadBalancer
滚动更新:kubectl set image、kubectl rollout undo

【Nginx】
负载均衡:轮询、权重、ip_hash、least_conn
限流:limit_req_zone + limit_req

【CI/CD】
流程:代码→构建→测试→扫描→镜像→部署
工具:Jenkins、GitLab CI、GitHub Actions

【监控】
三大件:Prometheus(指标) + ELK(日志) + Jaeger(链路)
排查:top → jstack → jmap → arthas
```

---

**文档版本**:v1.0  
**创建时间**:2026-01-19  
**适用场景**:后端开发运维面试


评论