5分钟让你理解K8S必备架构概念,以及网络模型(中)

写在前面

在这用XMind画了一张导图记录Redis的学习笔记和一些面试解析(源文件对部分节点有详细备注和参考资料,欢迎关注我的公众号:阿风的架构笔记 后台发送【导图】拿下载链接, 已经完善更新):
5分钟让你理解K8S必备架构概念,以及网络模型(中)

前言

在上一篇文章中介绍了K8S的基础架构流程,以及核心的组件;这篇文章继续K8S的相关的概念。

上篇介绍到了NodePort Service解决了外部请求K8S内部的应用的问题。下面我们看看如何搭建应用服务集群的?

应用集群

5分钟让你理解K8S必备架构概念,以及网络模型(中)

在传统应用中,我们一般利用nginx反向代理,通过配置域名指向多个IP地址,从而实现了应用的集群。如果需要增加应用或减少应用,都需要调整nginx的配置;还是相当繁琐的。

那K8S是如何实现应用集群的呢?

副本集ReplicaSet

5分钟让你理解K8S必备架构概念,以及网络模型(中)

上一篇文章中介绍了利用NodePort Service 的Selector 选择Label标签,路由到后端的其中一个Pod。

上图中由3个Pod组成的应用集群,那如何保证Pod集群的高可用呢?如果其中一个Pod挂了,被删除了,K8S会怎么处理?

K8S有个Replica Set组件,从字面上面来看就是副本集意思;它的作用就是用来保证Pod的高可用,如果我们在Replica Set中定义了应用数量为3,那么它会保证应用数量;即使一个pod挂了,它会自动会启动1个,始终保证pod应用数量为3。

5分钟让你理解K8S必备架构概念,以及网络模型(中)

编写yaml

apiVersion: extensions/v1beta1  #指定api版本
kind: ReplicaSet       #指定创建资源的角色/类型
metadata: 
  name: mc-user
spec: 
  replicas: 3       #副本集数量
  template:         #pod模板
    metadata:       #资源的元数据/属性  
      labels:       #标签定义
        app: mc-user  #标签值
    spec:           # 指定该资源的内容
      containers:    #容器定义
        - name: mc-user   #容器的名字  
          image: rainbow/mc-user:1.0.RELEASE    #容器镜像

上面就是定义了 mc-user的pod,副本集数始终为3。Service的yaml和之前一样,注意Selector的Label,可提供给外部访问端口31001

apiVersion: v1
kind: Service
metadata: 
  name: mc-user
spec: 
  ports:
    - name: http
      port: 8080
      targetPort: 8080
      nodePort: 31001
  selector:
    app: mc-user
  type: NodePort

执行kubectl apply -f 命令,启动ReplicaSet和Service

我们可以试着查看启动的3个pod,并选择其中一个pod将它删除。

# kubectl get all
# kubectl delete po mc-user-6adfw

我们再查看pod

kubectl get all

还是有3个pod,可以看出即使删除了一个pod;ReplicaSet会又帮我们启动了一个pod。

这个就是ReplicaSet的自愈能力,自我恢复能力。

滚动发布Rolling Update

我们先来谈谈什么是滚动发布?滚动发布是一种高级发布策略,按批次依次替换老版本,逐步升级到新版本。发布过程中,应用不中断,用户体验平滑。

5分钟让你理解K8S必备架构概念,以及网络模型(中)

现在Pod中是V1的版本,现在我们想升级到V2版本,整个流程是什么样子呢?

5分钟让你理解K8S必备架构概念,以及网络模型(中)

先删除其中一个V1的pod

5分钟让你理解K8S必备架构概念,以及网络模型(中)

然后发布V2的Pod

5分钟让你理解K8S必备架构概念,以及网络模型(中)

再删除一个V1的pod

5分钟让你理解K8S必备架构概念,以及网络模型(中)

再启动一个V2的Pod

5分钟让你理解K8S必备架构概念,以及网络模型(中)

再删除最后一个V1的pod

5分钟让你理解K8S必备架构概念,以及网络模型(中)

最终升级完成。

我们可以发现滚动发布的特点,就是老版本和新版本会共存一段时间。所以此种发布方式适用版本兼容的应用。也可以支持滚动回退。我们来看看和蓝绿发布的区别

5分钟让你理解K8S必备架构概念,以及网络模型(中)

滚动发布抽象Deployment

之前介绍的ReplicaSet 其实是对Pod的一次包装,Deployment又在基础上面对ReplicaSet的又一次包装。

5分钟让你理解K8S必备架构概念,以及网络模型(中)

注意点:ReplicaSet 和 Deployment是一个软件概念,它是没有具体的组件的;是抽象出来的名词,方便大家理解

5分钟让你理解K8S必备架构概念,以及网络模型(中)

上图就是描述了deployment滚动发布的架构;Deployment的滚动发布,对用户请求以及Service是透明的,无感知。

Deployment的yaml

apiVersion: apps/v1  #指定api版本,此值必须在kubectl apiversion中
kind: Deployment       #指定创建资源的角色/类型
metadata: 
  name: mc-user
spec: 
  selector:           #此deployment选择哪个标签进行滚动的发布
    matchLabels:      #滚动发布pod的标签,要跟下面template中的labels一致
      app: mc-user
  minReadySeconds: 10 #最小10s等待就绪时间,可以方便看到滚动发布流程
  replicas: 3       #副本集数量
  template:         #pod模板
    metadata:       #资源的元数据/属性  
      labels:       #标签定义
        app: mc-user  #标签值
    spec:           #指定该资源的内容
      containers:    #容器定义
        - name: mc-user   #容器的名字  
          image: rainbow/mc-user:1.0.RELEASE    #容器镜像

上面的yaml和ReplicaSet很类似,需要注意的

selector:        #此deployment选择哪个标签进行滚动的发布
   matchLabels:  #滚动发布pod的标签,要跟下面template中的labels一致
      app: mc-user

定义deployment管理哪个标签pod

Service的yaml

Service的yaml没有变化,需要定义selector,选择标签就行了

apiVersion: v1
kind: Service
metadata: 
  name: mc-user
spec: 
  ports:
    - name: http
      port: 8080
      targetPort: 8080
      nodePort: 31000
  selector:
    app: mc-user
  type: NodePort

我们用kubectl apply -f命令执行 deployment和service

我们再用kubectl get all获取运行情况,我们就可以发现有两个类型

deployment.apps/mc-user 以及 replicaset.apps/mc-user-4345afaa

要升级的时候,只需要更改deployment中的image名称,再执行apply

image: rainbow/mc-user:1.1.RELEASE    #容器镜像

我们用kubectl get all查看,就会发现replicaset 有2个;一个是老版本的,一个是新版本的。 老版本的pod数逐渐减少,新版本的pod数量逐渐增加,一直到新版本为3,老版本为0。

回退版本

如果发现版本有问题,我们可以回退版本,可以使用下面命令

kubectl rollout undo deployment/mc-user

这个我们就回退到V1.0的老版本了。

ConfigMap配置

在我们日常业务过程中,需要会配置一些配置参数,如:一次性的静态配置(数据库连接字符串,用户名,密码),以及可以运行过程中的动态配置(如:限购数量)等;那K8S中的Pod如何获得外部的配置信息呢?

5分钟让你理解K8S必备架构概念,以及网络模型(中)

上图中,K8S提供了ConfigMap这个功能,提供用户在外部进行配置,然后K8S把ConfigMap以环境变量的方式提供给Pod中的容器或者也可以通过Volume文件持久化的方式提供给Pod容器。

共享配置

因为我们会有很多服务的配置是相同的,那实现微服务之间共享一份配置信息,如下图

5分钟让你理解K8S必备架构概念,以及网络模型(中)

一份ConfigMap可以提供给多个服务使用,ConfigMap会把配置信息以env方式存在于每个服务的环境变量中。

ConfigMap的yaml

apiVersion: v1  #指定api版本,此值必须在kubectl apiversion中
kind: ConfigMap       #指定创建资源的角色/类型
metadata: 
  name: mc-user-config
data: #定义配置信息
  DATASOURCE_URL: jdbc:mysql://mysql/mc-user
  DATASOURCE_USERNAME: root
  DATASOURCE_PASSWORD: 123456

修改Deployment配置文件

增加envFrom属性

apiVersion: apps/v1  #指定api版本,此值必须在kubectl apiversion中
kind: Deployment     #指定创建资源的角色/类型
metadata: 
  name: mc-user
spec: 
  selector:           #此deployment选择哪个标签进行滚动的发布
    matchLabels:      #滚动发布pod的标签,要跟下面template中的labels一致
      app: mc-user
  minReadySeconds: 10 #最小10s等待就绪时间,可以方便看到滚动发布流程
  replicas: 3       #副本集数量
  template:         #pod模板
    metadata:       #资源的元数据/属性  
      labels:       #标签定义
        app: mc-user  #标签值
    spec:           #指定该资源的内容
      containers:    #容器定义
        - name: mc-user   #容器的名字  
          image: rainbow/mc-user:1.0.RELEASE    #容器镜像
          envFrom:  #环境变量来源
            - configMapRef: #容器应用的configmap引用
                name: mc-user-config #configMap的名称

envFrom中的configMapRef配置引用名称;这样我们就可以在pod容器中获取到configmap的配置信息了。我们可以用

kubectl exec mc-user-34wrwq-3423 printenv | grep DATASOURCE_NAME

获得pod容器中的环境变量。

configMap变更

5分钟让你理解K8S必备架构概念,以及网络模型(中)

如果服务已经运行中,我们更新了ConfigMap的配置信息,那么POD中的容器会即时获得新的配置信息吗?

很不幸,更新了configMap;再用kubectl apply -f 重新发布configmap;之前的pod容器是不会获得最新的配置信息的。

那如何让pod容器用最新的ConfigMap配置值呢?我们可以删除pod,因为replicaset会保证pod数量,会自动重启,那新的pod就会应用新的配置信息了。

总结

今天介绍K8S的副本集ReplicaSet、滚动发布Deployment、配置ConfigMap的概念;下一篇会介绍网络相关的模型。谢谢!!!

看完三件事❤️


如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  1. 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  2. 关注公众号 『 阿风的架构笔记 』,不定期分享原创知识。
  3. 同时可以期待后续文章ing
上一篇:动态规划总结1 一维dp


下一篇:arthas热部署测试-是否会中断已进入应用的用户线程