51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在360的云服务中,如何将Web服务端应用容器化(Docker)并部署到Kubernetes集群,以实现弹性伸缩和高可用?请说明Docker镜像构建、Kubernetes资源定义及高可用设计。

360Web服务端开发工程师难度:中等

答案

1) 【一句话结论】
在360云服务中,通过Docker多阶段构建轻量镜像封装应用,Kubernetes定义含资源限制的Deployment管理容器,Service(如ClusterIP)提供访问入口,结合多Master控制平面(etcd集群)、多节点数据平面及持久化存储(PV/PVC),实现弹性伸缩(CPU阈值触发)与高可用。

2) 【原理/概念讲解】
老师口吻:容器化是将应用及其依赖打包成独立容器,实现环境隔离。Docker镜像构建中,多阶段构建(如从编译环境到运行环境的分离)可大幅减少镜像体积(例如从golang编译应用,再复制到nginx镜像)。Kubernetes核心分为控制平面(API Server、Scheduler、Controller Manager、etcd集群,负责资源管理)和数据平面(Kubelet、Kube Proxy、容器运行时,负责执行操作)。资源对象中:

  • Deployment:管理Pod副本,支持滚动更新(逐步替换旧Pod为新Pod)、回滚、自动扩缩容(根据负载调整副本数)。
  • Service:抽象Pod集合,提供稳定IP/端口,类型有ClusterIP(内部服务)、NodePort(节点端口)、LoadBalancer(云服务商负载均衡)。
    高可用设计:控制平面用etcd集群(副本数≥3)避免单点故障;数据平面Pod分布在多节点,节点故障时自动重新调度;有状态应用用StatefulSet结合**PersistentVolume(PV)/PersistentVolumeClaim(PVC)**确保数据持久化。

3) 【对比与适用场景】

对比项Deployment (v1)ReplicaSet (v1)Service类型ClusterIPNodePortLoadBalancer
定义现代化资源,管理Pod副本管理Pod副本的旧资源负载均衡资源内部服务节点端口云服务商负载均衡
特性支持滚动更新、回滚、自动扩缩容仅管理副本数量,不支持更新提供稳定访问入口内部集群IP节点IP+节点端口云服务商分配的负载均衡器
使用场景大多数应用,需要弹性伸缩过渡期,或旧系统内部服务(ClusterIP)应用内部通信需要外部访问(如本地测试)云环境(如阿里云、腾讯云)的负载均衡
注意点需配合Selector匹配Pod会被Deployment继承,不建议直接用类型选择影响访问默认类型需节点端口范围(30000-32767)需云服务商负载均衡服务,成本较高

4) 【示例】

  • Dockerfile(多阶段构建,减少体积):
    # 第一阶段:编译应用
    FROM golang:1.18-alpine AS builder
    WORKDIR /app
    COPY go.mod go.sum ./
    RUN go mod download
    COPY . .
    RUN go build -o web-app .
    
    # 第二阶段:构建最终镜像
    FROM nginx:alpine
    COPY --from=builder /app/web-app /usr/local/bin/
    COPY static/index.html /usr/share/nginx/html/
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    
  • Deployment YAML(含资源限制,3个副本):
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web-deployment
      labels:
        app: web
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: web
      template:
        metadata:
          labels:
            app: web
        spec:
          containers:
          - name: web-container
            image: my-web-image:latest
            ports:
            - containerPort: 80
            resources:
              requests:
                cpu: "100m"
                memory: "128Mi"
              limits:
                cpu: "500m"
                memory: "512Mi"
    
  • Service YAML(ClusterIP,内部访问):
    apiVersion: v1
    kind: Service
    metadata:
      name: web-service
      labels:
        app: web
    spec:
      type: ClusterIP
      selector:
        app: web
      ports:
      - protocol: TCP
        port: 80
        targetPort: 80
    
  • StatefulSet(有状态应用,持久化存储):
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: db-statefulset
      labels:
        app: db
    spec:
      serviceName: "db-service"
      replicas: 3
      selector:
        matchLabels:
          app: db
      template:
        metadata:
          labels:
            app: db
        spec:
          containers:
          - name: db-container
            image: mysql:5.7
            ports:
            - containerPort: 3306
            volumeMounts:
            - name: db-pv
              mountPath: /var/lib/mysql
      volumeClaimTemplates:
      - metadata:
          name: db-pv
        spec:
          accessModes: [ "ReadWriteOnce" ]
          resources:
            requests:
              storage: 10Gi
    
  • Horizontal Pod Autoscaler(弹性伸缩,CPU阈值触发):
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: web-hpa
      labels:
        app: web
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: web-deployment
      minReplicas: 3
      maxReplicas: 10
      metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 70
    

5) 【面试口播版答案】
在360云服务中,容器化部署Web服务端应用通常分三步:首先用多阶段Dockerfile构建轻量镜像(如从golang编译应用,再复制到nginx镜像),推送到镜像仓库。接着在K8s中定义Deployment,指定3个副本,并设置CPU/内存资源限制(requests和limits),自动管理Pod扩缩容。再定义ClusterIP类型的Service,通过Kube Proxy实现内部负载均衡。高可用设计上,控制平面用3个Master节点组成的etcd集群(避免单点故障),数据平面Pod分布在多节点,节点故障时自动重新调度。对于有状态数据库,用StatefulSet结合PersistentVolumeClaim(PVC)绑定云存储(如ECS云盘),确保数据持久化。弹性伸缩通过Horizontal Pod Autoscaler,当CPU使用率超过70%时自动增加副本数,实现弹性伸缩。整个过程结合K8s的自动扩缩容和负载均衡,实现Web服务的高可用。

6) 【追问清单】

  • 问题1:如何优化Docker镜像体积?
    回答要点:使用多阶段构建(分离编译环境与运行环境),删除不必要的依赖,压缩镜像(如docker save -o 镜像.tar 镜像再docker load -i 镜像.tar)。
  • 问题2:Kubernetes中如何设置资源限制,避免容器资源耗尽?
    回答要点:在Deployment的容器资源部分添加requests(最小资源需求)和limits(最大资源限制),如CPU请求100m,限制500m,防止容器占用过多资源导致系统崩溃。
  • 问题3:高可用设计中etcd集群的副本数如何选择?
    回答要点:通常设置3个副本(奇数),确保数据一致性,避免单点故障,同时保证可用性(如2个节点故障时仍能提供服务)。
  • 问题4:弹性伸缩的触发指标除了CPU,还有哪些?
    回答要点:请求量(如QPS)、内存使用率、自定义指标(如请求延迟),根据业务需求选择合适的触发条件。
  • 问题5:持久化存储如何确保数据不丢失?
    回答要点:使用PersistentVolume(PV)和PersistentVolumeClaim(PVC),绑定云存储(如ECS云盘、NFS),结合StatefulSet的有序命名和持久化存储,确保数据在Pod迁移或故障时不会丢失。

7) 【常见坑/雷区】

  • 镜像构建时未使用多阶段构建,导致镜像体积过大,影响存储和传输效率。
  • Deployment的replicas设置为0,导致服务不可用,未考虑最小副本数。
  • Service类型选择错误(如用ClusterIP但需要外部访问),导致无法从外部访问服务。
  • 忽略资源限制,导致容器CPU或内存耗尽,应用崩溃,影响服务稳定性。
  • etcd集群副本数设置过少(如1个),导致数据丢失或服务不可用,未考虑高可用需求。
  • 弹性伸缩的触发指标设置不合理(如CPU阈值过低),导致频繁扩缩容,影响系统性能。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1