baby sword‘s blog baby sword‘s blog
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)

zhengjian

不敢承担失去的风险,是不可能抓住梦想的
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)
  • Spring Cloud

  • Spring Cloud Alibaba

  • docker

  • k8s

  • Arthas

  • k8s

    • 尚硅谷k8s
      • 背景
      • 介绍说明
        • 前生今世
        • 组件框架
        • borg
        • kebernates
        • 其他重要的组件
        • 关键字
      • 基础概念
        • pod概念
        • 管理器
        • 什么是管理器
        • rc、rs、dy
        • statefullSet
        • daemonSet
        • JOB、CronJob
        • 扩展
        • CloneSet
        • 通讯模式
        • 服务发现
        • 网络模型
      • kubernates
        • 安装
        • 自行构建集群
      • 资源清单
        • k8s中的资源
        • 语法 资源清单
        • 编写资源清单
        • pod生命周期(重难点)
        • 容器环境初始化
        • init
        • start
        • stop
        • readiness
        • liveness
      • pod 控制器(灵魂)
      • 服务发现
      • 存储
      • 调度器
      • 安全机制
      • HELM
      • 运维
  • Prometheus

  • 分布式架构

  • 微服务
  • k8s
xugaoyi
2023-01-22
目录

尚硅谷k8s

# 背景

基础设施即服务

平台即服务

软件设施即服务

问题:

在最老的未服务架构中,我们一台机器部署一个应用,每个机器之间通过地址端口就可以进行通信。

但是当我们使用容器技术时,每个容器中的端口需要映射到机器的实际端口,这种端口映射在服务很多后就很难管理,这时候我们就需要一种很好的管理工具。

解决方案:

  1. 资源管理器 MESOS

2019 推特由MESOS转向k8s

  1. docker SWARM

缺点:不能进行回滚等功能

2019 阿里云不再使用

  1. kubernetes

google、go语言编写

特点:

轻量级:消耗的资源少

# 介绍说明

# 前生今世

# 组件框架

# borg

了解组件的前提,先了解borg的架构

image-20230116235941881

  • borgmaster

首先borgMaster主要用作流量的分发,可以处理当一个请求过来了,相应的流量可以打到哪个borglet地方。

  • borglet

每一个具体的服务对应的节点,可能对应着一个服务

  • 访问方式

borgmaster有3种访问方式

  1. 命令行
  2. 浏览器
  3. 文件
  • Schedule

    调度器。决定调度的顺序。会将相应的调度保存到数据库paxos,然后borglet定时去数据库拉取数据。

# kebernates

image-20230117001051135

  • api server

所有服务访问的入口

  • scheduel

负责接收任务,选择合适的节点进行分配任务

  • 控制器ControllerManager

维护副本期望的数目,一个node可以设置一个期望的副本数目。

副本数量最好为>=3的基数个

  • etcd

存储k8s所有重要信息(持久化)

一个可信耐的分布式键值存储服务,它能为整个分布式集群存储一些关键数据,协助分布式集群的正常运转。

分为两种版本:memery和database

注意:kubuernates v1.11后etcd ,memery已经被弃用

etcd架构图:

image-20230117001912609

类比mysql,预写日志。

  • kubelet

直接跟容器引擎交互实现容器的生命周期管理

  • kubeproxy

负责写入规则至IPTAVLES、IPVS实现服务的映射

# 其他重要的组件

  • coreDNS(重要)

可以为集群中的SVC创建一个域名的对应关系解析

  • dashboard

给k8s提供b/s结构访问体系

  • ingress controller

官方只能实现4层代理,ingress可以实现7层代理

  • fedetation:提供一个可以夸集群中心多k8s统一管理的功能
  • prometheus

提供一个k8s集群的监控能力

  • ELK

提供k8s日志统一接入平台

# 关键字

# 基础概念

# pod概念

管理的最小单位

image-20230117003951692

概念:一个pod中,可能存在多个容器。启动一个pod,必须先要启动一个pause容器,然后再启动其他的容器A、B。启动后AB网络共享、存储卷共享,即AB两者采用映射的方式都使用的是pause的网络和存储。

  • 自主式 Pod

# 管理器

# 什么是管理器

K8S是容器 (opens new window)资源管理和调度平台,容器跑在Pod里,Pod是K8S里最小的单元。所以,这些Pod作为一个个单元我们肯定需要去操作它的状态和生命周期。那么如何操作?这里就需要用到控制器了。

这里一个比较通俗的公式:应用APP = 网络 + 载体 + 存储

image-20230117123355829

这里应用一般分为无状态应用、有状态应用、守护型应用、批处理应用这四种。

  • 无状态应用

    应用实例不涉及事务交互,不产生持久化数据存储 (opens new window)在本地,并且多个应用实例对于同一个请求响应的结果是完全一致的。举例:nginx或者tomcat

  • 有状态应用

    有状态服务可以说是需要数据存储功能的服务或者指多线程类型的服务、队列等。举例:mysql数据库 (opens new window)、kafka、redis、zookeeper等。

  • 守护型应用

    类似守护进程一样,长期保持运行,监听持续的提供服务。举例:ceph、logstash、fluentd等。

  • 批处理应用

    工作任务型的服务,通常是一次性的。举例:运行一个批量改文件夹名字的脚本。

这些类型的应用服务如果是安装在传统的物理机或者虚拟机上,那么我们一般会通过人肉方式或者自动化工具的方式去管理编排。但是这些服务一旦容器化了跑在了Pod里,那么就应该按照K8S的控制方式来管理了。上一篇文章我们讲到了编排,那么K8S靠什么具体的操作来做编排?答案就是这些控制器。

不会被管理器管理,死亡后不会复活

  • 控制器管理的Pod

# rc、rs、dy

pod管理器

image-20230117004515662

rs在大型项目中可以过滤标签进行管理,新版本已经抛弃了RC

deployment支持滚动更新:创建一个新的,删除一个旧的,进行滚动的更新。即当我们要更新一个pod时,会先删除一个新的,再删除一个旧的,这样可以让更新更加平滑。但是deployment并不支持pod的创建。

  • deployment创建流程

dy创建后,会由dy自己创建一个rs,rs会创建对应的pod。

  • 更新流程

因为采用的是滚动更新,此时dy会创建一个新的rs-1,然后进行滚动更新流程,rs-1更新的一个,rs中的pod停用一个,以此类推。更新完成后rs不会被删除而是停用

  • 回滚

因为之前的rs并没有被删除,所以可以支持回滚

HPA (HorizontalPodAutoScale)

仅适用于deployment和replicaSet,在V1版本中仅支持根据pod的cpu利用率扩容,在vlapha版本中,支持根据内容和自定义用户的metric扩容

解释:HPA会根据dy或rs中的pod的cpu利用率来创建新的pod或者回收pod。即可以根据节点性能自动创建或删除pod

# statefullSet

image-20230117102321866

docker是无状态的服务,而k8s是有状态的服务

有序删除:比如一个服务中,需要按照流程顺序启动mysql、apache、nginx等,如果顺序乱了,可能会报错

# daemonSet

不懂 TODO

# JOB、CronJob

# 扩展

# CloneSet

扩展了deployment

CloneSet (opens new window)

image-20230117104350199

# 通讯模式

pod与pod之间的通讯

# 服务发现

image-20230117104635130

service可以通过管理器去发现一组pod,service有一个地址和端口,这样client就可以访问service,service再通过负载均衡访问到pod

image-20230117105612827

比如我们创建了3个php-fpm,他们处于平行的服务,squid要调用它,如果在squid中写死了php-fpm的

# 网络模型

image-20230117133030935

image-20230117133149435

overlay network 怎么去实现?

Flannel :功能是让集群中的不同的节点主机创建docker容器具有全集群唯一的虚拟ip地址。而且它还能在这些ip地址之间建立一个覆盖网络,通过这个覆盖网络,将数据包原封不动地传递到目标容器内

案例:

image-20230117134043147

  • 解释

想象一下,backend后台需要调用app1、app2、app3,现在app2向backend发送数据包,app2节点表示的ip会发送至docker0,docker0再到网桥flannel0,再到flanneld,flanneld会在etcd中查看相关的地址映射信息,并组装成相应的数据包,通过udp的方式转发给其他的主机中对应的pod节点。

image-20230117134541862

iptables与lvs

ETCD非常重要:

  • 存储管理Flannel可分配的IP地址段资源

  • 监控ETCD中每个POD的实际地址,并在内存中建立维护POD节点路由表

如果要考虑高可用,第一个应该考虑的就应该是ETCD的高可用

image-20230117134917055

节点网络即是我们物理机的网络,是真实的网络,其中service网络和pod网络都是虚拟的网络

网络 (opens new window)

# kubernates

# 安装

  • minikube

首先进行Minikube的安装

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64
sudo install minikube-darwin-amd64 /usr/local/bin/minikube
1
2

Kubeadm

image-20230117222047701

# 自行构建集群

image-20230117221022819

# 资源清单

# k8s中的资源

k8s所有内容都被抽象为资源,资源实例化后都叫做对象

  • 名称空间

仅在此名称空间下生效

image-20230117233227232

  • 集群

全局都可见

image-20230117233401217

  • 元数据

# 语法 资源清单

必须存在的字段

image-20230117233546406

非必需

image-20230117233814411

image-20230117233942891

image-20230117234019918

image-20230117234040181

如何看更详细的信息?

kubectl explain pod
kubectl explain pod.spec
1
2

# 编写资源清单

image-20230117234838563

启动对应的资源清单

kubectl apply -f xx.yaml
1

​ 查看Pod状态

kubectl get pod
1

查看日志

//查看哪个容器有问题
kubectl describe pod xxxName

kubectl logs xxxName -c test//查看pod下的指定容器的日志
1
2
3
4

# pod生命周期(重难点)

image-20230118000231590

image-20230118150328240

成功:返回0,就表示成功返回。返回其他数据,就表示失败了。

# 容器环境初始化

# init

初始化容器(不能并行,必须串行,包括pause容器)

介绍:pod能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先应用容器启动的Init容器。

Init容器与普通的容器非常像,除了:

Init容器总是运行到成功为止

每个init容器必须在下一个init容器启动之前完成

如果pod的Init容器失败,kubernetes会不断地重启该pod,直到Init容器成功为止,然而,如果pod对应的restartPolicy为nerver,则它不会重新启动

作用:

image-20230118110334771

举例:

image-20230118110756470

比如我们有两个pod:mysql(pod1)、Apache+php(pod2)。

此时pod2需要调用pod1服务,如果pod1还没有成功启动,那么pod2就会调用失败。那我们要怎么做到pod2调用pod1之前,保证pod1已经启动成功呢?

可以在pod2之前加一个init容器,让其去监控pod1是否成功启动,只有当成功启动过后,pod2才开始启动

编写init模板:

image-20230118112010295

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; sleep2; done;']
  - name: init-mydb
    image: busybox
    command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2;done;']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

image-20230118124851122

kind: Service
apiVersion: v1
metadata:
 name: mydb
spec:
 ports:
  - protocol: TCP
    port: 80
    targetPort: 8377
1
2
3
4
5
6
7
8
9
kind: Service
apiVersion: v1
metadata:
 name: myservice

spec:
 ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
1
2
3
4
5
6
7
8
9
10

上面可知,当主main启动后,需要等待出初始化容器myservice、mydb执行完成后,才能真正进行main容器的执行

kind: service?

https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/ (opens new window)

注意事项:

image-20230118134610984

网路和数据初始化是在pause容器中完成的。

使用命令

kubectl edit pod podName
1

可以修改对应的yaml文件,如果修改了image字段相关的数据,会触发init容器的重新启动,也就表示整个pod都会进行重启。

image-20230118135704216

init容器的资源清单中很多字段都是和主容器字段一样的,除了readiness就绪检测字段。因为readiness是就绪检测,init容器的功能也是为主容器的初始过程服务,如果init也要进行就绪检测,那么就本末倒置,一层套一套更加复杂,所以init中不应该提供就绪检测的生命周期。

缺点:init容器不在main容器过程中,如果init容器放行通过了,那么如果在main容器启动过程中又出错了,那么init容器的存在不就没有意义了吗?

k8s还提供了容器探针的功能:即readinessProbe和livenessProbe

image-20230118140350014

主容器生命周期

# start

image-20230118145859233

start stop很简单。

# stop

image-20230118140616646

具体实现

# readiness

就绪检测。pod处于running状态,但是容器中的进程可能还没有真正被创建,不应该对外暴露服务,此时使用readiness,可以通过某种策略判断该容器是否可以真正的对外暴露服务了

就绪检测

image-20230118140748306

apiVersion: v1
kind: Pod
metadata:
 name: readiness-httpget-pod
 namespace: default

spec:
 containers:
 - name: readiness-httpget-container
   image: httpServiceImage
   imagePolicy: IfNotPresent
   readinessProbe:
    httpGet:
     port: 8080
     path: /index.html
    initialDelaySeconds: 1
    periodSeconds: 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

因为这里使用了就绪检测,会去Main中的容器看8080端口路径/indext.html是否能够通过index.html调用成功,如果成功了,则可以通过,否则就表示调用失败了。

使用kubectl get pod可以返现status虽然现在处于running状态,但是ready仍为0,因为我们的就绪检测失败了。

image-20230118141514655

那么怎么办呢?首先我们需要使用kubectl desribe pod 名字查看是具体什么原因造成的,然后我们会去容器内部去进行命令交互操作

kubectl exe podName.containName -it -- /bin/sh

进入交互页面,建立index.html页面即可。

# liveness

生存检测

检测僵尸进程

存活检测

image-20230118142755078

apiVersion: v1
kind: Pod
metadata;
  name: liveness-exec-pod
  namespace: default

spec:
  containers:
   - name: liveness-exec-container
     image: myServerImage
     imagePullPolicy: IfNotPresent
     command: ["/bin/sh","-c","touch /tmp/live ; sleep 60 ; rm -rf /tmp/live; sleep 3600"]
     livenessProbe:
      exec:
       command: ["test","-e","/tmp/live"]
      initialDelaySeconds: 1
      periodSeconds: 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

解释:

imagePullPolicy: IfNotPresent。 如果镜像在本地不存在,则到远程去拉去,否则只拉取本地的镜像

command: ["/bin/sh","-c","touch /tmp/live ; sleep 60 ; rm -rf /tmp/live; sleep 3600"]:创建一个文件60s后,删除该文件

livenessProbe:
      exec:
       command: ["test","-e","/tmp/live"]  # 检测指定的文件是否存在
      initialDelaySeconds: 1       # 主容器启动后1s才检测
      periodSeconds: 3     #每隔3s检测一次
1
2
3
4
5

检测成功返回0,否则返回1

我们可以启动以上容器并等待一分钟:

kubectl get pod -w
-w, --watch=false:
        After listing/getting the requested object, watch for changes.
1
2
3

即可返回相关变化的容器,我们可以等待1min等待变化。

可以看到restarts的数量发生了变化。

当存活检测后,如果存活检测失败,会干掉整个主main,并重pod。

存活检测的其他测试:

http

image-20230118144828706

tcp

总结:init成功后,容器进如running状态,但是仍没有进入ready状态,此时进入就绪检测,如果就绪检测未通过,则持续进行就绪检测,如果通过pod状态变为ready,此时开始存活检测,存活检测通过,则每隔一段时间检测一次,如果存活检测不通过,则挂掉整个pod,重新启动,即从init开始启动。

# pod 控制器(灵魂)

掌握各种控制器特点和使用方式

pod分类:自主式(pod退出了,cileixingpod不会被重新创建)、控制器(在控制器的生命周期里,始终要维持pod的副本数量)

一般情况下,我们都会使用控制器下的pod

k8s中有很多控制器,这些相当于一个状态机,用来控制pod的具体状态行为

image-20230119225227366

声明式定义:

image-20230119225318214

例如:sql语句,其不需要考虑底层怎么实现的

当创建一个deployment时,会自动创建rs,rs会自动创建对应的pod

image-20230119225756910

image-20230119225746977

image-20230119230059023

image-20230119231203322

以上的控制器大多适合于无状态服务的pod

以下可以做有状态得到服务

image-20230119231526065

  1. 自动扩容缩容方案

image-20230119231914910

  • RS于RC与Delpoyment的关联

image-20230119232502914

如果不知道yaml中某个标签的含义怎么办?

kubectl explain rs

# 服务发现

将内部私有服务暴露给客户端

掌握syc原理以及构建方式

# 存储

服务分类

  • 有状态服务

DBMS

  • 无状态服务

LVS APACHE

多种存储类型的特点,并且在不同环境中选择不同的存储方案

# 调度器

可以将pod节点进行组装

# 安全机制

集群的认证、鉴权、访问控制、原理即流程

# HELM

类似yum管理器

掌握HELM原理,自定义模板,可以实现部署插件

# 运维

kubernates源码修改

kubernamtes高可用构建

编辑 (opens new window)
上次更新: 2024/02/22, 14:03:19
Arthas入门
入门

← Arthas入门 入门→

最近更新
01
spark基础
02-22
02
mysql读写分离和分库分表
02-22
03
数据库迁移
02-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式