Kubernetes学习

616 阅读10分钟

为何要用K8S

开发者 VS 运维

让开发者和运维做他们擅长的事情

  • 运维
    • 掌管生产部署,硬件设施
    • 关心系统安全性,利用率以及其他开发人员不重视的方面
    • 不想处理应用内在的依赖
    • 不想怎么更改底层系统或者基础设施会影响应用
  • 开发
    • 喜欢开发新特性,提高用户体验
    • 不想参与底层系统处理,希望将管理交给运维

K8S达到了上述目标:

  • 通过抽象硬件,暴露出单独的管理平台

  • 使开发者可以配置,部署应用

  • 单体到微服务

  • 微服务的难题

  • 一台服务器跑多个微服务冲突问题

  • 虚拟机隔离VS容器隔离

  • APPS在多个虚拟机 vs 多个容器

  • Docker运行

  • VM VS 容器

K8S

  • 框架

容器技术

  • Namespace:隔离环境
    • Mount(mnt)
    • ProcessID(PID)
    • Network(NET)
    • Inter-Process Communication(IPC)
    • UTS
    • User ID(user)
  • CGroups:限制使用的资源,CPU,宽带,内存等等

Docker

  • Images:包含应用及其环境,由Image Layers组成
  • Registries:镜像中心
  • Containers:隔离资源

示例

const http = require('http');
const os = require('os');

console.log("Kubia server starting...");

var handler = function(request, response) {
  console.log("Received request from " + request.connection.remoteAddress);
  response.writeHead(200);
  response.end("You've hit " + os.hostname() + "\n");
};

var www = http.createServer(handler);
www.listen(8080);
  • Dockerfile
    • FROM:集成的基础镜像
    • ADD:添加内容
    • ENTRYPOINT:执行的命令
FROM node:7
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"]
$ docker build -t kubia .

  • Docker镜像组成

  • Docker VS 虚拟机

运行对比

  • 裸机,虚拟机,Docker

  • Docker核心开发流程

Kubernetes

好处:

  • 简化应用部署
  • 更合理的使用硬件资源
  • 监控检测及自我修复
  • 自动扩容
  • 简化应用开发

K8S集群

总结

  • 单体服务方便部署,但不方便扩展,很难维护,不方便开发
  • 微服务方便开发各个模块,但很难像单体服务一样部署,配置
  • Linux容器提供了一些虚拟机的好处,但更轻量,更好的利用硬件资源
  • Docker提升了已有的Linux容器技术,更快,更简单的打包应用的环境
  • Kubernetes将数据中心暴露给应用程序单个的可计算的资源
  • 应用开发人员可以不需要系统运维的帮助,通过Kubernetes自己部署应用
  • 运维人员可以自动弄化管理失败节点重试

基础组件

  • Master
    • K8S API Server:沟通
    • Scheduler:分配资源
    • Controller Manager:控制,比如复制,追踪处理失败节点等等
    • etcd:分布式存储,存储配置等信息
  • Worker
    • 容器:Docker或其他容器
    • Kubelet:沟通API Server,控制容器
    • Kube-Proxy:负载均衡

运维的职责

NameSpace

  • 属于namespace:
    • pod
    • service
    • ReplicatSet
    • Deployment
    • PVC(Persistent Volume Claim) ...
  • 不属于namespace
    • node
    • PV(persistent volume)
    • namespace

Node

Pod

  • 一个pod可以运行多个容器(最好是关联的进程)

  • Pod做为一个可以独立运行的服务单元,简化了应用部署的难度,以更高的抽象层次为应用部署管提供了极大的方便。

  • Pod做为最小的应用实例可以独立运行,因此可以方便的进行部署、水平扩展和收缩、方便进行调度管理与资源的分配。

  • Pod中的容器共享相同的数据和网络地址空间,Pod之间也进行了统一的资源管理与分配。

执行过程

POD网络分配

使用原则

  • 一个容器不应该跑多个进程
  • 如果两个容器不需要跑在同一个机器,不应该分在一个pod中

yml配置

Label

通过label分组pod

  • nodeSelector

Annotating

ReplicationController

三个要素

  • label selector: RC控制的范围
  • replica count: 控制pods数量
  • pod template: 创建pod使用

更新pod template,删除pod后才会更新替换

ReplicaSet

  • ReplicationController升级版本,

DaemonSet

  • 带有label selector

Job/CronJob

  • 并行或串行
  • completions:执行数
  • parallelism:并行数
  • activeDeadlineSeconds:限制执行时间

CronJob

  • startingDeadlineSeconds:最晚延迟启动时间

Service

pod对外提供服务的难题

  • Pod是短暂的,是随时可以挂掉的
  • K8S在pod分配给node后,pod启动前,分配了一个静态的IP给pod,这样客户端无法提取知晓pod服务的地址
  • 水平扩展意味着多个pod可能提供同样的服务,每一个pod都有自己的地址。而客户端想通过单一的地址访问pod服务

Service的用处

  • 有固定的ip和端口,对外输出服务,负载均衡器

设置一致性访问,基于ip固定路由 ! 通过port name引用

服务发现

NodePort Service

LoadBalancer

Ingress

具备Service没有的优势

  • 基于Cookie的 affinity

  • Ingress Controller通过Service发现pod,然后直接转发pod,不经过Service 通过ingress访问多个服务 映射不同的host

  • Ingress处理TLS

服务的启动问题

  • readiness probe
    • Exec probe
    • Http Get probe
    • TCP Socket probe 与liveness probe不同之处:
  • liveness通过替换掉不健康的pod来保持pod集群的正常使用
  • readiness probe只有监控的pod可以接受请求服务 给pod添加readiness probe

Volumes

给容器挂载硬盘

  • 每个容器都有自己的文件系统,容器重启,文件系统内的内容会丢失
  • Volume同pod的生命周期,是pod的一部分,所以重启的容器能看到前一容器保存的内容
  • 一个pod下的volume可以被多个容器共享
  • 每个容器都可以将volume挂载在自己的文件系统下任何地方

volume类型

  • emptyDir:空的目录,用于存储短暂数据
  • hostPath:将work node的节点挂载到pod文件系统下
  • configMap, secret, downwardAPI:特殊类型的volume,用于暴露K8S资源和集群信息给pod
  • persistentVolumeClaim:使用预置或动态存储
  • gitRepo:volume从git仓库初始化
  • nfs:NFS系统挂载在pod下
  • gcePersistentDisk (Google Compute Engine Persistent Disk), awsElastic BlockStore (Amazon Web Services Elastic Block Store Volume), azureDisk (Microsoft Azure Disk Volume):挂载云供应商的存储
  • cinder, cephfs, iscsi, flocker, glusterfs, quobyte, rbd, flexVolume, vsphere Volume, photonPersistentDisk, scaleIO:其他网络类型的存储

emptyDir选择volume介质

gitRepo

hostPath

外部存储

解耦底层存储技术与pod

PersistentVolumes PersistentVolumeClaims

  • 只需要管理员部署底层的存储,并通过PV注册在K8S集群,并可以控制PV控制大小和访问方式
  • 用户创建PVC,描述使用大小及访问方式,并提交给K8S API Server,K8S负责找到找到适合的PV绑定到PVC
  • PV并不属于任何的namespace

PVC

权限

  • RWO-ReadWriteOnce:只有单个node可以挂载volume,读写
  • ROX-ReadOnlyMany:多个node可以挂载volume,读
  • RWX-ReadWriteMany:多个node可以挂载volume,读写

pod中使用pvc

与其他的区分

persistentVolumeReclaimPolicy: + Retain:保留,不可被重复利用 + Recyle:删除内容,可被再次claim重复利用,可被不同的pvc使用 + Delete:删除存储

StorageClass-动态的提供PV

用户更自主选择供应商

  • PVC中claim StorageClass StorageClass PVC中使用

更简单的方式,不使用StorageClass

使用default pv

ConfigMap

配置应用的方式:

  • 容器命令行传参

    • 打包容器使用ENTRYPOINT指定容器启动后执行的命令
    • CMD:传给ENTRYPOINT参数 pod中覆盖命令
  • 给容器加环境变量

缺点:

  • 配置跟pod文件融合在一起,导致不同环境,必须定义不同的pod文件,无法重用!

解耦

  • 容器mount特殊的volume配置文件 环境变量+ConfigMap

ConfigMap的不同来源

pod中env引用ConfigMap

pod中的env全部来自ConfigMap

pod中命令行引用ConfigMap

ConfigMap Volume

  • subPath路径

  • defaultMode权限

Secret

  • K8S确保每个Secret只分发给需要的node(运行相关的pod)
  • node在内存存储Secret,绝不写到硬盘
  • Secret配置需要被存储在加密的存储上

plain text

Downward API

暴露pod的metadata信息给pod中运行的容器:

  • pod名词
  • pod ip
  • pod namespace
  • pod node name
  • 每个容器请求的CPU信息
  • 每个容器的CPU的上下限
  • pod的label
  • pod的annotation

通过环境变量暴露

通过downwardAPI volume暴露

通过K8S RestAPI暴露 kubectl proxy

Talk to K8S API Server

ambassador

客户端库连接

Deployment

升级pod的步方式

  • 先删除存在的旧pod,再启动新的pod

  • 先启动新的pod,再删除旧的pod 切换label selector,一次性切换service

  • Rolling update(已经废弃)

imagePullPolicy

  • Always
  • IfNotPresent

Rolling update

使用kubectl rolling-update命令

更改label 请求同时路由到v1和v2版本

废弃rolling update:

  • 更改了pod的label
  • 更改了ReplicateController label selector
  • 更新过程是通过client请求server完成的,网络出现问题会导致失败

使用Deployment声明式改动

  • Deployment是更高层级的资源管理手段
  • Deployment采用声明式的改动,K8S会对声明做处理
  • Deployment可以同时拥有多个版本pod,不应该元数据中不应该引用app版本
  • 隐藏了部署的详细细节
  • 可以自动回退

示例

RollingUpdate策略

  • Recreate:先删除老的pod,再创建新的pod

修改资源命令 流程

回退

部署历史像git一样管理部署 参数 revisionHistoryLimit:限制历史数 rollingUpdate: maxSurge:允许Deployment过程中超过replicaCount最大pod数 maxUnavailable:允许Update中,允许最大的不可服务的pod比例

pause resume deployment

Readiness probe

minReadySeconds作用:当容器启动后,最少多长时间返回ready,这样允许做readiness probe探测,当探测失败,就会block住deployment更新! progressDeadlineSeconds

StatefulSet

无状态pod和有状态pod 通过共用PV,volume configmap Storage保存状态 每个pod分配一个ReplicaSet 同一个volume,每个pod单独的目录 问题:

  • 不能一个pod模板配置,
  • 每次重新部署升级,都会生成新的pod name及ip地址

使用固定ip的service

StatefulSet

每个pod在重新部署的时候,保留状态和识别信息

每个pod固定的域名a-0.foo.default.svc.cluster.local 更新pod流程

扩展StatefulSet,顺序的增删 实现POD PVC template分离

scale down时,需要手动删除pvc,随机删除pod上的存储数据

示例 部署过程中,一个pod启动后,再顺序部署下一个 查看详情

重新部署过程

SRV记录 映射service和hostname:port

深入理解K8S

理解架构

  • Control Plane

    • etcd分布式存储
    • API Server
    • Scheduler
    • Controller Manager
  • Worker nodes

    • Kubelet
    • kube-proxy
    • Container Runtime(Docker, rkt, others)
  • Add-on 插件

    • Kubernetes DNS Server
    • The Dashboard
    • Ingress Controller
    • Heapster
    • Container Network Interface network plugin

  • 组件间通信通过API Server,组件间不直接通信,只有API Server连接etcd

  • etcd:存储集群状态及元数据

etcd分布式存储脑裂问题

API Server

注册监听模式,监听变化

Scheduler

  • 查找符合硬件资源请求的node

Controller Manager

部署过程

Controller类别

  • ReplicaSet
  • Deployment
  • StatefulSet
  • Node
  • Service
  • Endpoint
  • Namespace
  • PersistentVolume

Controller间协调

pod间网络

没有nat

Service实现原理

资源分配

资源申请 node实际分配情况 Scheduler分配失败情况

没有限制最高资源的时候,按比例分配剩余资源 超出资源上限

pod淘汰的依据:资源QOS

  • BestEffort(最低)
  • Burstable
  • Guaranteed(最高)

淘汰

最佳实战

pod删除事件

Helm k8s包管理器

  • helm是一个命令行工具,用于本地开发及管理chart,chart仓库管理等
  • Tiller是Helm的服务端。Tiller负责接收Helm的请求,与K8S的apiserver交互,根据chart来生成一个release并管理release
  • chart Helm的打包格式叫做chart,所谓chart就是一系列文件,它描述了一组相关的K8S集群资源
  • release 使用helm install命令在Kubernetes集群中部署的Chart称为release chart模板

未完待续