现代“十二要素应用”与 Kubernetes


“十二要素应用”为开发SaaS应用提供了方法上的指导,而Docker可以提供打包依赖,解耦后端服务等特性,使得二者很是吻合。这篇文章介绍了Docker特性怎样知足了开发“十二要素应用”的对应要点。mysql

“十二要素应用”为构建SaaS应用提供了方法论,是由知名PaaS云计算平台Heroku的创始人Adam Wiggins提出的。请参考这篇 Heroku 创始人 Adam Wiggins 发布十二要素应用宣言sql

Dockerfile 与k8s/helm 正在成为用代码定义服务的标准,经过它们能够定义服务的全部内容:依赖、环境、端口、各类进程以及后端服务。 Docker镜像和容器为操做系统提供了保证,使得开发环境和生产环境能够有效地保持一致。docker

依赖—显示地声明和隔离依赖关系

Docker镜像基于显示的Dockerfile构建,而Docker容器做为独立的运行环境。Dockerfile提供了显示声明基础操做系统的方法(FROM), 并且经过运行命令来安装附加的系统包以及应用的依赖包(RUN)。经过这些方法,你能够声明你须要ubuntu 18.0四、ASP.NET Core 2.2.2而后一次性安装。数据库

配置—在环境中储存配置

Docker容器很是依赖Linux的环境变量进行配置。k8s/helm 有一个环境变量的哈希表,你能够经过它显示的定义容器的环境变量。这些默认的或者未定义的值将在运行时从主机中继承。另外,还有Dokckerfile的ENV命令以及『docker run –env=[]』和『docker run –env-file=[]』运行选项能够设置环境变量。 经过这些方法,你能够声明你的应用须要环境变量GITHUB_AUTH_TOKEN。ubuntu

K8s 还有ConfigMap ,ConfigMap是存储通用的配置变量的。ConfigMap有点儿像一个统一的配置文件,使用户能够将分布式系统中用于不一样模块的环境变量统一到一个对象中管理;而它与配置文件的区别在于它是存在集群的“环境”中的,而且支持K8s集群中全部通用的操做调用方式。而资源的使用者能够经过ConfigMap来存储这个资源的配置,这样须要访问这个资源的应用就能够同经过ConfigMap来引用这个资源。至关经过建立Configmap封装资源配置。configmap以一个或者多个key:value的形式保存在k8s系统中供应用使用,既能够用于表示一个变量的值(eg.apploglevel:info),也能够用于表示一个完整配置文件的内容(eg: server.xml=<?xml...>...)后端

端口绑定—经过端口绑定来提供服务

Docker很是依赖端口绑定。k8s的pod也使用了端口映射的功能,能够把一个pod中的全部container的port都经过net container export出去,便于和外界通讯。 经过这些方法,你能够声明你的应用的网络服务器将监听端口5000,并且你能够经过主机的端口5000获取服务。api

后端服务—把后端服务看成附加资源

Docker容器与其它容器几乎彻底隔离,因此须要经过网络与后端服务进行通讯。在应用中,一个组件依赖指定的中间件服务和业务服务,在传统的软件部署方式中,应用启动、中止都要依照特定的顺序完成。当采用 Kubernetes 等容器编排技术在分布式环境下部署应用时,一方面不一样组件之间并行启动没法保证其启动顺序,另外一方面在应用运行时,其所依赖的服务实现有可能发生失败和迁移,咱们利用Kubernetes Pod自身机制添加依赖检查逻辑,一般是利用初始化容器来进行依赖服务的检查。首先咱们须要对Pod的生命周期有必定的理解,下图来自于 https://blog.openshift.com/kubernetes-pods-life/ 一文bash

首先在Pod中有三类容器服务器

  • infra container: 这就是著名的pause容器
  • init container: 初始化容器 一般用于应用的初始化准备,只有等全部的初始化容器正常执行完毕以后,才会启动应用容器
  • main container: 应用容器

下面咱们经过一个Wordpress的实例来展现其使用方法。网络

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: None
  ports:
  - name: mysql
    port: 3306
  selector:
    app: mysql
---
apiVersion: v1
kind: Service
metadata:
  name: wordpress
spec:
  ports:
  - name: wordpress
    port: 80
    targetPort: 80
  selector:
    app: wordpress
  type: NodePort
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql 
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "true"
        livenessProbe:
          exec:
            command: ["mysqladmin", "ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            # Check we can execute queries over TCP (skip-networking is off).
            command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
          initialDelaySeconds: 5
          periodSeconds: 2
          timeoutSeconds: 1
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - name: wordpress
        image: wordpress:4
        ports:
        - containerPort: 80
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql
        - name: WORDPRESS_DB_PASSWORD
          value: ""
      initContainers:
      - name: init-mysql
        image: busybox
        command: ['sh', '-c', 'until nslookup mysql; do echo waiting for mysql; sleep 2; done;']

咱们在Wordpress Deployment的Pod定义中添加了initContainers,它会经过检查 mysql 域名是否能够解析来判断所依赖的mysql服务是否就绪。

同时,在MySQL StatefulSet中咱们也引入了readinessProbelivenessProbe探针,它们会断定是否MySQL进程已经业务就绪。在K8S中,只有健康的Pod才能够经过ClusterIP访问或者DNS解析。

进程—以一个或者多个无状态进程运行应用

默认状况下,Docker容器是不带储存的进程。k8s/helm 定义了一系列服务,每个服务都有本身的镜像或者构建文件(Dockerfile)以及命令。 经过这些方法,你能够声明你的应用同时有一个网络进程和工做进程。

管理进程—后台管理任务当作一次性进程运行

Docker镜像能够很容易地运行一次性进程。‘docker run myapp CMD’能够在与你的网络进程一致的环境中运行任意命令。 经过这些方法,你能够基于你的Postgres数据库运行交互式的bash或者运行一次性的’rake db:migrate’进程。

相关文章
相关标签/搜索