6 容器类面试题
6.1 docker有几种网络模式?容器和容器之间怎么通信?主机和主机之间怎么通信?
docker 有四种网络模式
- none
- 桥接(默认模式)
- Host
- container
跨主机的容器之间通过静态路由进行通信,A主机的容器的下一跳指向B主机,这样B主机接收到请求解包后转发给本机的容器
6.2 docker和核心技术是什么
容器其实就是 Namespace + Cgroups
- Namespace:帮助容器实现各种资源的隔离
- Cgroups:主要对容器使用某种资源量的多少做一个限制
- docker 使用宿主机的内核,启动速度快,隔离性差,docker 确切来说是一个容器引擎
- 虚拟机使用自己的内核,启动速度慢,因为有自己的内核,所以隔离性好
header 1 | header 2 |
---|---|
FROM | 指定基础镜像,即构建新镜像是基于那个基础镜像 |
LABEL | 设置镜像的标签 |
RUN | 指定构建过程中要运行的 shell 命令 |
ENV | 设置环境变量 |
WORKDIR | 指定默认的工作目录,即进入容器后默认进入的目录 |
VOLUME | 创建挂载点,也称为容器卷,用于数据共享和持久化 |
CMD | 注定容器要运行的命令,与 RUN 不同的是,这些命令不是在镜像构建过程中执行的 |
ENTRYPOINT | 指定容器启动时要运行的命令,与 CMD 有区别 |
COPY | 拷贝文件/目录到镜像中,但是不会解压 |
ADD | 拷贝文件/目录到镜像中,且会自动解压 |
EXPOSE | 声明容器运行的服务端口,即,指定对外暴露的端口 |
USER | 为 RUN、CMD、ENTRYPOINT 执行命令指定运行用户 |
HEALTHCHECK | 容器中服务检查检查 |
ARG | 设置编译镜像时加入的参数 |
ONBUILD | 当构建一个被继承的 Dockerfile 的时候就会运行 ONBULID 指令,ONBUILD 是一个触发指令 |
STOPSIGNAL | 设置容器的退出信号量 |
共同点
-
- 都可以指定 shell 或者 exec 函数调用的方式执行命令
-
- 当在 dockerfile 中存在多个 CMD 或 ENTRYPOINT 指令时,只有最后一条指令生效,所以一般只有一条 CMD 或 ENTRYPOINT 指令
-
- CMD 指令可以被 docker run 之后的参数覆盖,而 ENTRYPOINT 指令指定的命令不会被覆盖,而是将 docker run 指定的参数当做 ENTRYPOINT 指定命令的参数
-
- CMD 指令可以为 ENTRYPOINT 指定设置默认参数,而且可以被 docker run 指定的参数覆盖
镜像内容是存储在一层虚拟文件系统(VFS)之上,由多个文件块(Blobs)、描述清单文件(Manifests)和 标签文件(tags)组成,因为镜像设计是多层的。所以这些文件会互相依赖,在没有确认文件块(Blob)是否被其他镜像使用的情况下,直接删除会让仓库不完整。所以一般的做法是只做删除标记,而不是真删除,通过垃圾回收机制来遍历当前仓库的有向关系图(DAG),然后在删除没有被引用的文件块
6.7 镜像下载很慢如何解决 ?
1)搞清楚 harbor 架构
2)测试网络速度
服务端:iperf -s -i 1 -w 1000000
客户端:iperf -c 10.201.18.62 -i 1 -w 1000000
3)IO 测试
pidstat -d 1
iostat -d -x 1
vmstat 1 100
4)优化镜像
- 只安装一些必须的软件包
- 不要将数据和日志打包进镜像
- 删除一些不需要的数据
- 镜像变动的东西放在最上层(命令的最下面几行)
Kubernetes 是一个开源的容器管理平台,简称 k8s,用于管理多个主机上的容器化应用程序 ; 提供应用程序的快速部署,维护和扩展的基本机制
- 自我修复:一旦某一个容器崩溃,能够在 1 秒中左右迅速启动新的容器
- 弹性伸缩:实时根据服务的并发情况,增加或缩减容器数量
- 自动部署
- 版本回滚:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
- 服务发现:服务可以通过自动发现的形式找到它所依赖的服务
- 负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
- 机密和配置共享管理
- 存续编排:可以根据容器自身的需求自动创建存储卷
二进制部署:
- 以守护进程的方式启动在宿主机上,类似于是 Nginx 一样使用 service 脚本启动,需要自开监控脚本
- 兼容性最好,类似于在宿主机上启动了一个服务,这个服务可以直接使用宿主机内核的很多特性
- 适合有二次开发需求的场景
- 以容器的方式启动,会在宿主机上启动很多容器,比如 api-server 容器、controller manager 容器等,这样就导致容器运行环境受限,只能使用容器中的命令,很多宿主机内核的功能无法使用
- 以容器化的方式启动可以实现故障自动恢复
https://kubernetes.io/zh/docs/concepts/overview/components/
文章图片
7.2.1 master节点组件
- kube-apiserver
Kubernetes API ,提供了资源操作的唯一入口,各组件协调者,以 RESTful API 提供接口服务,并提供认证、授权、访问控制、API注册和发现等机制,负责接收、解析、处理请求。 所有对象资源的增删改查和监听操作都交给 APIServer 处理后再提交给 Etcd 存储
- kube-scheduler
调度器,负责资源的调度,按照预定的调度策略将 Pod 调度到相应的 node 节点上,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上
- kube-controller-manager
控制器,负责维护集群的状态,检查 pod 的健康状态,比如故障检测、自动扩展、 滚动更新等一些操作
- etcd
etcd 是一个分布式的 key / value 形式的键值存储系统,保存了整个 kubernetes 集群的状态数据,比如 Pod、Service 等对象信息,在 kubernetes 中使用 etcd 时,需要对 etcd 做备份, 保证高可用;整个 kubernetes 系统中一共有两个服务需要用到 etcd 用来协同和存储配置,分别是:
- 网络插件calico、对于其它网络插件也需要用到 etcd 存储网络的配置信息
- kubernetes 本身,包括各种对象的状态和元信息配置
注意:网络插件操作 etcd 使用的是 v2 的 API,而 kubernetes 操作 etcd 使用的 v3 的 API,所以在下面我们执行etcdctl的时候需要 设置ETCDCTL_API环境变量,该变量默认值为2,表示使用v2版本的api,v3表示使用v3版本的api
- kubelet
kubelet: 是 Master 在 Node 节点上的 Agent,每个 Node 节点上的 kubelet 定期就会调用 API Server 的 REST 接口报告自身状态,API Server 接收这些信息后,将节点状态信息更新到 etcd 中。kubelet 负责管理本机运行容器的生命周期,通过 API Server 监听 Pod 信息,从而对 Node 机器上的 Pod 进行管理,比如创建容器、Pod 挂载数据卷、下载 secret、获取容器和节点状态等工作,Kubelet 将每个 Pod 转换成一组容器
注意:如果以 kubeadm 这种方式安装 k8s,由于 master 上的组件(kube-apiserver、kube-scheduler、kube-controller-manager)都是以 pod 的方式运行,所以在 master 上也需要安装 kubelet
- kube-proxy
k8s 代理,是在群集中的每个节点上运行的网络代理和负载均衡,是实现 service 的通信与负载均衡机制的重要组件,kube-proxy 负责请求转发,一旦发现了某一个 Service 关联的 Pod 信息发生了改变(如IP、Port等),由 KubeProxy 就会把变化后的 service 转换成 IPVS 或 IPtables 规则中,完成对后端 pod 的负载均衡
- docker
是一个容器引擎,用于运行容器
- coredns
k8s 1.11 之前使用的是 kubedns ,1.11 之后才有 coredns
coredns 是一个 DNS 服务器,能够为 Kubernetes services 提供 DNS 记录
- dashboard
k8s的web界面,通过这个界面可以对k8s资源进行操作
- Ingress Controller
七层负载均衡控制器,可以创建 nginx 或者 traefik 这种七层负载应用,实现域名和 https 访问
- prometheus+alertmanager+grafana
k8s 监控和报警展示
- EFK
k8s 日志收集展示和检索
- 第一步:kubectl create po
首先进行认证后,kubectl会调用master api创建对象的接口,然后向k8s apiserver发出创建pod的命令
- 第二步:k8s apiserver
apiserver收到请求后,并非直接创建pod,而是先创建一个包含pod创建信息的yaml文件
- 第三步:controller manager
创建Pod的yaml信息会交给controller manager,controller manager根据配置信息将要创建的资源对象(pod)放到等待队列中
- 第四步:scheduler
scheduler查看k8s api,类似于通知机制。首先判断:pod.spec.Node == null?
若为null,表示这个Pod请求是新来的,需要创建;然后进行预选调度和优选调度计算,找出最 “闲” 的且符合调度条件的node。最后将信息在etcd数据库中更新分配结果:pod.spec.Node2(设置一个具体的节点) 同样上述操作的各种信息也要写到etcd数据库中。
分配过程需要两层调度:预选调度和优选调度
- 预选调度:一般根据资源对象的配置信息进行筛选。例如NodeSelector、HostSeletor和节点亲和性等。
- 优选调度:根据资源对象需要的资源和node节点资源的使用情况,为每个节点打分,然后选出最优的节点创建资源对象(pod)
- 预选调度:一般根据资源对象的配置信息进行筛选。例如NodeSelector、HostSeletor和节点亲和性等。
- 第五步:kubelet
目标节点node2上的kubelet进程通过API Server,查看etcd数据库(kubelet通过API Server的WATCH接口监听Pod信息,如果监听到新的pod副本被调度绑定到本节点)监听到kube-scheduler 产生的Pod绑定事件后获取对应的Pod清单,然后调用node1本机中的docker api初始化volume、分配IP、下载image镜像,创建容器并启动服务
- 第六步:controller manager
controller manmager会通过API Server提供的接口实时监控资源对象的当前状态,当发生各种故障导致系统状态发生变化时,会尝试将其状态修复到 “期望状态”
- 用户向 apiServer 发送删除 pod 对象的命令
- apiServcer 中的 pod 对象信息会随着时间的推移而更新,在宽限期内(默认30s),pod 被视为 dead
- 将 pod 标记为 terminating 状态
- kubelet 在监控到 pod 对象转为 terminating 状态的同时启动 pod 关闭过程
- 端点控制器监控到 pod 对象的关闭行为时将其从所有匹配到此端点的 service 资源的端点列表中移除
- 如果当前 pod 对象定义 了preStop 钩子处理器,则在其标记为 terminating 后即会以同步的方式启动执行
- pod 对象中的容器进程收到停止信号
- 宽限期结束后,若 pod 中还存在仍在运行的进程,那么 pod 对象会收到立即终止的信号
- kubelet 请求 apiServer 将此 pod 资源的宽限期设置为0从而完成删除操作,此时 pod 对于用户已不可见
我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期,它主要包含下面的过程
- pod 创建过程
- 运行初始化容器(init container)过程
- 运行主容器(main container)
- 容器启动后钩子(post start)、容器终止前钩子(pre stop)
- 容器的存活性探测(liveness probe)、就绪性探测(readiness probe)
- 容器启动后钩子(post start)、容器终止前钩子(pre stop)
- pod终止过程
- 挂起(Pending):apiserver已经创建了pod资源对象,但它尚未被调度完成(如:nodeName: node3 指定调度到 node3 节点上,而这个 node3 节点不存在,就会出现 Pending 状态)或者仍处于下载镜像的过程中
- 运行中(Running):pod已经被调度至某节点,并且所有容器都已经被kubelet创建完成
- 成功(Succeeded):pod中的所有容器都已经成功终止并且不会被重启
- 失败(Failed):所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态
- 未知(Unknown):apiserver无法正常获取到pod对象的状态信息,通常由网络通信失败所导致
kubernetes支持配置三种拉取策略:
- Always:总是从远程仓库拉取镜像(一直使用远程下载)
- IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像(本地有就本地 本地没有则远程下载)
- Never:只使用本地镜像,从不去远程仓库拉取,本地没有就报错 (一直使用本地)
如果镜像tag为具体版本号, 默认策略是:IfNotPresent
如果镜像tag为:latest(最终版本) ,默认策略是always
7.7 容器探测
- liveness probes:存活性探针,用于检测应用实例当前是否处于正常运行状态,如果不是,k8s会重启容器
- readiness probes:就绪性探针,用于检测应用实例当前是否可以接收请求,如果不能,k8s不会转发流量
- livenessProbe 决定是否重启容器,readinessProbe 决定是否将请求转发给容器。
- Exec命令:在容器内执行一次命令,如果命令执行的退出码为0,则认为程序正常,否则不正常
- TCPSocket:将会尝试访问一个用户容器的端口,如果能够建立这条连接,则认为程序正常,否则不正常
- HTTPGet:调用容器内Web应用的URL,如果返回的状态码在200和399之间,则认为程序正常,否则不正常
场景:在实际环境中,不同的服务会对资源有不同的要求,根据实际需求,我们需要将这些应用部署到特定的服务器,从而提升服务性能和服务器资源使用率
应用调度类型与场景
- nodeSelector 定向调度
nodeSelector 是节点选择约束的最简单推荐形式,nodeSelector 是 PodSpec 的一个字段,通过设置 label 相关策略将 pod 关联到对应的 label 的节点上
- nodeName 定向调度
nodeName 是节点选择约束的最简单方法,但是由于其自身限制,通常不使用它,nodeName 是 PodSpec 的一个字段,如果指定 nodeName,调度器将优先在指定的 node 上运行 pod
- nodeAffinity 定向调度
nodeAffinity 类似于 nodeSelector,使用 nodeAffinity 可以根据节点的 labels 限制 Pod 能否调度到哪些节点,当前 nodeAffinity 有软亲和性和硬亲和性两种类型,节点亲和性与 nodeSelector 相比,亲和/反亲和功能极大地扩展了可以表达约束的类型,增强了如下功能
- 语言更具表现力
- 在调度器无法满足要求时,仍然调度该 Pod
- 语言更具表现力
kubectl label node qa-gpu082 env=dev
使用 nodeSelector 调度应用
nodeSelector:
env: dev
使用 nodeName 调度应用
nodeName: master1
使用 Affinity 调度应用
软亲和
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution
- weight: 100
preference:
matchExpressions:
- key: env
operator: In
values:
- dev
硬亲和
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution
nodeSelectorTerms:
- matchExpressions:
- key: env
operator: In
values:
- test
硬亲和性:当没有节点满足亲和性要求时,Pod 一直处于 Pending 状态
7.9 什么是亲和性,以及使用场景是什么 ?
- nodeAffinity(node亲和性): 以node为目标,解决pod可以调度到哪些node的问题
- podAffinity(pod亲和性) : 以pod为目标,解决pod可以和哪些已存在的pod部署在同一个拓扑域中的问题
- podAntiAffinity(pod反亲和性) : 以pod为目标,解决pod不能和哪些已存在pod部署在同一个拓扑域中的问题
- 亲和性:如果两个应用频繁交互,那就有必要利用亲和性让两个应用的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗。
- 反亲和性:当应用的采用多副本部署时,有必要采用反亲和性让各个应用实例打散分布在各个node上,这样可以提高服务的高可用性。
https://blog.csdn.net/qq_43280818/article/details/106910187
前面说过 pod 内部的容器也是一个独立的沙箱环境,因此也有自己的 ip 和 端口。如果内部容器还是通过 ip:port 来通信,相当于还是远程访问,这样的话性能会受到一定的影响。如何提高内部容器之间访问的性能呢?
pod 底层
- pod 内部容器创建之前,必须先创建 pause 容器。pause 有两个作用:共享网络和共享存储。
- 每个服务容器共享 pause 存储,不需要自己存储数据,都交给 pause 维护。
- pause 也相当于这三个容器的网卡,因此他们之间的访问可以通过 localhost 方式访问,相当于访问本地服务一样,性能非常高(就像本地几台虚拟机之间可以 ping 通)。
集群内部访问
- 容器间通信:同一个 Pod 内的多个容器间的通信,通过 localhost 实现
- Pod 间通信:Pod IP <----->Pod IP,Overlay Network(叠加网络),K8s要求Pod间通信必须是所见即所得,从一个 Pod IP 到另一个 Pod IP 必须是直达,不能经过任何地址转换,不同 pod 的容器访问可以使用 endpoint 方式(pod 的 ip + 容器的端口)
- Pod 与 Server 间通信:Pod IP<----->Cluster IP
kubectl get configmap -n kube-system kubectl get configmap kube-proxy -o yaml -n kube-system
- 直接访问容器(设置 pod 级别的 hostwork=true,直接通过主机 ip + hostport 访问)
- 通过service访问(NodePort方式,集群中任意一个 Node 的 IP 地址 + 具体的 NodePort 端口号访问)
- Ingress
K8s本身只有网络标准,没有网络方案,它只允许别人给他提供,Kubernetes 1.1之后采用CNI作为通用的容器网络标准
CNI(Container Network Interface)
- flannel:部署简单,支持网络地址分配,不支持网络策略
支持多种后端:
- VxLAN(Overlay叠加网络)
- 原生vxlan
- Directrouting(源和目标节点在同一网络用host-gw方式直接转发,不用隧道叠加。而不再同一网络就用vxlan隧道叠加,Directrouting是vxlan和host-gw的结合使用)
- 原生vxlan
- host-gw:Host Gateway(比calico性能并不差,但要求各节点必须工作在同一个二层网络中,不支持跨网络,如果有成千上万的Pod,容易产生广播风暴)
- UDP:性能差
- VxLAN(Overlay叠加网络)
- calico:部署复杂,既支持网络地址分配又支持网络策略,基于BGP协议实现三层网络路由
- canel
- kube-router
作用:Controllers 控制器,控制 pod,启动、停止、删除
- ReplicaSet:确保预期的 Pod 副本数量
- Deployment:无状态应用部署(
kubectl scale deployment nginx-1 -n test --replicas=3
)
- StatufulSet:有状态应用部署(mysql,redis,nacos,es,zookeeper等)
- DaemonSet:确保所有 Node 运行同一个类型的 Pod(监控客户端:node-exporter、日志收集客户端:filebeat)
- Job:一次性任务(比如 pod 运行完自行销毁的任务)
- Cronjob:定时任务(定期清理)
Service:将一组 pod 关联起来,提供一个统一个入口,即使 pod 地址发生改变,这个统一入口也不会变化,可以保证用户访问不受影响
- 防止 Pod 失联
- 定义一组 Pod 的访问策略
- 标签,附加到某个资源上,用于关联对象,查询和筛选
apiVersion: v1
kind: Service
metadata:
name: mall-bi-frontend-prelease
namespace: bi
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
k8s-app: mall-bi-frontend-prelease
type: ClusterIP
deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: mall-bi-frontend-prelease
namespace: bi
spec:
replicas: 1
selector:
matchLabels:
k8s-app: mall-bi-frontend-prelease
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
k8s-app: mall-bi-frontend-prelease
spec:
containers:
......
[root@web01 ~]# kubectl -n bi get pod --show-labels
NAMEREADYSTATUSRESTARTSAGELABELS
k8s-app=mall-bi-frontend,pod-template-hash=57f6696845
mall-bi-frontend-57f6696845-qc6p41/1Running04h12mk8s-app=mall-bi-frontend,pod-template-hash=57f6696845
mall-bi-frontend-prelease-7c8784c648-rdm5s1/1Running087mk8s-app=mall-bi-frontend-prelease,pod-template-hash=7c8784c648
[root@web01 ~]#
7.14 容器不停重启的原因有哪些
1)比如:busybox并不是一个程序,而是类似于一个工具类的集合,k8s集群启动管理后,它会自动关闭。并且不停的重启。解决方法就是让其一直在运行,这就用到了command配置
2)pod 数量达到了限制
3)资源限制达到了上限
4)存活探针(livenessProbe)检查失败,如(command: [“/bin/cat”,“/tmp/hello.txt”])如果这个文件(/tmp/hello.txt)不存在,容器则会不停的重启(当然,要受重启策略的影响)
5)node 地址设置冲突,calico 网络插件无法运行,导致调度到此 node 上的 pod 不停的重启
7.15 排查 Pod 异常的常用命令
查看 Pod 状态
kubectl get pods 【docker|docker和k8s面试题总结(未完待续)】 -n -o wideroot@sh-gpu101:~# kubectl get pods node-exporter-7xztd -n monitoring -o wide
NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES
node-exporter-7xztd1/1Running02d192.168.106.124node124
root@sh-gpu101:~#
查看 Pod 的 yaml 配置
kubectl get pods -n -o yaml
查看 Pod 的事件
kubectl describe pods -n
查看 Pod 容器日志
kubectl logs -n [-c ]# 可以 tailf 该 Pod 的日志观察进度
kubectl logs kibana-logging-7445dc9757-pvpcv -n kube-system -f
查看 kube-system 命名空间下的所有服务
kubectl get svc -n kube-system
7.16 pod排错步骤:
1)查看 kube-system 命名空间下的所有 pod 状态
kubectl -n kube-system get pods
# 显示IP信息和运行的node信息
kubectl -n kube-system get pods -o wide
2)查看 pod 的事件
kubectl -n kube-system describe pod metrics-server-v0.2.1-5988c5d6b8-8x4l2
3)查看日志
# 发现 pod 中有两个容器
root@172-16-244-214:~# kubectl get pod -n monitoring prometheus-r9xlm
NAMEREADYSTATUSRESTARTSAGE
prometheus-r9xlm1/2CrashLoopBackOff31028d# 查看 pod 日志报错,因为 pod 中有两个容器,必须选择一个容器后才能查看
root@172-16-244-214:~# kubectl logs -f -n monitoring prometheus-r9xlm
error: a container name must be specified for pod prometheus-r9xlm, choose one of: [configmap-reload prometheus]# 查看 configmap-reload 容器日志
root@172-16-244-214:~# kubectl logs -f -n monitoring prometheus-r9xlm -c configmap-reload
2022/02/22 16:00:59 Watching directory: "/etc/config"
2022/02/22 16:00:59 Watching directory: "/etc/prometheus/rules"
^C# 查看 prometheus 容器日志
root@172-16-244-214:~# kubectl logs -f -n monitoring prometheus-r9xlm -c prometheus
7.17 容器的存储
7.17.1 普通存储 EmptyDir
EmptyDir 是最基础的 Volume 类型,一个 EmptyDir 就是 Host 上的一个空目录。
EmptyDir 是在 Pod 被分配到 Node 时创建的,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为 kubernetes 会自动分配一个目录,当 Pod 销毁时, EmptyDir 中的数据也会被永久删除。
EmptyDir用途如下:
- 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保留
- 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)
EmptyDir中数据不会被持久化,它会随着Pod的结束而销毁,如果想简单的将数据持久化到主机中,可以选择HostPath。
HostPath 就是将 Node 主机中一个实际目录挂在到 Pod 中,以供容器使用,这样的设计就可以保证 Pod 销毁了,但是数据依据可以存在于 Node 主机上。
NFS
HostPath可以解决数据持久化的问题,但是一旦Node节点故障了,Pod如果转移到了别的节点,又会出现问题了,此时需要准备单独的网络存储系统,比较常用的用NFS、CIFS。
NFS是一个网络文件存储系统,可以搭建一台NFS服务器,然后将Pod中的存储直接连接到NFS系统上,这样的话,无论Pod在节点上怎么转移,只要Node跟NFS的对接没问题,数据就可以成功访问。
7.17.2 高级存储 kubernetes 支持的存储系统有很多,要求用户全都掌握,显然不现实。为了能够屏蔽底层存储实现的细节,方便用户使用, kubernetes 引入 PV 和 PVC 两种资源对象。
- PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下 PV 由 kubernetes 管理员进行创建和配置,它与底层具体的共享存储技术有关,并通过插件完成与共享存储的对接。
- PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC 其实就是用户向 kubernetes 系统发出的一种资源需求申请。
在kubernetes中,还存在一种和ConfigMap非常类似的对象,称为Secret对象。它主要用于存储敏感信息,例如密码、秘钥、证书等等。
7.18 K8s 是怎么进行程序发布的 ?
1)创建 secret
2)创建 configmap 和 pvc
3)打标签和污点
4)设置资源限制(resources)
5)设置亲和性
6)设置探针(就绪探针和存活探针)
7)发布 depoly
8)发布 svc
9)发布 ingress
10)访问测试
7.19 K8s 如何实现灰度发布 ?
7.20 kube-proxy 支持的三种工作模式
UserSpace:k8s v1.2 及以后就已经淘汰了Iptables:目前默认方式,1.1开始支持,1.2开始为默认IPVS:1.9 引入到 1.11 正式版本,需要安装 ipvsadm、ipset 工具包和加载 ip_vs 内核模板
IPVS 模式在 Kubernetes v1.8 中引入 alpha 版本,在v1.9 中处于beta版本,在v1.11中处于GA(也就是release版本,国外都是说GA版本)版本,IPTABLES模式已在v1.1中添加,并成为v1.2之后的默认操作模式,IPVS和IPTABLES都基于netfilter,IPVS模式和IPTABLES模式之间的差异如下
- IPVS为大型群集提供了更好的可伸缩性和性能
- 与IPTABLES相比,IPVS支持更复杂的负载平衡算法(最少连接,轮询,加权轮询等)
- IPVS支持服务器运行状况检查和连接重试等
skydns
kubedns
coredns---目前的主流
7.22 常用命令
# 基础命令
create
delete
edit
get
describe
logs
exec
scale
explain# 命令说明# 配置命令
lable:给 node 标记 label,实现 pod 与 node 亲和性# 标签管理
apply# 动态配置# 集群管理命令
cluster-info/top# 集群状态# node 节点管理
cardon:警戒线,标记 node 不被调用
uncardon:取消警戒标记为 cardon 的 node
drain:驱逐 node 上的 pod,用于 node 下线等场景
taint:给 node 标记污点,实现反 pod 与 node 反亲和性api-resource/api-versions/version# api 资源
config# 客户端 kube-config 配置
查看 bi 这个命名空间下的所有的配置文件
[root@node01 ~]# kubectl -n bi get cm
NAMEDATAAGE
bi-frontend1132d
bi-frontend-prelease1131d
编辑 bi 这个命名空间某个配置文件
kubectl -n bi edit cm bi-frontend
查看 bi 这个命名空间下的所有 pod,并显示 pod 的 IP 地址
kubectl -n bi get pods -o wide
查看 dev 命名空间下的 pod 名称为 ngx-1 的日志,并显示最后 30 行
kubectl logs ngx-1 -n dev | tail -n 30
如何查看 bi 命名空间下的所有 endpoints(endpoints:存储一组 pod 的 IP 地址)
[root@node01]# kubectl -n bi get ep
NAMEENDPOINTSAGE
bi-backend10.1.0.22:8080,10.1.1.225:8080,10.1.2.146:8080132d
bi-frontend10.1.1.6:80,10.1.2.238:80132d
如何列出所有 namespace 中的所有 pod
# 注意:生产中谨慎使用,尤其是在资源紧张的情况下
kubectl get pods --all-namespaces
kubectl get pods -A
如何查看 bi 命名空间下的所有 ingress
kubectl -n bi get ing
删除 bi 命名空间下某个 deploy,名称为 tianwen
kubectl -n bi delete deploy tianwen
如何缩减 bi 命名空间下 deploy 名称为 ngx-1 的副本数为 3
kubectl -n bi scale deployment ngx-1 --replicas=3
kubectl -n bi get pods -o wide
如何在不进入 pod 内查看命名空间为 dev , pod 名称为 metrics-server-v0.2.1-5988c5d6b8-8x4l2 的 hosts
kubectl exec -it metrics-server-v0.2.1-5988c5d6b8-8x4l2 -n dev -- cat /etc/hosts
如何设置节点 node-1 为不可调度以及如何取消不可调度
设置不可调度
# cordon:警戒线,标记 node 不被调度
# 设置 node-1 为不可调度
kubectl cordon node-1
注意:不要大量占用服务器根目录空间,可用容量低于 10% 后,服务器会进入异常状态(不可被调度)
取消不可调度
# uncordon:取消警戒标记为 cordon 的 node
# 取消 node-1 的不可调度
kubectl uncordon node-1
7.23 上云有哪些注意事项 ?
1)中间件(redis mysql nacos es zookeeper mq MongoDB Sentinel等)
- 有状态
- 数据导入(例如:通过 MySQL Workbench 将本地的数据导入到云上的 MySQL 中)
- 无状态
- 制作镜像
- 各种访问地址(内网 DNS 访问)
- 生产配置分离
- URL
1)打包
maven 打成可执行 jar,上传给服务器(master)
2)制作镜像
docker 根据 dockerfile 把包打成指定的镜像
3)推送镜像
将镜像推送给私有 Harbor
4)应用部署
给 k8s 部署应用,node1 节点部署应用
7.25 生产中应用部署(pod 发布)的注意事项
1)集群节点设置(lable 和 taint)
2)创建密钥文件(secret)
3)配置文件(configmap)
4)对于有状态的应用,还需要创建存储(pv和pvc)
5)资源限制(resources)
6)亲和性设置(affinity)
7)容忍设置(tolerations)
8)定向调度(nodeSelector)
9)探针设置(livenessProbe和readinessProbe)
7.26 port、targetport、nodeport的区别
- nodeport:集群外流量访问集群内服务的端口,比如客户访问 nginx、apache 等
- port:集群内的 pod 互相通信的端口,比如:lnmp架构中,php 访问 mysql,mysql 是不能让外部用户访问到的,port 是 service 的端口
- targetport:目标端口,也就是最终端口,也就是 pod 的端口
推荐阅读
- k8s学习|K8S学习之容器探测 livenessProbe、readinessProbe、startupProbe、lifecycle
- 前端面试题|【牛客网-公司真题-前端入门篇】——2021牛客模考-卷1
- 后端|GitHub 又爆新作!2 份 PDF+1 个插件算法刷题三件套!面试进阶双飞
- servlet|vue3验证码倒计时60秒(自用)
- Java|基于Vue的仿小米商城
- 数据库|使用 Apache Superset 可视化 ClickHouse 数据
- java|程序员网吧写代码挨顿打(网友(想笑死我继承我的花呗?))
- java|Ssm美众针纺有限公司人事管理毕业设计源码051708
- java|SSM在线学习网站的设计与实现毕业设计源码011451