适用于从今天开始使用Kubernetes在AWS上的最佳实践

今年我在AWS上使用Kubernetes的经验,以kube-aws维护者的眼光,总结了一些个人最佳实践,以便“从今天开始,尽可能轻松、稳定地进行生产运行”。

太长 直接看结论

    • EKSはまだプレビュー申込の段階。実際に動くものがあるかもわからない。

 

    • EKSとkops、kube-aws、kubesprayなどは組み合わせて使うもの。代替えにはならない。

 

    • SaaSありなら分散ログ、分散トレース、リソースモニタリングはDatadogに寄せると運用が楽

 

    • istioは安心して本番運用できるフェーズではない(Service Meshが必要なら、まだLinkerdのほうがよい)

 

    • アプリケーションにPrometheusエンドポイントを生やしてメトリクスを取れるようにすべき

 

    アプリケーションはOpenTracingやZipkin、Jaegerなどのトレーサを組み込み、Zipkin v1スパンを送るべき

开场白

由于kube-aws只是一个部分,所以kube-aws组件很少。

同时,为了不使文章变得过长,详细内容尽量不在这篇文章内进行叙述,而是交由各参考文章来负责(虽然有些地方我不禁写了进去)。

最后,我想以“从今天开始,尽量让运营尽可能简单、稳定”这一观点来总结,所以不会介绍太过尖锐的内容(实际上,也不打算介绍。大概)。

一劳永逸

以下是我最想保留的工具

    • kubectl

 

    • kubectx

 

    • kubens

 

    • helm

 

    minikube

这里有一些增强kubectl的工具。?它们一起运作得很好![1] https://t.co/b9EYQN0Fq8 [2] https://t.co/177WiwY2I9 #Kubernetes pic.twitter.com/utzizg9vzc— Ahmet Alp Balkan (@ahmetb) 2018年1月4日

应用程序的部署相关

可以通过创建新的Secret或Configmap来进行切换,而不是进行更改。

在Kubernetes中,应用程序的配置值和凭据被定义为名为Configmap和Secret的K8S资源,并将其映射到环境变量和本地文件中,以供应用程序进程读取。这种方法被广泛使用。

在使用K8S之前,如果假定环境变量的值不会自动替换为Configmap或Secret的更改,那么将会遇到困难。应用程序进程并不是从Configmap或Secret中读取环境变量,而是在K8S进行docker运行时读取并设置环境变量,这一点可能是显而易见的。

当对Configmap进行更改时,会自动重新创建Pod(包括容器)

有些人使用类似的OSS,这也是可以的,但是,不改变Configmap或Secret本身,而是创建一个新的并切换过去,有一个优点,就是如果内容出错,可以进行回退。

当使用头盔时。

如果使用Helm,您可以使用依赖的configmap/secret的checksum来自动重新创建Pod(和容器)。Helm只提供checksum的计算和引用,因此某些chart可能不支持此功能。如果使用的chart不支持,可以考虑使用Helm的唯一解决方案。另外,如果您要自己创建Helm chart,考虑到这一点会很方便。

以下为原文和一个可能的汉语翻译:

古いデプロイメントの
旧版部署的

(Note: The provided translation directly translates the term “older deployment”. If the full context is provided, a more accurate translation may be possible.)

我也想读。

    kubectl apply should be able to delete objects missing from supplied config · Issue #19805 · kubernetes/kubernetes

通过替换Pod和EC2实例以确保零停机时间。

    • ステートレスなPodは最低2個以上セットにする

Podがノードの入れ替え等で一時的に増減するのは当たり前に起こることなので、それに対処しておく
できるだけそれぞれ別のEC2インスタンスにスケジュールされるようにする

podAntiAffinity
クラスタ自体がMulti-AZの場合のみ。

できるだけそれぞれ別のAZにスケジュールされるようにする

podAntiAffinity
クラスタ自体がMulti-AZの場合のみ。

Podにreadiness/health probesを設定する

起動中のPod、障害発生中のPodを自動的にロードバランス対象から外すために必要

SIGTERMを受けたらGraceful Stopすること。N秒後にSIGKILLで強制停止させられるから。

NはterminationGracePeriodSecondsで変更可能

ノードが

PodDisruptionBudget

想要一起閱讀的文章:

A summary of how to do graceful terminations and zero-downtime upgrades in Kubernetes. pic.twitter.com/4v8ZBZpdtK— Ahmet Alp Balkan (@ahmetb) 2017年12月19日

プロダクションレディ Pods / Production-Ready Pods // Speaker Deck

通过EKS简化对K8S集群本身的运维工作。

AWS re:Invent 2017终于发布了Kubernetes的托管服务!

我總結了有關「Amazon Elastic Container Service for Kubernetes(EKS)的評價」的詳細信息。它目前還不能實際使用,但根據目前的資訊,

    • 「Masterノードのマネージドサービス」。WorkerノードはCloudFormationなどで自分で持ち寄る(これは個人的には圧倒的に良い判断だと思いますが、GKEのようなサービスを求めてた人からは評判悪そうですね

 

    • KubernetesのCluster NetworkingによりAWSネイティブなサポートを追加していく

amazon-vpc-cni-k8s
上記とCalicoの連携

Kubernetes on AWSを便利に使うためのOSSをバンドルしていく

kube2iam, heptio/authenticator

我认为,即使只是基于这一点,Kubernetes在AWS上的引入、操作和使用门槛都会大大降低,这是一个值得欢迎的服务。

同时,

    Fargate対応

这将取决于实际情况如何。

    • LambdaのようにENIをアタッチするために数十秒待たされるような仕様になると「すぐスケールしてほしい」というユースケースには対応できなくなる(むしろSpot Fleetで安価なインスタンスをホットスタンバイでおいておくほうがよいのでは)

virtual-kubeletで検討されているような抽象化をするとしたら、Daemonsetはどうするのか(fluentdやdatadog agentでFargateに起動したK8S Podのログやメトリクスをとれるの?たぶんとれない実装になりそう)

作为已经在AWS上使用Kubernetes进行生产运营的立场来看,这些事情令人担忧。

EKS加上kube-aws

很抱歉,目前的味噌版本是kube-aws。不过kube-aws计划与EKS整合。kube-aws不仅能够通过CloudFormation管理etcd和控制节点,但是将这些任务交给EKS后,对于kube-aws和使用者来说都会有好处。

※kube-aws是一个用于在AWS上构建可定制的Kubernetes集群的CloudFormation + cloud-init的封装工具,因此与EKS的范围不同。kops也是如此。因此,“因为EKS会出现,所以kops就不再需要”的说法有些错误。当然,“对于无法使用EKS创建的部分,可以使用手动操作或使用自己的脚本来完成”确实可以不再需要kops等工具,但是我仍然有疑问,自己制作类似kops的工具与现有工具之间有多大差别!

高效且易于操作的分布式日志。

在建立一个可以从fluentd发送日志到日志存储,并且能够几乎实时地进行日志过滤和追踪的环境时,调试工作会更加顺利。特别是对于采用微服务架构并在AWS上部署多个服务的情况来说,这是必不可少的。

以下是一些具体的组合建议。

    1. 流畅的+ Google Stackdriver Logging

有Google官方的fluent-plugin是很重要的。
毕竟市面上存在的fluent-plugin的维护态度非常糟糕对吧?
有了官方的插件,这种担忧也会有一定程度的减轻。

流畅的+ Datadog Logs(新!)

Datadog Logs的官方插件(功能少)和非官方插件(功能多,但未来不确定)。

流畅的+ Elasticsearch

使用AWS Elasticsearch Service或者是仅限于elasticsearch-operator。

在可以使用托管服务的地方,不使用托管服务是不正常的。基本上选择流畅 + ES,如果不涉及到Kinesis Firehose(目前还不支持VPC内的AWS ES),那就只能选择AWS ES。现在也有VPC支持。

我想推荐一番使用Fluentd + Stackdriver Logging,但当前的工作使用的是Datadog Logs。

为了自动收集在Kubernetes上的应用程序日志,我们可以在集群中部署kube-fluentd,并将日志发送到Stackdriver或Datadog Logs。这样做的目的和意图已经记录下来了。

Kubernetes原生资源监控服务

    • Prometheus

 

    • Datadog

 

    Stackdriver Monitoring

我们会选择使用支持Kubernetes的完善监控服务。有两个不可或缺的要点,第一个是是否支持自动发现的自定义指标,第二个是是否支持从Kubernetes节点到Pod、Deployment等通用指标的收集。特别是在自动发现方面,Prometheus和Datadog提供的解决方案可以通过为Pod添加特定的注释,在后端服务上自动抓取并发送指标,这让它们脱颖而出。

关于Datadog的自动发现功能,我们写道:“自动收集在Kubernetes部署的应用程序的度量指标”。

为了确定哪个微服务引起或可能引起故障,需要进行分布式跟踪。

如果你想要在尽量节省时间的同时为未来的迁移路径做好准备,并且希望在生产环境中使用,有一种像是「提到分散追踪就会想到OpenTracing」的氛围,那么我建议目前使用Zipkin + Datadog APM。

我在「分布式追踪微服务在Kubernetes上的详细方法」中详细说明了。

如果你当然想要为OpenTracing的发展做出贡献,并且愿意付诸行动,没有其他选择,就只有OpenTracing。

OpenTracing 由以下四个组成部分构成,但每个部分仍有改进的空间。

    • 各言語向けのクライアントライブラリであるTracer、

 

    • Tracerによる計測データを送る先となるバックエンド(Zipkin等)、

 

    • クライアントとバックエンドのプロトコルまたはspan format、

 

    マイクロサービス間でトレースを関連付けするためのpropagation format

在Kubernetes领域中,截至2017年12月,有以下几个贡献来源。

    • Envoy

OpenTracingトレーサに非対応

Zipkinサポートはビルド時に組み込まれている
OpenTracing Tracer(C++)をEnvoyに組み込んだり、OpenTracing Tracerの実装を動的にロードできるようにするようなコントリビューションが考えられます

nginx-ingress-controller

OpenTracingサポートがあるが、バックエンドはZipkinのみ対応

以最快的方式发布部署到Kubernetes的服务。

如果使用类似于Kubernetes的Deployment和Service来部署应用程序,也可以满足生产服务所需的要求

    • Route 53 RecordSet

 

    • ELB/ALB/NLB

 

    TLS証明書

需要另外准备。为此,

    • AWSへの一定のアクセス権をエンジニアに配布するのかしないのか、

 

    • CloudFormationやTerraformを使うのか、

 

    • どのRecordSet/*LB/証明書がどのサービスと対応するのか、

 

    • 証明書はどこに保存するのか

 

考虑到运营等方面问题,可以说烦恼是没有尽头的。
希望能够让服务更加轻松地发布,而不需要引入基础设施工程师或者学习除了Kubernetes以外的其他工具。

因此,我们只需要创建Kubernetes的Ingress,就可以自动生成ALB(应用负载均衡)、证书和记录集。

    • 「KubernetesでAWS ALBを自動作成する〜ついでにRoute53 Record Setも」では、Zalandoのskipperとkube-ingress-aws-controllerというOSSを利用して、KubernetesのIngressリソースをつくるだけで自動的にALBを作成し、WorkerノードをALBのターゲットグループに登録し、ALBにACMで作成しておいたTLS証明書を割り当てる(ACMの機能で証明書の更新も自動化されます)方法

 

    「Kubernetesのexternal-dnsでRoute53 RecordSetを自動作成する」ではexternal-dnsという準公式のOSSを利用して、KubernetesのServiceやIngressに所定のAnnotationをつけるだけでRoute 53 Record Setを自動生成する方法

我对每个进行了解释。

简化Kubernetes用户管理

与其为每个用户单独创建Kubernetes的Service Account或进行OpenID等设置,不如利用AWS IAM权限来进行Kubernetes的身份验证更为便捷。

使用即将被EKS采用的heptio/authenticator即可实现。

关于认证器的使用方法,请参考「heptio-authenticator-aws的使用方法」。

版本控制

secret的加密方法是使用mozilla/sops进行加密。

    • Manage Kubernetes secrets with SOPS | Frederic Hemberger

 

    ファイルをAWS KMSで暗号化して安全にgit commitできるようにするmozilla/sopsの使い方 – Qiita

人-团队

至少两个人可以熟练地操作和使用Kubernetes集群。

推荐培养至少一到两名具备低层级知识的人员,以使其达到通过Certified Kubernetes Administrator考试(CKA)的水平。

Kubernetes作为一个平台具有广泛适用性和相应的复杂性。

为了在AWS上运行它,还需要了解AWS。如果要进行实际的生产运营,还需要掌握与Jenkins等CI/CD的集成,监控,开发者和运营人员的工作流程等与Kubernetes应用相关的实践知识。即使可以使用EKS,本质仍然不会改变(虽然在Kubernetes自身的运营方面,需要负起一定的责任的范围会减少)。

学习Heptio博客中介绍的内容是快速掌握CKA合格水平知识的捷径。

何普蒂奥工程师如何通过认证的 Kubernetes 管理员考试

禁忌

在长期来看,它似乎有前途,但如果没有想要做出贡献的心情,那么就先不去碰它,这样可能更为稳妥。

如果想要为开源软件做出贡献,最好的方式就是积极采用并不断提供反馈和提案。

服务网格相关

Istio

驾驶员/代理(进入、边车),混合器。

Istio是一款优秀的服务网格,具有良好的架构、还有良好的未来前景作为服务网格,它使用golang,内存占用较小,并且支持Kubernetes原生化,因此是最佳的服务网格解决方案。

然而,由于我完全没有听说过类似的产品案例,所以对于在AWS上使用K8S进行“从今天开始,尽可能轻松、稳定地进行生产运营”的意图持反对态度。

此外,具體來講,以下這些方面是為了使實際應用更加「輕鬆」而努力的部分。

    • 専用のWeb UIがない

公式にもGrafanaのダッシュボードで賄ってくださいと書いてあります
Grafanaがだめなのではなく、汎用のWeb UI(+メトリクスのストア)ならPrometheusやDatadog、Stackdriverなども色々候補にあがってきますし、そうすると「Service Meshのモニタリングと操作に特化したダッシュボード」ってしばらくはどこにもない状態になるんですよね。
そうすると、たぶんどこかのベンダーがistioのWebダッシュボードをつくって、それとコマーシャルサポートをセット販売することになると思うのですが、それだけで果たしてビジネスになるのか疑問。ビジネスにならなければその独自ダッシュボードの進化も遅くなる。また、Grafana等で賄ってしまう会社も多いと思うので、istioベンダーがとれるパイも少なくなる
そういう状況だと、エンジニアが100人くらいはいるそこそこの規模の組織でないとistioは採用できないのでは

Grafeas 变得更可控的方式是通过为软件构建一个通用的审计和指纹系统。

https://github.com/Grafeas/Grafeas 的源代码
https://codefresh.io/blog/write-this-down-grafeas/ 的博客文章

Grafeas 是一个用于审计容器镜像的 API 规范。
鉴于截至 2018 年 1 月 5 日,Grafeas 自身没有一个可供生产使用的 API 服务器实现,因此可以说目前没有一种方便的方法用于生产环境的运营。(自己编写和部署 Grafeas API 的生产级实现不是一种方便的方法,对吧)

Grafeas API服务器的参考实现可以在官方GitHub仓库中找到。

    • ストレージの実装がインメモリのみ

2018/1/5現在、IssueでPostgreSQL実装が検討されています

ACL/Authzなし

在实际应用中,暂时没有需要的功能。

基于Web的应用程序目录和控制台相关

Kubeapps/Monocular 应用管理平台

Kubeapps 单眼器

与其输入helm install命令,更加友好的方式无疑是确切的。

然而,由于认证功能尚不完善,因此进行正式运营是令人担忧的(无法控制谁可以在正式集群中安装什么。是否可以记录日志呢?)

如果不需要细粒度权限管理,也可以使用。而且,从控制台方面来看,当能够像Rancher或Kubernetes控制台一样查看应用程序的日志和指标时,我认为它的使用优势会更加明显。

权限相关

将命名空间和权限按照团队、项目和特定系统的子系统进行细分。

最大的原因是,RBAC无法管理Secret的挂载和Service Account的使用权限。

只要具有创建Pod的权限,就意味着可以访问该命名空间中的所有Secret。即使使用RBAC禁止了对Secret的Read访问权限也是如此。

如果在同一命名空间中有创建Pod的权限,那么您就可以使用该命名空间中的所有服务账户。

因此,如果所有人和所有系统的K8S资源都在同一个命名空间中,那么访问重要功能和信息的Service Account和Secret将会有比预期更多的人可以访问。由于RBAC无法进行如此详细的权限管理,所以同时进行细分命名空间是一个好的选择。

只有在以下情况下才不分割命名空间。

    • アプリケーションのバージョン違い

ネームスペースを分けると、依存元からの依存先バージョンの切り替えが面倒など、色々と不都合が生じる
アプリケーションのバージョンアップに伴うコンテナのマイグレーションを自動的にやってくれるのがKubernetesのそもそものメリットの一つ

地理的分散

地理的に分散しているノードがあっても一つのクラスタでうまく扱えるのがKubernetesのそもそものメリットの一つ

コスト負担元の違い

クラウドプロバイダ側のビリングの仕組みで対応すべき。
AWSであれば、請求先が異なる別々のAWSアカウントで作ったWorkerノードを、同じK8Sクラスタに参加させる。

无论是哪种情况, Kubernetes: Kubernetes命名空间: 用例和见解都很好地总结在”Kubernetes: Kubernetes Namespaces: use cases and insights”一文中。

每个Namespace都设置Network Policy和Resource Quota。

有关网络策略的具体设置方法,请参考Kubernetes Network Policy Recipes。

其他主要用例包括Namespace和Network Policy,请参考以下内容。

    Kubernetes: Kubernetes Namespaces: use cases and insights

部署应用程序相关

前提:支持部署的工具。

对于Kubernetes应用程序的部署,可以根据架构和用途大致分类使用的工具为:

    • クライアントサイドで動くCLI

 

    • サーバサイドのみ(kubectl+カスタムリソースでサーバサイドに仕事をさせる、gitレポジトリを監視させるgitops指向など、性格はいろいろ)

 

    CLI + サーバサイドのセット

有三种类型。我所了解的工具有以下这些。

    • kubectl

 

    • helm

 

    • クラスタデーモン系

kube-applier

helm-crd (Bitnami)
landscraper

giantswarm/draughtsman

git pushのたびにhelm chartをhelm commandを使ってapprへリリースしてインストールする

landscape(複数のhelm releaseとenvのdesired stateをyamlに書くモデル。helm binaryに依存しない。cliあり。secretの扱いが独特)
helmのissueで話し合われているhelm/tiller operator
weaveworks/flux
upmc-enterprises/emmie
keel

CLI系

ksonnet

helmfile (Datadogの中の人)
helm-update-config

kubernetes-deploy (Shopify)
erbテンプレート利用

kubegen (Weaveworksの中の人)

テンプレートエンジン

kedge

docker-compose.ymlのようなフォーマットでkubernetes manifestsをかけるテンプレートエンジンのようなもの

datawire/forge

请务必参考@deeeet さん对于K8S/YAML问题和著名工具的详细总结及其补充。

个人认为,虽然我并不是一直推崇helm,但是我认为helm是综合实力最强的,所以如果不想现在就停止直接编写YAML文件的运维工作,而且通过sed来处理的方法也不够快的话,我觉得使用helm是一个不错的选择。

我想一起阅读

    How are people automating deployments? : kubernetes

前提:目前还没有一种事实上的方法来管理应用程序的凭证。

这个helm的问题在这里是值得参考的。

建议:秘密不应该存储在秘密之外;秘密轮换应该与发布升级解耦。

ksonnet(ks、ksonnet-lib)

Ksonnet有两个方面:其中一个是jsonnet库ksonnet-lib,另一个是使用ksonnet-lib创建k8s清单的框架及其命令行工具ks。

咖啡店

ksonnet-lib可能可用,但ks可能还为时过早。如果可以将机密信息git commit,或者将机密信息在git之外进行管理的话,似乎可以使用,但个人觉得不推荐。

支持单向加密的机密,例如 bitnami/sealed-secrets · Issue #255 · ksonnet/ksonnet。

密封的秘密

密封的秘密

创建一个名为SealedSecret的自定义资源并在Kubernetes中使用它来管理Kubernetes的秘密。由于可以在使用kubectl时以明文形式查看Kubernetes的秘密,因此只有在对此表示担忧的情况下才可以使用?

然而,关于被描述为使用它的一个优势之一的“可以将保存在Kubernetes的机密信息(Secret)提交到Git”这一点还存在疑问。

如果一个组织可能采用Kubernetes,除了Kubernetes Secret以外,我认为他们可能还有想要用Git进行管理的机密信息。如果是这样的话,那么最好使用一种不依赖于特定平台或配置工具,以与Git相结合为前提的工具,例如sops。

此外,密封的秘密解密到秘密需要在集群上异步执行。因此,如果同时部署密封的秘密和应用程序,应用程序Pod将无法启动,直到解密完成。这是分布式系统的特点。

自定义Helm图表仓库

Helm Chart Registry是一个普通的HTTP服务器,如果准备了自定义的Helm插件,还可以将其他类型的Chart Registry设为HTTP服务器。例如,

以下是一些支持将AWS S3作为后端的图表注册表的开源软件选项:

    kubernetes-helm/chartmuseum

如果你愿意使用基于本地文件系统的图表注册表作为后端,以下是一些可选择的OSS。

    caicloud/helm-registry

另外,还有一个名为 App Registry 的规范,以及其实现(Quay.io的应用程序注册表)。

    • https://github.com/app-registry/appr-helm-plugin

 

    https://coreos.com/blog/quay-application-registry-for-kubernetes.html

我认为,在以下事项得到支持之前,可以不必故意将其投入实际运营中。

    • 手間のかからない権限管理(Application Registryのユーザとその権限管理を個別にやるのがめんどう。せめてIAM User/Roleと統合したい)

 

    Audit Log(どのChartを誰がいつダウンロードしたか)

灾难恢复相关

以下是一个能够帮助您在K8S集群无论何时何地出现故障或崩溃时,能够相对较短时间内进行恢复的建议。在这里,我们将介绍一些看起来可以用于此目的但实际上无法使用(我们判断无法使用)的工具。

K8S集群的完整备份工具 —— ark

一个可以为部署在Kubernetes集群中的资源进行完整备份的工具。还支持S3的服务器端加密,方便解决疑难问题。

了解该工具是用于灾难恢复的,但我个人仍然怀疑在什么情况下可以使用。
对于用于灾难恢复的工具,我已经明白了,但我个人仍然怀疑在哪些场景下会用到它。

在需要无停机时间进行集群备份、恢复、迁移或重新构建的场景中,例如生产环境和预备环境,可以直接使用这种功能。不能直接使用那是因为无法进行时间点恢复。如果能够将Kubernetes的API服务器设置为只读(仅限用户可更改的资源),结合ark,似乎也可以实现时间点恢复……。

如果目的是为了灾难恢复,我认为与其使用不完整的ark,不如彻底采用GitOps的方式,即“一旦集群启动,根据Git仓库的内容部署应该部署的资源”。但是,我认为如果不使用GitOps,这种方法根本无法使用,那么ark是否成为一个可行的选择呢?

无论是否在重要的集群部署中使用GitOps,要是个人使用集群或者开发用集群需要有停机时间来重新构建的话,或许可以考虑使用ark?

广告
将在 10 秒后关闭
bannerAds