《Kubernetes权威指南》基本概念

不打扰是莪最后的温柔 提交于 2021-02-09 09:58:03

一 、基本概念

kubernetes中的NodePodReplication ControllerService等都是一种“资源对象”,基本都可以通过kubectl或者通过API编程调用,执行增删改查操作都保存在ETCD中持久化存储

1.1 Master

作用:每个k8s集群都需要一个mater节点来管理,master一般是单独部署

核心组件:

  • Kubernetes API Server(kube-apiserver),提供HTTP REST 接口的关键服务进程,是k8s里所有资源增删改查

等操作的唯一入口

  • Kubernetes Controller Manager (kube-controller-manager),k8s所有资源的自动化控制中心。
  • Kubernetes Scheduler(kube-scheduler),调度(POD)的进程。
  • ETCD,master节点一般还启动一个ETCD Server进程,所有资源对象的数据全部保存在ETCD中

1.2 Node

除了Master,k8s集群的其他节点都称为Node节点,Node节点是k8s集群中的工作负载节点,当某个Node宕机,骑上的工作负载会被master自动转移到其他节点上

核心组件:

  • kubelet:负责Pod对象的容器创建、启停等任务,同时与Master节点密切协作

  • kube-proxy:实现kubernetes Service 的通信与负责均衡机制的组件

  • Docker Engine (Docker):docker引擎,负责本机的容器创建和管理工作

    默认kubelet会向master注册自己,会上传Node的信息,定时向master上报数据,超时则标记不可用(Not Ready)

查看集群中Nodes

$ kubectl get nodes
NAME			STATUS		AGE
kubernetes-minion1	Ready		2d

查看某个Node详细信息

$ kubectl describe node kubernetes-minion1

1.3 Pod

每个Pod都有一个根容器的Pause容器和其他用户业务容器,Pod里的业务容器共享Pause容器的IP和Volume,一个Pod的容器于另外主机上的Pod容器能够直接通信。

Pod分类

  • 普通Pod:普通Pod创建就存储在ETCD中,被Master调度到某node上进行绑定
  • 静态Pod(static Pod):静态Pod不受kubernetes管理,不再ETCD存储,放在某个具体node的具体文件中,只在此具体文件所在的node上启动运行。

例子:pod创建模板

Endpoint

Pod的IP和containerPort组成Endpoint,他代表Pid里的一个服务进程的对外通信地址,一个pod可以有多个endpoint。

Volume

k8s的Volume相对于docker的Volume支持了GlusterFS等等分布式存储。

Event

可以查看event来定位错误

#查看pod描述信息
$ kubectl describe pod xxx

配额

每个pod都可以进行计算资源的限制。

  • Requests:该资源的最小申请量
  • Limites:该资源最大允许使用量,超过会被k8s kill 并重启

配置管理

k8s使用configMap来实现对pod的配置管理

使用方法:

  • 生成为容器内的环境变量
  • 设置容器的启动命令的启动参数(需设置为环境变量)
  • 以Volume的形式挂载为容器内部的文件或者目录

Pod的生命周期

Pod的状态:

状态 描述
挂起(Pending) API Server创建了Pod资源对象并已经存入了etcd中,但是它并未被调度完成,但pod内还有一个或者多个容器的进行没有创建,包括仍然处于从仓库下载镜像的过程中。
运行中(Running) Pod已经被调度到某节点之上,并且所有容器都已经被kubelet创建完成。
成功(Succeeded) Pod 中的所有容器都被成功终止,并且不会再重启。
失败(Failed) Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
未知(Unknown) 因为某些原因无法取得 Pod 的状态,可能由于网络通信不畅。

pod的重启策略:

  • Always:当容器失效时,由kubelet自动重启容器
  • **OnFailure **: 当容器终止运行且退出代码不为0时,由kubelet自动重启
  • Never:不论容器运行状态如何,都不重启

RC和DaemonSet必须设置为Always

Job:OnFailure或Never,确保容器执行完成后不再重启

kubelet:Pod失效时自动重启他,不论RestartPolicy设置为什么值,并且也不会对Pod进行健康检查。

1.4 Label(标签)

Label是一个key=value键值对,可以附加在Node、Pod、Service、RC等,一个资源对象可以定义任意数量Label。

作用:通过Label分组管理,过滤筛选,通过Label Selector 来查询过滤资源对象,类似于SQL。

Label Selector分类

  • equility-based(等式),例如:name=redis-slave
  • set-based(集合),例如name in (redis-master,redis-slave),name not in...

1.5 Repliaction Controller(RC)

​ 声明pod的期望副本数量,某个Node节点宕机,k8s会调度在其他node上部署pod,已达到期望数量。

#修改RC来实现POD动态缩放
$ kubectl scale rc redis-slave --replicas=3

注意:删除RC不会动态的删除Pod,应该设置replicas=0,并更新RC,或者通过kubectlstopdelete一次性删除RC和RC控制的全部Pod

​ k8s升级版本后使用Replica Set替换RC,区别在RS支持equility-based和set-based,而RC支持equility-based,一般Replica Set和Deployment配置使用。

###1.6 Deployment

使用Deployment来替代RC,内部使用了Replica Set实现。Deployment相对RC可以随时知道Pod的部署进度。部署模板中使用kind: Deployment

使用场景

  • 替换RC
  • 查看部署状态
  • 更新Deployment以创建新的pod(比如镜像升级)
  • 回滚上一个Deployment版本
  • 挂起、恢复一个Deployment

使用方法

  • 创建

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp-deploy
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: myapp
          release: dev
      template:
        metadata:
          labels:
            app: myapp
            release: dev
        spec:
          containers:
          - name: myapp-containers
            image: ikubernetes/myapp:v1
            ports:
            - name: http
              containerPort: 80
    

    运行命令

    $ kubectl create -f tomcat-deployment.yaml
    
  • 查看

    $ kubectl get deployments
    NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    myapp-deploy   1         1         1            1           1m
    
    • DESIRED: Pod副本数量的期望值, 既Deployment里定义的Replica
    • CURRENT: 当前Replica的值,这个值不断增加,直到达到DESIRED为止, 完成整个部署过程
    • UP-TO-DATE: 最新版本的Pod的副本数量,用于指示在滚动升级的过程中,有多少Pod副本已成功升级
    • AVAILABLE: 当前集群可用Pod副本数量, 既集群中当前存活的Pod数量。
  • 查看Replica Set

    $ kubectl get rs
    NAME                     DESIRED   CURRENT   READY     AGE
    myapp-deploy-f4bcc4799   1         1         1         10m
    

1.7 Horizontal Pod Autoscale(HPA)

横向扩容,通过分析指标来动态扩容。

支持pod负载度量指标:

  • CPUUtilizationPercentage(暂不建议在生产使用)
  • 应用程序自定义的度量指标,比如服务在美妙内的相应请求书(TPS或QPS)

1.8 Service(服务)

service定义一个服务的访问入口,使用每个Node上的kube-proxy转发到具体Pod,实现负载均衡。每个service分配了一个全局唯一的虚拟IP地址,这个虚拟IP被称为Cluster IP,并在service的整个生命周期内,不会改变。

模板实例

apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  ports:
    - port: 8080
  selector:
    tier: frontend

上述内容定义了一个名为tomcat-svc的Service,他的服务端口为8080,拥有tier:=frontend这个Label的所以Pod实例都属于它。

三种IP:

  • NodeIP: Node节点的Ip地址。物理网卡上的IP。

  • Pod Ip: Pod的Ip地址。docker engine根据docker0网桥的ip地址段进行划分的。

  • ClusterIp :

    • Cluster IP 只作用于 Kubernetes Service 这个对象,并由k8s管理和分配IP地址 (来源于 Cluster IP 地址池)

    • 无法被Ping, 没有一个"实体网络对象"来响应

    • 只能结合Service Port 组成一个具体的通信端口,单独的Cluster IP 不具备TCP/IP通信的基础,并且他们属于集群内部封闭空间,如集群外想访问,需要额外的工作

    • k8s 集群内 Node IP网、Pod IP网与 Cluster IP网之间通信,采用k8s自己设计的一套特殊路由规则,与我们熟悉的IP路由有很大不同

    • 无法在集群外部直接使用这个地址

    • 采用NodePort 解决上述问题

      apiVersion: v1
      kind: Service 
      metadata:
        name: tomcat-service
      spec:
        type: NodePort
        ports:
        - port: 8080
          nodePort: 31002  # 手动指定NodePort 端口号,不然会自动分配。
        selector:
          tier: frontend 
      

​ NodePort还没完全解决外部访问Service的所有问题,如负载均衡。最好使用一个负载均衡器,由负载均衡器负责转发流量到后面某个Node的NodePort。如: 使用硬件 Load balancer 负载, 活 HAProxy 或者 Nginx。

创建

$ kubectl create -f tomcat-svc.yaml

查看

$ kubectl get endpoints
NAME         ENDPOINTS             AGE
kubernetes   192.168.18.131:6443   6m
tomcat-svc	 172.17.1.3:8080       1m
$ kubectl get svc tomcat-svc -o yaml

三种Port

  • containerPort:容器暴露的端口。也就是说可以通过该容器端口,访问对应的服务。
  • targetPort: 当service中指定的端口和pod中暴露出的端口不一致时,需要用targetPort指定出pod暴露出的端口
  • nodePort:  出现在Service中,指定外部机器可通过该物理端口,访问服务。其中type必须是NodePort

通过Add-On增值包的方式引入了DNS系统, 把服务名作为DNS域名, 这样程序就可以直接使用服务名查询ip进行通信连接了。

###1.9 Volume(存储卷)

与docker的volume区别

  • 定义在pod上
  • 被pod中多个容器共享
  • 与pod的声明周期相同
  • 支持多种类型Volume(ClusterFS、Ceph)

例如:给 Pod 增加一个 名字为 datavol 的 Volume, 挂载到 /mydata-data上

template:     
metadata:
  labels:
    app: mysql  
spec:
  volumes: 
    - name: datavol
      emptyDir: {}
  containers:    
  - name: mysql   
    image: mysql  
    volumeMounts:
      - mountPath: /mydata-data
        name: datavol

Volume类型

  • emptyDir:临时空间,Pod删除,则删除

  • hostPath:挂载宿主机上的文件和目录

    • 日志永久保存
    • 访问docker文件系统

    注意:不同的Node上具有相同配置的Pod可能会因为宿主机上文件和目录不同导致对Volume上目录和文件访问结果不一致;无法将hostPath纳入k8s资源配额管理。

  • gcePesistentDisk:使用谷歌公有云提供的永久磁盘。

  • awsElasticStore:亚马逊EBS Volume存储。

  • NFS:NFS网络文件系统。

    volumes: 
    - name: nfs
      nfs:
        server: nfs-server.localhost
        path: "/"
    

...

1.10 Persistent Volume

通过从虚拟机中定义一个网络存储,然后划出一个网盘并挂载在虚拟机上。Persistent Volume:简称 PV ,Persistent Volume Claim 简称PVC,PV和PVC功能类似。

与Volume区别:

  • PV只能是网络存储,不属于任何Node,但可以在每个Node访问
  • PV不定义在Pod上
  • PV支持多种类型

下面给出NFS类型的PV的一个yaml定义文件,声明了需要5Gi的存储空间:

apiVersion: v1
kind: PersistentVolume 
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs: 
    path: /somepath
    server: 172.17.0.2  

PV 的 accessModes 类型

  • ReadWriteOnce: 读写权限、并且只能被单个Node挂载
  • ReadOnlyMany: 只读权限、允许多个Node挂载
  • ReadWriteMany: 读写权限、允许多个Node挂载

如果Pod 想申请PV,,需要先定义一个PVC

apiVersion: v1
kind: PersistentVolumeClain 
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources: 
    requests:
      storage: 8Gi

然后在Pod 的 Volume 定义上引用上述PVC :

volumes: 
- name: datavol
  persistentVolumeClain:
    claimName: myclaim

1.11 Namespace(命名空间)

多用于多租户的资源隔离。

k8s 启动后,会创建一个名为default的Namespace 通过

kubectl get namespaces

如果不特别指明,则用户创建的Pod、RC、Service都将被系统创建到这个默认namespace。

创建命名空间

apiVersion: v1
kind: Namespace 
metadata:
  name: development

创建后可以指定这个资源对象属于哪个Namespace.

定义一个名为busybox的Pod, 放入上面创建的:

apiVersion: v1
kind: Pod 
metadata:
  name: busybox
  namespace: development
spec:
  containers:
  - image: busybox
  	command: 
  	- sleep
  	- "3600"
  	name: busybox

这时使用命令将看不到上面创建的pod, 默认使用的是default

kubectl get pods

需要添加参数--namespace 来查看

kubectl get pods --namespace=development

可以给每个命名空间实现租户隔离的同时,还是可以资源配额管理。

1.12 Annotation 注释

使用key=value键值对定义。作用是定义k8s对象的元数据(metadata),并用于label selector。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!