これは、Openshift Originでのソフトウェア製品の自動テストに関する一連の3つの記事( 最初の記事 、 3番目の記事 )の続きです。 この記事では、Openshiftの主要なオブジェクトについて説明し、クラスター操作の原理についても説明します。 これは非常に時間のかかる作業であり、この記事の範囲外であるため、意図的にすべての可能なオブジェクトとその機能を説明しようとはしません。
クラスター:

一般に、Openshift Originクラスターは他のソリューションとそれほど違いはありません。 着信タスクは、ワークロードに基づいて作業ノード間で分散され、スケジューラがこの分散を処理します。
コンテナーを実行するには、内部または外部レジスターからロードできるDockerイメージが必要です。 コンテナの直接起動は、さまざまなセキュリティコンテキスト (さまざまなリソースへのコンテナアクセスを制限するセキュリティポリシー)で発生します。
デフォルトでは、異なるプロジェクトのコンテナは、 オーバーレイネットワークを使用して相互に通信できます (1つの大きなサブネットが割り当てられ、クラスターのすべての作業ノードの小さなサブネットに分割されます)。 作業ノードで実行されているコンテナには、このノードに割り当てられたサブネットからIPアドレスが割り当てられます。 オーバーレイネットワーク自体は、作業ノード間の通信にVXLANを使用するOpen vSwitchに基づいて構築されます。
各作業ノードで、専用のDnsmasqインスタンスが起動され、すべてのDNSコンテナー要求がSkyDNSに内部サービスサブネットにリダイレクトされます。
コンテナがクラッシュするか、単に初期化できない場合、コンテナを展開するタスクは別の作業ノードに転送されます。
それは注目に値する:
SELinuxは厳密なクラスター状態ではありません。 これを無効にすると( セキュリティ上の理由で推奨されません )、コンテナを操作するときに速度がいくらか向上します(また、監視が無効になります)。 SELinuxがコンテナ内のアプリケーションに干渉する場合、クラスターの作業ノードにSELinux例外を直接追加する可能性があります。
デフォルトでは、 LVMは Docker Engineリポジトリとして使用されます。 これは最速のソリューションではありませんが、他の種類のストレージ( BTRFSなど)を使用できます。
サービスの名前(サービスを参照)は、長さと有効な文字の制限を伴うDNS名であることに注意してください。
Dockerイメージをアセンブルする際の時間とハードウェアコストを削減するには、いわゆる「レイヤード」アプローチ( Dockerのマルチステージ )を使用できます。 このアプローチでは、互いに補完する基本イメージと中間イメージを使用します。 基本イメージ「centos:7」(完全に更新済み)、中間イメージ「centos:7-tools」(インストール済みツール)、最終イメージ「centos:7-app」(「centos:7」および「centos:7を含む」) -tools ")。 つまり、他のイメージに基づいたビルドタスクを作成できます(BuildConfigを参照)。
Dockerイメージのアセンブルのみを処理し、これらのイメージを他のプロジェクトにリンクするプロジェクトが1つしかない場合は、十分に柔軟なソリューションがアプローチです(ImageStreamを参照)。 これにより、各プロジェクトで不必要なエンティティを生成しないようにすることができ、何らかの統一につながります。
クラスター内のほとんどのオブジェクトには任意のラベルを割り当てることができます。これらのラベルを使用して、これらのオブジェクトに対して一括操作を実行できます(たとえば、プロジェクト内の特定のコンテナーを削除します)。
アプリケーションがLinuxカーネルの特定のカーネル機能を必要とする場合、このアプリケーションを起動する必要があるすべての作業ノードでこのモジュールをダウンロードする必要があります。
古い画像や忘れられた環境をすぐに削除する必要があります。 ガベージコレクター/ oadm pruneを使用して最初の問題を解決した場合、2番目の問題は、Openshift Originでのコラボレーションのルールに関するすべての参加者の調査と習熟が必要です。
クラスターはリソースによって制限されるため、少なくとも作業ノードのレベルで監視を編成することが非常に望ましいです(コンテナー内のアプリケーションレベルでの監視は可能です)。 これは、既製のOpenshift Metricsソリューションとサードパーティのソリューション( Sysdigなど)の両方を使用して実行できます。 クラスター負荷メトリックが存在する場合(全体として、または設計上)、着信タスクの柔軟なスケジューリングを編成できます。
特に、作業ノードを動的に初期化できること、つまり、既存のIaaS施設でOpenshift Originクラスターを拡張できることに注意してください。 つまり、プレリリーステスト中に、容量を大幅に拡張し、テスト時間を短縮できます。
オブジェクト:
プロジェクト -オブジェクトはKubernetes名前空間です。 他のオブジェクトを含む抽象化の最上位レベル。 プロジェクトで作成されたオブジェクトは、他のプロジェクトのオブジェクトと交差しません。 プロジェクトには、クォータ、特権、クラスターノードのラベルなどを設定できます。 プロジェクト間にネストされた階層や継承はなく、「フラットな」プロジェクト構造が利用可能です。 クラスターの正常な機能のために設計されたいくつかのシステムプロジェクト(kube-system、openshift、openshift-infra)があります。
新しいプロジェクトの作成:
oc adm new-project project1 --node-selector='node_type=minion'
プロジェクト設定の編集:
oc edit namespace project1
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: Namespace metadata: annotations: openshift.io/description: "" openshift.io/display-name: "" openshift.io/node-selector: node_type=minion ...
Podは決定的な要因の1つになったオブジェクトです。これにより、コンテナ内で任意のコマンドを(特別なフックだけでなく)使用して実行できるようになります。 ポッドは、クラスター内の主要な作業単位です。 クラスタで実行されているコンテナはすべてポッドです。 基本的に、これらのコンテナの同じネームスペース(ネットワーク、ipc、uts、cgroup)で動作する1つ以上のコンテナのグループは、共通のデータストレージであるシークレットを使用します。 Podを構成するコンテナーは常に同じクラスターノードで実行され、すべてのノードに均等に配分されません(Podが10個のコンテナーで構成されている場合、10個すべてが同じノードで動作します)。
ポッド:
apiVersion: "v1" kind: "Pod" metadata: name: "nginx-redis" spec: containers: - name: "nginx" image: "nginx:latest" - name: "redis" image: "redis:latest"
ポッドステータス:
NAME READY STATUS RESTARTS AGE nginx-redis 2/2 Running 0 7s
シークレット -Podの機密情報(etcdにクリアテキストで保存( Kubernetes 1.7の暗号化サポート ))を転送するように設計された行またはファイルです。 1つのシークレットには多くの値を含めることができます。
秘密の作成:
oc secrets new gitconfig .gitconfig=/home/user/.gitconfig
BuildConfigでシークレットを使用:
apiVersion: "v1" kind: "BuildConfig" metadata: name: "nginx-bc" spec: source: type: "Git" git: uri: "https://github.com/username/nginx.git" sourceSecret: name: "gitconfig" strategy: type: "Docker" dockerStrategy: dockerfilePath: docker/nginx-custom noCache: true output: to: kind: "ImageStreamTag" name: "nginx-custom:latest"
ServiceAccountは、クラスターリソースと対話するように設計された特別なタイプのオブジェクトです。 その中心は、システムユーザーです。
デフォルトでは、新しいプロジェクトには3つのServiceAccountが含まれています。
- builder-Dockerイメージをビルドし、レジスターにアップロードします(BuildConfigを参照)。
- deployer-展開タスクはこのアカウントから起動されます(DeploymentConfigを参照)。
- デフォルト-他のすべてのポッド(展開タスクに関連しない)は、このアカウントから起動されます。
リストされたサービスアカウント:
- クラスタリソースへのアクセスに使用される自動生成されたシークレットが含まれます。
- クラスター内で特定のアクションを実行できるようにする役割があります。
ServiceAccount:
apiVersion: "v1" kind: "ServiceAccount" metadata: name: "jenkins"
ServiceAccountプロパティ:
Name: jenkins Namespace: project1 Labels: <none> Image pull secrets: jenkins-dockercfg-pvgsr Mountable secrets: jenkins-dockercfg-pvgsr jenkins-token-p8bwz Tokens: jenkins-token-p8bwz jenkins-token-zsn9p
ServiceAccountプロジェクト管理者権限の追加:
oc policy add-role-to-user admin system:serviceaccount:project1:jenkins
DeploymentConfigは同じPodで動作するオブジェクトですが、同時に実行中のアプリケーションのライフサイクルを管理するための多くの追加メカニズムを導入します。
- 展開戦略、つまり 新しいバージョンがリリースされたときにアプリケーションが更新され、障害が発生した場合に作業バージョンへのロールバックが行われます。
- 構成の再展開をトリガーするトリガーを設定できます。
- アプリケーションのインスタンス/レプリカの数を指定できます。
DeploymentConfig:
apiVersion: "v1" kind: "DeploymentConfig" metadata: name: "nginx-dc" spec: template: metadata: labels: name: "nginx-dc" spec: containers: - name: "nginx" image: "nginx:latest" replicas: 3 selector: name: "nginx-dc"
DeploymentConfigステータス:
NAME READY STATUS RESTARTS AGE nginx-dc-1-1wl8m 1/1 Running 0 7s nginx-dc-1-k3mss 1/1 Running 0 7s nginx-dc-1-t8qf3 1/1 Running 0 7s
ImageStream-本質的に、Image Dockerまたは他のImageStreamを指す「リンク」(ImageStreamTag)の「コンテナ」です。
ImageStream:
apiVersion: "v1" kind: "ImageStream" metadata: name: "third-party"
プロジェクト間のDockerイメージへのタグ/リンクの作成:
oc tag project2/app:v1 project1/third-party:app
DockerハブにあるDockerイメージへのタグ/リンクを作成します。
oc tag --source=docker nginx:latest project1/third-party:nginx
BuildConfig-オブジェクトは、Dockerイメージがどのように組み立てられ、どこに配置されるかのシナリオです。 新しい画像の組み立ては他の画像に基づいて行うことができ、「from:」セクションがこれを担当します
アセンブリのソース(アセンブリのソースデータがある場所):
- バイナリ
- Dockerfile
- Git
- 画像
- 入力シークレット
- 外部アーティファクト
戦略の構築(データソースの解釈方法):
アセンブリの目的(アセンブリされたイメージがアップロードされる場所):
- DockerImage
- ImageStreamTag
BuildConfig:
apiVersion: "v1" kind: "BuildConfig" metadata: name: "nginx-bc" spec: source: type: "Git" git: uri: "https://github.com/username/nginx.git" strategy: type: "Docker" dockerStrategy: from: kind: "ImageStreamTag" name: "nginx:latest" dockerfilePath: docker/nginx-custom noCache: true output: to: kind: "ImageStreamTag" name: "nginx-custom:latest"
このBuildConfigが実行する操作:
- ImageStream "nginx:latest"を基礎として
- Gitリポジトリのクローンを作成し、このリポジトリでdocker / nginx-customファイルを見つけ、Dockerfileファイルから命令をロードし、これらの命令を基本イメージで実行します。
- 結果のイメージは、ImageStreamに「nginx-custom:latest」を配置します
サービス -環境を起動するシステムを選択する際に決定的な要因の1つになったオブジェクト。環境間の通信を柔軟に構成できるため(テストでは非常に重要です)。 他のシステムを使用する場合、IPアドレスの範囲の割り当て、DNS名の登録、転送ポートなどの準備操作が必要でした。 など サービスは、アプリケーションを実際にデプロイする前に宣言できます。
サービスがプロジェクトで公開されるとどうなりますか:
- サービスの場合、IPアドレスは特別なサービスサブネットから割り当てられます。
- このサービスのDNS名が登録されています。 サービスの公開の前後に起動されたプロジェクト内のすべてのPodは、このDNS名を解決できます。
- サービスが公開された後に起動されるプロジェクト内のすべてのポッドは、公開されたサービスのIPアドレスとポートを含む環境変数のリストを受け取ります。
サービス:
apiVersion: v1 kind: Service metadata: name: "nginx-svc" spec: selector: name: "nginx-pod" ports: - port: 80 targetPort: 80 name: "http" - port: 443 targetPort: 443 name: "https"
DNS名前解決:
root@nginx-pod:/# ping nginx-svc PING nginx-svc.myproject.svc.cluster.local (172.30.217.250) 56(84) bytes of data.
環境変数:
root@nginx-pod:/# env | grep -i nginx NGINX_SVC_PORT_443_TCP_ADDR=172.30.217.250 HOSTNAME=nginx-pod NGINX_VERSION=1.13.1-1~stretch NGINX_SVC_PORT_80_TCP_PORT=80 NGINX_SVC_PORT_80_TCP_ADDR=172.30.217.250 NGINX_SVC_SERVICE_PORT=80 NGINX_SVC_PORT_80_TCP_PROTO=tcp NGINX_SVC_PORT_443_TCP=tcp://172.30.217.250:443 NGINX_SVC_SERVICE_HOST=172.30.217.250 NGINX_SVC_PORT_443_TCP_PROTO=tcp NGINX_SVC_SERVICE_PORT_HTTPS=443 NGINX_SVC_PORT_443_TCP_PORT=443 NGINX_SVC_PORT=tcp://172.30.217.250:80 NGINX_SVC_SERVICE_PORT_HTTP=80 NGINX_SVC_PORT_80_TCP=tcp://172.30.217.250:80
結論:
すべてのクラスターオブジェクトはYAMLを使用して記述できます。これにより、Openshift Originで発生するプロセスを完全に自動化できます。 クラスタでの作業の全体的な難しさは、作業の原則とオブジェクトの相互作用のメカニズムの知識にあります。 新しい作業ノードの初期化などの日常的な操作は、Ansibleスクリプトを使用します。 Accessibility APIは、仲介者なしでクラスターを直接操作する機会を開きます。