kubernetes-容器的设计模式

350 阅读4分钟

背景

场景1 nmp模式

nginx mysql php应该怎么配置? 超亲密关系? 这几个服务 只需要通信就可以

场景2 mysql监控

mysql服务 和 mysql-exporter为了方便监控 应该放到一个pod中

场景3 redis cluster

需要运行3个数据库实例 应该怎么配置 怎么遵循分布式设计的规范

一、分布式系统中常用的 3类设计模式

单容器模式

单一容器形式运行的应用 一个容器中运行了很多进程

很少用

单节点模式

由强耦合的多个容器协同共生 一个pod中运行多个容器(分布式应用会被限制)

违反了分布式设计 单节点故障问题

多节点模式

基于特定部署单元(Pod)实现分布式算法

  • 每个实例运行在一个pod中 每个pod分布在单一节点
  • 多个pod 就有多个节点

例如lnmp模式

单节点多容器模式 (单pod中 运行多个container)

跨容器的设计模式 超亲密关系的应用 应该放在一个pod中

  • 目的是在单个节点之上同时运行多个共生关系的容器,因而容器管理系统需要由将它们作为一个原子单位进行统一调度
  • Pod概念就是这个设计模式的实现之一

mysql服务 和 mysql-exporter为了方便监控 应该放到一个pod中

单节点多容器模式的常见实现

Sidecar模式 边车

使用场景: 一个主容器 一个辅助容器 例如 proxy sidecar 做网络代理

  • Pod中的应用由主应用程序(通常是基于HTTP协议的应用程序)以及一个Sidecar容器组成
  • 辅助容器用于为主容器提供辅助服务以增强主容器的功能,是主应用程序是必不可少的一部分,但却未必非得运行为应用的一部分

例如服务网格 proxy sidecar 需要给主程序提供网络代理的

github.com/iKubernetes…

# Maintainer: MageEdu <mage@magedu.com>
# URL: http://www.magedu.com
# ---
apiVersion: v1
kind: Pod
metadata:
  name: sidecar-container-demo
  namespace: default
spec:
  containers:
  - name: proxy
    image: envoyproxy/envoy-alpine:v1.14.1
  - name: demo
    image: ikubernetes/demoapp:v1.0
    imagePullPolicy: IfNotPresent
    env:
    - name: HOST
      value: "127.0.0.1"
    - name: PORT
      value: "8080"

Ambassador模式 大使容器(代理)

Pod中的应用由主应用程序和一个Ambassador容器组成

  • 辅助容器代表主容器发送网络请求至外部环境中,因此可以将其视作主容器应用的“大使”
  • 应用场景:云原生应用程序需要诸如断路、路由、计量和监视等功能,但更新已有的应用程序或现有代码库以添加这些功能可能很困难,甚至难以实现,进程外代理便成了一种有效的解决方案

github.com/iKubernetes…

示例

# Create By: "MageEdu <mage@magedu.com>"
# Site: www.magedu.com
apiVersion: v1
kind: Pod
metadata:
  name: ambassador-container-demo
spec:
  containers:
  - name: curl
    image: ikubernetes/admin-box:v1.2
    command: ["sleep", "999999"]
  - name: ambassador
    image: bitnami/kubectl:latest
    command: ["/bin/sh","-c","kubectl proxy"]
    args:    
    # 传递给 kubectl proxy 的选项,若需要改变默认监听的tcp/8001端口,可以额外附加“--port=NUM”选项;
    - --server="https://kubernetes.default.svc"
    - --certificate-authority="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
    - --token="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
    - --accept-paths='^.\*'

Adapter模式 适配器容器

Pod中的应用由主应用程序和一个Adapter容器组成

  • 例如exporter容器 监控mysql 然后转换成promethues能识别的数据结构
  • Adapter容器为主应用程序提供一致的接口,实现了模块重用,支持标准化和规范化主容器应用程序的输出以便于外部服务进行聚合

Init Container模式 初始化容器

需要先跑一个前置的初始化容器 然后退出 然后再启用主容器

  • 一个Pod中可以同时定义多个Init容器 顺次运行 上一个结束 下一个才会开始运行
  • Init容器负责以不同于主容器的生命周期来完成那些必要的初始化任务,
    • 包括在文件系统上设置必要的特殊权限、数据库模式设置或为主应用程序提供初始数据等,
    • 但这些初始化逻辑无法包含在应用程序的镜像文件中,
    • 或者出于安全原因,应用程序镜像没有执行初始化活动的权限等等
  • Init容器需要串行运行,且在所有Init容器均正常终止后,才能运行主容器

使用场景 tomcat主容器没有管理员权限 先用init contaner配置存储卷 修改文件权限

github.com/iKubernetes…

apiVersion: v1
kind: Pod
metadata:
  name: init-container-demo
  namespace: default
spec:
  initContainers:
  - name: iptables-init
    image: ikubernetes/admin-box:latest
    imagePullPolicy: IfNotPresent
    command: ['/bin/sh','-c']
    args: ['iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80']
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
  containers:
  - name: demo
    image: ikubernetes/demoapp:v1.0
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80