Kubernetes基础

  • kube-apiserver:集群的控制中枢,各个模块之间信息交互都需要经过api-server,同时也是集群管理、资源配合、整个集群安全机制的入口

  • Controller-Manager:集群的状态管理器。保证Pod或者其他资源达到期望值。也是需要和apiserver进行通信,在需要的时候创建、更新或删除它所管理的资源

  • Scheduler:集群的调度中心,根据指定的一系列条件选择一个或一批最佳的节点部署我们的Pod。

  • etcd:一个kv数据库,强制性要求ssd硬盘。保存一些集群的信息。一般是奇数个

  • Node:工作节点

  • Kubelet:负责监听节点上Pod的状态,同时负责上报节点和节点上Pod的状态,负责与Master节点通信,并管理节点上的Pod

  • kube-proxy:负责Pod之间的通信和负载均衡,将指定的流量分发到后端正确的机器上 curl 127.0.0.1:10249/proxyMode

  • ipvs:监听Master节点增加和删除service以及endpoint的消息,调用Netlink接口创建相应的IPVS规则,通过IPVS规则,将流量转发至相应的Pod上

  • iptables:监听Master节点增加和删除service以及endpoint的消息,对于每一个service,他都会创建一个iptables规则。将service的clusterIP代理到后端对应的Pod上。

  • eBPF:新的一种网络的东西

  • Calico:符合CNI标准的网络插件,给每个Pod生成一个唯一的ip地址。并且把每个节点当做一个路由器。

# 在对应节点上
route -n
  • CoreDNS:用于Kubernetes集群内部Service的解析,可以让Pod把Service名称解析成IP地址,然后通过Service的IP地址进行连接到对应的应用上
Pod是什么
  • PV/PVCRBACstorageClassingressClass是没有namespace隔离的

  • Podkubernetes中最小的单元。它由一组、一个或多个容器组成,每个Pod运行包含了pause容器。Pause容器是pod的父容器,主要负责僵尸进程的回收管理,通过Pause容器可以使同一个Pod里面多个容器共享存储、网络、PID、IPC等

在这里插入图片描述
引入pod是因为后面不一定是docker,并且微服务的关联性会很强,每一个pod都有独立的ip,便于管理

定义一个Pod
apiVersion: v1  # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
  namespace: default # 可选,Pod所在的命名空间,不指定默认为default,可以使用-n 指定namespace 
  labels:       # 可选,标签选择器,一般用于过滤和区分Pod
    app: nginx
    role: frontend # 可以写多个
  annotations:     # 可选,注释列表,可以写多个
    app: nginx
spec:              # 必选,用于定义容器的详细信息
  initContainers:  # 初始化容器,在容器启动之前执行的一些初始化操作
  - command:
    - sh
    - -c
    - echo "I am InitContainer for init some configuration"
    image: busybox
    imagePullPolicy: IfNotPresent   # 镜像拉取策略
    name: init-container
  containers:   # 必选,容器列表
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: nginx:latest    # 必选,容器所用的镜像的地址
    imagePullPolicy: Always     # 可选,镜像拉取策略
    command: # 可选,容器启动执行的命令
    - nginx 
    - -g
    - "daemon off;"
    workingDir: /usr/share/nginx/html       # 可选,容器的工作目录
    volumeMounts:   # 可选,存储卷配置,可以配置多个
    - name: webroot # 存储卷名称
      mountPath: /usr/share/nginx/html # 挂载目录
      readOnly: true        # 只读
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号
      protocol: TCP # 端口协议,默认TCP
    env:    # 可选,环境变量配置列表
    - name: TZ      # 变量名
      value: Asia/Shanghai # 变量的值
    - name: LANG
      value: en_US.utf8
    resources:      # 可选,资源限制和资源请求限制
      limits:       # 最大限制设置
        cpu: 1000m
        memory: 1024Mi
      requests:     # 启动所需的资源
        cpu: 100m
        memory: 512Mi
#    startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式同时只能使用一种。
#      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
#            path: /api/successStart # 检查路径
#            port: 80
    readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
            path: / # 检查路径
            port: 80        # 监控端口
    livenessProbe:  # 可选,健康检查
      #exec:        # 执行容器命令检测方式
            #command: 
            #- cat
            #- /health
    #httpGet:       # httpGet检测方式
    #   path: /_health # 检查路径
    #   port: 8080
    #   httpHeaders: # 检查的请求头
    #   - name: end-user
    #     value: Jason 
      tcpSocket:    # 端口检测方式
            port: 80
      initialDelaySeconds: 60       # 初始化时间
      timeoutSeconds: 2     # 超时时间
      periodSeconds: 5      # 检测间隔
      successThreshold: 1 # 检查成功为2次表示就绪
      failureThreshold: 2 # 检测失败1次表示未就绪
    lifecycle:
      postStart: # 容器创建完成后执行的指令, 可以是exec httpGet TCPSocket
        exec:
          command:
          - sh
          - -c
          - 'mkdir /data/ '
      preStop:
        httpGet:      
              path: /
              port: 80
      #  exec:
      #    command:
      #    - sh
      #    - -c
      #    - sleep 9
  restartPolicy: Always   # 可选,默认为Always
  #nodeSelector: # 可选,指定Node节点的标签
  #      region: subnet7
  imagePullSecrets:     # 可选,拉取镜像使用的secret,可以配置多个
  - name: default-dockercfg-86258
  hostNetwork: false    # 可选,是否为主机模式,如是,会占用主机端口
  volumes:      # 共享存储卷列表
  - name: webroot # 名称,与上述对应
    emptyDir: {}    # 挂载目录
        #hostPath:              # 挂载本机目录
        #  path: /etc/hosts
Pod探针
  • StartupProbe:k8s 1.16后新加的探测方式,用于判断容器内应用程序是否已经启动。StartupProbe成功后才会用另外两个探针方式。只执行一次 。如果配置了startupProbe,就会先禁止其他的探测,直到它成功为止,成功后将不在进行探测。主要用于程序启动特别忙的情况

  • LivenessProbe:用于探测容器是否运行,如果探测失败,kubelet会根据配置的重启策略进行相应的处理。若没有配置该探针,默认就是success。

  • ReadinessProbe:一般用于探测容器内的程序是否健康,它的返回值如果为success,那么代表这个容器已经完成启动,并且程序已经是可以接受流量的状态

Pod 探针的检测方式
  • ExecAction:在容器内执行一个命令,如果返回值为0,则认为容器健康
  • TCPSocketAction:通过TCP连接检查容器内的端口是否是通的,如果是通的就认为容器健康。
  • HTTPGetAction:通过应用程序暴露的API地址来检查程序是否是正常的,如果状态码为200~400之间,则认为容器健康。
Pod退出流程
  • lifecycle:容器的生命周期
  • podStart:容器创建完成之后,pod启动之前完成的命令 并不能保证命令的启动在启动之前,很少用
  • preStop:在容器被清理掉之前完成的命令

在这里插入图片描述
preStop:先去请求Eureka接口,把自己的IP地址和端口号,进行下限,euraka从注册表中删除该应用的IP地址,然后容器进行sleep 90操作

RC 和 RS
  • Replication Controller(复制控制器,RC)和 ReplicaSet(复制集,RS)是两种简单部署 Pod的方式。因为在生产环境中,主要使用更高级的 Deployment 等方式进行 Pod 的管理和部署,所以本节只对 Replication Controller 和 Replica Set 的部署方式进行简单介绍。

  • ReplicaSet 是支持基于集合的标签选择器的下一代 Replication Controller,它主要用作Deployment 协调创建、删除和更新 Pod,和 Replication Controller 唯一的区别是,ReplicaSet 支持标签选择器。在实际应用中,虽然 ReplicaSet 可以单独使用,但是一般建议使用 Deployment 来自动管理 ReplicaSet,除非自定义的 Pod 不需要更新或有其他编排等。 一般是使用 deployment 部署和管理ReplicaSet,再由 ReplicaSet 部署和管理 Pod

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # modify replicas according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
    matchExpressions:
      - {key: tier, operator: In, values: [frontend]}
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
         # If your cluster config does not include a dns service, then to
         # instead access environment variables to find service host
         # info, comment out the 'value: dns' line above, and uncomment the
         # line below.
         # value: env
        ports:
        - containerPort: 80
Deployment [无状态的应用部署控制器]

deployment详解

用于部署无状态的服务,这个最常用的控制器。一般用于管理维护企业内部无状态的微服务,比如configserver、zuul、springboot。他可以管理多个副本的 Pod 实现无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。

nginx-deploy.yaml如下:

apiVersion: apps/v1       # 指定api版本,此值必须在kubectl api-versions中
kind: Deployment          # 控制器类型,用来指定创建资源的角色/类型
metadata:                 # 资源的元数据/属性
  annotations:            # deployment 的注释
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2020-09-19T02:41:11Z"   # 创建时间
  generation: 1           
  labels:                 # deployment本身的labels 设定资源的标签
    app: nginx
  name: nginx             # deployment 的名字,在同一个 namespace 中必须唯一
  namespace: default      # deployment 部署的 namespace 的名字
spec:                     # 资源规范字段
  progressDeadlineSeconds: 600
  replicas: 1              # 副本数
  revisionHistoryLimit: 3  # 历史记录保留的个数,默认是10个
  selector:                # 选择器
    matchLabels:           # replicas匹配pod的labels,必须和template。metadata.labels一致
      app: nginx
  strategy:                # 策略
    rollingUpdate:         # 滚动升级的策略
      maxSurge: 25%        # 最大额外可以存在的副本数,可以为百分比,也可以为整数
      maxUnavailable: 25%  # 在更新过程中能够进入不可用状态的pod的最大值,可以为百分比,也可以为整数
    type: RollingUpdate    # 滚动更新策略
 template:                 # template下面的就是pod的一些参数模版
   metadata:               # 资源的元数据/属性
     creationTimestamp: null
     annotations:          # 自定义注解列表
        sidecar.istio.io/inject: "false"  # 自定义注解名字
     labels:        # pod的labels, 必须和spec.selectors.matchLabels一致。用来给replicas匹配的
       app: nginx
   spec:            # pod资源规范字段
     containers:
     - image: nginx:1.15.2   # 镜像
       imagePullPolicy: IfNotPresent  # 每次pod启动拉取镜像的策略  三个选择 Always、Never、IfNotPresent  Always,每次都检查;Never,每次都不检查(不管本地是否有);IfNotPresent,如果本地有就不检查,如果没有就拉取
       name: nginx         # 容器的名字
       command: [string]    #容器的启动命令列表,如不指定,使用打包时使用的启动命令
       args: [string]     #容器的启动命令参数列表
       ports:
       - name: http  # 名称
         containerPort: 8080  # 容器对外开放的端口
         protocol: TCP  # 协议
       env:       # 容器运行前需设置的环境变量列表
       - name: string     # 环境变量名称
         value: string    # 环境变量的值
       workingDir: string   # 容器的工作目录
       volumeMounts:        # 挂载到容器内部的存储卷配置
       - name: string     # 引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
         mountPath: string    # 存储卷在容器内mount的绝对路径,应少于512字符
         readOnly: boolean    # 是否为只读模式
       volumes:       # 在该pod上定义共享存储卷列表
       - name: string     # 共享存储卷名称 (volumes类型有很多种)
         emptyDir: {}     # 类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
         hostPath: string     # 类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
           path: string     # Pod所在宿主机的目录,将被用于同期中mount的目录
         secret:      # 类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
           scretname: string  
           items:     
           - key: string
             path: string
         configMap:     #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
           name: string
           items:
           - key: string
             path: string
       resources:          # 资源管理
         limits:           # 最大使用
           cpu: 300m       # CPU, 1核心 = 1000m
           memory: 500Mi   # 内存,1G = 1024 Mi
         requests:         # 容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
           cpu: 100m
           memory: 100Mi
       startupProbe: # 检测容器内进程是否完成启动。 exec httpGet TCPSocket 中任意一个
         exec:      #对Pod容器内检查方式设置为exec方式
           command: [string]  #exec方式需要制定的命令或脚本
         tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
           port: number
         httpGet:  # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。 返回200-399之间,则认为容器正常
           path: /api/successStart # httpGet 检查的url路径
           port: 80  # 端口
           scheme: HTTP # 协议
           HttpHeaders:  # 需要添加请求头的时候使用
             - name: string
               value: string
       livenessProbe: # pod 内部健康检查的设置 exec httpGet TCPSocket 中任意一个
         exec:      #对Pod容器内检查方式设置为exec方式
           command: [string]  #exec方式需要制定的命令或脚本
         tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
           port: number
         httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
           path: /healthCheck # URI地址
           port: 8080 # 端口
           scheme: HTTP # 协议
         initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
         timeoutSeconds: 5 # 检测的超时时间
         periodSeconds: 30 # 检查间隔时间
         successThreshold: 1 # 成功门槛  检查成功几次算完全成功
         failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
       readinessProbe: # Pod 的服务健康检查设置  exec httpGet TCPSocket 中任意一个
         exec:      #对Pod容器内检查方式设置为exec方式
           command: [string]  #exec方式需要制定的命令或脚本
         tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
           port: number
         httpGet:  # 不止这一种方式,但一般比较推荐
           path: /healthCheck
           port: 8080
           scheme: HTTP
         initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
         timeoutSeconds: 5 # 检测的超时时间
         periodSeconds: 30 # 检查间隔时间
         successThreshold: 1 # 成功门槛  检查成功几次算完全成功
         failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
       lifecycle:
         postStart:     # 容器创建完成之后,pod启动之前完成的命令,  
           exec:        # 可以是exec httpGet TCPSocket
             command:
               - sh
               - -c
               - 'mkdir /data/ '
         preStop:      # 在容器被清理掉之前完成的命令
           exec:       # 可以是exec httpGet TCPSocket
             command: ['sh -c sleep 9']   
       terminationMessagePath: /dev/termination-log
       terminationMessagePolicy: File
     dnsPolicy: ClusterFirst
     restartPolicy: Always  # Pod的重启策略 Always表示一旦不管以何种方式终止运行,kubelet都将重启 OnFailure表示只有Pod以非0退出码退出才重启  Nerver表示不再重启该Pod
     nodeSelector: obeject  # 设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
     schedulerName: default-scheduler
     securityContext: {}
     terminationGracePeriodSeconds: 30
StatefulSet [有状态的应用部署控制器]

StatefulSet(有状态集,缩写为 sts)常用于部署有状态的且需要有序启动的应用程序,比如在进行 SpringCloud 项目容器化时,Eureka 的部署是比较适合用 StatefulSet 部署方式的,可以给每个 Eureka 实例创建一个唯一且固定的标识符,并且每个 Eureka 实例无需配置多余的 Service,其余 Spring Boot 应用可以直接通过 Eureka 的 Headless Service 即可进行注册

DaemonSet [守护进程集控制器]

守护进程集,缩写为 ds,在所有节点或者是匹配的节点上都部署一个 Pod

  • 运行集群存储的 daemon,比如 ceph 或者 glusterd
  • 节点的 CNI 网络插件,calico
  • 节点日志的收集:fluentd 或者是 filebeat
  • 节点的监控:node exporter
  • 服务暴露:部署一个 ingress nginx
Logo

开源、云原生的融合云平台

更多推荐