K8S入门知识概念

1.查看节点的日志信息:journalctl -u kubelet -n 1000  

2.查看对应deployment的pod数量,并对其进行设置:kubectl get deployments & kubectl scale deployment nginx-deployment --replicas

3.node节点加入k8s集群:kubeadm join --token 1f627e.a37793601a406d7e 10.0.1.22:6443 --discovery-token-ca-cert-hash sha256:e12a8e1d1be7d308dad31bebdb2684d9d4ba7e5ae290f4fd1f855089b1abe71a    

4.K8S给node设置污点策略:

kubectl taint nodes node1 key=value:NoSchedule --新的不能容忍的pod不能再调度过来,可是老的运行在node上不受影响html

kubectl taint nodes node1 key=value:NoExecute --新的不能容忍的pod不能调度过来,老的pod也会被驱逐前端

kubectl taint nodes node1 key=value:PreferNoSchedule --pod会尝试将pod分配到该节点node

5.K8S如何给节点去除对应的污点:kubectl taint nodes master key:NoExecute-

6.重启kubeletsystemctl restart kubelet.service  

7.设置kubelet开机自启动:systemctl enable kubelet.service  

8.查看k8s存在的命名空间:kubectl get namespaces

9.查看命名空间里的服务:kubectl get services --namespace=logging

10.查看系统中所运行的容器:kubectl get po -n kube-system -o wide

11.查看对应的错误日志:kubectl describe pod XXX -n kube-system 

12.K8S的pod调度策略:

能够参考连接详细学习:https://www.qikqiak.com/post/kubernetes-affinity-scheduler/mysql

nodeSelector调度:强制调度pod到某个节点上nginx

亲和性和反亲和性调度:git

nodeAffinity(节点亲和性)、podAffinity(pod 亲和性) 以及 podAntiAffinity(pod 反亲和性)github

亲和性调度能够分红软策略硬策略两种方式:web

  • 软策略就是若是你没有知足调度要求的节点的话,pod 就会忽略这条规则,继续完成调度过程,说白了就是知足条件最好了,没有的话也无所谓了的策略
  • 硬策略就比较强硬了,若是没有知足条件的节点的话,就不断重试直到知足条件为止,简单说就是你必须知足个人要求,否则我就不干的策略。

对于亲和性和反亲和性都有这两种规则能够设置: preferredDuringSchedulingIgnoredDuringExecutionrequiredDuringSchedulingIgnoredDuringExecution,前面的就是软策略,后面的就是硬策略。sql

affinity:后端

        nodeAffinity:

          requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略

            nodeSelectorTerms:

            - matchExpressions:

              - key: kubernetes.io/hostname

                operator: NotIn

                values:

                - node03

          preferredDuringSchedulingIgnoredDuringExecution:  # 软策略

          - weight: 1

            preference:

              matchExpressions:

              - key: com

                operator: In

                values:

                - youdianzhishi

nodeSelectorTerms属性类型

  • In:label 的值在某个列表中
  • NotIn:label 的值不在某个列表中
  • Gt:label 的值大于某个值
  • Lt:label 的值小于某个值
  • Exists:某个 label 存在
  • DoesNotExist:某个 label 不存在

若是nodeSelectorTerms下面有多个选项的话,知足任何一个条件就能够了;若是matchExpressions有多个选项的话,则必须同时知足这些条件才能正常调度 POD。

13.k8s pod erro exit code 137 该错误码表示node节点的内存不足

14.开启代理协议端口:kubectl  proxy --address='192.168.30.30' --port=8888 --accept-hosts='^*$' &

15.K8s中yaml的资源类型(kind字段)

工做负载型资源对象(workload):POD,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob ...
服务发现及均衡资源对象:Service,Ingress ...
配置与存储资源对象:Volume(存储卷),CSI(容器存储接口,能够扩展各类各样的第三方存储卷),ConfigMap,Secret,DownwardAPI
集群级资源:Namespace,Node,Role,ClusterRole,RoleBinding,ClusterRoleBinding
元数据型资源:HPA,PodTemplate,LimitRange

16.K8S中存储卷volume的类型

.本地存储

1,EmptyDir

若是在此目录中建立删除文件,都将对容器中的/data目录有影响,若是删除Pod,文件将所有删除,即便是在宿主机上建立的文件也是如此,在宿主机上删除容器则k8s会再自动建立一个容器,此时文件仍然存在。

2.HostDir

在宿主机上指定一个目录,挂载到Pod的容器中,其实跟上面的写法不尽相同,这里只截取不一样的部分,当pod删除时,本地仍然保留文件

.网络数据卷(NFS)

1.NFS

如何加入NFS文件系统

# 安装nfs服务

[root@nfs01 ~]# yum install nfs-utils rpcbind

# 建立nfs挂载目录

[root@nfs01 ~]# mkdir /data/volums/data01/ -p

# 启动服务

[root@nfs01 ~]# systemctl start rpcbind

[root@nfs01 ~]# systemctl enable rpcbind

[root@nfs01 ~]# systemctl start nfs-server

[root@nfs01 ~]# systemctl enable nfs-server

# 配置nfs服务

[root@nfs01 ~]# cat /etc/exports

/data/volums/data01 *(async,insecure,no_root_squash,no_subtree_check,rw)

# 查看nfs状态

[root@nfs01 ~]# showmount -e 192.168.17.195

Export list for 192.168.17.195:

/data/volums/data01 192.168.17.0/24

注意:对应的节点须要安装客户端:yum install nfs-utils

采用nfc存储的yaml样例

spec:

  containers:

    - name: web

      image: nginx

      imagePullPolicy: Never        #若是已经有镜像,就不须要再拉取镜像

      ports:

        - name: web

          containerPort: 80

          hostPort: 80        #将容器的80端口映射到宿主机的80端口

      volumeMounts:

        - name : nfs        #指定名称必须与下面一致

          mountPath: "/usr/share/nginx/html"        #容器内的挂载点

  volumes:

    - name: nfs            #指定名称必须与上面一致

      nfs:            #nfs存储

        server: 192.168.30.32       #nfs服务器ip或是域名

        path: "/nfs-data"                #nfs服务器共享的目录

/test目录中建立index.html文件后,这个文件也将在容器中生效,当Pod删除时,文件不受影响,实现了数据持久化。

三. Persistent Volume(PV)和Persistent Volume Claim(PVC)

其实这两种数据卷也属于网络数据卷,单拎出来是由于我以为这个比前面的数据卷要酷多了,有种大数据,云平台的意思,当用户要使用数据存储的时候他是否还须要知道是什么类型的数据存储,答案是不须要,用户只想要安全可靠的数据存储,并且实现起来很简单,管理员创建一个存储平台,用户按本身的需求消费就能够了

PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员建立和维护。与 Volume 同样,PV 具备持久性,生命周期独立于 Pod。

PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 一般由普通用户建立和维护。须要为 Pod 分配存储资源时,用户能够建立一个 PVC,指明存储资源的容量大小和访问模式(好比只读)等信息,Kubernetes 会查找并提供知足条件的 PV。

静态Pvc示例

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

  name: efk-pvc

  namespace: kube-system  #注意pvc所在的命名空间和所引用的pod须要在同一个

spec:

  accessModes:

    - ReadWriteMany

  resources:

    requests:

      storage: 2Gi

  storageClassName: efk-nfs

pod如何引用pvc

        volumeMounts:

        - name: elasticsearch-logging

          mountPath: /data

        env:

        - name: "NAMESPACE"

          valueFrom:

            fieldRef:

              fieldPath: metadata.namespace

      volumes:

      - name: elasticsearch-logging

        persistentVolumeClaim:

          claimName: efk-pvc

 

具体建立和使用参考:

https://blog.51cto.com/forall/2135152

 

动态pvc的使用

建立和使用参考连接:https://blog.51cto.com/goome/2423200

过程当中遇到的问题

nfs-client-provisioner这个pod一直报错error retrieving resource lock default/fuseim.pri-ifs: Unauthorized

最后参考连接

https://github.com/kubernetes-incubator/external-storage/issues/953

把下面这段替换rbac.yaml文件就行,大概的缘由是rbac分配给nfs-client的权限不够

kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:

  name: efs-provisioner-runnerrules:

  - 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: ["list", "watch", "create", "update", "patch"]

  - apiGroups: [""]

    resources: ["endpoints"]

    verbs: ["get", "list", "watch", "create", "update", "patch"]

再也不须要再建立pod前先申请pvc而后再挂载进pod,能够经过在部署podyaml文件中采用StatefulSet

statefulset,能够翻译成有状态的设定.

deployment的对比

deployment部署建立的pod是无状态的,从新调度pod,pod名字hostname,启动pod顺序删除pod顺序都是随机的.deployment使用的是共享存储,全部pod共用一个存储卷.

statefulset部署建立的pod是有状态的,从新调度pod,pod名字hostname保持固定不变,启动pod顺序删除pod顺序均可以根据定义的顺序有序执行操做,有序的动态更新,statefulset使用的存储,不是共用一个存储卷,一个pod对应一个存储卷(pv).pod从新建立调度挂载的存储卷保持不变.

 

apiVersion: apps/v1

kind: StatefulSet

metadata:

  name: statefulset-testspec:

  serviceName: headless-svc

  replicas: 3

  selector:

    matchLabels:

      app: headless-pod

  template:

    metadata:

      labels:

        app: headless-pod

    spec:

      containers:

      - image: httpd

        name: myhttpd

        ports:

        - containerPort: 80

          name: httpd

        volumeMounts:

        - mountPath: /mnt

          name: test

  volumeClaimTemplates:

  - metadata:

      name: test

      annotations:

        volume.beta.kubernetes.io/storage-class: managed-nfs-storage

    spec:

      accessModes: [ "ReadWriteOnce" ]

      resources:

        requests:

          storage: 100Mi

 

accessModes

用于定义资源的访问方式,受限于存储底层的支持,访问方式包括如下几种:

ReadWriteOnce – 被单个节点mount为读写rw模式

ReadOnlyMany – 被多个节点mount为只读ro模式

ReadWriteMany – 被多个节点mount为读写rw模式

 

17.K8S进入pod中:kubectl exec -ti curl-6bf6db5c4f-hm96f  -n default  -- /bin/sh

18.K8S的service介绍

service是一个抽象概念,定义了一个服务的多个pod逻辑合集和访问pod的策略,通常把service称为微服务

 

服务类型

ClusterIP

分配一个内部集群IP地址,只能在集群内部访问(同Namespace内的Pod),默认ServiceType

Service对象在Cluster IP range池中分配到的IP只能在内部访问,若是服务做为一个应用程序内部的层次,仍是很合适的。若是这个Service做为前端服务,准备为集群外的客户提供业务,咱们就须要给这个服务提供公共IP了。

 

NodePort

分配一个内部集群IP地址,并在每一个节点上启用一个端口来暴露服务,能够在集群外部访问。

访问地址:<NodeIP>:<NodePort>

 

LoadBalancer

分配一个内部集群IP地址,并在每一个节点上启用一个端口来暴露服务。

除此以外,Kubernetes会请求底层云平台上的负载均衡器,将每一个Node[NodeIP]:[NodePort])做为后端添加进去。

 

service的类型

ClusterIP          默认模式,只能在集群内部访问

NodePort        在每一个节点上都监听一个一样的端口号(30000-32767)ClusterIP和路由规则会自动建立。集群外部能够访问<NodeIP>:<NodePort>联系到集群内部服务,能够配合外部负载均衡使用(我如今公司用的就是这个模式配合阿里云的SLB

LoadBalancer     要配合支持公有云负载均衡使用好比GCEAWS。其实也是NodePort,只不过会把<NodeIP>:<NodePort>自动添加到公有云的负载均衡当中

ExternalName    建立一个dns别名指到service name上,主要是防止service name发生变化,要配合dns插件使用用户能够指定一个任意的名字,做为该service被解析的CNAME,这种类型的servcie不用指定clusterIP,所以kube-proxy不会管理这类service,这类service须要使用1.7版本以上的kubedns。好比用户想建立一个service,但要让全部容器访问该service的请求都引导到用户本身定义的外部域名服务,就能够经过这个方式实现。能够说这个是最自由的一个方式:你但愿服务被如何解析,服务就能被如何解析。你甚至能够给多个service配置同一个externalName。

---

kind: Service

apiVersion: v1

metadata:

  name: mysql-5-7-01-service

spec:

  type: ExternalName

  externalName: ai-production-mysql-bot.cfyipcsxzevb.rds.cn-northwest-1.amazonaws.com.cn

---

经过上面建立的servicename去访问对应的aws上的mysql服务

 

集群中容器访问集群外部服务

DNS

Service type:ExternalName

Docker环境中,因为Docker Engine自带 DNS Server,咱们使用容器名来访问其它容器,由于容器是不稳定的,当容器宕掉,再从新启动相同镜像的容器,IP地址会改变,因此咱们不使用IP访问其它容器;一样的,在Kubernetes集群中,因为咱们使用 kube-DNS,咱们经常使用Service名称来访问某个服务,Service资源对象能保证其背后的容器副本始终是最新的IP

 

所以,咱们能够利用这个特性,对Service名称和外部服务地址作一个映射,使之访问Service名称既是访问外部服务。例以下面的例子是将 svc1 xxx.xxx.xxx.xxx 作了对等关系。

 

kind: Service

apiVersion: v1

metadata:

  name: svc1

  namespace: default

spec:

  type: ExternalName

  externalName: somedomain.org

 

设置 Service EndPoint

Kubernetes集群中,同一个微服务的不一样副本会对集群内或集群外(取决于服务对外暴露类型)暴露统一的服务名称,一个服务背后是多个 EndPointEndPoint解决映射到某个容器的问题,在 EndPoint 中不只能够指定集群内容器的IP,还能够指定集群外的IP,咱们能够利用这个特性使用集群外部的服务。

 

EndPoint 方式的缺点是只能指定IP,不能使用网址,好比网址,好比RDS的地址,这种状况下只能使用ExternalName来解决。

 

apiVersion: v1

kind: Service

metadata:

  name: mysql-production

spec:

  ports:

    - port: 3306

---

kind: Endpoints

apiVersion: v1

metadata:

  name: mysql-production

  namespace: default

subsets:

  - addresses:

      - ip: 192.168.1.25

    ports:

      - port: 3306

总结

本文介绍了集群内部访问外部服务的两种方法,ExternalName 类型的服务适用于外部服务使用域名的方式,缺点是不能指定端口;而EndPoint的方式适合于外部服务是IP的状况,可是能够指定端口。根据须要使用吧!

 

19. K8S中pod的内存和cpu设置

下面是如何给一个pod分配cpu和内存

Kubernetes系统上,l个单位的CPU至关于虚拟机上的l颗虚拟CPU(vCPU)或物理机上的一个超线程(Hyperthread,或称为一个逻辑CPU),它支持分数计量方式,一个核心(1core)至关于1000个微核心(millicores),所以500m至关因而0.5个核心

memory-request-limit.yaml 

apiVersion: v1

kind: Pod

metadata:

  name: memory-demo

spec:

  containers:

  - name: memory-demo-ctr

    image: vish/stress

    resources:

      limits:

        memory: "200Mi"

      requests:

        memory: "100Mi"

    args:

    - -mem-total

    - 150Mi

    - -mem-alloc-size

    - 10Mi

    - -mem-alloc-sleep

- 1s

超出容器的内存限制报错

NAME            READY     STATUS      RESTARTS   AGE

memory-demo-2   0/1       OOMKilled   1          24s

配置超出节点能力范围的内存申请pod会一直处于pending状态

kubectl get pod memory-demo-3 --namespace=mem-example

NAME            READY     STATUS    RESTARTS   AGE

memory-demo-3   0/1       Pending   0          25s

查看具体报错信息以下

Events:

  ...  Reason            Message

       ------            -------

  ...  FailedScheduling  No nodes are available that match all of the following predicates:: Insufficient memory (3).

 

 

若是不配置内存限制

若是不给容器配置内存限制,那下面的任意一种状况可能会出现:

容器使用内存资源没有上限,容器可使用当前节点上全部可用的内存资源。

容器所运行的命名空间有默认内存限制,容器会自动继承默认的限制。

内存申请和限制的缘由

经过配置容器的内存申请和限制,你能够更加有效充分的使用集群里内存资源。配置较少的内存申请, 可让Pod跟任意被调度。设置超过内存申请的限制,能够达到如下效果:

Pod能够在负载高峰时更加充分利用内存。

能够将Pod的内存使用限制在比较合理的范围。

 

20. 强制删除pod:  kubectl delete po <your-pod-name> -n <name-space> --force --grace-period=0

21. K8S的镜像拉取策略

Always 老是拉取镜像

IfNotPresent 本地有则使用本地镜像,不拉取

Never 只使用本地镜像,从不拉取,即便本地没有

若是省略imagePullPolicy 镜像tag为 :latest 策略为always ,不然 策略为 IfNotPresent

 

22. Pod健康检测机制

对于Pod的健康状态检测,kubernetes提供了两类探针(Probe)来执行对Pod的健康状态检测:

  • LivenessProbe探针:
    用于判断容器是否存活,即Pod是否为running状态,若是LivenessProbe探针探测到容器不健康,则kubelet将kill掉容器,并根据容器的重启策略是否重启,若是一个容器不包含LivenessProbe探针,则Kubelet认为容器的LivenessProbe探针的返回值永远成功。
  • ReadinessProbe探针:
    用于判断容器是否启动完成,即容器的Ready是否为True,能够接收请求,若是ReadinessProbe探测失败,则容器的Ready将为False,控制器将此Pod的Endpoint从对应的service的Endpoint列表中移除,今后再也不将任何请求调度此Pod上,直到下次探测成功。

每类探针都支持三种探测方法:

  • exec:经过执行命令来检查服务是否正常,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康。
  • httpGet:经过发送http请求检查服务是否正常,返回200-399状态码则代表容器健康。
  • tcpSocket:经过容器的IP和Port执行TCP检查,若是可以创建TCP链接,则代表容器健康。

探针探测的结果有如下三者之一:

    • Success:Container经过了检查。
    • Failure:Container未经过检查。
    • Unknown:未能执行检查,所以不采起任何措施。
相关文章
相关标签/搜索