Think Deep,Work Lean

k8s官网阅读

Posted on By zack

前言

kubsphere 启用istio组件时,发现这个Pod总不正常,descibe pods提示 cpu不足:

  Warning  FailedScheduling  58s (x5 over 2m28s)  default-scheduler  0/1 nodes are available: 1 Insufficient cpu, 1 Insufficient memory.
看Limit  
Limits:
      cpu:     2
      memory:  1Gi
    Requests:
      cpu:     100m
      memory:  128Mi
但是cpu其实是够的:
%Cpu0  :  5.7 us,  2.7 sy,  0.0 ni, 88.6 id,  0.0 wa,  0.0 hi,  0.3 si,  2.7 st
%Cpu1  :  4.8 us,  3.7 sy,  0.0 ni, 88.8 id,  0.0 wa,  0.0 hi,  0.0 si,  2.7 st
%Cpu2  :  6.2 us,  2.7 sy,  0.0 ni, 88.7 id,  0.0 wa,  0.0 hi,  0.0 si,  2.4 st
%Cpu3  :  6.9 us,  3.5 sy,  0.0 ni, 86.5 id,  0.0 wa,  0.0 hi,  0.3 si,  2.8 st

requests和实际使用不一样,requests是声明要用多少资源

kubectl describe node 看下节点的requests

Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests          Limits
  --------           --------          ------
  cpu                3550m (100%)      24680m (695%)
  memory             5846592000 (79%)  21147340032 (288%)
  ephemeral-storage  0 (0%)            0 (0%)

cpu requests已经100%了,没法再分配cpu了

https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

要求:k8s官网的文档从头到尾一遍不落的看完,官网文档写得很好,很多问题都解释的很清楚

其实之前describe node过,这个信息也看到了,但是没有理解到。

现在喜欢用xmind,并且看文档喜欢用xmind把网站层级结构画下,这样有利于理解作者的意图。使用文档也更顺手。

对于cpu资源不足的情况,可以增加节点:

可以通过现在的allinone add-nodes.sh脚本变成multi-node方式,只不过因为原来是local volume,多节点之后还是local volume

Managing Resources for Containers

容器资源管理

Note that although actual memory or CPU resource usage on nodes is very low, the scheduler still refuses to place a Pod on a node if the capacity check fails. This protects against a resource shortage on a node when resource usage later increases, for example, during a daily peak in request rate.

对于资源不足的处理方法:

In the preceding example, the Pod named “frontend” fails to be scheduled due to insufficient CPU resource on the node. Similar error messages can also suggest failure due to insufficient memory (PodExceedsFreeMemory). In general, if a Pod is pending with a message of this type, there are several things to try:

Add more nodes to the cluster. Terminate unneeded Pods to make room for pending Pods. Check that the Pod is not larger than all the nodes. For example, if all the nodes have a capacity of cpu: 1, then a Pod with a request of cpu: 1.1 will never be scheduled.

describe nodes


[root@ks-allinone ~]# kubectl describe nodes|less
...
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Tue, 21 Apr 2020 08:47:14 +0800   Tue, 21 Apr 2020 08:47:14 +0800   CalicoIsUp                   Calico is running on this node
  MemoryPressure       False   Tue, 21 Apr 2020 12:00:02 +0800   Tue, 21 Apr 2020 08:46:28 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Tue, 21 Apr 2020 12:00:02 +0800   Tue, 21 Apr 2020 08:46:28 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Tue, 21 Apr 2020 12:00:02 +0800   Tue, 21 Apr 2020 08:46:28 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Tue, 21 Apr 2020 12:00:02 +0800   Tue, 21 Apr 2020 08:47:19 +0800   KubeletReady                 kubelet is posting ready status
...

这个condition中有些正常有些不正常,分别是什么意思?

QA

  • 为什么在kubectl get cm时,出现的的data都是数字?

    edit可以看到key跟value的值,这个get看到的数字是表明有几个键值对。

  • 频繁看到istio operator, k8s operator,这个operator是什么意思?

    operator是运维的意思,k8s的初衷设计是像让程序自动化、开箱即用的本意,operator就是这个过程的实施者。可以理解为执行crd的过程。Operators are software extensions to Kubernetes that make use of custom resources to manage applications and their components.

    而istio operator就是operator auto的一个很好的实践。https://istio.io/blog/2019/introducing-istio-operator/

  • 在describe pod的时候,有时候会发现如下:
    QoS Class:       Burstable
    Node-Selectors:  <none>
    Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                   node.kubernetes.io/unreachable:NoExecute for 300s
    Events:          <none>
    

    这个 tolerations是什么意思?

    tolerations跟taints是一组,taints是应用到node节点,不允许pod分配到脏节点。tolerations是应用到pods,允许pod分配到taint节点。

  • annotations与lable的区别?
    You can use either labels or annotations to attach metadata to Kubernetes objects. Labels can be used to select objects and to find collections of objects that satisfy certain conditions. In contrast, annotations are not used to identify and select objects. The metadata in an annotation can be small or large, structured or unstructured, and can include characters not permitted by labels.
  "metadata": {
  "annotations": {
    "key1" : "value1",
    "key2" : "value2"
  }
}
  • k8s中的secret具体是怎样的?
    secrets是用来保存敏感信息的,如密码、tokens令牌、ssh密钥。存在secret object中,胜过直接存在Pod的镜像中。两种方式来实现:
    1. As files in a volume mounted on one or more of its containers.
    2. By the kubelet when pulling images for the Pod.
  • k8s在使用-o yaml的时候,为什么有些命令提示没有这个参数?而有些又可以?
    在kubelete describe pods的时候会提示没有这个参数;只有在get的时候才能输出yaml.

  • replica/set有什么区别? rc - replicationcontroller: A ReplicationController ensures that a specified number of pod replicas are running at any one time. In other words, a ReplicationController makes sure that a pod or a homogeneous set of pods is always up and available

    rs - replicatset:A ReplicaSet’s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods. This actually means that you may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section.

    rs 是下一代的 rc,替代方案,可用 deployment来代替(建议),还有 daemonset/job 等。

  • controller是什么,还有api,这两个是k8s中的很大的概念?具体起到什么作用,如何体现它的作用? controller好比是一个房间的恒温器,你设置好温度后,控制器会自动打开或是关闭开关,来保证这个温度是不断与你设定的值不断接近的。

  • 关于 clusterrolebinding是怎样的? ``` ~ ❯ kubectl get clusterrolebindings ks-kube-state-metrics -o yaml 15:09:31 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {“apiVersion”:”rbac.authorization.k8s.io/v1”,”kind”:”ClusterRoleBinding”,”metadata”:{“annotations”:{},”labels”:{“app.kubernetes.io/name”:”kube-state-metrics”,”app.kubernetes.io/version”:”v1.9.4”},”name”:”ks-kube-state-metrics”},”roleRef”:{“apiGroup”:”rbac.authorization.k8s.io”,”kind”:”ClusterRole”,”name”:”kube-state-metrics”},”subjects”:[{“kind”:”ServiceAccount”,”name”:”kube-state-metrics”,”namespace”:”kubesphere-monitoring-system”}]} creationTimestamp: “2020-04-01T07:27:00Z” labels: app.kubernetes.io/name: kube-state-metrics app.kubernetes.io/version: v1.9.4 name: ks-kube-state-metrics resourceVersion: “338725” selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/ks-kube-state-metrics uid: 917070f2-3707-43f2-b19c-13686e794946 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: kube-state-metrics subjects:
  • kind: ServiceAccount name: kube-state-metrics namespace: kubesphere-monitoring-system ```

  • 经常看到 rbac,它的工作原理是怎样的?如何使用?
    四种类型:
    Role: ns resource
    ClusterRole: none-ns resource
    Role/ClusterRole定义 rule,给某个或某些资源定义角色,给定操作权限。 rule 都是 accept 的 permission,没有 deny 的 permission
    RoleBinding
    ClusterRoleBinding
    这两个是将这个角色是否绑定到一个或多个用户

  • API groups起什么作用?

kubectl api-resources可以看到,每个 kind 的资源都属于一个 apiGroup。对于 apiGroup 还有一些版本,如 v1、v1alpha3等。这些怎么看呢?

这要看这个 kind 定义的时候,要用哪个 api,如果是 k8s 本身的一些 kind,可以直接在官网上找到对应的版本。发果是拓展的 api,如 crd 定义的 kind,那么就要看这个 crd 对这个 Kind 的定义。

那么什么是 api 呢?

就是操作对象的方法,每个 object 都会有一个 api, kubectl工具其实就是把你的操作转换成 api然后 跟 API controller 来进行交互的。在 k8s 的 reference 里面定义了各语言的调用方式。

  • sa 是什么意思?
    ServiceAccount 用户,如果创建一个 pod,那么默认是 default 用户。在 secret 的 annotation里面可以指定 kubernetes.io/service-account.name

  • endpoint 起什么作用?

如果您想要在应用程序中使用 Kubernetes 接口进行服务发现,则可以查询 API server 的 endpoint 资源,只要服务中的Pod集合发生更改,端点就会更新。

对于非本机应用程序,Kubernetes提供了在应用程序和后端Pod之间放置网络端口或负载均衡器的方法。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

上述配置创建一个名称为 “my-service” 的 Service 对象,它会将请求代理到使用 TCP 端口 9376,并且具有标签 “app=MyApp” 的 Pod 上。 Kubernetes 为该服务分配一个 IP 地址(有时称为 “集群IP” ),该 IP 地址由服务代理使用。 (请参见下面的 VIP 和 Service 代理). 服务选择器的控制器不断扫描与其选择器匹配的 Pod,然后将所有更新发布到也称为 “my-service” 的Endpoint对象。

  • ingress service deployment pod container 之间的关系?

container 遭遇意外情况会退出,为了解决这个问题,因此有了 pod。一个 pod 可以有多个 container,第一个 container 永远是 pause 容器。当container 意外退出时,会马上再启动一个类似的 container。那么 pause 容器是干嘛的呢?pause容器是 pid 为 1 的进程,可以管理普通容器的整个生命周期。关于 pause 容器,请参考。同一个 pod 的容器间,相互共享网络存储。
pod 有独立的 ip,不同的 pod 之间可以通过这个 ip 通信。但是如果遭遇意外 pod 退出后重启,Ip就变了,因此不可靠,因此有了 service。
service 是一组 pods的抽象,有统一的 ip和访问端口,且固定不变。 service 有几种类型,ClusterIp 是集群中的 Ip,不对外暴露,只在集群中 pod 能访问;NodePort,可以通过与 Node 的端口一一映射来访问到内部的服务;LoadBalancer,需要与平台的 Lb 来配合使用;还有一个是 ExternalName/ExternalIPs 模式,主要是兼容外部服务用的。service通过 spec/selector中定义的 key:value 与 pod lable 的 key=value 进行关联。
那 deployments 呢?deployment 是无服务状态的负载,管理 pod的状态,如期望的副本数replicaset、request QOS 、镜像等。当一个 pod 删除时,会马上同过 deployment中定义的 template 马上创建一个新的。可以通过kubectl expose 将这个 Deployment 的服务暴露出来。gg
那么 statefulset 就是与 depoyments 平行的,只不过它是有状态的。
ingress 是 7 层负载,类似同过 nginx 的 7 层负载,可以通过请求的 header/path 来实现不同请求的分发。外部 internet 进入集群的入口,api 的入口。

  • crd是什么,有什么用?
    crd 是让用户自己来创建资源类型kind,可以定义成新的 api rest 类型,然后可以根据 crd 来创建资源对象 objects

通俗来讲,就是比如你要创建一个应用,这个应用有很多个服务组成,每个服务又是与一个或多个pods 进行关联的,pod 是实际的执行者。疑问?那么service 与 deployment 如何关联?可以直接 expose deployment 把服务暴露出来。

In the Kubernetes API, a resource is an endpoint that stores a collection of API objects of a certain kind. For example, the built-in Pods resource contains a collection of Pod objects. A Custom Resource Definition (CRD) object defines a new, unique object Kind in the cluster and lets the Kubernetes API server handle its entire lifecycle.

在 k8s 中,一个资源就是个 endpoint,存储了一系列特定类型的 api 对象。一个 crd 就是定义了一个新的 kind,并让 k8s api server 管理整个生命周期。

When you create a new CustomResourceDefinition (CRD), the Kubernetes API Server creates a new RESTful resource path for each version you specify. The CRD can be either namespaced or cluster-scoped, as specified in the CRD’s scope field. As with existing built-in objects, deleting a namespace deletes all custom objects in that namespace. CustomResourceDefinitions themselves are non-namespaced and are available to all namespaces.