K8S架构图

在这里插入图片描述
通过架构图可以看到K8S的几个关键组件之间的工作方式

  1. APIS 是接受 scheduler ,controller manager, kubectl , etcd 等组件的调用
  2. 左边的是master节点,master节点里面的apis收到请求之后,就把请求发往对应的node节点里面的 kubelet中

k8s 组件

  1. APIS: 所有服务访问统一入口
  2. controller manager: 维护副本的期望数目
  3. scheduler: 负责接受任务,选择合适的节点分配任务
  4. etcd: 键值对数据库, 存储K8S所有信息
  5. kubelet: 直接跟容器引擎交互,实现容器的生命周期管理
  6. kube-proxy:负责写入规则至 IPTABLES,IPVS 实现服务映射访问

插件

  1. COREDNS: 可以为集群中的SVC创建一个域名IP的对应关系解析
  2. DASHBOARD:给K8S集群提供一个B/S结构访问体系
  3. INGRESS CONTROLLER: 实现7层代理
  4. FEDERATION:提供一个跨集群中心多K8S统一管理功能
  5. PROMETHEUS: 提供K8S集群的监控能力

概念

POD 概念

pod被控制器管理,不同类型的控制器管理的pod状态不同,控制器分为几种

ReplicationController & ReplicaSet & Deployment

replicationController 确保容器应用副本数始终保持在用户定义的副本数,如果有容器异常退出,会自动创建新的pod来替代。
replicaSet 跟 replicationController没有本质不同,官方建议使用replicaSet
建议使用Deployment来管理ReplicaSet

statefulSet

statefulSet 是为了解决 有状态服务的问题,其场景包括:
稳定的持久化存储,pod重新调度后还能访问到相同的持久化数据,基于PVC实现
稳定的网络标志,pod重新调度后其podname和hostname不变,基于headless service实现
有序部署,有序扩展,有序收缩,有序删除

DaemonSet

DaemonSet 确保全部nde上运行一个pod的副本,当有node加入集群时,会为他们新增一个pod。
典型用法:
在每个node上运行日志收集 daemon,例如 fluentd,logstash。
每个node上运行监控daemon,例如 prometheus

Job , Cronjob

job负责批处理任务,仅执行一次的任务,它保证批处理任务的一个或多个pod成功结束
Conjob管理基于时间的job,
给定时间点只运行一次
周期性的在给定时间点运行

网络通讯方式

同一个Pod内多个容器之间:lo
各pod之间通讯:overlay network
pod与service之间的通讯:各节点的iptables规则

flannel 网络解决方案

在这里插入图片描述
ETCD 给 flannel提供的数据:
存储管理flannel可分配id地址,监控ETCD中每个pod的实际地址,并在内存建立pod节点路由表

K8S中的资源

资源类型

  1. 名称空间级别: 不同名称空间之间相互资源是看不到的
    工作负载型资源: pod,replicaSet,Deployment,statefulSet,DaemonSet,Job,ConJob
    服务发现及负载均衡资源: service, ingress
    配置与存储资源: volume,CSI
    特殊类型 ConfigMap当配置中心使用,Secret保存敏感数据,DownwardAPI外部环境输出给容器
  2. 集群级别: role, 定义了之后,全部集群都可见
  3. 元数据型: HPA, 通过指标操作

资源清单

k8s中,使用yaml格式的文件来创建符合预期的pod,这样的 yaml文件成为资源清单
必须存在的属性

参数名字段类型说明
versionstringk8s API 的版本,基本上是V1
kindstringyaml文件定义的资源类型和角色,比如pod
metadataobject元数据对象,固定就写metadata
metadata.namestring元数据对象的名字,这里由我们编写,比如命名Pod的名字
metadata.namespacestring元数据对象的命名空间,由我们自身定义
specobject详细定义对象,固定值就写spec
spec.containers[]listspec对象的容器列表定义,是一个列表
spec.containers[].namestring这里定义容器的名字
spec.containers[].imagestring这里定义要用的镜像名称
spec.containers[].imagePullPolicystring定义镜像拉取策略,有Always,Never,IfNotPersent,默认Always
spec.containers[].command[]list指定容器启动命令,因为是数组可以指定多个,不指定则使用镜像打包时使用的启动命令
spec.containers[].args[]list指定容器启动命令参数,可以指定多个
spec.containers[].workingDirstring指定容器工作目录
spec.containers[].volumeMounts[]list指定容器内部的存储卷配置
spec.containers[].volumeMounts[].namestring指定可以被容器挂载的存储卷的名称
spec.containers[].volumeMounts[].mountPathstring指定可以被容器挂载的存储卷路径
spec.containers[].volumeMounts[].readOnlystring设置存储卷路径的读写模式,默认为读写模式
spec.containers[].ports[]list指定容器需要用到的端口列表
spec.containers[].ports[].namestring指定端口名称
spec.containers[].ports[].containerPortstring指定容器需要监听的端口号
spec.containers[].ports[].hostPortstring指定容器所在主机需要监听的端口号,设置了hostport不能在同一台启动两个副本
spec.containers[].ports[].protocolstring指定端口协议,默认为tcp
spec.containers[].env[]list指定容器运行前需要设置的环境变量列表
spec.containers[].env[].namestring指定环境变量名称
spec.containers[].env[].valuestring环境变量的值
spec.containers[].resourcesobject指定资源限制和资源请求的值
spec.containers[].resources.limitsobject指定容器运行时资源的上限
spec.containers[].resources.limits.cpustring指定cpu的限制
spec.containers[].resources.limits.memorystring内存的限制
spec.containers[].resources.requestsobject指定容器启动和调度时限制设置
spec.containers[].resources.requests.cpustringcpu请求
spec.containers[].resources.requests.memorystring内存请求
spec.restartolicystring定义pod重启策略,Always,OnFailure,Never
spec.nodeSelectorobject定义node的label过滤标签,kv格式指定
spec.imagePullSecretsobject定义pull镜像时使用secret名称,kv格式
spec.hostNetworkboolean定义是否使用主机网络,默认false

容器生命周期

在这里插入图片描述

  1. init容器
    pod能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的 init容器
    init容器总是运行到成功完成为止
    每个init容器必须在下一个init容器启动之前成功完成
    如果pod的init容器启动失败K8S会不断重启pod直到成功,如果 pod 的 restartPolicy为Never就不会重启
  2. init 模板
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
    - name: myapp-container
      image: busybox
      command: ['sh','-c','echo The app is running! && sleep 3600']
  initContainers:
    - name: init-myservice
      image: busybox
      command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
    - name: init-mydb
      image: busybox
      command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

这个模板创建了一个容器叫 myapp-container 然后两个init容器 init-myservice,init-mydb, init容器监听 myservice 和mydb
启动后发现init容器过不去,因为缺少了 myservice和mydb
在这里插入图片描述
创建一个myservice

apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

当创建了一个myservice之后,init-service的容器就找到了myservice于是就是结束
在这里插入图片描述
再创建一个mydb

apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377
  1. initC特殊说明
    在pod启动过程中,init容器混顺序在 网络和数据卷初始化之后启动,每个容器必须在下一个容器启动之前成功退出。网络和数据卷的初始化是在 pause中完成的

探针

探针是由 kubelet 对容器执行的定期诊断,要执行诊断, kubelet 调用由容器实现的handler,有三种类型的处理程序

  1. execAction: 在容器内执行指定命令,如果命令退出时返回码为0则诊断成功
  2. TCPSocketAction 对指定端口的容器ip地址进行tcp检查,如果端口打开,则诊断被认为是成功的
  3. HTTPGetAction 对指定端口路径的容器进行get请求,如果状态码大于200小于400则认为是成功的

探测方式

  1. livenessProbe: 在整个生命周期中一直存在,不断探测容器是否存活,如果不存活了,kubelet就会杀死容器
  2. readinessProbe: 指示容器是否准备好请求,如果没准备好,容器状态就不是就绪状态
探针检测-
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  containers:
    - name: test
      image: .....
      # 一直检测
      livenessProbe:
        httpGet:
          path: /health
          port: 8080
          scheme: HTTP
      # 程序开始的时候检测,如果不通过状态就不会就绪
      readinessProbe:
        httpGet:
          path: /health
          port: 8080
          scheme: HTTP

start stop

apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  containers:
    - name : test
      image: .....
      lifecycle:
      	# 开始之前执行的东西
        postStart:
          exec:
            command: ["bin/sh","-c","echo hello message > /usr/local/message"]
        # 结束的之前执行的东西
        preStop:
          exec:
          	command: ["/usr/bin/nginx","-s","quit"]

容器的状态

  1. Pending : pod 已经被k8s系统接受,但有一个或多个镜像尚未被创建,需要等待
  2. Running : 正在运行中
  3. Succeeded : pod中所有容器被成功终止
  4. Failed : 所有容器终止,但是至少有一个是异常退出
  5. Unknow: pod与主机通信失败

k8s 排查错误

  1. 如果一个容器出现报错的时候, 调用 kubectl get pod查看
    在这里插入图片描述
  2. 调用kubectl describe pod pod名称 ,查看pod信息
    在这里插入图片描述
  3. 已经确定是test的容器出错,就查看test容器的日志信息, kubectl logs pod名称 -c 容器名称
    在这里插入图片描述
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐