K8s与容器设计模式 目前K8s社区推出的容器设计模式主要分为三大类:

第一类,单容器管理模式;

第二类,单节点多容器模式;

第三类,多节点多容器模式;

一类比一类更复杂。

根据复杂性的不同,本系列文章给出不同篇幅的实践案例介绍。对于第一类,只在本文中用一小节给与介绍;对于第二类,在本文中,针对每一种典型设计模式分一个小节给与介绍;对于较复杂的第三类,每一种典型设计模式将用一篇文章给与介绍。

单容器管理模式

K8s的最大特色是支持多容器的微服务实例。当然,单容器的模式也是支持的,只不过这种模式并不能突出K8s的特色和强大。很多人对K8s一直以来的印象是:功能强大,但入门较难。其实,单单就启动一个单容器微服务实例,K8s的命令行操作跟docker原生命令一样简单。

运行一个nginx容器

[root@demo-k8s ~]# kubectl run nginx --image=nginxdeployment "nginx" created[root@demo-k8s ~]# kubectl get deploymentNAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGEnginx     1         1         1            1           24s[root@demo-k8s ~]# kubectl get rsNAME               DESIRED   CURRENT   AGEnginx-3137573019   1         1         1m

由上面的例子可以看到,K8s只要一个命令既可以启动以nginx为镜像的一个微服务实例。与此同时,K8s的强大之处在于,方便用户用一个命令的同时,仍然保证了K8s应用体系的完整性和规范性。也就是说,虽然用户只运行了一个命令,但K8s为用户自动创建了四种API对象,包括:Deployment,ReplicaSet(RS),Pod和Container

要想扩展伸缩同一服务的实例个数也非常简单。

依靠这种兼顾易用性和模型一致性的设计理念,K8s使自己既适合简单场景也适合复杂场景。

单节点多容器模式

从单节点多容器模式开始的容器设计模式,是真正体现K8s设计特点的地方,也就是基于多容器微服务模型的分布式应用模型。

在K8s体系中,Pod是一个轻量级的节点,同一个Pod中的容器可以共享同一块存储空间和同一个网络地址空间,这使得我们可以实现一些组合多个容器在同一节点工作的模式。既然Pod的特点是共享存储空间和网络地址,那么单节点多容器模式一定是利用这两种特性的。

挎斗模式(Sidecar pattern) 第一种单节点多容器模式是挎斗模式。这种模式主要是利用在同一Pod中的容器可以共享存储空间的能力。

一个典型的挎斗应用场景如图所示:一个工具容器写文件到共享的文件目录,应用主容器从共享的文件目录读文件。

例如,我们可以用Nginx构建一个代码发布仓库,简单的将代码放到某个本地目录即可。为了保持同步,我们同时用一个装有Git客户端的容器定时到原始代码仓库同步下拉最新的代码。这种模式的好处是,工具容器的镜像,也就是打包有Git客户端的镜像可以重用,而不需要跟应用的容器打包在一起。同样的应用,应用主容器不用Nginx也可以用Apache Httpd,都可以跟工具容器组合起来形成微服务。

另一个典型的挎斗模式如图所示:一个工具容器读文件,应用容器写文件。

例如:一个基于Nginx的Web应用向系统文件系统写入日志,而一个收集日志的容器从共享目录读出日志,并输出到集群的日志系统。这一模式的好处在于,工具容器的镜像是可以重用的,不需要在每次更新应用容器打包的时候,把工具容器的执行文件打包进去。

外交官模式(Ambassador pattern)

第二种单节点多容器模式是外交官模式。这种模式主要利用同一Pod中的容器可以共享网络地址空间的特性。

如图所示,在一个Pod中给应用容器搭配一个工具容器作为代理服务器。工具容器帮助应用容器访问外部服务,使得应用容器访问服务时不需要使用外网的IP地址,而只需要用localhost访问本地服务。

在这种模式下,作为代理服务器的工具容器好像外部服务派驻在Pod中的“外交官”,使得应用容器办理业务时只需要跟本Pod的外交官打交道,而不需要出国了,因此而得名。

在这种模式下,作为代理服务器的工具容器好像外部服务派驻在Pod中的“外交官”,使得应用容器办理业务时只需要跟本Pod的外交官打交道,而不需要出国了,因此而得名。

我们这里用一个访问Redis服务的简单案例,来实践体验一下Ambassador模式和K8s单节点多容器模式的应用细节。本案例的文件清单在Github上:https://github.com/xwangqingyuan/kube-templates/tree/master/examples/redis

创建一个初始的Redis Master实例

先创建一个Redis Master节点的Pod用于初始化Redis集群。

kubectl create -f examples/redis/redis-master.yaml

创建一个初始的Redis Master实例

先创建一个Redis Master节点的Pod用于初始化Redis集群。

kubectl create -f examples/redis/redis-master.yaml

创建redis的replication controller

创建控制多个redis服务Pod的RC,当然也可以用Deployment或ReplicaSet来创建。

kubectl create -f examples/redis/redis-controller.yaml[root@demo-k8s ~]# kubectl get rcNAME             DESIRED   CURRENT   AGEredis            1         1         19h

创建完后可以用kubectl get命令查看rc和Pod,会发现并没有产生新的Redis Pod,这是因为原来的Pod redis-master已经满足了replica=1的要求。

创建redis sentinel服务。

kubectl create -f examples/redis/redis-sentinel-service.yaml

创建控制多个redis sentinel服务Pod的RC。

kubectl create -f examples/redis/redis-sentinel-controller.yaml

将redis实例和redis-sentinel实例扩展成3个

kubectl scale rc redis --replicas=3
kubectl scale rc redis-sentinel --replicas=3

删除掉手工启动的redis实例redis-master

删除掉我们已开始手工创建的redis master的Pod,redis的rc会自动启动新的redis以满足replicas=3的要求。同时,Redis sentinel节点会选举出一个新的节点作为master节点。

kubectl delete pods redis-master

Redis集群的验证方法

查询redis集群中所有redis实例的IP。

[root@demo-k8s ~]# kubectl describe pod -l name=redis | grep IPIP:10.120.44.3IP:10.120.63.3IP:10.120.80.5

我们知道,这3个redis实例中,只有一个是Master节点,是可写的,可以调用SET命令和GET命令;其他两个节点是Slave节点,是只读的,只能调用GET命令。我们可以用下面的命令测试三个redis节点。

通过上面的测试我们可以知道只有IP为10.120.80.5的redis pod是Master节点,其他两个是slave节点。

对于只读的操作,我们可以利用redis的service IP,通过K8s的kube-proxy来访问,如下,我们得到redis的CLUSTER-IP为10.123.248.129,可以用这个IP来读取Redis数据。那么,如果用这个IP来写数据将怎么样呢,后面将看到。

制作Ambassador容器镜像

截至目前,我们还没有用到外交官模式。下面我们用Haproxy制作一个外交官代理,用来访问Redis服务,使得跟该容器在同一个Pod里的容器,在访问Redis读写服务的时候,都只需要访问本地localhost服务。

本例中的文件在Github上可以找到:https://github.com/xwangqingyuan/kubetemplates/tree/master/examples/redis/haproxy

Dockerfile文件清单:Dockerfile

FROM haproxy:1.5COPY tmpl-haproxy.cfg /COPY starthaproxy.sh /CMD ["sh", "-c", "/starthaproxy.sh"]

启动haproxy的文件清单:starthaproxy.sh

echo "Proxying localhost ${INPUT_PORT} to ${TARGET_IP}:${TARGET_PORT}"cat tmpl-haproxy.cfg | sed -e "s/INPUT_PORT/${INPUT_PORT}/" -e "s/TARGET_IP/${TARGET_IP}/" -e "s/TARGET_PORT/${TARGET_PORT}/" > /haproxy.cfghaproxy -f /haproxy.cfg

通过这里的Dockerfile构建的代理服务器容器,根据输入的环境变量INPUT_PORT,TARGET_IP和TARGET_PORT,可以将发向本地INPUT_PORT的服务请求转发到目标TARGET_IP:TARGET_PORT上去。
因此这个容器可以作为一个简单方便的本地代理服务器使用。

使用Ambassador代理服务器的pod

使用Ambassador代理服务的Pod文件清单:demo-redis-amb-centos.yaml

在这个Pod中,我们用一个CentOS容器作为应用的主容器来使用Ambassador工具容器,当然也可以用实际的应用容器Tomcat,Nodejs,PHP等等,因为这里只是为了演示测试Ambassador代理,我们用CentOS作为应用容器。其中我们有两个外交官容器,一个用来从Redis集群读数据,容器的名字为redis-amb-read,它将发向本地6379端口的请求转发到redis服务的CLUSTER-IP,最终会轮训地发送给任意一个redis实例;另一个用来向Redis集群写数据,容器的名字为redis-amb-write,它将发向本地16379端口的请求转发到redis master Pod的IP

测试一个使用Ambassador模式的pod

创建一个使用Ambassador代理的Pod,并登陆到主容器进行测试。

kubectl create -f /home/centos/worktemp/redis/demo-redis-amb-centos.yamlkubectl exec -it demo-redis-amb-centos /bin/bash

测试对读容器本地Ambassador的访问。

从测试结果可以发现,对读容器执行GET操作时,操作总是成功的,说明3个redis pod都可以读取数据。而对读容器执行SET操作时,3个操作只有一个是成功的,也就是说只有负载均衡将请求发给redis master pod时,操作能够成功。

测试对写容器本地Ambassador的访问

从测试结果可以发现,对写容器执行SET操作时,操作总是成功的,说明redis-amb-write容器将所有请求都转发给了redis master pod 适配器模式(Adapter pattern) 第三种单节点多容器模式是适配器模式。这种模式对于监控和管理分布式系统尤为重要。 对分布式系统的一种理想设计目标,就是能够实现“分布地执行和存储,统一的监控和管理”。要想实现“统一的监控和管理”,应用和监控管理交互的接口需要是统一的,而且其接口是依照“统一的监控服务”的接口模式来实现。这和面向对象设计模式中的“适配器模式”也非常相似。

一个典型的可以采用适配器模式的系统,是利用Prometheus作为监控服务的分布式系统。在Prometheus周边项目中,有诸多适用于不同应用系统的监控数据输出器(Exporter),负责收集跟特定应用相关的监控数据,使得Prometheus服务可以以统一的数据模式收集不同应用系统的监控数据,每个Exporter同时也都是一个适配器模式的实现。

总结

本文主要介绍了K8s集群中,单节点单容器模式和基于Pod模型所支持的几种单节点多容器模式,包括挎斗模式、外交官模式和适配器模式。并且对于外交官模式,利用一个redis集群案例演示了如何利用外交官模式以访问本地服务的模式访问网络服务。

后续,K8s社区肯定还会发展出其他的容器设计模式,但不论如何,单节点多容器模式主要是利用同一Pod中的容器可以共享存储空间和网络地址空间的特点。本文案例中的代码只能用来演示,还比较简单,有很多的地方可以增强。

例如:用Replication Controller的地方,可以用Deployment或Replica Set来部署,这是K8s社区更为推荐的方式;对于案例中的外交官容器,Master Pod的IP和Redis服务的IP未必需要写死,而是可以通过脚本从指定的服务读取;此外,演示中所用的代理服务器容器也可以增强为支持多个端口映射的代理服务器。

Kubernetes(K8s)容器设计模式实践案例 单节点多容器模式相关推荐

  1. Kubernetes(K8s)容器设计模式实践案例 – 分散收集模式

    <Kubernetes与云原生应用>专栏是InfoQ向轻元科技首席架构师王昕约稿的系列 文章.本专栏包含8篇内容,将会从介绍和分析Kubernetes系统以及云原生应用 入手,逐步推出基于 ...

  2. kubernetes部署1——ectd部署(单节点)

    kubernetes--ectd部署(单节点) 一.环境部署 二.部署Master1 1.创建K8s目录 2.将证书脚本和服务脚本拖进目录 3.下载证书制作工具 4.制作ca和ca签名并创建ca证书 ...

  3. k8s安装sqlite3_kubernetes环境部署单节点redis数据库的方法

    kubernetes部署redis数据库(单节点) redis简介 Redis 是我们常用的非关系型数据库,在项目开发.测试.部署到生成环境时,经常需要部署一套 Redis 来对数据进行缓存.这里介绍 ...

  4. Kubernetes 部署 Mysql 8.0 数据库(单节点)

    作者:超级小豆丁 http://www.mydlq.club/article/75 目录 简介 Mysql 参数配置 创建 ConfigMap 存储 Mysql 配置文件 通过 Kubectl 工具部 ...

  5. Kubernetes(k8s)四、Pod生命周期(初始化容器的应用,探针liveness、readliness应用,)

    Pod生命周期 学习目标:初始化容器的应用及两个探针的应用 探针 是由 kubelet 对容器执行的定期诊断: Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应: liveness ...

  6. Springboot 使用管道设计模式 , 实践案例玩一玩

    前言 这段时间,学习群里大家讨论设计模式频率很高,可以看出来 日常搬砖 CRUD 已经让人从麻木到想脱离麻木,对代码有了些许追求. 当然也有还没放开的小伙(N重打码照顾兄弟),不敢参与讨论,但是私下还 ...

  7. 从零开始入门 K8s| 详解 Pod 及容器设计模式

    作者|张磊 阿里云容器平台高级技术专家,CNCF 官方大使 一.为什么需要 Pod 容器的基本概念 我们知道 Pod 是 Kubernetes 项目里面一个非常重要的概念,也是非常重要的一个原子调度单 ...

  8. 理解 Pod 和容器设计模式

    本节课程要点 为什么需要 Pod: Pod 的实现机制: 详解容器设计模式. 为什么需要 Pod 容器的基本概念 现在来看第一个问题:为什么需要 Pod?我们知道 Pod 是 Kubernetes 项 ...

  9. Monitor:单节点监控之Cadvisor

    Cadviosr是Google用来监测单节点的资源信息的监控工具.虽然Docker提供了一些CLI的命令行的功能,但是在一个看图的时代,基本的功能是很难满足人民群众日益增长的物质文化需求,Cadvis ...

  10. 为什么我们需要Pod?(容器设计模式sidecar)

    Pod,是 Kubernetes 项目中最小的 API 对象 容器的本质是进程,就是未来云计算系统中的进程:容器镜像就是这个系统里的".exe"安装包 Kubernetes 就是操 ...

最新文章

  1. mac攻略(1) -- 简单配置php开发环境
  2. 时间序列数据库概览——基于文件(RRD)、K/V数据库(influxDB)、关系型数据库...
  3. iOS网络传输Delegate不被触发的本质原因
  4. js 数组/对象/日期的浅克隆
  5. leetcode 640. Solve the Equation | 640. 求解方程(字符串处理)
  6. 对pca降维后的手写体数字图片数据分类_【AI白身境】深度学习中的数据可视化...
  7. C语言试题二十九之编写函数int function(int lim,int aa[max])求出小于或等于lim的所有素数并放在aa数组中,该函数返回所求的素数的个数。
  8. oracle权限培训,Java培训-ORACLE数据库学习【2】用户权限
  9. linux基础磁盘管理,Linux基础入门-文件系统操作与磁盘管理
  10. 程序员里面开源_如何以开源程序员的身份开始
  11. 什么是罗技LogitechFlow技术
  12. 【JS点滴】substring和substr以及slice和splice的用法和区别。
  13. 【TSP】基于matlab人工鱼群算法求解旅行商问题【含Matlab源码 422期】
  14. HTML Layui Distpicker 住址/收货地址选择 联动选择框
  15. android百度地图注册,百度地图API key申请申请详细步骤
  16. html中动态添加元素属性值,JavaScript实现动态添加、移除元素或属性的方法分析...
  17. easyui mysql_Easyui 添加查询功能_EasyUI 教程
  18. 无法搜索到对方电脑共享的文件
  19. 大专生三面蚂蚁金服,工信部java工程师证书
  20. golang牛牛算法规则与聊天功能

热门文章

  1. cef 获取 html代码,CefGlue获取网页源代码
  2. layer的move要怎么用
  3. Leetcode--Java--212. 单词搜索 II
  4. 极致”神话和产品观念
  5. 北京科技大学计算机复试面试,北京科技大学考研复试
  6. html里获得农历时间,获取阴历(农历)和当前日期的js代码_javascript技巧
  7. CUDA中的Warp Shuffle
  8. python字典保存为文件_关于python:如何将字典列表保存到文件中?
  9. Win7 Hiberfil.sys pagefile.sys
  10. MVC项目使用easyui的filebox控件上传文件