1、常用命令

//查看所有ns下的cr: 
kubectl get application --all-namespaces

//切换到指定的ns
kubens <namespace-name>

//删除优雅退出失败的terminating的pod
kubectl delete pods <pod> --grace-period=0 --force

//查看pod日志的最后10行
kubectl logs <podname> -n <ns> --tail=10


//更新镜像
kubectl set image deployment <dploy-name> <容器名>=<image-name>

//输出yaml文件到本地
kubectl get deploy <deploy-name> -o yaml > <file-name>

//持续观察
kubectl get pod <pod-name> -w

//查看端口占用
netstat -anp | grep 8080

//scale
kubectl scale --replicas=3 deploy <deployment-name>

//重启deployment
kubectl rollout restart deploy <deployment-name>

// 查看历史版本
kubectl rollout history deploy <deployment-name>

//回滚到历史版本3
kubectl rollout undo daemonset/abc --to-revision=3

//统计数目
kubectl get app -A | wc -l

//创建clusterrolebinding
kubectl create clusterrolebinding vela-core-clusterrolebinding --clusterrole=cluster-admin --user=vela-core

//vi查找关键字
进入vi中,先按下"ESC"跳转成命令输入模式;
输入斜杠“/”,这时屏幕会跳转到底部,输入栏出现"/";
输入你需要查找的关键字,回车;
如果要继续查找关键字,输入n;
向前查找,输入N(大写);

2、CRD.yaml编写

(1)CRD的type:integer类型--reconcile的int类型;

(2)CRD的format:float64 type:number类型--reconcile的float64类型;

(3)CRD的type: object  x-kubernetes-preserve-unknown-fields: true类型--map[string]interface{}类型

// +kubebuilder:pruning:PreserveUnknownFields
CompStatus runtime.RawExtension `json:"compStatus,omitempty"`

对于map类型的CRUD,可以使用gjson和sjson进行操作,

参考链接:k8s之CRD定义map[string]interface{}类型_fourierr的博客-CSDN博客

3、k8s错误事件

1、back-off restarting failed container
// 说明pod启动成功后又退出了,一般是容器里没有能持续运行的常驻进程。

4、return ctrl.Result{},err 时如果err不为空则表示reconcile error,会打印堆栈信息,如果是自定义错误返回,则会打印出日志打印的堆栈

github.com/go-logr/zapr.(*zapLogger).Error
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler    
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker
k8s.io/apimachinery/pkg/util/wait.BackoffUntil.func1
k8s.io/apimachinery/pkg/util/wait.BackoffUntil
k8s.io/apimachinery/pkg/util/wait.JitterUntil
k8s.io/apimachinery/pkg/util/wait.Until

ResourceQuota 用来限制 namespace 中所有的 Pod 占用的总的资源 request 和 limit。
LimitRange 用来限制 namespace 中 单个Pod 默认资源 request 和 limit

4、port、targetPort、nodePort

targetPort是pod上的端口;

port是service暴露在cluster ip上的端口,<cluster ip>:port 是提供给集群内部访问service的入口;

nodePort是提供给集群外部访问service的一种方式;

5、PV、PVC、StorageClass

PV是用来定义一个存储卷的;
PV是用来描述或定义一个存储卷的;
StorageClass作用是创建PV模板,用户提交PVC指定StorageClass,对用的sc则会为其自动创建PV并进行绑定

6、serviceAccount

Kubernetes 内部的账号系统有 User、Group、ServiceAccount,当我们通过 RBAC 授权获得资源权限之后,其实这 3 个资源的权限能力是一样的。因为使用场景的不同,针对人的权限一般会提供 User、Group 对象;当面对 Pod 之间或外部系统服务对 Kubernetes API 的调用一般会采用 ServiceAccount。

7、k8s的命名要求必须小写字母开头,且只能包含字母、数字、减号

8、k8s调度成功->pending,这时候会执行pod绑定到节点、拉取镜像等;
pod里的容器进程都启动成功->running,至少一个容器在运行或重启。

9、pod内存占用超过80%,就有OOMKill和被驱逐的风险

10、kubevela主要是把workload和trait都抽象成crd,application统一管理这些crd,实现traid和workload解耦,可扩展性更强,一键式混合环境部署。

11、 Scheme用于提供GVK与对应Go types 的映射关系,每一种Controller都需要一个scheme

12、k8s event事件默认1小时自动删除;

13、DiscoveryClient发现客户端用于获取Resource资源组、Version版本等信息;

15、Terraform能在任意的基础设施上管理维护任意资源,是HashCorp公司开源的,比如针对AWS,我们可以用它创建,修改,删除S3 Bucket等各种资源,同时可以通过自定义terraform Provider来支持新的基础设施,provider其实也是对crud和import的 rest api的一层抽象,有点类似于CNI,CSI这种。

16、不应该在一个reconciler逻辑中进行两次资源的update(update status除外),否则会引发版本不一致的报错

17、FluxCD,GitOps——使用Git去管理Kubernetes集群:在GitOps中,一旦Git仓库中的代码被更改,CI/CD Pipeline也就会对Kubernetes集群进行更改,同时也应用了Kubernetes控制循环的思想,用Git管理的Kubernetes集群的期望状态也会和Git仓库中的实时状态不断地进行比较。

18、云原生三大开源项目OAM/KubeVelaOCM 、OpenKruise(Kubernetes 的扩展,CloneSet、UnitedDeployment、AdvancedStatefulSet)

19、metadata.generation是版本迭代的概念,表示这个资源的spec被修改了多少次,每次spec的修改generation都会增长1,而status.observedGeneration就是最近观察到的可用的版本迭代。

对于deployment而言,spec和anno的变化都能引起generation的变化;

对于cr而言,spec的变化能引起generation的变化;

20、配置漂移(Infrastructure/Configuration Drift)即当用户声明的应用部署计划和生产环境实际运行的实例状态发生不一致。

21、Finalizers是一种删除拦截机制,能够实现删除前回调Pre-delete,比如资源a种创建了外部资源b,希望在删除该资源a的同时级联删除关联的外部资源。也就是说删除存在Finalizers字段的资源时,不会立即删除该资源,而是会首先设置deletionTimestamp值,deletionTimestamp值被设置后该资源就只能等待被删除而不能进行其他操作,同时负责watch该对象的控制器会删除级联的资源,然后再更新清除对应的资源的对应的Finalizer值,之后apiserver会自动将该对象删除。

22、ControllerRevision主要用来保存历史版本信息,每一个ControllerRevision对应了资源的一个版本,通过ControllerRevision,控制器能够管理资源的不同版本,并进行更新以及回滚操作。
对于资源的更新操作,会先查看有没有对应的ControllerRevision,如果没有说明资源已经更新过,Controller就会创建一个新版本的ControllerRevision及一个新的 ControllerRevision hash 版本号。

24、kubectl create时会自动添加注解kubectl.kubernetes.io/last-applied-configuration,同时,kubectl apply命令会通过比较配置文件与last-applied-configuration注解的内容,计算删除、增加、重新设置的字段

25、apiservice是k8s的第二种扩展机制,原理是apiserver其实由两个组件组成,一个是aggregator是一个web代理服务器,另一个才是真正的apiserver即https服务器,kubectl的请求首先到达aggregator,由aggregator根据请求的GVK将请求路由至apiserver。apiservice就是在aggregator中注册自定义资源的路由信息,然后路由的自定义的svc和deploy进行处理。

26、就绪探针:把检查失败(是否ready)的pod从service的endpoint中摘掉,不杀死pod;
存活探针:把检查失败(是否running)的pod杀死,启动新的pod;

参考:k8s-Pod状态和探针_LK丶旋律的博客-CSDN博客_k8s 监控pod状态

27、pod状态

Error: #pod 启动过程中发生错误
NodeLost: #Pod 所在节点失联
Unkown: #Pod 所在节点失联或其它未知异常
Waiting: #Pod 等待启动
Pending: #Pod 等待被调度
Terminating: #Pod 正在被销毁
CrashLoopBackOff:#pod,但是kubelet正在将它重启
InvalidImageName:#node节点无法解析镜像名称导致的镜像无法下载
ImageInspectError:#无法校验镜像,镜像不完整导致
ErrImageNeverPull:#策略禁止拉取镜像,镜像中心权限是私有等
ImagePullBackOff:#镜像拉取失败,但是正在重新拉取
RegistryUnavailable:#镜像服务器不可用,网络原因或harbor宕机
ErrImagePull:#镜像拉取出错,超时或下载被强制终止
CreateContainerConfigError:#不能创建kubelet使用的容器配置
CreateContainerError:#创建容器失败
PreStartContainer: #执行preStart hook报错,Pod hook(钩子)是由 Kubernetes 管理的 kubelet 发
起的,当容器中的进程启动前或者容器中的进程终止之前运行,比如容器创建完成后里面的服务启动之前可以检查一下
依赖的其它服务是否启动,或者容器退出之前可以把容器中的服务先通过命令停止。
PostStartHookError:#执行 postStart hook 报错
RunContainerError:#pod运行失败,容器中没有初始化PID为1的守护进程等
ContainersNotInitialized:#pod没有初始化完毕
ContainersNotReady:#pod没有准备完毕
ContainerCreating:#pod正在创建中
PodInitializing:#pod正在初始化中
DockerDaemonNotReady:#node节点docker服务没有启动
NetworkPluginNotReady:#网络插件还没有完全启动

28、StatefulSet与ControllerRevision 

        StatefulSet Controller 直接管理下属的 Pod,并通过 Pod 上的一个 Label 来表示版本。
ControllerRevision能方便地管理不同版本的Pod template 模板,每一个版本的 Template对应一个 ControllerRevision ,也对应一个 ControllerRevision hash,其实在 Pod label 上的 ControllerRevision hash,就是 ControllerRevision 的名字。

29、GenericEvent

GenericEvent指未知类型的事件,包括非集群内资源事件或外部请求触发的事件Webhook等,一般不会使用。

30、Deployment中pod创建的流程

Deployment中pod创建的流程
1、apiserver收到创建deployment的请求,存储至etcd,告知controller-manager
2、controller-manager创建pod的壳子,打上creationTimeStamp,发送请求到apiserver
3、apiserver收到创建pod的请求,发送至etcd,推送到scheduler。
4、schduler选择node,填充nodeName,向apiserver更新pod信息。此时pod处于pending状态,pod也没有真正创建。
5、apiserver向etcd更新pod信息,同时推送到相应节点的kubelet
6、kubelet创建pod,填充HostIP与resourceVersion,向apiserver发送更新请求,pod处于pending状态
7、apiserver更新pod信息至etcd,同时kubelet继续创建pod。等到容器都处于running状态,kubelet再次发送pod的更新请求给apiserver,此时pod running
8、apiserver收到请求,更新到etcd中,并推送到informer中,informer记录下watchPhase

31、k8s版本迭代Generation

(1)metadata.generation由k8s client写,对资源的spec每次修改都会使其增长1;
(2)status.observedGeneration需要在status.patch()时手动赋值;
即if app.Status.ObservedGeneration != app.Generation { app.Status.ObservedGeneration = app.Generation}
(3)通过判断metadata.generation==status.observedGeneration可以得到是否是本次更新的状态;

metadata.generation是只有spec变化才会变化;

metadata.resourceVersion是只要yaml变化就会变化;

32、RateLimitingQueue

优先级队列PriorityQueue:出队时,最高优先级的元素最先出队,实现是heap(完全二叉树);
延迟队列DelayingQueue:延时阻塞出队,实现是PriorityQueue+waitingLoop;
限速队列RateLimitingQueue:实现是令牌桶+DelayingQueue+PriorityQueue;

33、BookMark

前提:因为client的watch有filter机制,如果是客户端不关心的事件,那么client的resourceverseion不会更新;
考虑这种例子:
如果client的resourceVersion=1,然后服务器的resourceVersion变为10(2-10为client过滤掉的事件),这时候watch断开了连接,在重新连接后client的resourceVersion=1,但是服务端最旧的resourceVersion=5,client就必须清理缓存重新listAndWatch,这会花费大量时间;
通过bookmark,服务端会将每次的resourceVersion变更作为bookmark事件告知client,且只会告知resourceVersion的变更不会告知具体内容,这样将list次数降低到了原来的3%。

34、runtime.Object

runtime.Object接口有GetObjectKind和DeepCopyObject两个方法;

35、Scheme和RestMapper

GVK和资源go type的对应关系,资源的默认值函数,资源版本转换函数,资源的标签转换等等全部由 schema 维护,源码目录"kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/scheme.go"

其中,包含 map 类型的 gvkToType 属性来维护 GVK 和 model 对象类型的关系。
包含 map 类型的 typeToGVK 属性来维护 model 对象类型和 GVK 的关系。
包含 map 类型的 defaulterFuncs 属性维护 model 对象类型和默认值函数的关系。
包含 conversion.Converter 指针类型的 converter 属性实现资源不同版本的转化。
map 类型的 fieldLabelConversionFuncs 属性维护 GVK label 标签转换函数的关系。
包含 string 类型的 schemaName 属性用来定义 schema 的名称。

同时一般通过schemabuilder 对象用以完成资源在 schema 中的注册。

RestMapper:go types 和 k8s api的对印关系由 restmapper维护;

36、crd-controller开发

可基于k8s/sample-controller开发controller,在没有kubebuiler时:

(1)修改sample-controller为app-controller

(2)生成 clientset listers informers deepcopy

        go mod vendor

        ./hack/update-codegen.sh

(3)修改reconcile逻辑

(4)生成crd

        获取controller-tools的代码并执行

        go install ./cmd/{controller-gen,type-scaffold}

        controller-gen crd paths=./... output:crd:dir=artifacts/crds

37、command和args

ENTRYPOINT 正统的定义容器启动以后的执行体,是容器的入口,对应pod的command
CMD 容器启动以后,默认的执行的命令,对应pod的args

38、--v=8

 kubectl get deploy -n fourier01 --v=8   显示接口的详细信息;

39、operator的开发

编写operator主要有kubebuilder和operator-sdk两种方式,kubebuilder是基于golang进行编写,operator-sdk是基于golang或helm或ansible进行编写; 不论是kubebuilder还是operator-sdk都是在controller-runtime 基础上做了一层封装。

40、resources为空

当设置limits而没有设置requests时,默认令requests等于limits;

resources为空时即limit为0,表示内存和cpu无限制;

41、k8s在apiserver中的数据访问层和service服务层

资源的数据访问层,即访问etcd,源码目录k8s.io/apiserver/pkg/storage/interfaces.go
etcd是一个典型的分布式 kv 数据库,提供存储,查询,更新,监控对象变化的 watch 等操作
包括接口以及相关的 etcd3 数据访问层实现,支持 dry run 的数据访问层实现。

资源的服务层
kubernetes 在服务层上定义分为两大类,一类是增删改查类接口,定义增删改查 watch 等操作。另一类是操作的策略类型接口,用来定义资源在增删改查等不同操作中的逻辑。

增删改查类接口源码目录"staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go"
增删改查类实现源码目录"k8s.io/apiserver/pkg/registry/generic/registry/store.go"
registry.store.Store 结构体实现了增删改查类型接口定义的函数。

策略类接口源码目录"k8s.io/apiserver/pkg/registry/rest/create.go"
一般资源的操作策略类实现源码目录在"kubernetes/pkg/registry/{group}/{kind}/strategy.go中"

42、k8s的资源api类型

43、etcd随笔

etcd 是分布式键值存储数据库,etcd 主要提供以下四个能力:

1、提供存储以及获取数据的接口,它通过协议保证 etcd 集群中的多个节点数据的强一致性。
2、提供监听机制,客户端可以监听某个key或者某些key的变更,用于监听和推送变更(v2和v3的机制不同)。
3、提供key的过期以及续约机制,客户端通过定时刷新来实现续约,用于集群监控以及服务注册发现(v2和v3的实现机制也不一样)。
4、提供原子的CAS(Compare-and-Swap)和 CAD(Compare-and-Delete)乐观锁的支持,用于分布式锁以及leader选举(v2通过接口参数实现,v3通过批量事务实现)。

etcd 存储层包含预写日志 (WAL,write ahead log) 模块、快照 (Snapshot) 模块、boltdb 模块。
其中 WAL 记录了数据变化的全过程并可保障 etcd crash 后数据不丢失,boltdb 则保存了集群元数据和用户写入的数据。
Snapshot (快照)文件则存储了某一时刻 etcd 的所有数据,默认设置为每 10000 条记录做一次快照,经过快照后 WAL 文件即可删除。
同时,etcd 是典型的读多写少存储,在我们实际业务场景中,读一般占据 2/3 以上的请求。

etcd的一致性实现是raft,raft协议本身不关注数据部分,raft只关心日志的同步状态,一致性都通过同步wal日志来实现,每个节点将从主节点收到的数据应用到本地的存储,如果本地存储实现的有bug,比如没有正确的将data apply到本地,也可能会导致数据不一致。

44、强制删除pod

强制删除pod时需要额外指定 --grace-period=0  --force才能发起强制删除请求。

kubectl delete pod -n vela-system kubevela-core-666aassad-sdsad --force --grace-period=0

执行强制删除操作时,apiserver不再等待来自 kubelet 的关于 Pod 已经在原来运行的节点上终止执行的确认消息。 API 服务器直接删除 Pod 对象, 在节点侧,被设置为立即终止的 Pod 仍然会在被强行杀死之前获得一点点的宽限时间。

45、--field-selector

部分字段支持
kubectl get pods --field-selector status.phase=Running
不支持的字段可以考虑使用
kubectl get application | grep -A 3 "running"

46、访问k8s的接口

kubectl get nodes --kubeconfig=./config

获取ServiceAccount,kubectl get sa -n vela-system;
获取ServiceAccount对应Secret的token;
将token base64 -d反解码;
将反解码后的token放在header的Authorization: Bearer

curl -k https://172.20.0.100:10250/metrics/cadvisor --insecure -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjEtSlFGVVRFZUZybEpGS0IyWkpyVzY5aXBSZUU2MjRxYkN4MEdHQ3ZDa28ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJ2ZWxhLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJldmVsYS12ZWxhLWNvcmUtdG9rZW4tZmJ0bTgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoia3ViZXZlbGEtdmVsYS1jb3JlIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYTlmNmQ5ZWYtMzVhZi00ZjVlLWIwMmQtZGQzOTVhNmM3MGUyIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OnZlbGEtc3lzdGVtOmt1YmV2ZWxhLXZlbGEtY29yZSJ9.whnf6U8HQZ_o7YGUFIpJte1nfSqXCVljQD6bswLbCSECmvrAqU-maJfcI9hYiUY_Gousj4Pk5M9RMSCDWp2ZgxHpadcSDWB9N0A9SCFDE95-PX71Sml5zb1SF1mP8KRSxL9p1nZb9jCUOpZrCusMNtftGYfMMf_hJh06jHVgEk3yUvB1KwDKTkomaRNHio-IDEA_eZjnN_p1mAOToJiP2tFtgvGjFeJiJaZrsBqRXkzRTlrDv-uKYyk-4xp-GBlMjeb9UMuplwOw584d_qGt1--IyhKXvetN-CSaEq9aD06Z7P1-e86NGdpbYxzhKX6djaOZcNmX7Ef2ooCDhN2_DA"

47、crd scoped

crd.spec.scoped  集群级别资源还是命名空间级别资源;

ctrl.options.Namespace 默认是所有命名空间,若指定ns则仅处理该ns中的cr;

48、WithEventFilter和EventHandler

1、使⽤WithEventFilter配置变更过滤器,是针对reconciler watch的所有资源,统⼀地设置事件监听规则;

2. 使⽤EventHandler,能够在reconciler watch特定资源时,对该资源设置单独的事件监听规则。

49、k8s 事件回调

不带finalizer的资源被删除时只有一次delete事件。
带finalizer的资源被删除时,会有update 和delete两次事件,才能被删除。

50、k8s的优化

阿里巴巴通过一系列的增强与优化,成功将Kubernetes应用到生产环境并达到了单集群10000 节点的超大规模,具体包括:
1、通过将索引和数据分离、数据shard等方式提高etcd存储容量,并最终通过改进etcd底层bboltdb存储引擎的块分配算法,大幅提高了etcd在存储大数据量场景下的性能,通过单 etcd集群支持大规模Kubernetes集群,大幅简化整个系统架构复杂性;
2、通过落地Kubernetes轻量级心跳、改进HA集群下多个API Server节点的负载均衡、ListWatch机制中增加 bookmark、通过索引与Cache的方式改进了 Kubernetes大规模集群中最头疼的List性能瓶颈,使得稳定的运行万节点集群成为可能;
3、通过热备的方式大幅缩短controller/scheduler在主备切换时的服务中断时间,提高整个集群的可用性;

4、一般需要配置单独的 Etcd 集群存储 kube-apiserver 的 event。
5、node节点数量 >= 3000, 推荐设置如下配置:
--max-requests-inflight=3000--max-mutating-requests-inflight=1000node节点数量在 1000 — 3000, 推荐设置如下配置:
--max-requests-inflight=1500--max-mutating-requests-inflight=500

51、负载均衡器或反向代理

主要有 nginx(七层),HAProxy(四层或七层),traefik(七层),APISIX(七层),他们四个都是ingress的具体实现,ingress是标准化 Kubernetes 中将服务暴露给外部流量的方式(和ingress对等的还有ocp router、k8s Gateway)。

52、spec和status

create只能创建metadata和spec,不能创建status
update和patch只能更新metadata和spec,不能更新status
status.update和status.patch只能更新status

53、ps -ef和ps aux

ps -ef  查看进程的父进程ID和完整的COMMAND命令

ps aux 查看进程的CPU占用率和内存占用率

54、SharedInformer

如果在一个应用中有多处相互独立的业务逻辑都需要监控同一种资源对象,用户会编写多个 Informer 来进行处理。这会导致应用中发起对 K8s API Server 同一资源的多次 ListAndWatch 调用,并且每一个 Informer 中都有一份单独的本地缓存,增加了内存占用。
K8s 在 client go 中基于 Informer 之上再做了一层封装,提供了 SharedInformer 机制。采用 SharedInformer 后,客户端对同一种资源对象只会有一个对 API Server 的 ListAndWatch 调用,多个 Informer 也会共用同一份缓存,减少了对 API Server 的请求,提高了性能。
SharedInformerFactory 中有一个 Informer Map,当应用代码调用 InformerFactory 获取某一资源类型的 Informer 时, SharedInformer 会判断该类型的 Informer 是否存在,如果不存在就新建一个 Informer 并保存到该 Map 中,如果已存在则直接返回该 Informer。

55、TokenReview及SubjectAccessReview

TokenReview:有token相关的身份认证请求发到kubelet等服务时,会创建TokenReview并将 token 信息放在该对象中发送至kube-apiserver进行身份认证。

SubjectAccessReview:有用户或组相关的鉴权请求发到kubelet等服务时,会创建SubjectAccessReview并将该对象中发送至kube-apiserver进行鉴权,检查用户或组是否可以执行某操作。

56、watch超时时间

client-go 会把 Watch的超时设置为 [5min, 10min),即在超时后会重新发起 Watch,主要是考虑通过超时来释放不再发送事件的watchServer,降低kube-apiserver的负载,但是也要考虑在 kubelet 上增大这个值。

57、client-go transport

提供安全的 TCP 连接,支持 Http Stream,exex、attach等操作需要在客户端和容器之间传输二进制流,该功能由内部的 spdy 包提供支持。

58、resync时controller的eventfilter不会生效

对的

59、查看kubeconfig过期时间

cat kubeconfig

复制clusters部分的certificate-authority-data

echo xxxxx| base64  -d 得到结果

将结果复制到tmp.txt中

然后执行 openssl x509 -in ./tmp.txt -text

得到的返回结果中,Validity部分即为有效期

60、client-go tryThrottle

超过50ms没有拿到令牌桶中令牌的请求的会打印Waited for 50ms due to client-side throttling, not priority and fairness

61、HostAliases与dnsPolicy

k8s Pod内域名的解析是一般是通过集群中的kube-dns完成的,如果我们希望k8s上的Pod增加一些域名的解析,直接操作dns模块又不太方便,那么k8s上有没有像linux主机那样可以直接在host文件设置域名解析的方式呢。k8s从1.7版本开始支持了 HostAliases 特性,可以设置域名解析, 域名解析的记录也会写到容器的/etc/hosts文件中。

hostAlias 相当于设置linux主机的/etc/hosts(指定域名到ip的解析)
dnsPolicy和dnsConfig 相当于设置linux主机的/etc/resolv.conf(指定dns服务器)
dnsPolicy有四种
- ClusterFirst:默认策略,表示使用集群内部的CoreDNS来做域名解析,即Pod内/etc/resolv.conf文件中配置的nameserver就是kube-dns的地址。
- Default:Pod直接继承集群node节点的域名解析配置,即Pod会直接使用宿主机上的/etc/resolv.conf文件内容。
- None:忽略k8s集群中的DNS设置,Pod会使用其dnsConfig字段所提供的DNS配置。
- ClusterFirstWithHostNet:未知

62、--previous

kubectl logs pod-name --previous -c container-name

kubelet实现previous的原理是pod的日志存放在pod所在node的/var/log/pods/podname目录中,并且是链接文件,链接到docker的容器的日志文件,该目录下有两个日志文件,一个是当前pod里在跑的容器,一个是pod上次跑的容器现在已经退出了,通过--previous可以看到上次跑的容器的日志。

63、list大量cr报错

stream error when reading response body,may be caused by closed connection

unexpected error when reading response body. Please retry. Original error: read tcp 99.15.138.55:64118->55.57.162.37:6443: wsarecv: An existing connection was forcibly closed by the remote host.

通过设置kube-apiserver的request-timeout能够解决,默认值是60s

64、Informer HasSynced(不一定对)

指一次完整的List操作并将结果全部存入DeltaFIFO,再从DeltaFIFO中全部pop出队,重新存入indexer并触发各种Handler。

65、resourceVersion

resourceVersion=0 表示会从apiserver缓存中获取数据,resourceVersion=""表示从etcd获取数据,etcd是 KV 存储,能支持limit/continue和namespace过滤,其余的 label/field 过滤功能都需要kube-apiserver处理,所以 resourceVersion=0 会导致 limit=500被忽略。

66、Dockerfile中exec格式

Dockerfile中只有Shell形式才会直接获取相关环境变量;Exec格式需要以shell脚本的方式去执行才能获取相关环境变量。
Pod yaml中以Shell方式运行["/bin/sh", "-c", "while true; do echo hello; sleep 10;done"]。

67、client-go的watch超时时间

client-go 会把 Watch的超时设置为 [5min, 10min),即在超时后会重新发起 Watch,主要是考虑通过超时来释放不再发送事件的watchServer,降低kube-apiserver的负载,但是也要考虑在 kubelet 上增大这个值。

68、GOAWAY

Apiserver add a new flag --goaway-chance which is the fraction of requests that will be closed gracefully(GOAWAY) to prevent HTTP/2 clients from getting stuck on a single apiserver. 
  After the connection closed(received GOAWAY), the client's other in-flight requests won't be affected, and the client will reconnect. 
  The flag min value is 0 (off), max is .02 (1/50 requests); .001 (1/1000) is a recommended starting point.

GOAWAY允许端点正常停止接受新的流,同时仍然完成对先前建立的流的处理。这可以实现管理操作,例如服务器维护。

69、etcd events 拆分配置

–etcd-servers-overrides=/events#https://etcd1.events.xxx:2xxx;https://etcd2.events.xxx:2xxx;https://etcd3.events.xxx:2xxx

70、存储相关


文件存储,通过共享目录/文件夹的方式,实现可以让多人共享和操作,大多数使用NFS、Samba等协议,适用于需要频繁修改和共享的大量文件,受网络带宽影响,读写效率慢,传输速率稍低。
NAS(Network Attached Storage):专用文件数据存储服务器;
CFS(Cloud File Storage):腾讯公有云上的NAS产品,即可靠性、可用性、扩展性更高的分布式文件存储服务,提供了标准的 NFS 文件系统访问协议,为多个 CVM 实例提供共享的数据源;
ceph/glusterFS :分布式文件存储系统,可能是腾讯CFS或华为SFS的底层实现,同时提供了对象,块、文件存储(可以理解为CFS=腾讯ceph+CFS的CSI+CFS的配套);
NFS(Network File System):基于TCP/IP传输的网络文件系统协议,通过使用NFS协议或CIFS/SMB文件系统访问协议,客户机可以像访问本地目录一样访问远程服务器中的共享资源。


对象存储,扁平化结构,不需要去维护复杂的文件目录,常用S3协议可通过URL来访问一个空间及其中的文件,适合放静态的图片镜像等非结构性的文件,不适合存放内容变动性大的文件。
COS(Cloud ObjectStorage):腾讯云对象存储,支持 HTTP/HTTPS 协议访问的分布式存储服务,并且兼容 S3 的 API 接口;
OSS(Object Storage Service):阿里云对象存储;
ECS:xxx;
AWS S3(Simple Storage Service):AWS的对象存储;

S3协议或S3 API:标准通用的对象存储数据管理接口。

71、k8s为什么会有单独某种资源查询超时?

APIServer 在启动的时候,会根据 Kubernetes 中的每个资源和版本创建一个独立etcd client,并根据配置决定是否开启 watch cache,每个 client 一般 1 个 TCP 连接,一个 APIServer 实例会高达上百个 etcd 连接。etcd client 与 etcd server 通信使用的是 gRPC 协议,而 gRPC 协议是基于 HTTP/2 协议的。

PVC 资源超时,Pod、Node 等资源没超时,这说明是 PVC 资源对应的底层 TCP 连接/应用层 HTTP/2 连接出了问题。

在 HTTP/2 协议中,通过 HTTP/2 的多路复用机制(HTTP1.1长连接的升级版),一个 etcd HTTP/2 连接就可以满足各种 client 对 PVC 的查询、创建、删除、更新、Watch 请求。

HTTP/1.1 提出长连接,后一个请求只能等前一个请求的响应返回之后才可以被发送。

HTTP/2 提出多路复用,单一的 http2 连接上并行交错的传输请求和响应,而不需要顺序一一对应。HTTP/2的消息被分解独立的帧(Frame),交错发送,帧是最小的数据单位。每个帧会标识属于哪个流(Stream),流由多个数据帧组成,每个流拥有一个唯一的 ID,一个数据流对应一个请求或响应包。如上图所示,client 正在向 server 发送数据流 5 的帧,同时 server 也正在向 client 发送数据流 1 和数据流 3 的一系列帧。一个连接上有并行的三个数据流,HTTP/2 可基于帧的流 ID 将并行、交错发送的帧重新组装成完整的消息。

72、mountPath与subPath

mountPath 挂载整个volume到Pod的mountPath目录下
mountPath+subPath  只挂载volume的subPath目录到Pod的mountPath目录下

73、apiserver.latency.k8s.io/total

对于超过100ms的慢请求在k8s apiserver event中会有apiserver.latency.k8s.io/total字段记录链路。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐