現代「十二要素應用」與 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’進程。

相關文章
相關標籤/搜索