Kubernetes学习笔记及重点知识解析

前言

本文是我在学习Kubernetes的过程中做的一些笔记,主要围绕着Kubernetes的核心API展开,讲解Pod、Service、Volume、Deployment等的概念、功能和原理,以及如何使用它们来部署一个容器化项目。本文只涉及了Kubernetes核心和常用的知识,如果需要深入的学习,推荐Kubernetes Handbook——Kubernetes中文指南/云原生应用架构实践手册

搭建Kubernetes集群,可以参考:使用Rancher搭建Kubernetes集群

一.Kubernetes工作原理

下图非常直观的展示了Kubernetes是如何运作的。
操作对象是指Kubernetes的API,这些API可以通过模板文件(.yaml格式)进行配置;功能组件是指运行在物理机上的Kubernetes服务进程,这些服务进程根据模板文件中的配置,通过协同工作完成用户需求;功能特性是Kubernetes能够实现的功能特性。本文重点介绍Kubernetes的API,即如何使用Kubernetes集群

在这里插入图片描述

二.Kubernetes中的API

以下列举的内容是Kubernetes中的Object,这些对象都可以在模板文件中作为一种 API 类型来配置。

Pod
Node
Namespace
Service
Volume
PersistentVolume
Deployment
Secret
StatefulSet
DaemonSet
ServiceAccount
ReplicationController
ReplicaSet
Job
CronJob
SecurityContext
ResourceQuota
LimitRange
HorizontalPodAutoscaling
Ingress
ConfigMap
Label
CustomResourceDefinition
Role
ClusterRole

这些Object分别可以完成不同的功能,下表是对他们的分类:

类别名称
资源对象Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition
存储对象Volume、PersistentVolume、Secret、ConfigMap
策略对象SecurityContext、ResourceQuota、LimitRange
身份对象ServiceAccount、Role、ClusterRole

在资源对象中还可以进行细分:

负责定义容器:

Pod是基本的资源单位,它们可以对需要部署到Kubernetes集群的容器进行各种配置

负责管理Pod:

ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、HorizontalPodAutoscaling、Job、CronJob是Pod管理器,可以创建和管理多个Pod,Pod的定义可以在这些管理器中完成。

负责管理网络:

Service、Ingress可以给Pod设置网络服务,让集群外的用户和集群内的负载可以访问Pod

负责进行资源隔离和资源调度:

Node、Namespace、Label和Kubernetes如何分配调度资源对象(Pod)有关

从下图可以看出,Kubernetes集群中的这些API主要是围绕着Pod来工作的。Pod定义容器,然后由其他API通过操作Pod完成具体的功能。
在这里插入图片描述

三.一个简单的将容器部署到Kubernetes集群的例子

向Kubernetes集群部署应用需要先在一个.yaml文件(模板)中对这个应用进行配置,设置名称、存储、网络服务等内容。
然后执行命令kubectl create -f 文件名.yaml

在这里插入图片描述
下图是一个简单的模板文件的内容,下文会详细的介绍如何在模板文件中进行配置,这个模板文件完成了以下几项配置:

  1. 创建了两个资源类型,ReplicationController和Service
  2. Pod的定义被放到了ReplicationController中,ReplicationController中定义了:
    Pod的名称 — tomcat
    创建Pod的数量 — 1个
    该Pod使用的镜像 — 192.168.110.171:5000/tomcat
    Pod对集群内的其他应用暴露端口5002
    Pod在mykubernetes这个名称空间下运行
  3. Service定义了集群外部的用户可以通过端口30035来访问容器的5002端口发布的内容
apiVersion: v1
kind: ReplicationController                #设置Kubernetes中的API类型,
metadata:
 name: tomcat
 namespace: mykubernetes             #设置名称空间,在mykubernetes这个名称空间下运行,对其他名称空间中的应用不可见
spec:
 replicas: 1                                  # 设置实例数,Pod管理器均具备这样的功能,可以同时创建多个Pod
 selector:
  app: tomcat
 template:
  metadata:
   labels:
    app: tomcat
  spec:
   containers:                              # 对容器的配置
   - name: tomcat
     image: 192.168.110.171:5000/tomcat
     ports:
     - containerPort: 5002
---
apiVersion: v1
kind: Service
metadata:
 name: tomcat
spec:
 type: NodePort
 ports:
  - port: 5002
    nodePort: 30035
 selector:
   app: tomcat


四.Kubernetes中的资源管理(Pod及其控制器等)

Pod

Pod是kubernetes中可以创建和部署的最小的单位。Pod代表着集群中运行的进程,

在Kubernetes集群中,一个Pod中可以运行一个或多个容器,一个Pod中运行一个容器最常见的用法;在这种使用方式中,你可以把Pod想象成是单个容器的封装。kuberentes管理的是Pod而不是直接管理容器。一个Pod中也可以同时运行多个容器,它们共享容器存储、网络和容器运行配置项。

Pod中的容器总是被同时调度,有共同的运行环境。你可以把一个Pod想象成是运行独立应用的一个“逻辑主机”——其中运行着一个或者多个紧密耦合的应用容器。每个Pod都有自己的IP地址(Kubernetes集群内部的虚拟IP),有自己独占的存储单元。

Pod的完整定义

apiVersion: v1                    #必选,版本号,例如v1,版本号必须可以用 kubectl api-versions 查询到 .
kind: Pod                      #必选,Pod
metadata:                      #必选,元数据
  name: string                    #必选,Pod名称
  namespace: string               #必选,Pod所属的命名空间,默认为"default"
  labels:                       #自定义标签
    - name: string                 #自定义标签名字
  annotations:                           #自定义注释列表
    - name: string
spec:                            #必选,Pod中容器的详细定义
  containers:                       #必选,Pod中容器列表
  - name: string                        #必选,容器名称,需符合RFC 1035规范
    image: string                       #必选,容器的镜像名称
    imagePullPolicy: [ Always|Never|IfNotPresent ]  #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
    command: [string]               #容器的启动命令列表,如不指定,使用打包时使用的启动命令
    args: [string]                     #容器的启动命令参数列表
    workingDir: string                     #容器的工作目录
    volumeMounts:                 #挂载到容器内部的存储卷配置
    - name: string                 #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
      mountPath: string                 #存储卷在容器内mount的绝对路径,应少于512字符
      readOnly: boolean                 #是否为只读模式
    ports:                      #需要暴露的端口库号列表
    - name: string                 #端口的名称
      containerPort: int                #容器需要监听的端口号
      hostPort: int                    #容器所在主机需要监听的端口号,默认与Container相同
      protocol: string                  #端口协议,支持TCP和UDP,默认TCP
    env:                          #容器运行前需设置的环境变量列表
    - name: string                    #环境变量名称
      value: string                   #环境变量的值
    resources:                          #资源限制和请求的设置
      limits:                       #资源限制的设置
        cpu: string                   #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
        memory: string                  #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
      requests:                         #资源请求的设置
        cpu: string                   #Cpu请求,容器启动的初始可用数量
        memory: string                    #内存请求,容器启动的初始可用数量
    livenessProbe:                    #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
      exec:                     #对Pod容器内检查方式设置为exec方式
        command: [string]               #exec方式需要制定的命令或脚本
      httpGet:                    #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:            #对Pod内个容器健康检查方式设置为tcpSocket方式
         port: number
       initialDelaySeconds: 0       #容器启动完成后首次探测的时间,单位为秒
       timeoutSeconds: 0          #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodSeconds: 0           #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged: false
    restartPolicy: [Always | Never | OnFailure] #Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
    nodeSelector: obeject         #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
    imagePullSecrets:         #Pull镜像时使用的secret名称,以key:secretkey格式指定
    - name: string
    hostNetwork: false            #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
    volumes:                  #在该pod上定义共享存储卷列表
    - name: string              #共享存储卷名称 (volumes类型有很多种)
      emptyDir: {}              #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
      hostPath: string            #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
        path: string                #Pod所在宿主机的目录,将被用于同期中mount的目录
      secret:                 #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
        scretname: string  
        items:     
        - key: string
          path: string
      configMap:                      #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
        name: string
        items:
        - key: string
          path: string

Pod管理器

Pod的控制器可以分为持久性控制器和非持久性控制器。持久性控制器有ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet等,非持久性控制器有Job、CronJob。

ReplicationController

ReplicationController提供了自动化的Pod管理功能。可以控制Pod的副本数量,实现Pod的自动创建、补足、替换、删除Pod副本,提高应用的容灾能力,减少由于节点崩溃等意外状况造成的损失。
ReplicaSet、Deployment都是对ReplicationController的升级,他们完成的功能是一样的,在较早的Kubernetes版本中只有ReplicationController,而现在随着Deployment的退出,ReplicationController已经逐渐被淘汰。

ReplicaSet

ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,ReplicaSet比ReplicationController多了支持集合式的selector的功能(ReplicationController 仅支持等式)。随着Deployment的推出,ReplicaSet很少被用在项目中。

Deployment

Deployment为Pod提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController 来方便的管理应用。他有ReplicationController的所有功能,是Kubernetes官方最推荐的部署持久性无状态应用的Pod管理器。

下图是一个Deployment的创建流程

在这里插入图片描述

StatefulSet

StatefulSet是管理有状态应用的Pod控制器。在Pods管理的基础上,保证Pods的顺序和一致性。StatefulSet可以根据需要按顺序部署和扩展Pod,按顺序终止及删除Pod,按顺序滚动更新Pod

DaemonSet

DaemonSet确保全部(或者一些)Node 上运行一个Pod的副本。当有Node加入集时,DaemonSet会自动的为新加入的节点创建一个Pod副本 。当有Node被移除集群时,DaemonSet也会自动的将Pod副本删除。删除DaemonSet将会删除它创建的所有Pod。

HorizontalPodAutoscaling

HorizontalPodAutoscaling(HPA),即Pod 的水平自动扩展。自动扩展主要分为两种,其一为水平扩展,针对于实例数目的增减;其二为垂直扩展,即单个实例可以使用的资源的增减。HPA属于前者。
HPA的操作对象是RC、RS或Deployment对应的Pod,HPA会自动检测物理资源的使用情况和Pod的负责情况,动态的调整集群中Pod的副本数量。在访问量高的时候,自动增加Pod副本数,访问量减小时自动减小Pod副本。

在这里插入图片描述

Job

上文提到的Deployment等类型的控制器,会控制Pod保持预期数目、持久运行下去,除非用户明确删除,否则这些对象一直存在,它们针对的是耐久性任务。对于非耐久性任务,比如压缩文件,任务完成后,Pod需要结束运行,不需要Pod继续保持在系统中,这个时候就要用到Job。因此Job是对Deployment等持久性控制器的补充。

CronJob

Kubernetes官网对CronJob的定义是:管理基于时间的Job。CronJob可以在给定时间点只运行一次Job,也可以周期性地在给定时间点运行Job,可以说是Job的管理器。

五.Kubernetes中的网络管理(服务发现)

Kubernetes集群中的网络是比较复杂的,Kubernetes集群有自己的虚拟网络,在Kubernetes集群中的Pod不经过配置是无法被外部用户访问到的。

Service

Service是Kubernetes里最核心的资源对象之一,Kubernetes通过Service为一组具有相同功能的容器应用提供一个统一的入口地址,并且可以将请求进行负载均衡后分发到后端的各个容器应用上。

上游的应用通过Service提供的入口地址来访问Service负责代理的一组Pod实例。 Service与其负责代理的Pod副本之间通过Label Selector来实现对接。Label Selector还可以连接ReplicationController和Pod,关于Label Selector实现的功能,在后文会详细介绍

在这里插入图片描述

Service的出现主要是为了解决Pod频繁更迭的问题。在没有Service时,Kubernetes集群会为每一个Pod分配一个虚拟网络中的IP,集群内部和外部的用户都通过这个虚拟IP来访问Pod。但是,Pod生命周期短,状态不稳定,Pod异常后,Kubernetes会为新生成的Pod分配新的IP,Pod的IP更新后所有需要访问这个Pod的应用都需要做一定的调整,非常麻烦。

Service出现后,通过Service对pod做代理,Service有固定的IP(ClusterIP),当Pod更迭后Service还能继续给新的Pod做代理,上游应用就不用调整了。这样,通过Service提供的固定IP,用户再也不用关心需要访问哪个Pod,以及Pod是否发生改变,大大提高了服务质量。如果Pod使用Deployment创建了多个副本,那么Service就能代理多个相同的Pod,通过kube-proxy,实现负载均衡。

下面是一个简单的Service类型的模板文件的定义,它只给出了一个Service必不可少的配置:

apiVersion: v1
kind: Service
metadata:
 name: tomcat
spec:
 type: NodePort
 ports:
  - port: 5002
    targetPort:5002
    nodePort: 30035
 selector:
   app: tomcat

这里的spec.type选择的是NodePort,可选项一共有三种:

  1. ClusterIP:虚拟IP类型,使用ClusterIP定义的端口只能在集群内部使用
  2. NodePort:配置外部用户可以直接访问到的端口
  3. LoadBalancer:配置外部用户可以访问的端口,同时有负载均衡的功能,在公有云中使用

在Service中可以定义三种类型的端口,分别是:

  1. Port :Seriver暴露在Kubernetes内部的虚拟网络Cluster上的端口,是提供给集群内部客户访问Pod的入口,Port定义的端口。
  2. NodePort:Kubernetes提供给集群外部客户访问Pod的一种方式,外部用户可以使用集群中任意一个节点的IP+NodePort访问到Pod。NodePort虽然提供了给外部用户访问集群内Pod的方式,但是NodePort有一个严重的缺点就是没有负载均衡功能,所以实际使用中不会使用NodePort发布服务。
  3. targetPort:targetPort定义了Pod上的端口,发送到Pod端口和NodePor端口的请求,经过kube-proxy服务进程的代理,转发到Pod的targetPort端口,从而让Pod接收到请求。

Kubernetes内部的虚拟网络非常复杂,一篇文章根本讲不清楚,Kubernetes官网的中文文档写的非常好,如果想对Kubernetes的虚拟网络有更深的认识,推荐看看官网对Service的讲解 Kubernetes中的Service详解

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值