将12Factor原则应用于Kubernetes应用开发的评论

这个 “The Twelve-Factor App”(https://12factor.net/ja/)是由Heroku创始成员Adam Wiggins编写的一种用于构建Web应用和SaaS的方法。它基于作者的丰富实际经验总结而成,是一种优秀的方法,可以应用于各种编程语言、数据库等服务类型,与其无关。许多开发者都推荐参考这种方法。

最初,「The Twelve-Factor App」可以被视为与Heroku平台兼容的应用程序方法,但与使用容器技术的应用程序也有很多共同点,在使用Kubernetes运行应用程序的情况下也是有用的。

因此,为了将该方法应用于K8s,我们总结了Twelve-Factor的要点,并用评论和图表做了K8s的兼容性概述。


1. 代码库 kù)

从一个代码库中创建多个部署。

    • コードベースとは、GitやSubversionなどのコードのバージョン管理ツール

 

    • デプロイは、開発者のPC、テスト環境、本番環境などで実行されるアプリのインスタンス

 

    それぞれのデプロイは、一つのコードベースからビルドされたものであるべき

k8s的适应性评论

由于在K8S上部署容器需要从同一个镜像仓库中进行,所以使得依赖软件保持一致变得更加容易。

    • レジストリに、アプリの実行形式とそれが依存するOSやライブラリを含んだコンテナを登録

 

    レジストリに登録されたコンテナから、各環境へデプロイする
スクリーンショット 2018-07-16 0.46.59.png

容器注册表和仓库的关系。

由于经常缺乏对注册表和仓库的区分描述,因此我们使用图表进行整理。

    • レジストリは、複数のリポジトリを収容するサービスであり、リポジトリ名とアプリが対応する

 

    アプリケーション名とリポジトリ名を対応させ、コンテナのバージョン管理はタグを利用する。
スクリーンショット 2018-07-16 0.47.19.png

Docker和K8s的参考资料

    • Docker Docs, Understanding Registry, https://docs.docker.com/registry/introduction/

Docker Docs, Overview of Docker Hub, https://docs.docker.com/docker-hub/

Kubernetes Documentaion, Concepts images, https://kubernetes.io/docs/concepts/containers/images/

Kubernetes Documentaion, Tasks Pull an Image from a Private Registry, https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/

Kubernetes API, secret docker-registry, https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-secret-docker-registry-em-


2. 互相依赖的关系

依存関係を明示的に宣言し分離する

    • OSとそのパッケージを含めたすべての依存関係を 依存関係宣言 マニフェストで完全かつ厳密に宣言

 

    • 依存関係分離 ツール(vituralenv,pip,gemなど)を使って、暗黙の依存関係が“漏れ出ない”ことを保証

 

    この指定は、本番環境と開発環境の両方に対して同様に適用

k8s適応のコメント

Dockerfileに、依存関係分離ツールの実行を記述することで、アプリが依存する全てのパッケージをコンテナへインストールする

スクリーンショット 2018-07-16 0.47.38.png

Docker与K8s的参考资料

    • Docker Docs, Dockerfile reference, https://docs.docker.com/engine/reference/builder/#usage

 

    • Docker Docs, Best practices for writing Dockerfiles, https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

Docker Docs, Push images to Docker Cloud, https://docs.docker.com/docker-cloud/builds/push-images/


3. 设定

将设置存储为环境变量

    • アプリ設定は、デプロイ(ステージング、本番、開発環境など)の間で異なり得る唯一のモノとする。

 

    • 環境変数は、コードを変更することなくデプロイごとに簡単に変更できる。

 

    設定ファイルとは異なり、誤ってリポジトリにチェックインされる可能性はほとんどない。

K8s的适应性评论

只要将所有设置都转化为环境变量,工作量反而会增加。因此,应该启用能够将设置文件作为永久卷进行挂载的功能,并利用Secret来限制访问权限。

    • ConfigMap : 設定ファイルをk8sのネームスペースに保存する

 

    • Secret : ユーザーID/パスワード、証明書など資格情報を、他者に見られない様にk8sのネームスペースに保存する

 

    • Service : k8sサービスとしてデプロイすることで、それ以降のポッドの環境変数で、エンドポイントを環境変数で参照可能

 

    ポッド・テンプレート : ConfigMapやSecretの情報を、コンテナの環境変数、または、ボリュームとしてマウントして参照可能
スクリーンショット 2018-07-16 0.48.12.png

Docker 和 K8s 有用的資料来源

    • Kubernetes Documentaion, Tasks Configure a Pod to Use a ConfigMap, https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

Kubernetes Blog, Configuration management with Containers, https://kubernetes.io/blog/2016/04/configuration-management-with-containers/

Kubernetes Documentaion, Concepts Secrets, https://kubernetes.io/docs/concepts/configuration/secret/

Kubernetes Documentaion, Concepts Service, https://kubernetes.io/docs/concepts/services-networking/service/

Kubernetes Documentaion, Concepts DNS for Services and Pods, https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/

Kubernetes Documentaion, Concepts Writing a Deployment Spec, https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#writing-a-deployment-spec


4. 后端服务

将后端服务视为已附加的资源。

    • バックエンドサービス はアプリが通常の動作の中でネットワーク越しに利用するすべてのサービスを言う。

 

    例としては、データストア(例:MySQL や CouchDB)、メッセージキューイングシステム(例:RabbitMQ や Beanstalkd)、電子メールを送信するためのSMTPサービス(例:Postfix)、キャッシュシステム(例:Memcached)などがある。

k8s适应性的评论

由于参考的方式相同,可以使用k8s的DNS进行地址解析,因此注意以下两点来创建服务。

    • 内部サービスの場合、サービスタイプにClusterIPを選択して、セレクタのラベルを設定して、対応するポッドのラベルとマッチさせる。

 

    外部サービスの場合、サービスタイプにExternalNameを設定して、外部サービスのIPアドレスやポート番号を設定する
スクリーンショット 2018-07-16 10.25.39.png

Docker和K8s的参考资料

    • Kubernetes Documentaion, Concepts Connecting Applications with Services, https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/

Kubernetes Documentaion, Concepts Headless services, https://kubernetes.io/docs/concepts/services-networking/service/#headless-services


构建、发布、执行

严格将构建、发布和执行这三个阶段分开。

    • ビルド・ステージ : 依存するファイルを集め実行形式を生成する

 

    • リリース・ステージ : 実行形式を受け取り、デプロイの現在の設定と結合する

 

    実行・ステージ : プロセスを起動して、アプリケーションを開始する

k8s适应的评论

由于原先的Heroku构建包有三个阶段,所以调整为与k8s相适应的如下步骤。

    • ビルド : アプリコードと依存パッケージをまとめて、Dockerfileを使ってビルドして、コンテナとしてレジストリへ登録する

 

    • リリース: 設定ファイル、資格情報を環境に登録、k8s DeploymentやStatefulSetのマニフェストをk8sクラスタへ適用する

 

    実行: kubectl apply -f マニフェストで、◯◯環境でアプリの実行を開始する
スクリーンショット 2018-07-16 0.49.35.png

Docker和K8s的参考资料

    • Docker Docs, docker build, https://docs.docker.com/engine/reference/commandline/build/

Kubernetes Documentaion, Concepts Configuration Best Practices, https://kubernetes.io/docs/concepts/configuration/overview/

Kubernetes Documentaion, Concepts Pod Lifecycle, https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/


6. 进程

将应用程序作为一个或多个无状态进程运行

    • ステートレスとは、ウェブサーバーの様に、一回毎のリクエストとレスポンスだけで処理する事を意味している。つまり、ロードバランサーのステッキーセッションやセッション・アフィニティなどと呼ばれる機能を使って、セッションを確立したコンテナへ固定的に振り向ける事は、コンテナ上のアプリがセッションの状態を持つことになり、12Factor に違反することになります。

 

    • セッションの情報は、外にあるキャッシュ・サービスなどを利用して、アプリ・コンテナの突然の停止に備える必要があります。

 

    リクエストを受けてから応答する間の一時的なメモリ上のデータは対象外

k8s适应性的评论

k8sでは、ステートレスなアプリケーション用に、Deploymentコントローラーがある。また、ステートフルなアプリケーション用に StatefulSet コントローラーがあるが、リクエストを特定のポッドへ振り分けるものではない。 このため、セッション情報などは、外部のキャッシュやDBサービス、または、永続ボリュームに保存しなければなりません。

    • サービスを作成すると生成されるClusterIPは、kube-proxyによって、リクエストをランダムにポッドへ振り分ける。セッションを開始したポッドへ降り先を固定する機能はない。

 

    セッションを開始したアプリケーションのポッドに、継続してリクエストを向けるには、Ingressを利用できる。しかし、このIngressは外部への公開用なので、k8sクラスタ内のアクセスに適用できない。
スクリーンショット 2018-07-16 0.50.14.png

Docker和Kubernetes的参考资料

    • Kubernetes Documentaion, Tasks Run a Stateless Application Using a Deployment, https://kubernetes.io/docs/tasks/run-application/run-stateless-application-deployment/

Kubernetes Documentaion, Concepts Deployments, https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

Kubernetes Documentaion, Concepts StatefulSets, https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/

Kubernetes Documentaion, Concepts Ingress, https://kubernetes.io/docs/concepts/services-networking/ingress/


7. 端口绑定

通过端口绑定来公开服务

    HerokuではWebアプリとして、PHP、Python、Rubyなどプログラミング言語のフレームワーク等のサーバーポートをバインドして、サービスを公開することを勧めており、公開のためにHTTPサーバーの利用を推奨していません。

k8s適応のコメント

    • K8sでは、アプリのポートを公開するために、Nginx等のHTTPサーバーのコンテナと組み合わせ事もでき、次の機能によってコンテナのポート番号を公開用ポート番号に対応づける事ができる。

NodePort : ノードのIPアドレスでポートを公開、ポードフォワーディングと負荷分散
Ingress : URL変換、TLS暗号化、負荷分散等

スクリーンショット 2018-07-16 0.51.14.png

Docker和K8s相关参考资料

    • Kubernetes Documentaion, Concepts Service, https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

Kubernetes Documentaion, Concepts Ingress, https://kubernetes.io/docs/concepts/services-networking/ingress/


8.同时进行的能力

通过进程模型来进行横向扩展。

    • 個々のワークロードの種類を処理タイプに割り当てることで、開発者はアプリケーションが多様なワークロードを扱えるように設計する

 

    これが真価を発揮するのはスケールアウトが必要になったときである。シェアードナッシングで水平分割可能なTwelve-Factor Appプロセスの性質は、並行性を高める操作が単純かつ確実なものである。

k8s适应的评论

処理タイプでコンテナを分けて、水平分割可能な並列度の高い設計を目指すべきは、k8sでも同じである。

スクリーンショット 2018-07-16 0.52.55.png

Docker & K8s 参考資料

    • Kubernetes Documentaion, Tasks Horizontal Pod Autoscaler, https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/

Kubernetes Blog, Principles of Container-based Application Design, https://kubernetes.io/blog/2018/03/principles-of-container-app-design/


9.廃棄容易性

用快速启动和优雅关机来最大化稳定性。

    • アプリの起動時間を最小化する努力は常に必要である。この素早い起動は、設定条件の変更、ハード障害からの回復、ワークロードの急増に迅速に対応するためである。

 

    終了要求シグナル(SIGTERM)を受け取ると、速やかに終了処理を実行して、プロセスを終了することを推奨している。

k8s适应的注释

    • k8sがノードの一つを保守作業のために停止させる場合、ポッドをライブマイグレーションするのではなく、SIGTERMを送ってポッドが停止することを要求する。このためコンテナのSIGTERMの処理の実装は必須である。

 

    コンテナのサイズが大きいと、レジストリからのダウンロードに時間を要し、起動が遅くなる。特にコンテナは無駄なパッケージが含まない様に注意を払うべきである。
スクリーンショット 2018-07-16 0.53.31.png

Docker与K8s的参考资料

    • Kubernetes Blog, Principles of Container-based Application Design, https://kubernetes.io/blog/2018/03/principles-of-container-app-design/

Kubernetes Documentaion, Concepts Pods, https://kubernetes.io/docs/concepts/workloads/pods/pod/


10. 开发和生产环节一致

尽量保持开发、预备环境和正式环境尽可能一致的状态。

    • 開発者が書いたコードは、出来るだけ早くデプロイする。

 

    • コードを書いた開発者は、デプロイ作業に関わり、その後、モニタリングする。

 

    開発環境と本番環境をできだけ一致した状態に保つ

k8s适应性评论 (K8s

可以通过使用命名空间将K8s集群分割,在同一硬件环境上,实现开发和生产环境的相互独立共存,互不干扰。

ネームスペースで実現できる分割

CPUとメモリの利用上限、ネットワークのアクセス範囲
kubectlコマンドの有効範囲
RBACベースのサービスアカウントにより、開発者やSREのアクセス範囲を限定

スクリーンショット 2018-07-16 0.54.07.png

Docker 和 K8s 参考资料

    • Kubernetes Documentaion, Concepts Namespaces, https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

Kubernetes Documentaion, Tasks Namespaces Walkthrough, https://kubernetes.io/docs/tasks/administer-cluster/namespaces-walkthrough/

Kubernetes Documentaion, Concepts Configure Default Memory Requests and Limits for a Namespace, https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/

Kubernetes Documentaion, Tasks Use Calico for NetworkPolicy, https://kubernetes.io/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy/


11. 日志 (rì zhì)

将日志作为事件流进行处理

    • アプリケーションはログファイルに書き込んだり、ログをローテション管理しない。

 

    • それぞれの実行中のコンテナは、イベントストリームを標準出力にバッファリングせずに書きだす

 

    ローカルでの開発中、このストリームをターミナルで見ることで、アプリケーションのデバッグを実施

k8s适应性的评论

在K8s中,容器发布的事件流会被Logstash筛选并转发到ElasticSearch进行汇总。可以使用Kibana来跨Pod和容器全面了解事件的发生情况。

    コンテナ内のログファイルに書き出さず、標準出力へ書き出す事は同じである。
スクリーンショット 2018-07-16 0.54.40.png

Docker & K8s 参考資料

    • Kubernetes Documentaion, Tasks Logging Using Elasticsearch and Kibana, https://kubernetes.io/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana/

Kubernetes Documentaion, Concepts Logging Architecture, https://kubernetes.io/docs/concepts/cluster-administration/logging/


12. 管理过程

管理タスクを1回限りのプロセスとして実行する

    • アプリケーションのメンテナンスのための一回限りの処理の管理用コードは、同じアプリケーションのコンテナ内で実行されるべき

 

    • 同じコードベース(Gitリポジトリ等)に含まれるべき

 

    アプリと同じコミットの世代が利用できる様に、同じコンテナに含まれるべき

k8s适应的评论

    kubectl exec pod -c コンテナ名 実行コマンド を利用して、一回限りの処理を実行する。
スクリーンショット 2018-07-16 0.55.11.png

Docker & K8s 参考資料

    Kubernetes Documentaion, Tasks Get a Shell to a Running Container, https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/

IBM云Kubernetes服务https://www.ibm.com/cloud/container-service

广告
将在 10 秒后关闭
bannerAds