kubernetes、遊び場、マイクロサービス、そしてちょっとした魔法

DevOpsエンジニアの生活の中で、開発チームのための遊び場を作成する必要があります。 いつものように、彼は賢く、賢く、最小限のリソースを消費するべきです。 この記事では、kubernetesのマイクロサービスアプリケーション用にこのような獣を作成する問題をどのように解決したかについてお話したいと思います。







着信条件と要件



遊び場を作成する必要があったシステムの目的について少し説明します。









チームリーダーとの積極的なコミュニケーションで策定できた要件:





トピックに関する考察



最初から、k8sで並列スペースを作成する最も論理的な方法は、仮想クラスターのネイティブツールまたはk8sの用語である名前空間を使用する最も論理的な方法であることは明らかでした。 また、タスクは、クラスター内のすべての対話がkube-dnsによって提供される短い名前を使用して実行されるという事実によって簡素化されます。つまり、接続を失うことなく、構造を別のネームスペースで起動できます。

このソリューションには、1つの問題しかありません。利用可能なすべてのサービスをネームスペースにデプロイする必要があります。これは長く、不便で、大量のリソースを消費します。



名前空間とDNS



サービスを作成するとき、k8sは<service-name>。<namespace-name> .svc.cluster.localの形式のDNSレコードを作成します。 このメカニズムにより、起動された各コンテナのresolv.confに加えられた変更により、同じ名前空間内の短い名前を介した通信が可能になります。



通常の状態では、次のようになります。

search <namespace-name>.svc.cluster.local svc.cluster.local cluster.local

nameserver 192.168.0.2

options ndots:5






つまり、同じ名前空間のサービスは、名前<service-name>でアクセスでき、隣接する名前空間では名前<service-name>でアクセスできます。



システムを回る



この時点で、単純な考えが思い浮かびます:「 ベースは一般的であり、api-gatewayはリクエストをサービスにルーティングする責任があります。名前空間で最初にサービスにアクセスし、デフォルトで存在しない場合はどうですか?

はい、同様のソリューションを名前空間設定で整理することができます(nginxであることを覚えています)が、同様のソリューションはpgと他のクラスターの設定に違いを生じさせ、不便で多くの問題を引き起こす可能性があります。



そのため、文字列の置換方法が選択されました

search <namespace-name>.svc.cluster.local svc.cluster.local cluster.local







search <namespace-name>.svc.cluster.local svc.cluster.local cluster.local default.svc.cluster.local





このアプローチは、ネームスペースに必要なサービスがない場合、ネームスペースのデフォルトに自動的に切り替わります。







次のように、クラスターで同様の結果を得ることができます。 Kubeletはホストマシンのresolve.confからコンテナに検索パラメーターを追加するため、各ノードの/etc/resolv.confに次の行を追加します。



search default.svc.cluster.local







ノードにサービスのアドレスを解決させたくない場合は、kubeletの起動時に--resolv-confオプションを使用できます。これにより、/ etc / resolv.confの代わりに他のファイルを指定できます。 たとえば、同じ行の/etc/k8s/resolv.confファイル。



技術の問題



さらなる決定は非常に簡単で、次の契約に同意するだけです。





SSLオフローダー設定



リクエストを対応するネームスペースのapi-gwにリダイレクトするNginx構成



  server_name ~^(?<namespace>.+)\.cluster\.local; location / { resolver 192.168.0.2; proxy_pass http://api-gw.$namespace.svc.cluster.local; }
      
      





ジェンキンス



展開プロセスを自動化するには、Jenkins Pipeline Multibranch Pluginプラグインが使用されます。



プロジェクト設定では、play / *パターンに一致するブランチのみが収集されることを示し、コレクターが使用するすべてのプロジェクトのルートにJenkinsfileを追加します。

groovyスクリプトは処理に使用されますが、全体を説明するのではなく、いくつかの例を示します。 展開の残りの部分は、基本的に通常と変わりません。



ブランチ名の取得:



 def BranchName() { def Name = "${env.BRANCH_NAME}" =~ "play[/]?(.*)" Name ? Name[0][1] : null }
      
      





名前空間の最小構成にはデプロイ済みのapi-gatewayが必要なので、名前空間を作成してそこにapi-gatewayをデプロイするプロジェクトへの呼び出しを追加します。



  def K8S_NAMESPACE = BranchName() build job: 'Create NS', parameters: [[$class: 'StringParameterValue', name: 'K8S_NAMESPACE', value: "${K8S_NAMESPACE}"]] build job: 'Create api-gw', parameters: [[$class: 'StringParameterValue', name: 'K8S_NAMESPACE', value: "${K8S_NAMESPACE}"]]
      
      





おわりに



特効薬はありませんが、ベストプラクティスだけでなく、サンドボックスが他の人によってどのように編成されているかについての説明も見つからなかったため、k8に基づいてサンドボックスを作成するために使用した方法を共有することにしました。 おそらくこれは理想的な方法ではないので、この問題がどのように解決されるかについてのコメントやストーリーを喜んで受け入れます。



All Articles