Kubernetes面试题
说明
Kubernetes面试题
# Kubernetes面试题
# 1、Docker与虚拟机有什么不同?
Docker是轻量级的沙盒,在其中运行的只是应用,资源使用率较低
虚拟机中还有额外独立操作系统运行
Docker
资源利用率更高
台物理机可以运行数百个容器,但是一般只能运行数十个虚拟机。
Docker
开销更小
不需要启动单独的虚拟机占用硬件资源。
Docker
启动速度更快
可以在数秒内完成启动。
使用虚拟机是为了更好的实现服务运行环境隔离,每个虚拟机都有独立的内核,虚拟化可以实现不同操作系统的虚拟机,但是通常一个虚拟机只运行一个服务,很明显资源使用率比较低且造成不必要的性能损耗,我们创建虚拟机的目的是为了运行应用程序,比如Nginx、PHP、TomCat等web程序,使用虚拟机无疑带来了一些不必要的资源开销,但是容器技术则基于减少中间运行环节带来了较大的性能提升。
# 2、简述Kubernetes与Docker的关系?
Docker通过Dockerfile将应用程序运行所需要的设置和依赖打包到一个镜像中,从而实现了可移植的特性。
Kubernetes用于关联和编排在多个主机上运行的容器。
Docker作为Kubernetes的CRI ( Container Runtime Interface) 实现之一,但是Kubernetes的CRI并非只有Docker。
# 3、kube-proxy采用ipvs和iptables的区别?
iptables是为防火墙而设计的;
ipvs则是专门用于高性能负载均衡,并使用更高效的数据结构(Hash表),允许无限的规模扩张。
相同之处:
- ipvs和iptables都是基于netfilter内核模块转发流量的。
与iptables相比,ipvs有以下明显优势:
- 为大型集群提供了更好的可扩展性和性能
- 支持比iptables更复杂的负载均衡算法(最小负载、最少连接、加权等等)
- 支持服务器监控检查和连接重试等功能
- 可以动态修改ipset的集合
iptables:
优点:
- 灵活
- 功能强大(对TCP不同阶段的包进行操作)
缺点:
- 表中规则较多时,查询缓慢,影响性能
ipvs
优点:
- 转发效率高
- 调度算法丰富: rr, wrr, lc, wlc, ip_hash ...
缺点:
- 低版本内核支持不全,需要升级内核版本
扩展:Kubernetes还有哪些代理模式?
- UserSpace:Kubernetes早期版本使用
- KernelSpace:专用于Windows
- iptables
- ipvs
# 4、简述kube-proxy切换为ipvs负载
Kubernetes默认的kube-proxy模式是使用iptables的,但是iptables的性能在大规模集群中会变得很差,而且有时候会出现一些问题,比如 clusterip 不能 ping 通。所以一般在安装Kubernetes的时候会将 kube-proxy 模式切换为 ipvs。
大致步骤如下:
查看kube-proxy信息
kubectl get pods -n kube-system -o wide | grep proxy
1使用kubectl logs可以查看当前kube-proxy的proxy模式
kubectl logs -n kube-system kube-proxy-6kwzc I0923 00:08:06.511166 1 node.go:172] Successfully retrieved node IP: 192.168.126.20 I0923 00:08:06.511240 1 server_others.go:142] kube-proxy node IP is an IPv4 address (192.168.126.20), assume IPv4 operation W0923 00:08:06.915071 1 server_others.go:578] Unknown proxy mode "", assuming iptables proxy
1
2
3
4
5Unknown proxy mode "", assuming iptables proxy,默认情况下就是
iptables
代理模式。所有节点启用ipvs模块
cat <<EOF > /etc/sysconfig/modules/ipvs.modules #!/bin/bash ipvs_modules="/usr/lib/modules/\`uname -r\`/kernel/net/netfilter/ipvs/" echo \$ipvs_modules for kernel_module in \`ls \$ipvs_modules | sed -r 's#(.*).ko.xz#\1#'\`; do /sbin/modinfo -F filename \${kernel_module} > /dev/null 2>&1 if [ 0 -eq 0 ]; then /sbin/modprobe \${kernel_module} fi done EOF # 给予可执行权限 chmod +x /etc/sysconfig/modules/ipvs.modules
1
2
3
4
5
6
7
8
9
10
11
12
13
14确保所有节点的ipvs模块以及成功运行
lsmod | grep ip_vs
1修改kube-proxy的配置文件
kubectl edit configmaps kube-proxy -n kube-system # 将 mode: "",修改为 mode: "ipvs"
1
2
3删除旧的Pod
kubectl delete pods -n kube-system $(kubectl get pods -n kube-system | grep -v grep| grep "kube-proxy" | awk '{print $1}') # 或者使用下面的命令 kubectl delete pods -l k8s-app=kube-proxy -n kube-system # 确保新的kube-proxy的Pod正常启动运行
1
2
3
4
5
6查看ipvs模式是否生效
kubectl logs -n kube-system kube-proxy-7thk6 yum install ipvsadm ipvsadm -L -n
1
2
3
4
5
# 5、简述微服务部署中的蓝绿发布
蓝绿发布(Blue/Green Deployment)
蓝绿部署中,一共有两套系统:
- 正在线上提供服务的系统,标记为绿色
- 准备发布的新版本,标记为蓝色
两套系统都是功能完善的、正在运行的系统,只是系统版本和对外提供的服务不同。
开发新版本,需要使用新版本替换线上的旧版本,在线上的旧系统之外,搭建一个使用新版本代码的系统。这时候,一共有两套系统正在运行,正在对外提供服务的旧版本是绿色系统,新部署的是蓝色系统。
蓝色系统不对外提供服务,用来做发布前的测试,测试过程中有任何问题,都可以直接在蓝色系统中直接修改,不干扰用户正在使用的绿色系统。
蓝色系统经过反复的测试、修改、验证,确定达到上线标准之后,直接将用户流量切换到蓝色系统。确定没有问题之后,绿色系统就可以停机下线。
# 6、简述蓝绿发布的特点
蓝绿部署无需停机,并且风险最小
蓝绿发布的优势
- 升级、切换和回退速度非常快
不足:
- 全量切换需要两倍的机器资源
# 演示
green.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp-v1
namespace: default
spec:
selector:
matchLabels:
app: demoapp-v1
version: v1
replicas: 1
template:
metadata:
labels:
app: demoapp-v1
version: v1
spec:
containers:
- name: demoapp-v1
image: ikubernetes/demoapp:v1.0
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: demoapp-visit-svc
spec:
type: NodePort
selector:
app: demoapp-v1
version: v1
ports:
- port: 80
name: http
protocol: TCP
targetPort: 80
nodePort: 31980
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
浏览器访问:
此时需要更新版本:
blue.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp-v2
namespace: default
spec:
selector:
matchLabels:
app: demoapp-v2
version: v2
replicas: 1
template:
metadata:
labels:
app: demoapp-v2
version: v2
spec:
containers:
- name: demoapp-v2
image: ikubernetes/demoapp:v1.1
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
kubectl apply -f blue.yaml
部署完bule版本,并且测试通过之后,需要进行版本切换:
kubectl edit svc demoapp-visit-svc
# 将 app: demoapp-v1 修改为 app: demoapp-v2
# 将 version: v1 修改为 version: v2
2
3
4
修改完成保存退出,访问的流量马上就发生了变化:
# 7、简述Kubernetes静态Pod
- 由Kubelet创建,并且总是在kubelet所在的节点上运行。
- 静态Pod的配置文件路径
- kubeadm安装的:
/var/lib/kubelet/config.yaml
,其中staticPodPath: /etc/kubernetes/manifests
- 二进制安装的:需要在
/usr/li/systemd/system/kubelet.service
文件中添加一行--pod-manifest-path=<dir>
指定
- kubeadm安装的:
如果要创建自己的静态Pod,只需要在对应的配置文件路径下创建自己的配置文件即可。
cat <<EOF >/etc/kubernetes/manifests/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: static-web
image: nginx:1.17.1
ports:
- name: web
protocol: TCP
containerPort: 80
EOF
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
此时,无需任何操作,kubelet会自动创建该Pod。
kubectl get pods -A
停止或者删除静态Pod的方式:
- 删除
/etc/kubernetes/manifests/static-web.yaml
文件
其他方式删除或者停止Pod都会被kubelet自动创建。
# 8、简述Kubernetes数据持久化的方式有哪些?
- emptyDir:空目录 临时存储
- hostPath:挂载宿主机目录
- pv存储:NFS、glusterfs、ceph ......
# 9、简述Dockerfile中COPY和ADD指令有啥区别
- COPY
- 文件复制,将宿主机的文件复制到容器内
- ADD
- 文件复制,将宿主机的文件复制到容器内
- 支持文件解压缩
- 支持URL
# 10、如何为Kubernetes集群删除或者添加新的节点
# 10.1 删除节点
首先确认节点是否故障不能开机,如果不能开机需要维修的,直接在master节点上删除该节点就可以:
kubectl delete nodes k8s-node03
如果节点仍在正常运行并且运行着Pod,那么首先需要将节点上的Pod进行驱逐:
# 方法1:在节点上打上污点即可驱逐大部分业务Pod
kubectl taint node k8s-node03 node-type=production:NoExecute
# 方法2:通过kubectl drain将指定节点上的资源迁移至集群中其他节点
kubectl drain k8s-node03 --delete-emptydir-data --force --ignore-daemonsets
2
3
4
5
污点排斥等级排序:
NoExecute
>NoSchedule
>PreferNoSchedule
然后删除节点:
kubectl get nodes -o wide
kubectl delete nodes k8s-node03
2
3
确认Pod驱逐完成之后,将节点重置,并清除数据:
# 在你需要删除的节点上执行
kubeadm reset -f
systemctl stop kubelet.service
systemctl stop docker.service
rm -rf /var/lib/cni/
rm -rf /var/lib/kubelet/*
rm -rf /etc/cni/
ifconfig cni0 down
ifconfig flannel.1 down
ifconfig docker0 down
ip link delete cni0
ip link delete flannel.1
system start docker.service
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
ipvsadm -C
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 10.2 添加新的节点
需要在需要加入的节点上做好环境准备工作,必须一些必须的Kubernetes组件的安装等等。
如果是kubeadm
安装的节点,需要查看加入集群的token是否失效:
# 查看token的名称
kubeadm token list
# 查看token的值
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
2
3
4
5
如果Token失效了,那么就需要通过kubeadm
目录重新生成Token:
# 生成临时的Token,有效期24小时
kubeadm token create --print-join-command
# 生成永久的Token
kubeadm token create --print-join-command --ttl 0
2
3
4
5
然后根据要将该节点加入到工作节点还是控制节点,执行不同的命令加入集群:
# 加入控制节点
kubeadm join 192.168.126.10:6443 --token mhls2v.xqoxslpkzj89l9bc --discovery-token-ca-cert-hash sha256:7207de86a81efadf0ec20bb117a33501fc6352ef218b1505b38e779554876a71 \
--control-plane
# 加入工作节点
kubeadm join 192.168.126.10:6443 --token mhls2v.xqoxslpkzj89l9bc --discovery-token-ca-cert-hash sha256:7207de86a81efadf0ec20bb117a33501fc6352ef218b1505b38e779554876a71 \
--control-plane
2
3
4
5
6
7