提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
工作多年,最近面试一直被问k8s相关的知识。k8s几年前搞过,最近几年一直在做开源项目相关的工作,又不是专业运维,好多知识点早已经模糊了。但是面试又喜欢问,叫什么,是什么,如何实现的,有没有这样的功能,原理是什么,原理的原理是什么,等等吧。
下面准备100道k8s面试题,不知道有没有人能顶得住。
Deployment的作用:
流程:
maxSurge:允许超出期望副本数的最大Pod数量(例如25%或固定值),用于加速新版本启动
maxUnavailable:更新期间允许不可用的Pod最大数量(例如25%或固定值),避免服务中断。
#回滚到上一个版本
kubectl rollout undo deployment/<deployment-name>
#回滚到指定版本
kubectl rollout undo deployment/<name> --to-revision=<revision-number>
# 查看历史记录
kubectl rollout history deployment/<name>
RollingUpdate:逐步替换旧Pod,确保服务不中断,适合新环境
Recrete:先终止所有旧Pod,在启动新Pod,适用于需避免版本共存的情况。
#暂停更新,允许多次修改配置
kubectl rollout pause deployment/<name>
#恢复
kubectl rollout resume deployment/<name>
定义:Pod就绪后等待的额外时间,用于确保应用稳定后在接受流量。
影响:若Pod在minReadySeconds内崩溃,会被视为未就绪,触发重新创建。
蓝绿发布:维护新旧两套独立的环境,通过流量切换实现全量版本更新。新版本验证通过之后,将流量从蓝环境切换到绿环境。旧版本随时可回滚。
# Service 切换示例
selector:
app: my-app
version: green # 原为 blue
金丝雀发布/灰度发布:逐步将部分流量导向新版本,验证稳定性后扩大范围,直至全量替换旧版本。金丝雀定向向小范围用户进行验证。灰度发布按照比例分配流量。
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
kubectl rollout history deployment/<name>
命令式:
kubectl scale deployment/<name> --replicas=<number>
声明式:修改YAML文件的replicas字段后重新引用
核心作用:
类型 | 特点 | 适用场景 |
---|---|---|
ClusterIP | 默认类型,分配集群内部虚拟IP,仅集群内部访问 |
微服务间内部通信,如API调用 |
NodePort | 在ClusterIP基础上,会在集群所有节点上开放固定端口 ,允许外部通过节点IP访问 |
临时测试或非云环境外部访问 |
LoadBalancer | 集成云厂商负载均衡器,分配外部IP和端口 | 公有云环境对外暴露服务 |
ExternalName | 映射到外部服务的DNS名称,不代理流量 | 访问集群外服务 |
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:1.20
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Service 端口
targetPort: 80 # Pod 端口
nodePort: 30080
Service通过selector关联Deployment的pod标签app:my-app
iptables模式:
用途:用于无代理场景(如StatefulSet),直接返回Pod IP列表,支持自定义轮训。或自定义负载均衡
适用于需要直接访问单个Pod的场景(如数据库主从节点)
apiVersion: v1
kind: Service
metadata:
name: mysql-headless # Service 名称
spec:
clusterIP: None # 标识为 Headless Service
selector:
app: mysql # 匹配 Pod 标签
ports:
- protocol: TCP
port: 3306 # Service 端口
targetPort: 3306 # Pod 端口
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-headless # 指定关联的 Headless Service
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
volumeClaimTemplates: # 为每个 Pod 分配独立存储
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard"
resources:
requests:
storage: 10Gi
kubectl run -it --rm debug --image=busybox --restart=Never -- /bin/sh
# 进入容器后执行:
nslookup mysql-headless
# 输出示例:
# Name: mysql-headless..svc.cluster.local
# Address 1: 10.244.1.5 mysql-0.mysql-headless
# Address 2: 10.244.2.4 mysql-1.mysql-headless
# Address 3: 10.244.3.3 mysql-2.mysql-headless
直接访问Pod:
通过Pod的DNS名称直接访问(mysql-0.mysql-headless:3306),适用于主从复制需要定向通信的场景
总结:通过clusterIP:None 定义Headless Service,配合StatefulSet实现Pod级别的直接访问,适用于需要稳定网络拓扑的有状态服务。
作用:
维度 | Service | Ingress |
---|---|---|
层级 | L4 (TCP UDP) | L7(HTTP/HTTPS) |
功能 | 提供基础负载均衡和固定IP | 支持复杂路由、SSL、流量拆分 |
依赖 | 无需额外组件 | 需部署Ingress控制器 如Nginx |
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port: 80
作用:定义Pod间网络通信规划(如允许特定命名空间的Pod访问)
示例:限制frontend的Pod仅允许来自backend Pod的流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend
spec:
podSelector:
matchLabels:
app: frontend
ingress:
- from:
- podSelector:
matchLabels:
app: backend
机制:
访问示例:
ExternalIP:手动指定节点IP对外暴露服务(需节点有公网IP)
LoadBalancer IP:由云厂商自动分配,集成外部负载均衡器。
直接通过DNS名臣访问:..svc.cluster.local
示例:命名空间nsl的Pod访问ns2中的服务
curl http://my-service.ns2.svc.cluster.local
作用:将本地端口转发到集群被的Pod或Service,用于临时调试
kubectl port-forward service/my-service 8080:80
本地访问localhost:8080即可访问集群内Service
基于一些部署和服务,网络和安全面试题的一些总结。