11.2 Kubernetes基础

面试重要程度:⭐⭐⭐⭐⭐

常见提问方式:Kubernetes的核心组件有哪些?Pod和Container的区别?

预计阅读时间:35分钟

📋 知识点概览

Kubernetes(K8s)是容器编排领域的事实标准,掌握其核心概念和实践对于现代Java开发者至关重要。本节将深入讲解K8s架构、核心资源对象以及服务发现机制。

🏗️ Kubernetes架构详解

集群架构组件

/**
 * Kubernetes集群架构
 */
public class KubernetesArchitecture {
    
    /**
     * Master节点组件
     */
    public enum MasterComponent {
        API_SERVER("kube-apiserver", "集群的统一入口,提供RESTful API"),
        ETCD("etcd", "分布式键值存储,保存集群状态"),
        SCHEDULER("kube-scheduler", "负责Pod调度到合适的Node"),
        CONTROLLER_MANAGER("kube-controller-manager", "运行控制器进程"),
        CLOUD_CONTROLLER_MANAGER("cloud-controller-manager", "云平台相关控制器");
        
        private final String name;
        private final String description;
        
        MasterComponent(String name, String description) {
            this.name = name;
            this.description = description;
        }
    }
    
    /**
     * Node节点组件
     */
    public enum NodeComponent {
        KUBELET("kubelet", "节点代理,管理Pod生命周期"),
        KUBE_PROXY("kube-proxy", "网络代理,实现Service负载均衡"),
        CONTAINER_RUNTIME("container-runtime", "容器运行时(Docker/containerd)");
        
        private final String name;
        private final String description;
        
        NodeComponent(String name, String description) {
            this.name = name;
            this.description = description;
        }
    }
    
    /**
     * 集群网络组件
     */
    public static class NetworkComponents {
        
        public static final String[] CNI_PLUGINS = {
            "Flannel",      // 简单的overlay网络
            "Calico",       // 支持网络策略的CNI
            "Weave Net",    // 易于安装的网络方案
            "Cilium",       // 基于eBPF的高性能网络
            "Antrea"        // VMware开源的CNI插件
        };
        
        /**
         * 网络模型说明
         */
        public static void explainNetworkModel() {
            System.out.println("Kubernetes网络模型要求:");
            System.out.println("1. 每个Pod都有独立的IP地址");
            System.out.println("2. 同一Node上的Pod可以直接通信");
            System.out.println("3. 不同Node上的Pod可以直接通信(无需NAT)");
            System.out.println("4. Pod内的容器共享网络命名空间");
        }
    }
}

🚀 核心资源对象详解

Pod资源管理

# Pod配置示例
apiVersion: v1
kind: Pod
metadata:
  name: spring-boot-app
  labels:
    app: spring-boot
    version: v1.0
  annotations:
    description: "Spring Boot应用Pod"
spec:
  # 重启策略
  restartPolicy: Always
  
  # 节点选择器
  nodeSelector:
    disktype: ssd
  
  # 容器配置
  containers:
  - name: app
    image: myregistry/spring-boot-app:v1.0
    ports:
    - containerPort: 8080
      name: http
    
    # 资源限制
    resources:
      requests:
        memory: "512Mi"
        cpu: "250m"
      limits:
        memory: "1Gi"
        cpu: "500m"
    
    # 环境变量
    env:
    - name: SPRING_PROFILES_ACTIVE
      value: "prod"
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password
    
    # 健康检查
    livenessProbe:
      httpGet:
        path: /actuator/health
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 5
      failureThreshold: 3
    
    readinessProbe:
      httpGet:
        path: /actuator/health/readiness
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 3
      failureThreshold: 3
    
    # 数据卷挂载
    volumeMounts:
    - name: config-volume
      mountPath: /app/config
    - name: log-volume
      mountPath: /app/logs
  
  # 数据卷定义
  volumes:
  - name: config-volume
    configMap:
      name: app-config
  - name: log-volume
    emptyDir: {}
  
  # Init容器
  initContainers:
  - name: init-db
    image: busybox:1.35
    command: ['sh', '-c', 'until nslookup db-service; do echo waiting for db; sleep 2; done;']

Deployment控制器

/**
 * Deployment资源管理
 */
public class DeploymentManagement {
    
    /**
     * Deployment配置示例
     */
    public static String getDeploymentYaml() {
        return """
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: spring-boot-deployment
              labels:
                app: spring-boot
            spec:
              # 副本数量
              replicas: 3
              
              # 选择器
              selector:
                matchLabels:
                  app: spring-boot
              
              # 更新策略
              strategy:
                type: RollingUpdate
                rollingUpdate:
                  maxUnavailable: 1
                  maxSurge: 1
              
              # Pod模板
              template:
                metadata:
                  labels:
                    app: spring-boot
                spec:
                  containers:
                  - name: app
                    image: myregistry/spring-boot-app:v1.0
                    ports:
                    - containerPort: 8080
                    resources:
                      requests:
                        memory: "512Mi"
                        cpu: "250m"
                      limits:
                        memory: "1Gi"
                        cpu: "500m"
                    livenessProbe:
                      httpGet:
                        path: /actuator/health
                        port: 8080
                      initialDelaySeconds: 30
                      periodSeconds: 10
                    readinessProbe:
                      httpGet:
                        path: /actuator/health/readiness
                        port: 8080
                      initialDelaySeconds: 5
                      periodSeconds: 5
            """;
    }
    
    /**
     * 滚动更新策略
     */
    public static class RollingUpdateStrategy {
        
        public static void performRollingUpdate() {
            String[] commands = {
                "# 更新镜像版本",
                "kubectl set image deployment/spring-boot-deployment app=myregistry/spring-boot-app:v2.0",
                "",
                "# 查看更新状态",
                "kubectl rollout status deployment/spring-boot-deployment",
                "",
                "# 查看更新历史",
                "kubectl rollout history deployment/spring-boot-deployment",
                "",
                "# 回滚到上一版本",
                "kubectl rollout undo deployment/spring-boot-deployment",
                "",
                "# 回滚到指定版本",
                "kubectl rollout undo deployment/spring-boot-deployment --to-revision=2",
                "",
                "# 暂停更新",
                "kubectl rollout pause deployment/spring-boot-deployment",
                "",
                "# 恢复更新",
                "kubectl rollout resume deployment/spring-boot-deployment"
            };
            
            for (String command : commands) {
                System.out.println(command);
            }
        }
    }
}

Service服务发现

# Service配置示例
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-service
  labels:
    app: spring-boot
spec:
  # 服务类型
  type: ClusterIP  # ClusterIP/NodePort/LoadBalancer/ExternalName
  
  # 选择器
  selector:
    app: spring-boot
  
  # 端口配置
  ports:
  - name: http
    port: 80
    targetPort: 8080
    protocol: TCP
  
  # 会话亲和性
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800

---
# NodePort Service示例
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-nodeport
spec:
  type: NodePort
  selector:
    app: spring-boot
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080

---
# LoadBalancer Service示例
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-lb
spec:
  type: LoadBalancer
  selector:
    app: spring-boot
  ports:
  - port: 80
    targetPort: 8080
  loadBalancerSourceRanges:
  - 10.0.0.0/8

🔧 ConfigMap和Secret管理

配置管理最佳实践

/**
 * Kubernetes配置管理
 */
public class ConfigurationManagement {
    
    /**
     * ConfigMap使用示例
     */
    public static class ConfigMapExample {
        
        /**
         * 创建ConfigMap的多种方式
         */
        public static void createConfigMap() {
            String[] methods = {
                "# 1. 从字面值创建",
                "kubectl create configmap app-config \\",
                "  --from-literal=database.host=localhost \\",
                "  --from-literal=database.port=5432",
                "",
                "# 2. 从文件创建",
                "kubectl create configmap app-config \\",
                "  --from-file=application.properties",
                "",
                "# 3. 从目录创建",
                "kubectl create configmap app-config \\",
                "  --from-file=config/",
                "",
                "# 4. 使用YAML文件创建",
                "kubectl apply -f configmap.yaml"
            };
            
            for (String method : methods) {
                System.out.println(method);
            }
        }
        
        /**
         * ConfigMap YAML配置
         */
        public static String getConfigMapYaml() {
            return """
                apiVersion: v1
                kind: ConfigMap
                metadata:
                  name: app-config
                  namespace: default
                data:
                  # 简单键值对
                  database.host: "localhost"
                  database.port: "5432"
                  
                  # 配置文件内容
                  application.properties: |
                    server.port=8080
                    spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
                    spring.datasource.username=user
                    spring.jpa.hibernate.ddl-auto=update
                    logging.level.com.example=DEBUG
                  
                  # JSON配置
                  config.json: |
                    {
                      "redis": {
                        "host": "redis-service",
                        "port": 6379,
                        "timeout": 3000
                      },
                      "features": {
                        "enableCache": true,
                        "enableMetrics": true
                      }
                    }
                """;
        }
    }
    
    /**
     * Secret安全管理
     */
    public static class SecretManagement {
        
        /**
         * Secret类型
         */
        public enum SecretType {
            OPAQUE("Opaque", "通用密钥"),
            SERVICE_ACCOUNT_TOKEN("kubernetes.io/service-account-token", "服务账户令牌"),
            DOCKER_CONFIG_JSON("kubernetes.io/dockerconfigjson", "Docker镜像仓库认证"),
            TLS("kubernetes.io/tls", "TLS证书");
            
            private final String type;
            private final String description;
            
            SecretType(String type, String description) {
                this.type = type;
                this.description = description;
            }
        }
        
        /**
         * Secret创建和使用
         */
        public static String getSecretYaml() {
            return """
                # 通用Secret
                apiVersion: v1
                kind: Secret
                metadata:
                  name: db-secret
                type: Opaque
                data:
                  username: dXNlcg==  # base64编码的"user"
                  password: cGFzc3dvcmQ=  # base64编码的"password"
                
                ---
                # Docker镜像仓库Secret
                apiVersion: v1
                kind: Secret
                metadata:
                  name: registry-secret
                type: kubernetes.io/dockerconfigjson
                data:
                  .dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS5jb20iOnsidXNlcm5hbWUiOiJ1c2VyIiwicGFzc3dvcmQiOiJwYXNzIiwiYXV0aCI6ImRYTmxjanB3WVhOeiJ9fX0=
                
                ---
                # TLS Secret
                apiVersion: v1
                kind: Secret
                metadata:
                  name: tls-secret
                type: kubernetes.io/tls
                data:
                  tls.crt: LS0tLS1CRUdJTi...  # base64编码的证书
                  tls.key: LS0tLS1CRUdJTi...  # base64编码的私钥
                """;
        }
        
        /**
         * Secret使用方式
         */
        public static void useSecret() {
            String[] examples = {
                "# 1. 作为环境变量使用",
                "env:",
                "- name: DB_USERNAME",
                "  valueFrom:",
                "    secretKeyRef:",
                "      name: db-secret",
                "      key: username",
                "",
                "# 2. 作为文件挂载使用",
                "volumeMounts:",
                "- name: secret-volume",
                "  mountPath: /etc/secrets",
                "volumes:",
                "- name: secret-volume",
                "  secret:",
                "    secretName: db-secret",
                "",
                "# 3. 作为镜像拉取密钥",
                "spec:",
                "  imagePullSecrets:",
                "  - name: registry-secret"
            };
            
            for (String example : examples) {
                System.out.println(example);
            }
        }
    }
}

🌐 Ingress流量管理

Ingress控制器配置

# Ingress配置示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: spring-boot-ingress
  annotations:
    # Nginx Ingress控制器注解
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
    
    # 负载均衡策略
    nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"
    
    # CORS配置
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization"

spec:
  # TLS配置
  tls:
  - hosts:
    - api.example.com
    - app.example.com
    secretName: tls-secret
  
  # 路由规则
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /api/v1
        pathType: Prefix
        backend:
          service:
            name: spring-boot-service
            port:
              number: 80
      - path: /api/v2
        pathType: Prefix
        backend:
          service:
            name: spring-boot-v2-service
            port:
              number: 80
  
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

---
# 默认后端服务
apiVersion: v1
kind: Service
metadata:
  name: default-backend
spec:
  selector:
    app: default-backend
  ports:
  - port: 80
    targetPort: 8080

📊 资源监控与管理

资源配额和限制

/**
 * Kubernetes资源管理
 */
public class ResourceManagement {
    
    /**
     * 资源配额配置
     */
    public static String getResourceQuotaYaml() {
        return """
            apiVersion: v1
            kind: ResourceQuota
            metadata:
              name: compute-quota
              namespace: development
            spec:
              hard:
                # 计算资源限制
                requests.cpu: "4"
                requests.memory: 8Gi
                limits.cpu: "8"
                limits.memory: 16Gi
                
                # 存储资源限制
                requests.storage: 100Gi
                persistentvolumeclaims: "10"
                
                # 对象数量限制
                pods: "10"
                services: "5"
                secrets: "10"
                configmaps: "10"
                replicationcontrollers: "5"
            """;
    }
    
    /**
     * 限制范围配置
     */
    public static String getLimitRangeYaml() {
        return """
            apiVersion: v1
            kind: LimitRange
            metadata:
              name: limit-range
              namespace: development
            spec:
              limits:
              # Pod限制
              - type: Pod
                max:
                  cpu: "2"
                  memory: 4Gi
                min:
                  cpu: 100m
                  memory: 128Mi
              
              # Container限制
              - type: Container
                default:
                  cpu: 500m
                  memory: 512Mi
                defaultRequest:
                  cpu: 100m
                  memory: 128Mi
                max:
                  cpu: "1"
                  memory: 2Gi
                min:
                  cpu: 50m
                  memory: 64Mi
              
              # PVC限制
              - type: PersistentVolumeClaim
                max:
                  storage: 10Gi
                min:
                  storage: 1Gi
            """;
    }
    
    /**
     * 水平Pod自动扩缩容
     */
    public static String getHPAYaml() {
        return """
            apiVersion: autoscaling/v2
            kind: HorizontalPodAutoscaler
            metadata:
              name: spring-boot-hpa
            spec:
              scaleTargetRef:
                apiVersion: apps/v1
                kind: Deployment
                name: spring-boot-deployment
              
              minReplicas: 2
              maxReplicas: 10
              
              metrics:
              # CPU使用率
              - type: Resource
                resource:
                  name: cpu
                  target:
                    type: Utilization
                    averageUtilization: 70
              
              # 内存使用率
              - type: Resource
                resource:
                  name: memory
                  target:
                    type: Utilization
                    averageUtilization: 80
              
              # 自定义指标
              - type: Pods
                pods:
                  metric:
                    name: http_requests_per_second
                  target:
                    type: AverageValue
                    averageValue: "100"
              
              # 扩缩容行为
              behavior:
                scaleUp:
                  stabilizationWindowSeconds: 60
                  policies:
                  - type: Percent
                    value: 100
                    periodSeconds: 15
                scaleDown:
                  stabilizationWindowSeconds: 300
                  policies:
                  - type: Percent
                    value: 10
                    periodSeconds: 60
            """;
    }
}

💡 面试常见问题

Q1: Pod和Container的区别是什么?

标准回答:

Pod和Container的关系:

1. 基本概念:
   - Container:运行应用的最小单位
   - Pod:Kubernetes中最小的调度单位,包含一个或多个容器

2. 资源共享:
   - Pod内的容器共享网络命名空间和存储卷
   - 容器间可以通过localhost通信
   - 共享相同的IP地址和端口空间

3. 生命周期:
   - Pod作为整体被调度和管理
   - Pod内所有容器同时启动和停止
   - 容器失败会影响整个Pod状态

4. 使用场景:
   - 单容器Pod:最常见的模式
   - 多容器Pod:紧密耦合的应用(如主应用+日志收集)

Q2: Kubernetes的Service有哪些类型?

标准回答:

Kubernetes Service类型:

1. ClusterIP(默认):
   - 只能在集群内部访问
   - 提供稳定的内部IP地址
   - 适用于内部服务通信

2. NodePort:
   - 在每个Node上开放指定端口
   - 外部可通过NodeIP:NodePort访问
   - 端口范围:30000-32767

3. LoadBalancer:
   - 创建外部负载均衡器
   - 需要云平台支持
   - 自动分配外部IP地址

4. ExternalName:
   - 将服务映射到外部DNS名称
   - 不创建代理,只做DNS解析
   - 适用于访问外部服务

Q3: 如何实现Kubernetes的滚动更新?

标准回答:

Kubernetes滚动更新机制:

1. 更新策略配置:
   - maxUnavailable:最大不可用Pod数量
   - maxSurge:最大超出期望副本数的Pod数量

2. 更新过程:
   - 创建新版本Pod
   - 等待新Pod就绪
   - 删除旧版本Pod
   - 重复直到所有Pod更新完成

3. 回滚机制:
   - 保存历史版本信息
   - 支持快速回滚到任意版本
   - 自动检测更新失败并回滚

4. 健康检查:
   - readinessProbe确保Pod就绪
   - livenessProbe监控Pod健康状态
   - 失败时自动停止更新

核心要点总结:

  • ✅ 理解Kubernetes集群架构和核心组件
  • ✅ 掌握Pod、Deployment、Service等核心资源
  • ✅ 熟悉ConfigMap和Secret配置管理
  • ✅ 具备Ingress流量管理和资源监控能力
Java面试圣经 文章被收录于专栏

Java面试圣经

全部评论

相关推荐

不愿透露姓名的神秘牛友
08-31 11:35
不太懂数据结构,放过孩子吧
投递字节跳动等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务