运维面试 高频10题 · 第三组

K8s RBAC / Keepalived / Harbor / 网络策略 / iptables · 点击展开答案

已展开 0 / 10 题
Q21
Kubernetes RBAC 是什么?如何给 Jenkins 授权操作集群?
K8sRBAC安全
+
  • ServiceAccount:Pod/工具的身份标识
  • Role / ClusterRole:定义"能做什么"(get/list/create/delete 哪些资源)
  • RoleBinding / ClusterRoleBinding:把身份绑定到角色
# 1. 创建 ServiceAccount
kubectl create serviceaccount jenkins-sa -n devops

# 2. 创建 ClusterRole(允许操作 Deployment/Service/Pod)
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: jenkins-deployer
rules:
- apiGroups: ["apps", ""]
  resources: ["deployments", "services", "pods", "pods/log"]
  verbs: ["get", "list", "create", "update", "patch", "delete"]
EOF

# 3. 绑定 SA 和 ClusterRole
kubectl create clusterrolebinding jenkins-binding \
  --clusterrole=jenkins-deployer \
  --serviceaccount=devops:jenkins-sa

# 4. 导出 kubeconfig 给 Jenkins 使用
kubectl create token jenkins-sa -n devops --duration=87600h
生产原则:最小权限。Jenkins 只给它需要的 namespace 和资源类型,不要直接用 cluster-admin。
Q22
Keepalived 高可用原理是什么?脑裂如何预防?
Keepalived高可用
+
  • 基于 VRRP 协议,多台机器竞选一个虚拟 IP(VIP)
  • Master 定期发送 VRRP 心跳包;Backup 收不到心跳则抢占 VIP
  • VIP 漂移后,发 Gratuitous ARP 通知交换机更新 MAC 映射表
# /etc/keepalived/keepalived.conf(Master 节点)
vrrp_instance VI_1 {
    state MASTER            # 备节点改为 BACKUP
    interface eth0          # 绑定网卡
    virtual_router_id 51   # 主备必须一致
    priority 100            # 备节点设 90,优先级高的为 Master
    advert_int 1            # 心跳间隔1秒
    authentication {
        auth_type PASS
        auth_pass 1234      # 主备相同,防止非法节点加入
    }
    virtual_ipaddress {
        192.168.1.100/24   # VIP
    }
    # 检测 Nginx 是否存活,挂了就降优先级触发漂移
    track_script { check_nginx }
}

vrrp_script check_nginx {
    script "killall -0 nginx"  # 返回非0则判定故障
    interval 2
    weight -20                  # 故障时优先级降20
}
  • 原因:主备之间网络中断,Backup 误以为 Master 挂了,两台同时持有 VIP
  • 预防1:配置 authentication 密码,防止误加入
  • 预防2:用独立心跳网络(双网卡)
  • 预防3:脚本检测到两台都有 VIP 时自动告警
Q23
Harbor 镜像仓库如何搭建?镜像安全扫描怎么配置?
Harbor镜像
+
# 下载 offline installer
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
tar xf harbor-offline-installer-*.tgz && cd harbor

# 修改配置
cp harbor.yml.tmpl harbor.yml
vim harbor.yml
# 关键配置项:
# hostname: harbor.yourdomain.com
# https.certificate / https.private_key  (或注释掉 https 用 http)
# harbor_admin_password: Admin@123

# 安装(依赖 docker-compose)
./install.sh --with-trivy   # --with-trivy 启用漏洞扫描
  • 安装时加 --with-trivy 即集成 Trivy 扫描引擎
  • 在 Harbor UI → 项目 → 配置 → 开启"推送时自动扫描"
  • 可设置漏洞阈值:高危漏洞阻止部署
# 每个节点都要做(否则 imagePullBackOff)
mkdir -p /etc/docker/certs.d/harbor.yourdomain.com
cp harbor.crt /etc/docker/certs.d/harbor.yourdomain.com/ca.crt

# containerd 节点额外配置
vim /etc/containerd/config.toml
# [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.xx.com".tls]
#   ca_file = "/etc/ssl/certs/harbor.crt"
systemctl restart containerd
面试加分:提到"Harbor 配置了 Robot Account 给 Jenkins 使用,不用管理员账号"体现安全意识。
Q24
iptables 四表五链是什么?如何用 iptables 实现端口转发?
iptables网络
+
  • 四表(功能):filter(过滤)/ nat(地址转换)/ mangle(修改包头)/ raw(跳过跟踪)
  • 五链(时机):PREROUTING → INPUT → FORWARD → OUTPUT → POSTROUTING
  • 最常用组合:filter 表的 INPUT/OUTPUT/FORWARD 控制访问;nat 表的 PREROUTING/POSTROUTING 做转发
# 场景:外部访问本机 8080,转发到内网 192.168.1.10:80
# 开启内核转发
echo 1 > /proc/sys/net/ipv4/ip_forward

# DNAT:进来的包目标地址改掉
iptables -t nat -A PREROUTING -p tcp --dport 8080 \
  -j DNAT --to-destination 192.168.1.10:80

# MASQUERADE:出去的包做源地址伪装
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.10 --dport 80 \
  -j MASQUERADE

# 查看 nat 表规则
iptables -t nat -L -n --line-numbers

# 持久化规则
iptables-save > /etc/sysconfig/iptables
K8s 关联:kube-proxy 就是在 nat 表写 DNAT 规则实现 Service → Pod 转发的,理解 iptables 是理解 K8s 网络的基础。
Q25
Kubernetes NetworkPolicy 是什么?如何限制 Pod 间访问?
K8s网络策略安全
+

默认 K8s 所有 Pod 互通。NetworkPolicy 是 K8s 的"防火墙",基于标签控制哪些 Pod 能互相访问。需要 CNI 支持(Calico/Cilium 支持,Flannel 不支持)。

# 限制:只有带 app=frontend 标签的 Pod 能访问 app=backend 的 3000 端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-allow-frontend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend          # 这条策略作用于 backend Pod
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend     # 只允许 frontend Pod 进来
    ports:
    - protocol: TCP
      port: 3000
# 先建一个"默认拒绝"策略,再按需放行(安全最佳实践)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}           # 匹配所有 Pod
  policyTypes:
  - Ingress                 # ingress 为空 = 拒绝所有入流量
Q26
进程、线程、协程的区别?Linux 如何查看线程数?
Linux操作系统
+
  • 进程:资源分配的最小单位,有独立内存空间,进程间切换开销大
  • 线程:CPU 调度的最小单位,共享进程内存,切换比进程快,但有锁竞争问题
  • 协程:用户态调度,不需要内核介入,切换极快(无系统调用),Go/Python asyncio 大量使用
# 查看某进程的线程数
cat /proc/<pid>/status | grep Threads

# 查看所有线程(H = 显示线程)
top -H -p <pid>

# ps 查看线程(-L 展开线程)
ps -eLf | grep <进程名>

# 系统当前总线程数
ps -eo nlwp | tail -n +2 | awk '{sum+=$1} END {print sum}'

# 查看系统线程数上限
cat /proc/sys/kernel/threads-max
运维关联:Java 应用线程数暴涨(几千个线程)是常见内存告警原因,用 top -H -p 定位后结合 jstack 分析线程堆栈。
Q27
MySQL 事务的四个特性(ACID)和四种隔离级别?
MySQL事务
+
  • A 原子性:事务要么全成功要么全回滚,靠 undo log 实现
  • C 一致性:事务前后数据满足业务约束(转账总额不变)
  • I 隔离性:并发事务互不干扰,靠锁 + MVCC 实现
  • D 持久性:提交后数据永久保存,靠 redo log + fsync 实现
  • READ UNCOMMITTED:可读未提交数据 → 脏读
  • READ COMMITTED:只读已提交 → 不可重复读(Oracle 默认)
  • REPEATABLE READ:同一事务内读到一致快照 → 幻读(MySQL 默认,MVCC 解决大部分幻读)
  • SERIALIZABLE:串行执行 → 性能最差,完全无并发问题
# 查看当前隔离级别
SELECT @@transaction_isolation;

# 修改会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
记住:MySQL 默认 RR 级别,通过 MVCC(多版本并发控制)实现无锁读,性能好且基本避免幻读。面试必考。
Q28
K8s 中 ConfigMap 和 Secret 的区别?如何热更新配置?
K8s配置管理
+
  • ConfigMap:存普通配置(明文),如应用配置文件、环境变量
  • Secret:存敏感信息,base64 编码(不是加密!),如密码、token、证书
# 方式1:环境变量注入(不支持热更新)
env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: db-secret
      key: password

# 方式2:挂载为文件(支持热更新,约1分钟生效)
volumeMounts:
- name: config
  mountPath: /etc/app/config.yaml
  subPath: config.yaml
volumes:
- name: config
  configMap:
    name: app-config
  • 挂载为 Volume 时,ConfigMap 变更约 1分钟后自动同步到 Pod 里的文件
  • 但应用需要自己监听文件变化并重载(如 Nginx 需手动 nginx -s reload
  • subPath 挂载的文件不会自动更新,这是常见坑
生产建议:Secret 不要直接存 Git,用 Vault 或云厂商 KMS 管理敏感信息,再通过 External Secrets Operator 同步到 K8s Secret。
Q29
grep / awk / sed 三剑客:各自适用场景和高频用法?
Shell文本处理
+
  • grep:按关键词过滤行,找内容用它
  • awk:按列处理、统计、计算,处理结构化文本用它
  • sed:按行替换、插入、删除,批量修改文件用它
# === grep ===
grep -i "error" app.log          # 忽略大小写
grep -v "DEBUG" app.log          # 排除匹配行
grep -E "ERROR|WARN" app.log     # 多关键词(扩展正则)
grep -A3 -B2 "Exception" app.log # 匹配行前2行+后3行(上下文)
grep -c "404" access.log         # 统计匹配行数

# === awk ===
awk '{print $1, $7}' access.log          # 打印第1、7列
awk -F: '{print $1}' /etc/passwd         # 以:为分隔符
awk '$9==500 {print $0}' access.log      # 过滤第9列=500的行
awk '{sum+=$10} END{print sum}' a.log    # 累加第10列
awk 'NR>=10 && NR<=20' app.log           # 打印10-20行

# === sed ===
sed 's/old/new/g' file.txt               # 全局替换(不修改原文件)
sed -i 's/old/new/g' file.txt            # 原地替换(修改文件)
sed -n '5,10p' file.txt                  # 打印5到10行
sed '/^#/d' nginx.conf                   # 删除注释行
sed -i "/server_name/a\    listen 443;" f # 在匹配行后插入
组合使用:grep "ERROR" app.log | awk '{print $1}' | sort | uniq -c | sort -rn → 统计每分钟 ERROR 次数,面试现场写出这种管道命令加分明显。
Q30
什么是蓝绿部署和金丝雀发布?K8s 如何实现?
K8s发布策略DevOps
+
  • 同时维护两套环境:蓝(当前生产)/ 绿(新版本)
  • 新版本测试完成后,切换流量(改 Service selector)一次性全量切换
  • 出问题立即切回蓝色,回滚秒级
# 蓝绿切换:修改 Service 的 selector 标签
# 当前 Service 指向 version: blue
kubectl patch service myapp-svc \
  -p '{"spec":{"selector":{"version":"green"}}}'
# 出问题一键回滚
kubectl patch service myapp-svc \
  -p '{"spec":{"selector":{"version":"blue"}}}'
  • 新版本只承接一小部分流量(如 10%),逐步放大,发现问题影响面小
  • K8s 原生用副本比例控制:10个 Pod 中 1个跑新版 = 10% 流量
# 金丝雀:新旧 Deployment 共存,用同一 Service selector
# old-deployment: replicas=9, labels: app=myapp, track=stable
# new-deployment: replicas=1, labels: app=myapp, track=canary
# Service selector 只用 app=myapp,自动按副本比例分流

# 验证没问题后,逐步扩大新版副本数:
kubectl scale deployment myapp-canary --replicas=5
kubectl scale deployment myapp-stable --replicas=5
# 最终全量切换,下线旧版
区别总结:蓝绿 = 一刀切,回滚快但成本高(双倍资源);金丝雀 = 慢慢放量,风险低但流程复杂。生产大版本用蓝绿,功能迭代用金丝雀。