目录

k8s学习笔记——基础篇——基本概念

简介:k8s常用组件的介绍。

Kubernetes基础

Kubernetes是谷歌以Borg为前身,基于谷歌15年生产环境经验的基础上开源的一个项目,Kubernetes致力于提供跨主机集群的自动部署、扩展、高可用以及运行应用程序容器的平台。

Master节点

整个集群的控制中枢。

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

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

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

  • Etcd:键值数据库,保存一些集群的信息,一般生产环境中建议部署三个以上节点(奇数个)。

Node节点

工作节点。又称Worker、node节点、minion节点

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

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

    • 查看Kube-proxy工作模式:curl 127.0.0.1:10249/proxyMode

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

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

  • 其他组件

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

    • CoreDNS:用于Kubernetes集群内部Service的解析,可以让Pod把Service名称解析成IP地址,然后通过Service的IP地址进行连接到对应的应用上。

    • Docker:容器引擎,负责对容器的管理。

Pod

Pod是Kubernetes中最小的单元,它由一组、一个或多个容器组成。每个Pod还包含了一个Pause容器。

  • Pause容器是Pod的父容器,主要负责僵尸进程的回收管理,通过Pause容器可以使同一个Pod里面的多个容器共享存储、网络、PID、IPC等。
image-20220815204649925

定义一个Pod

1
vim pod.yaml

添加以下内容:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
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

常用命令

1
2
3
4
5
6
7
8
# 生成pod
kubectl create -f pod.yaml

# 查询pod
kubectl get pod -n "namespace"

# 删除pod
kubectl delete -f pod.yaml

Pod探针

  • StartupProbe:k8s1.16版本后新加的探测方式,用于判断容器内应用程序是否已经启动。如果配置了startupProbe,就会先禁止其他的探测,直到它成功为止,成功后将不在进行探测。

    • 用于程序启动特别慢的情况下。

    • 只启动一次,就不再检查了。

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

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

Pod探针的检测方式

  • ExecAction:在容器内执行一个命令,如果返回值为0,则认为容器健康。

  • TCPSocketAction:通过TCP连接检查容器内的端口是否是通的,如果是通的就认为容器健康。

  • HTTPGetAction:通过应用程序暴露的API地址来检查程序是否是正常的,如果状态码为200~400之间,则认为容器健康。(用的最多

探针检查参数配置

1
2
3
4
5
initialDelaySeconds: 60   # 初始化时间
timeoutSeconds: 5         # 超时时间
periodSeconds: 10          # 检测间隔
successThreshold: 1       # 检查成功为1次表示就绪
failureThreshold: 5       # 检测失败5次表示未就绪

问题:计算pod的重启时间

答:

  1. 每次检查的间隔是10秒,最长超时时间是5秒,也就是单次检查应该是10 + 5 = 15秒。

  2. 所以最长的重启时间为(10 + 5)* 5 。

此时又分为了两种情况:

  1. 首次启动时:最长重启时间需要加上initialDelaySeconds,因为需要等待initialDelaySeconds秒后才会执行健康检查。最长重启时间:(periodSeconds + timeoutSeconds) × failureThreshold + initialDelaySeconds 。

  2. 程序启动完成后:此时不需要计入initialDelaySeconds,最长重启时间:(periodSeconds + timeoutSeconds) × failureThreshold 。

注意

  1. initialDelaySeconds时长小于程序启动时间,会导致程序未启动就被重启,导致死循环。
  2. LivenessProbe检查通过,而ReadinessProbe一直未通过,则会导致pod一直无法工作,却又不能杀死。

pod退出

Prestop:进行pod结束前的收尾工作。比如在JavaCloud项目中:先去请求eureka接口,把自己的IP地址和端口号,进行下线,eureka从注册表中删除该应用的IP地址。然后容器执行:

1
2
sleep 90
kill `pgrep java`
image-20220815205037507

注:如果超过了k8s预留的时间,即使sleep没有结束,pod也会被杀掉。

1
2
# deployment.yaml
terminationGracePeriodSeconds: 30