最新要闻
- 每日精选:专访|田耳:文学或有江湖,写作难以停歇
- 饭一定要吃七分饱才健康?新研究推翻传统观念 全球热闻
- 全球简讯:欧洲人最爱!蔚来ET5旅行版实车亮相:真心优雅
- 当前要闻:环保人士赢了?大众董事长演讲被蛋糕袭击 官方回应:新能源车保护环境吗?
- 环球视讯!只做了2年 日本家电巨头巴慕达退出手机市场:价格比iPhone还贵
- 北方今年首轮高温来袭:14日起多地冲击35℃高温
- 世界观速讯丨促进消费潜能释放 4月份汽车市场产销量同比快速增长
- 微软本周不会为 Win11 Canary 或 Dev 频道发布新版本|精选
- 重庆未来三年将实施水利项目超1800个 环球短讯
- 跑分最高的安卓旗舰!已有1000多人下单iQOO Neo8系列|天天快看
- NVIDIA一代神卡RTX 3060 Ti要停产了:清完库存即止
- 惊了!女网红用AI同时交往1000多个“男友” 年入4亿?-世界实时
- 电脑也能秒开3A大作!Win11或将引入Xbox Quick Resume功能-全球消息
- 世界速看:女大学生坐高铁拒绝补票刁难乘务长 后排乘客理论遭辱骂
- 团结就是力量合唱动作编排视频_团结就是力量合唱动作 焦点快报
- 辅助工具管理器_辅助工具管理器-焦点关注
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
云原生第三周--kubernetes组件详解|每日播报
etcd组件
etcd简介:
etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现。
(相关资料图)
etcd具有下面这些属性:
完全复制:集群中的每个节点都可以使用完整的存档高可用性:Etcd可用于避免硬件的单点故障或网络问题一致性:每次读取都会返回跨多主机的最新写入简单:包括一个定义良好、面向用户的API(gRPC)安全:实现了带有可选的客户端证书身份验证的自动化TLS快速:每秒10000次写入的基准速度可靠:使用Raft算法实现了存储的合理分布Etcd的工作原理
etcd配置文件
root@192:~# cat /etc/systemd/system/etcd.service [Unit]Description=Etcd ServerAfter=network.targetAfter=network-online.targetWants=network-online.targetDocumentation=https://github.com/coreos[Service]Type=notifyWorkingDirectory=/var/lib/etcd #数据保存目录ExecStart=/usr/bin/etcd \ #二进制文件路径 --name=etcd-192.168.110.180 \ #当前node 名称 --cert-file=/etc/kubernetes/ssl/etcd.pem \ --key-file=/etc/kubernetes/ssl/etcd-key.pem \ --peer-cert-file=/etc/kubernetes/ssl/etcd.pem \ --peer-key-file=/etc/kubernetes/ssl/etcd-key.pem \ --trusted-ca-file=/etc/kubernetes/ssl/ca.pem \ --peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \ --initial-advertise-peer-urls=https://192.168.110.180:2380 \#通告自己集群端口 --listen-peer-urls=https://192.168.110.180:2380 \ #集群之间通讯端口 --listen-client-urls=https://192.168.110.180:2379,http://127.0.0.1:2379 \#客户端访问地址 --advertise-client-urls=https://192.168.110.180:2379 \#通告自己的客户端端口 --initial-cluster-token=etcd-cluster-0 \#创建集群使用的token,一个集群内的节点保持一致 --initial-cluster=etcd-192.168.110.180=https://192.168.110.180:2380,etcd-192.168.110.181=https://192.168.110.181:2380,etcd-192.168.110.183=https://192.168.110.183:2380 \#集群所有节点信息 --initial-cluster-state=new \新建集群时为new,若是已经存在的集群为existing --data-dir=/var/lib/etcd \数据目录路径 --wal-dir= \ --snapshot-count=50000 \ --auto-compaction-retention=1 \ --auto-compaction-mode=periodic \ --max-request-bytes=10485760 \ --quota-backend-bytes=8589934592Restart=alwaysRestartSec=15LimitNOFILE=65536OOMScoreAdjust=-999[Install]WantedBy=multi-user.target
etcd-选举
etcd 是一个分布式的k/V存储系统。核心使用了RAFT分布式一致性协议。一致性这个概念,它是指多个服务器在状态达成一致,但是在一个分布式系统中,因为各种意外可能,有的服务器可能会崩溃或变得不可靠,它就不能和其他服务器达成一致状态。这样就需要一种Consensus协议,一致性协议是为了确保容错性,也就是即使系统中有一两个服务器当机,也不会影响其处理过程。为了以容错方式达成一致,我们不可能要求所有服务器100%都达成一致状态,只要超过半数的大多数服务器达成一致就可以了,假设有N台服务器,N/2 +1 就超过半数,代表大多数了。
节点角色:集群中每个节点只能处于 Leader、Follower 和 Candidate 三种状态的一种follower:追随者(Redis Cluster的Slave节点)candidate:候选节点,选举过程中。leader:主节点(Redis Cluster的Master节点)
节点启动后基于termID(任期ID)进行相互投票,termID是一个整数默认值为0,在Raft算法中,一个term代表leader的一段任期周期,每当一个节点成为leader时,就会进入一个新的term, 然后每个节点都会在自己的term ID上加1,以便与上一轮选举区分开来。选举过程
首次选举:1、各etcd节点启动后默认为 follower角色、默认termID为0、如果发现集群内没有leader,则会变成 candidate角色并进行选举 leader。2、candidate(候选节点)向其它候选节点发送投票信息(RequestVote),默认投票给自己。3、各候选节点相互收到另外的投票信息(如A收到BC的,B收到AC的,C收到AB的),然后对比日志是否比自己的更新,如果比自己的更新,则将自己的选票投给目的候选人,并回复一个包含自己最新日志信息的响应消息,如果C的日志更新,那么将会得到A、B、C的投票,则C全票当选,如果B挂了,得到A、C的投票,则C超过半票当选。4、C向其它节点发送自己leader心跳信息,以维护自己的身份(heartbeat-interval、默认100毫秒)。5、其它节点将角色切换为Follower并向leader同步数据。6、如果选举超时(election-timeout )、则重新选举,如果选出来两个leader,则超过集群总数半票的生效。后期选举:当一个follower节点在规定时间内未收到leader的消息时,它将转换为candidate状态,向其他节点发送投票请求(自己的term ID和日志更新记录),并等待其他节点的响应,如果该candidate的(日志更新记录最新),则会获多数投票,它将成为新的leader。新的leader将自己的termID +1 并通告至其它节点。如果旧的leader恢复了,发现已有新的leader,则加入到已有的leader中并将自己的term ID更新为和leader一致,在同一个任期内所有节点的term ID是一致的。
附录:raft选举机制示例 非常清晰
thesecretlivesofdata.com/raft/
配置优化--max-request-bytes=10485760
#request size limit 10M(请求的最大字节数默认1.5M,官方推荐不超过10B)--quota-backend-bytes=8589934592
#storage size limit(磁盘存储空间大小限制,默认为2G,此值超过8G启动会有警告信息)
集群碎片整理ETCDCTL_API=3 /usr/local/bin/etcdctl defrag --cluster --endpoints=https://192.168.110.206 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/etcd.pem --key=/etc/kubernetes/ssl/etcd-key.pem
etcd 查看成员信息
etcd有多个不同的API访问版本,v1版本已经废弃,etcd v2 和 v3 本质上是共享同一套 raft 协议代码的两个独立的应用,接口不一样,存储不一样,数据互相隔离。也就是说如果从 Etcd v2 升级到 Etcd v3,原来v2 的数据还是只能用 v2 的接口访问,v3 的接口创建的数据也只能访问通过v3 的接口访问。
ETCDCTL_API=3 etcdctl --help
使用v3版本 查看帮助
ETCDCTL_API=3 etcdctl --write-out=table member list --endpoints=https://192.168.110.180:2379 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/etcd.pem --key=/etc/kubernetes/ssl/etcd-key.pem
查看成员信息
验证节点心跳状态
for ip in ${NODE_IPS}; do ETCDCTL_API=3 etcdctl --endpoints=https://${ip}:2379 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/etcd.pem --key=/etc/kubernetes/ssl/etcd-key.pem endpoint health; done
查看详细信息for ip in ${NODE_IPS}; do ETCDCTL_API=3 etcdctl --write-out=table endpoint status --endpoints=https://${ip}:2379 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/etcd.pem -- key=/etc/kubernetes/ssl/etcd-key.pem; done
查看etcd数据ETCDCTL_API=3 etcdctl get / --prefix --keys-only
#以路径的方式查询所有key信息ETCDCTL_API=3 etcdctl get / --prefix --keys-only | grep pod
查看podETCDCTL_API=3 etcdctl get / --prefix --keys-only | grep namespaces
查看namespaceETCDCTL_API=3 etcdctl get / --prefix --keys-only | grep deployment
查看deploymentETCDCTL_API=3 etcdctl get / --prefix --keys-only | grep calico
查看calico
etcd增删改查添加 putETCDCTL_API=3 etcdctl put /name "lily"
查询 getETCDCTL_API=3 etcdctl get /name
改动数据 put直接覆盖ETCDCTL_API=3 etcdctl put /name "lusy"
删除数据 delETCDCTL_API=3 etcdctl del /name "lusy"
etcd进阶etcd数据watch机制基于不断监看数据,发生变化就主动触发通知客户端,Etcd v3 的watch机制支持watch某个固定的key,也支持watch一个范围ETCDCTL_API=3 etcdctl watch /data
ETCDCTL_API=3 etcdctl put /data "test v1"
ETCDCTL_API=3 etcdctl put /data "test v2"
etcd V3 API版本数据备份与恢复
WAL是write ahead log(预写日志)的缩写,顾名思义,也就是在执行真正的写操作之前先写一个日志,预写日志。wal: 存放预写式日志,最大的作用是记录了整个数据变化的全部历程。在etcd中,所有数据的修改在提交前,都要先写入到WAL中
V3备份数据命令
ETCDCTL_API=3 etcdctl snapshot save snapshot.db
备分到WAL中
V3恢复数据命令
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db --data-dir=/opt/etcd-v3bak
#将数据恢复到一个新的不存在的目录中 如果目录存在就会报错!
自动备份数据
mkdir /data/etcd-backup-dir/ -pcat etcd-backup.sh#!/bin/bashsource /etc/profileDATE=`date +%Y-%m-%d_%H-%M-%S`ETCDCTL_API=3 etcdctl snapshot save /data/etcd-backup-dir/etcd-snapshot-${DATE}.db
etcd集群V3版本数据备份与恢复
./ezctl backup k8s-master1
备份目录在 clusters/[clusters-name]/backup查看备份文件覆盖文件删除掉两个pod 然后恢复
./ezctl restore k8s-cluster1
重新查看pod 又恢复回来了
集群也正常了
当etcd集群宕机数量超过集群总节点数一半以上的时候(如总数为三台宕机两台),就会导致整合集群宕机,后期需要重新恢复数据,则恢复流程如下:1、恢复服务器系统2、重新部署ETCD集群3、停止kube-apiserver/controller-manager/scheduler/kubelet/kube-proxy4、停止ETCD集群5、各ETCD节点恢复同一份备份数据6、启动各节点并验证ETCD集群7、启动kube-apiserver/controller-manager/scheduler/kubelet/kube-proxy8、验证k8s master状态及pod数据
coredns
CoreDNS 是一个灵活可扩展的 DNS 服务器,可以作为 Kubernetes 集群 DNS。 与 Kubernetes 一样,CoreDNS 项目由 CNCF 托管。
coredns插件配置
errors:错误信息标准输出。health:在CoreDNS的 http://localhost:8080/health 端口提供 CoreDNS 服务的健康报告。ready:监听8181端口,当coredns的插件都已就绪时,访问该接口会返回 200OK。kubernetes:CoreDNS 将基于 kubernetes service name进行 DNS 查询并返回查询记录给客户端.prometheus:CoreDNS 的度量指标数据以 Prometheus 的key-value的格式在http://localhost:9153/metrics URI上提供。forward: 不是Kubernetes 集群内的其它任何域名查询都将转发到 预定义的目的server,如 (/etc/resolv.conf或IP(如8.8.8.8)).cache:启用 service解析缓存,单位为秒。loop:检测域名解析是否有死循环,如coredns转发给内网DNS服务器,而内网DNS服务器又转发给coredns,如果发现解析是死循环,则强制中止 CoreDNS 进程(kubernetes会重建)。reload:检测corefile是否更改,在重新编辑configmap 配置后,默认2分钟后会优雅的自动加载。loadbalance:轮训DNS域名解析, 如果一个域名存在多个记录则轮训解析。
coredns域名解析pod优先从coredns查找可解析域名,如没有则转到powerdns查找,还找不到最后从223.6.6.6查找。
示例kubectl run net-test1 --image=centos:7.9.2009 sleep 360000
kubectl exec -it net-test1 bash
yum install net-tools bind-utils
nslookup kubernetes
k8s设计理念
API设计原则
- 所有API应该是声明式的。
- API对象是彼此互补而且可组合的。
- 高层API以操作意图为基础设计。
- 低层API根据高层API的控制需要设计。
- 尽量避免简单封装,不要有在外部API无法显式知道的内部隐藏的机制。
- API操作复杂度与对象数量成正比。
- API对象状态不能依赖于网络连接状态。
- 尽量避免让操作机制依赖于全局状态,因为在分布式系统中要保证全局状态的同步是非常困难的。
kubernetes 内置API及资源对象查看k8s api资源对象命令如下:curl --cacert /etc/kubernetes/ssl/ca.pem -H "Authorization: Bearer TOKEN" https://127.0.0.1:6443
资源对象类别简介
kubernetes 资源对象详解及示例
yaml详解
yaml文件:为了方便后期管理,通过使用yaml文件通过API管理资源对象。yaml必需字段:
- apiVersion - 创建该对象所使用的 Kubernetes API 的版本
- kind - 想要创建的对象的类型
- metadata - 定义识别对象唯一性的数据,包括一个 name 名称 、可选的 namespace
- spec:定义资源对象的详细规范信息(统一的label标签、容器名称、镜像、端口映射等) ##期望状态
- status(Pod创建完成后k8s自动生成status状态)##实际状态
pod简介
- pod是k8s中的最小单元。
- 一个pod中可以运行一个容器,也可以运行多个容器。多容器可以是不同的文件系统。
- 运行多个容器的话,这些容器是一起被调度的。
- Pod的生命周期是短暂的,不会自愈,是用完就销毁的实体。
- 一般我们是通过 Controller 来创建和管理 pod
示例:创建一个php/nginx多容器pod
其中php容器添加command语句是为了方式容器因自动关闭而报错
进入pod时如果有多容器,需要用-c指定想要进入的容器,不添加默认进入最先创建的容器
Job
Job 会创建一个或者多个 Pod,并将继续重试 Pod 的执行,直到指定数量的 Pod 成功终止。 随着 Pod 成功结束,Job 跟踪记录成功完成的 Pod 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pod。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。
创建一个job该job生成实时时间并输出到容器中/cache/data.log中,然后将/cache目录挂载到宿主机/tmp/jobdata中。
kubectl apply -f 1.job.yaml
如上图 job在worker01生成一个pod,因此容器中的/cahce/就被挂载到worker01的/tmp/jobdata
Cronjob
CronJob 创建基于时隔重复调度的 Job。CronJob 用于执行排期操作,例如备份、生成报告等。 一个 CronJob 对象就像 Unix 系统上的 crontab(cron table)文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。kubectl apply -f 2.cronjob.yaml
Replication Controller/ReplicaSet/Deployment
ReplicationController第一代副本控制器,确保在任何时候都有特定数量的 Pod 副本处于运行状态。 换句话说,ReplicationController 确保一个 Pod 或一组同类的 Pod 总是可用的。ReplicaSet第二代副本控制器,目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。与ReplicationController区别是其中selector 选项还支持in notin的用法。Deployments第三代副本控制器,目前最推荐使用。为 Pod 和 ReplicaSet 提供声明式的更新能力。你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。
创建Deployment的yaml
测试Deployment滚动更新特性,更改yaml中nginx镜像
重新执行yaml文件
从上面两图可以看出 deployment优先创建一个新镜像pod,等其running后创建第二个新pod时将第一个旧pod关闭,如此可以保证至少有2个pod正常运行,以保证服务稳定。
最后结果滚动替换pod成功。
deployment滚动更新机制Deployment 可确保在更新时仅关闭一定数量的 Pod。默认情况下,它确保至少所需 Pod 的 75% 处于运行状态(最大不可用比例为 25%)。
Deployment 还确保仅所创建 Pod 数量只可能比期望 Pod 数高一点点。 默认情况下,它可确保启动的 Pod 个数比期望个数最多多出 125%(最大峰值 25%)。例如,如果仔细查看上述 Deployment ,将看到它首先创建了一个新的 Pod,然后删除旧的 Pod, 并创建了新的 Pod。它不会杀死旧 Pod,直到有足够数量的新 Pod 已经出现。 在足够数量的旧 Pod 被杀死前并没有创建新 Pod。它确保至少 3 个 Pod 可用, 同时最多总共 4 个 Pod 可用。 当 Deployment 设置为 4 个副本时,Pod 的个数会介于 3 和 5 之间。
service
Kubernetes 中 Service 是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法。 它的一个关键目标是让你无需修改现有应用程序就能使用不熟悉的服务发现机制。 你可以在 Pod 中运行代码,无需顾虑这是为云原生世界设计的代码,还是为已容器化的老应用程序设计的代码。 你可以使用 Service 让一组 Pod 在网络上可用,让客户端能够与其交互。
ervice API 是 Kubernetes 的组成部分,它是一种抽象,帮助你通过网络暴露 Pod 组合。 每个 Service 对象定义一个逻辑组的端点(通常这些端点是 Pod)以及如何才能访问这些 Pod 的策略。
Service服务类型
Kubernetes ServiceTypes 允许指定你所需要的 Service 类型。
Type 的取值以及行为如下:
- ClusterIP:通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是你没有为服务显式指定 type 时使用的默认值。 你可以使用 Ingress 或者 Gateway API 向公众暴露服务。
- NodePort:通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 为了让节点端口可用,Kubernetes 设置了集群 IP 地址,这等同于你请求 type: ClusterIP 的服务。
- LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。
- ExternalName:通过返回 CNAME 记录和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理。
clusterIP集群模式
apiVersion: v1kind: Servicemetadata: name: ng-deploy-80spec: ports: - name: http port: 80 ##暴露给服务的端口 targetPort: 80 ##容器的端口 protocol: TCP type: ClusterIP ##指定服务类型为ClusterIP selector: ##标签选择器,必须指定pod资源本身的标签 app: ng-deploy-80
生成的svc如下,可以看到endpoints有两个ip,这是发现并加入了2个拥有app=ng-deploy-80相同标签的pod。
进入pod内部curl 集群ip 可以获取pod信息
nodeport方式
apiVersion: v1kind: Servicemetadata: name: ng-deploy-80spec: ports: - name: http port: 81 targetPort: 80 nodePort: 30012 #与cluster相比,增加了svc服务端口,该地址为集群外部访问内部pod时使用的端口。 protocol: TCP type: NodePort #svc改为nodeport方式 selector: app: ng-deploy-80
如图可见,由于selector匹配成功,svc绑定了两2个endpoint;同时暴露了宿主机外网端口30012,集群外可以通过访问宿主机30012端口,访问到svc的cluster ip,再由svc的endpoint找到后端pod ip,以达到访问pod内容的效果。
下图是将nodeip地址由haproxy代理,外网可以访问haproxy虚拟ip来访问到pod内容。
nodeport模式外网访问pod过程
外网(global)先通过防火墙访问slb,然后由slb将请求转到宿主机外网端口(node1,node2,node3),从而找到集群svc的clusterip,然后由svc根据自己的selector;将请求转给匹配的pod ip(endpoint),从而访问到pod。
volume存储卷
为了保证数据的持久性,必须保证数据在外部存储在docker容器中,为了实现数据的持久性存储,在宿主机和容器内做映射,可以保证在容器的生命周期结束,数据依旧可以实现持久性存储。但是在k8s中,由于pod分布在各个不同的节点之上,并不能实现不同节点之间持久性数据的共享,并且,在节点故障时,可能会导致数据的永久性丢失。为此,k8s就引入了外部存储卷的功能。
常用的几种卷:
- Secret:是一种包含少量敏感信息例如密码、令牌或密钥的对象
- configmap: 配置文件
- emptyDir:本地临时卷
- hostPath:本地存储卷
- nfs等:网络存储卷
emptyDir
一个emptyDir 第一次创建是在一个pod被指定到具体node的时候,并且会一直存在在pod的生命周期当中,正如它的名字一样,它初始化是一个空的目录,pod中的容器都可以读写这个目录,这个目录可以被挂在到各个容器相同或者不相同的的路径下。当一个pod因为任何原因被移除的时候,这些数据会被永久删除。注意:一个容器崩溃了不会导致数据的丢失,因为容器的崩溃并不移除pod.
emptyDir 磁盘的作用:(1)普通空间,基于磁盘的数据存储(2)作为从崩溃中恢复的备份点(3)存储那些那些需要长久保存的数据,例web服务中的数据
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deploymentspec: replicas: 1 selector: matchLabels: #rs or deployment app: ng-deploy-80 template: metadata: labels: app: ng-deploy-80 spec: containers: - name: ng-deploy-80 image: nginx ports: - containerPort: 80 volumeMounts: - mountPath: /cache #容器内部卷地址 name: cache-volume volumes: - name: cache-volume emptyDir: {}
在存储卷里创建1.txt文件
在pod所在宿主机可以找到该文件
删除pod后 宿主机该文件也消失了,证明emptydir无法持久保存数据。
hostPathhostPath宿主机路径,就是把pod所在的宿主机之上的脱离pod中的容器名称空间的之外的宿主机的文件系统的某一目录和pod建立关联关系,在pod删除时,存储数据不会丢失。
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deploymentspec: replicas: 1 selector: matchLabels: app: ng-deploy-80 template: metadata: labels: app: ng-deploy-80 spec: containers: - name: ng-deploy-80 image: nginx ports: - containerPort: 80 volumeMounts: - mountPath: /cache ##容器存储卷位置 name: cache-volume volumes: - name: cache-volume hostPath: path: /data/kubernetes #宿主机存储地址 对应容器存储
创建pod在容器中存储卷里写入文件,而后删除pod
在宿主机存储位置依然可以看到之前写入的文件,可见hostpath模式有数据持久化的能力。
nfs共享存储卷
nfs使的我们可以挂在已经存在的共享到的我们的Pod中,和emptyDir不同的是,emptyDir会被删除当我们的Pod被删除的时候,但是nfs不会被删除,仅仅是解除挂在状态而已,这就意味着NFS能够允许我们提前对数据进行处理,而且这些数据可以在Pod之间相互传递.并且,nfs可以同时被多个pod挂在并进行读写
注意:必须先报纸NFS服务器正常运行在我们进行挂在nfs的时候
(1)在harobr02节点上安装nfs,并配置nfs服务
apt install nfs-servercat /etc/exports/data/k8sdata 192.168.110.0/24(rw,no_root_squash)mkdir -p /data/k8asdata
搭建nfs存储yaml如下:
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deploymentspec: replicas: 1 selector: matchLabels: app: ng-deploy-80 template: metadata: labels: app: ng-deploy-80 spec: containers: - name: ng-deploy-80 image: nginx ports: - containerPort: 80 volumeMounts: - mountPath: /usr/share/nginx/html/mysite name: my-nfs-volume volumes: - name: my-nfs-volume nfs: server: 192.168.110.184 path: /data/k8sdata---apiVersion: v1kind: Servicemetadata: name: ng-deploy-80spec: ports: - name: http port: 81 targetPort: 80 nodePort: 30016 protocol: TCP type: NodePort selector: app: ng-deploy-80
创建yaml文件后,在nfs存储中创建1.txt文件
之后在任意node节点访问svc开放的30016端口。可以看到共享的文件1.txt
pv pvc
PersistentVolume(PV)是集群中已由管理员配置的一段网络存储。 集群中的资源就像一个节点是一个集群资源。 PV是诸如卷之类的卷插件,但是具有独立于使用PV的任何单个pod的生命周期。 该API对象捕获存储的实现细节,即NFS,iSCSI或云提供商特定的存储系统。
PersistentVolumeClaim(PVC)是用户存储的请求。PVC的使用逻辑:在pod中定义一个存储卷(该存储卷类型为PVC),定义的时候直接指定大小,pvc必须与对应的pv建立关系,pvc会根据定义去pv申请,而pv是由存储空间创建出来的。pv和pvc是kubernetes抽象出来的一种存储资源。
虽然PersistentVolumeClaims允许用户使用抽象存储资源,但是常见的需求是,用户需要根据不同的需求去创建PV,用于不同的场景。而此时需要集群管理员提供不同需求的PV,而不仅仅是PV的大小和访问模式,但又不需要用户了解这些卷的实现细节。 对于这样的需求,此时可以采用StorageClass资源。这个在前面就已经提到过此方案。
PV是集群中的资源。 PVC是对这些资源的请求,也是对资源的索赔检查。 PV和PVC之间的相互作用遵循这个生命周期:
Provisioning(配置)---> Binding(绑定)--->Using(使用)---> Releasing(释放) ---> Recycling(回收)
Provisioning这里有两种PV的提供方式:静态或者动态
静态-->直接固定存储空间: 集群管理员创建一些 PV。它们携带可供集群用户使用的真实存储的详细信息。 它们存在于Kubernetes API中,可用于消费。
动态-->通过存储类进行动态创建存储空间: 当管理员创建的静态 PV 都不匹配用户的 PVC 时,集群可能会尝试动态地为 PVC 配置卷。此配置基于 StorageClasses:PVC 必须请求存储类,并且管理员必须已创建并配置该类才能进行动态配置。 要求该类的声明有效地为自己禁用动态配置。
Binding在动态配置的情况下,用户创建或已经创建了具有特定数量的存储请求和特定访问模式的PersistentVolumeClaim。 主机中的控制回路监视新的PVC,找到匹配的PV(如果可能),并将 PVC 和 PV 绑定在一起。 如果为新的PVC动态配置PV,则循环将始终将该PV绑定到PVC。 否则,用户总是至少得到他们要求的内容,但是卷可能超出了要求。 一旦绑定,PersistentVolumeClaim绑定是排他的,不管用于绑定它们的模式。
如果匹配的卷不存在,PVC将保持无限期。 随着匹配卷变得可用,PVC将被绑定。 例如,提供许多50Gi PV的集群将不匹配要求100Gi的PVC。 当集群中添加100Gi PV时,可以绑定PVC。
UsingPod使用PVC作为卷。 集群检查声明以找到绑定的卷并挂载该卷的卷。 对于支持多种访问模式的卷,用户在将其声明用作pod中的卷时指定所需的模式。一旦用户有声明并且该声明被绑定,绑定的PV属于用户,只要他们需要它。 用户通过在其Pod的卷块中包含PersistentVolumeClaim来安排Pods并访问其声明的PV。
Releasing当用户完成卷时,他们可以从允许资源回收的API中删除PVC对象。 当声明被删除时,卷被认为是“释放的”,但是它还不能用于另一个声明。 以前的索赔人的数据仍然保留在必须根据政策处理的卷上.
ReclaimingPersistentVolume的回收策略告诉集群在释放其声明后,该卷应该如何处理。 目前,卷可以是保留,回收或删除。 保留可以手动回收资源。 对于那些支持它的卷插件,删除将从Kubernetes中删除PersistentVolume对象,以及删除外部基础架构(如AWS EBS,GCE PD,Azure Disk或Cinder卷)中关联的存储资产。 动态配置的卷始终被删除
Recycling如果受适当的卷插件支持,回收将对卷执行基本的擦除(rm -rf / thevolume / *),并使其再次可用于新的声明。
PersistentVolume参数:kubectl explain PersistentVolume
Capacity: #当前PV空间大小,kubectl explain PersistentVolume.spec.capacityaccessModes :访问模式,#kubectl explain PersistentVolume.spec.accessModes
- ReadWriteOnce – PV只能被单个节点以读写权限挂载,RWO
- ReadOnlyMany – PV以可以被多个节点挂载但是权限是只读的,ROX
- ReadWriteMany – PV可以被多个节点是读写方式挂载使用,RWXpersistentVolumeReclaimPolicy #删除机制即删除存储卷卷时候,已经创建好的存储卷由以下删除操作:
kubectl explain PersistentVolume.spec.persistentVolumeReclaimPolicy
Retain – 删除PV后保持原装,最后需要管理员手动删除Recycle – 空间回收,及删除存储卷上的所有数据(包括目录和隐藏文件),目前仅支持NFS和hostPathDelete – 自动删除存储卷
volumeMode #卷类型,kubectl explain PersistentVolume.spec.volumeMode定义存储卷使用的文件系统是块设备还是文件系统,默认为文件系统mountOptions #附加的挂载选项列表,实现更精细的权限控制ro等
PersistentVolumeClaim创建参数:
accessModes:PVC 访问模式,#kubectl explain PersistentVolumeClaim.spec.volumeMode- ReadWriteOnce – PVC只能被单个节点以读写权限挂载,RWO- ReadOnlyMany – PVC以可以被多个节点挂载但是权限是只读的,ROX- ReadWriteMany – PVC可以被多个节点是读写方式挂载使用,RWXresources: #定义PVC创建存储卷的空间大小selector: #标签选择器,选择要绑定的PVmatchLabels #匹配标签名称matchExpressions #基于正则表达式匹配volumeName #要绑定的PV名称volumeMode #卷类型定义PVC使用的文件系统是块设备还是文件系统,默认为文件系统
Volume-存储卷类型static:静态存储卷 ,需要在使用前手动创建PV、然后创建PVC并绑定到PV,然后挂载至pod使用,适用于PV和PVC相对比较固定的业务场景。dynamin:动态存储卷,先创建一个存储类storageclass,后期pod在使用PVC的时候可以通过存储类动态创建PVC,适用于有状态服务集群如MySQL一主多从、zookeeper集群等。
Volume静态存储卷示例创建pv
apiVersion: v1kind: PersistentVolumemetadata: name: myserver-myapp-static-pv namespace: myserverspec: capacity: storage: 10Gi accessModes: - ReadWriteOnce nfs: path: /data/k8sdata/myserver/myappdata server: 192.168.110.184 #存储地址
创建pvc
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: myserver-myapp-static-pvc namespace: myserverspec: volumeName: myserver-myapp-static-pv accessModes: - ReadWriteOnce resources: requests: storage: 10Gi
创建pod和svc
kind: Deployment#apiVersion: extensions/v1beta1apiVersion: apps/v1metadata: labels: app: myserver-myapp name: myserver-myapp-deployment-name namespace: myserverspec: replicas: 1 selector: matchLabels: app: myserver-myapp-frontend template: metadata: labels: app: myserver-myapp-frontend spec: containers: - name: myserver-myapp-container image: nginx:1.20.0 #imagePullPolicy: Always volumeMounts: - mountPath: "/usr/share/nginx/html/statics" name: statics-datadir volumes: - name: statics-datadir persistentVolumeClaim: claimName: myserver-myapp-static-pvc ---kind: ServiceapiVersion: v1metadata: labels: app: myserver-myapp-service name: myserver-myapp-service-name namespace: myserverspec: type: NodePort ports: - name: http port: 80 targetPort: 80 nodePort: 30080 selector: app: myserver-myapp-frontend
执行创建命令
kubectl apply -f 1-myapp-persistentvolume.yaml kubectl apply -f 2-myapp-persistentvolumeclaim.yaml kubectl apply -f 3-myapp-webserver.yaml
查看pv与pvc绑定状态
可以看到pv已经和pvc绑定查看svc和pod状态
修改haproxy 后端端口为30080 ,访问成功
Volume动态存储卷 StorageClass
在pv和pvc使用过程中存在的问题,在pvc申请存储空间时,未必就有现成的pv符合pvc申请的需求,上面nfs在做pvc可以成功的因素是因为我们做了指定的需求处理。那么当PVC申请的存储空间不一定有满足PVC要求的PV事,又该如何处理呢?为此,Kubernetes为管理员提供了描述存储"class(类)"的方法(StorageClass)。举个例子,在存储系统中划分一个1TB的存储空间提供给Kubernetes使用,当用户需要一个10G的PVC时,会立即通过restful发送请求,从而让存储空间创建一个10G的image,之后在我们的集群中定义成10G的PV供给给当前的PVC作为挂载使用。在此之前我们的存储系统必须支持restful接口,比如ceph分布式存储,而glusterfs则需要借助第三方接口完成这样的请求。如图:
使用示例:1 创建rbac
apiVersion: v1kind: Namespacemetadata: name: nfs---apiVersion: v1kind: ServiceAccountmetadata: name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: nfs---kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: nfs-client-provisioner-runnerrules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "update", "patch"]---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: run-nfs-client-provisionersubjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: nfsroleRef: kind: ClusterRole name: nfs-client-provisioner-runner apiGroup: rbac.authorization.k8s.io---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: nfsrules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"]---kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: nfssubjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: nfsroleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io
2 创建存储类 用于自动创建pv
apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: managed-nfs-storage annotations: storageclass.kubernetes.io/is-default-class: "true" #将该类设定为默认类,之后创建pvc后会自动创建pv匹配provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment"s env PROVISIONER_NAME"reclaimPolicy: Retain #PV的删除策略,默认为delete,删除PV后立即删除NFS server的数据mountOptions: #- vers=4.1 #containerd有部分参数异常 #- noresvport #告知NFS客户端在重新建立网络连接时,使用新的传输控制协议源端口 - noatime #访问文件时不更新文件inode中的时间戳,高并发环境可提高性能parameters: #mountOptions: "vers=4.1,noresvport,noatime" archiveOnDelete: "true" #删除pod时保留pod数据,默认为false时为不保留数据
3 创建deployment (pod)
apiVersion: apps/v1kind: Deploymentmetadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: nfsspec: replicas: 1 strategy: #部署策略 type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner #image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 image: registry.cn-qingdao.aliyuncs.com/zhangshijie/nfs-subdir-external-provisioner:v4.0.2 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: k8s-sigs.io/nfs-subdir-external-provisioner - name: NFS_SERVER value: 192.168.110.184 - name: NFS_PATH value: /data/volumes volumes: - name: nfs-client-root nfs: server: 192.168.110.184 path: /data/volumes
4 创建绑定类的pvc
kind: PersistentVolumeClaimapiVersion: v1metadata: name: myserver-myapp-dynamic-pvc namespace: myserverspec: storageClassName: managed-nfs-storage #调用的storageclass 名称 accessModes: - ReadWriteMany #访问权限 resources: requests: storage: 500Mi #空间大小
5创建svc
kind: Deployment#apiVersion: extensions/v1beta1apiVersion: apps/v1metadata: labels: app: myserver-myapp name: myserver-myapp-deployment-name namespace: myserverspec: replicas: 1 selector: matchLabels: app: myserver-myapp-frontend template: metadata: labels: app: myserver-myapp-frontend spec: containers: - name: myserver-myapp-container image: nginx:1.20.0 #imagePullPolicy: Always volumeMounts: - mountPath: "/usr/share/nginx/html/statics" name: statics-datadir volumes: - name: statics-datadir persistentVolumeClaim: claimName: myserver-myapp-dynamic-pvc ---kind: ServiceapiVersion: v1metadata: labels: app: myserver-myapp-service name: myserver-myapp-service-name namespace: myserverspec: type: NodePort ports: - name: http port: 80 targetPort: 80 nodePort: 30080 selector: app: myserver-myapp-frontend
在nfs服务器上创建/data/volumes目录 用于存储
查看创建的pv pvc pod
上图看可以看到 为匹配pvc由storageclass 两个自动创建的pv
pvc已经绑定
访问负载均衡入口 成功
关键词:
云原生第三周--kubernetes组件详解|每日播报
记录--9个封装Vue组件的小技巧 每日讯息
CH32内部参考电压的使用-即时焦点
全球头条:【金融街发布】外汇局:一季度货物贸易顺差处于历史同期较高水平
每日精选:专访|田耳:文学或有江湖,写作难以停歇
饭一定要吃七分饱才健康?新研究推翻传统观念 全球热闻
全球简讯:欧洲人最爱!蔚来ET5旅行版实车亮相:真心优雅
当前要闻:环保人士赢了?大众董事长演讲被蛋糕袭击 官方回应:新能源车保护环境吗?
环球视讯!只做了2年 日本家电巨头巴慕达退出手机市场:价格比iPhone还贵
北方今年首轮高温来袭:14日起多地冲击35℃高温
世界观速讯丨促进消费潜能释放 4月份汽车市场产销量同比快速增长
手写Promise教程_then方法|今日热门
Json序列化对象后,使用Lombok后属性xAxis大写变成小写xaxis解决方法-天天时讯
微软本周不会为 Win11 Canary 或 Dev 频道发布新版本|精选
重庆未来三年将实施水利项目超1800个 环球短讯
跑分最高的安卓旗舰!已有1000多人下单iQOO Neo8系列|天天快看
NVIDIA一代神卡RTX 3060 Ti要停产了:清完库存即止
惊了!女网红用AI同时交往1000多个“男友” 年入4亿?-世界实时
电脑也能秒开3A大作!Win11或将引入Xbox Quick Resume功能-全球消息
世界速看:女大学生坐高铁拒绝补票刁难乘务长 后排乘客理论遭辱骂
团结就是力量合唱动作编排视频_团结就是力量合唱动作 焦点快报
如何注册appuploader账号
【申请教程】ChatGPT访问互联网插件-焦点信息
夺冠秘诀?华为软件精英挑战赛两届冠军这样复盘比赛经验
当前速讯:没关系,前端还死不了
Java设计模式【单例模式】 当前速读
【新华500】新华500指数(989001)12日收跌1.31%_每日消息
辅助工具管理器_辅助工具管理器-焦点关注
东莞一锂电池厂深夜大火:照亮整个天空 无人伤亡
部分男厕改女厕引不满 四川大学再回应:进一步完善优化
汶川地震15周年 微信地震预警功能四川上线:秒级预警
世界今热点:《庆余年2》海报疑似抄袭 海报设计公司致歉
别说“刹车失灵”了!特斯拉回应大规模召回:降低交通事故概率
环球热文:PTP主时钟(时间同步装置)是怎样实现时钟同步的?
MSCI中国指数季度调整出炉 新纳入53只标的|全球速看料
【天天热闻】4月MPV销量排名出炉 别克GL8大战腾势D9 受伤的是五菱宏光
0糖0脂 清新甜润:平仄青柑乌龙茶12瓶39元
自研半固态技术!蔚来1000公里续航车型申报:比宁王麒麟电池还猛 世界热头条
特斯拉FSD再不来真没机会了 比亚迪出手:智能驾驶年内上车 每日快报
榴莲涨到39.9元/斤 网友直呼吃不起 盒马回应:货源少了
袋鼠云产品功能更新报告05期|应有尽“优”,数栈一大波功能优化升级!
环球快报:易基因:DNA甲基化和转录组分析揭示野生草莓干旱胁迫分子调控机制|植物抗逆
今日讯!NES 系统架构
环球热资讯!被任天堂拉黑媒体发声:有人给《塞尔达传说:王国之泪》打6分很好
世界今日报丨法拉第晒财报 贾跃亭真成了!FF:已生产40辆FF91 百万豪车买不买?
三次输错密码后,系统是怎么做到不让我继续尝试的?|全球短讯
在C#中使用默认值初始化字符串数组的3种方式
世界热头条丨OPPO终止ZEKU芯片业务:这是一个艰难的决定!
天天看热讯:OPPO终止自研芯片业务!小米王化:确实不容易
哪吒汽车CEO:电吸门是脑残无用设计 出门基本不动手的人才用-当前速看
又菜又爱玩 加塞不成一路别车:结局笑出了声!|最新资讯
天天视点!签约保底要400万?孟羽童回应董明珠给百万年薪:在格力月薪没过万 工作21小时
环球头条:开源.NetCore通用工具库Xmtool使用连载 - 随机值篇
JDK8 新特性之新的日期&时间API,一篇讲清楚!
智能化生产应用搭建的实战案例 世界微头条
精彩看点:echarts的散点图和中国地图配合使用
【经验分享】最新Microsoft Edge Dev游览器游览Flash网页的办法_今日聚焦
iPhone/iPad全系可用:闪魔MFi苹果认证线21.8元大促 世界简讯
4月轿车销量排名出炉 燃油车新能源“混战” 好戏即将开场
环球时讯:某日系车一把手摊牌了:现在最害怕比亚迪
格局有了!SteamDeck官方庆祝ROG Ally开卖
精彩看点:深圳某公司母亲节放假3天不调休:和妈妈度过完整的母亲节
驾特斯拉遭遇车祸后 林志颖现身珠海首次参加赛车比赛:状态良好
战斗力爆表!无人机航拍时被鹰叼走:画面剧烈晃动
高通骁龙8 Gen2下放!一加Ace2 Pro曝光
曾盛赞比亚迪股票的巴菲特又减持了!本人回应:不想跟马斯克的特斯拉竞争
不止安装失败!Win11 KB5026372更新出现诸多问题 天天观天下
当前短讯!【转】为什么 TCP 建立连接需要三次握手
快看:Linux驱动开发笔记(三):基于ubuntu的helloworld驱动源码编写、makefile编写以及驱动编译加载流程测试
Java设计模式-适配器模式
“原神玩家”和“塞尔达玩家”打起来了?不过是恶臭互联网的又一次狂欢_世界新消息
别了机械硬盘?全固态玩家转向了当“垃圾佬”
全系2.0T+8AT比BBA香多了!新款林肯冒险家上市:24.58万起
环球即时看!最大96GB内存不是梦!笔记本将迎来单条48GB DDR5内存
7499元 华硕天选4R游戏本上架:锐龙7-7735H、165Hz高刷
取代C++!微软改用Rust语言重写的Win11内核:正式来了
中药成香饽饽! “药茅”片仔癀20年涨价18次 专家称没病别跟风买_全球快资讯
多省加入封杀行列!老头乐销冠雷丁汽车申请破产 创始人被曝身居海外
SSD能有多便宜:2TB新品不到700元!长江存储232层原片颗粒加持
全球微资讯!Windows7 上运行docker实战
4月份以来17家银行下调存款利率 有望助推债市继续走牛 聚焦
美债上限谈判无进展 债务违约风险加大-环球速讯
沙特等减产石油 美国被逼补库存:印度捡漏俄油占大便宜 2022年省下50亿美元
当前资讯!国内第一!深圳要打造5G-A之城 全市5G网速平均必500Mbps 上行下载更狠
焦点热议:1000W用户1Wqps高并发签到系统的架构和实操
学系统集成项目管理工程师(中项)系列21a_整体管理(上)
长沙霸占车位车主致歉 栏杆拆除:双方均再次道歉 从没想会被网暴-环球今亮点
众望所归!马斯克宣布卸任推特CEO:神秘女子将接班
狗狗失踪7年后回家 主人煮饺子庆团圆:网友感慨万物皆有灵
IGN 10分新神作!《塞尔达传说:王国之泪》港服日服已正式解锁
热消息:刘强东真兄弟!20年投入员工福利近500亿、建设公寓2.5万套
【天天播资讯】百度的“New Bing”终于来了!但别高兴得太早
全球看热讯:苹果年度跳水王!M2版Mac mini降到3399元了:不用领券
当前动态:Python学习之二:不同数据库相同表是否相同的比较方法
中芯国际人事再变动 刘训峰担任副董事长:基本年薪334万元 世界信息
性能逼近PS5 ROG掌机正式发布:首发锐龙Z1处理器 畅玩3A大作-天天观速讯
两个妈妈!英国首批三亲婴儿诞生:体内有三个人的DNA
[Linux] 如何查看Centos用户登陆记录?[转载]_全球即时
今日热讯:【财经分析】REITs二级市场止跌回稳 机构看好高速板块后续表现
5月26日上映!迪士尼《小美人鱼》内地版配唱阵容官宣:黄绮珊领衔 短讯