オンプレ版OpenShift 4でインフラノードの設定手順

※当ブログではアフィリエイト広告を利用しています

どうも、はむきち(@hamtechham)です。

公式ドキュメントだとIPIインストールが前提の手順がメインで、オンプレでUPIインストールした場合の手順がほぼありませんでした。

4.2ぐらいの時代はサポートに聞いてやっていたのですが、最近また調べていたら良い手順がKnowledge Baseにあったので紹介しようと思います。

AWSなどのクラウドへIPIインストールしている場合は、以下の手順となります。

こちらはv4系での情報です。v3の場合は手順が異なると思います(よく知らない)

インフラノードとは

インフラノード(Infrastructure Node)はワーカーノード(Worker Node)の一種で、OpenShiftの運用系のコンポーネントを動かすための専用ノードです。2台あれば構成できますが、3台で構築することが多いです。

以下のコンポーネントをインフラノードで動作させることができます。

  • モニタリング(Prometheus、Alertmanager、Grafana)
  • ロギング(Elasticsearch、Kibana)
  • ルーター(Router)
  • イメージレジストリー(Image Registry)

検証用クラスターなど超小規模環境なら構築する必要も無いかもしれませんが、長期間運用する予定であれば構築しておいたほうがいいかな、というのが個人的な感覚です。

インフラノードが必要な理由

ユーザーのアプリと互いに影響し合うことがなくなる

ユーザーがデプロイしたアプリケーションがとんでもなくCPUやメモリを使うアプリだった場合を考えてみます。

もしインフラノードがない場合、ユーザーのアプリがノードのリソースを使い果たしてしまうと、OpenShiftの他の運用系のコンポーネントの動作にも影響してしまいます。

逆に、ロギングのPodがリソースをとんでもなく使ってしまった場合、そのノードで動作するユーザーのアプリケーションへの影響もあるかもしれません。

OpenShiftのコンポーネントをインフラノードとして分離しておくことで、お互いの影響をなくす狙いがあります。

メンテナンスや障害調査がしやすくなる

インフラノードを再起動してもユーザーのアプリケーションには一切影響がありません。

特定のノードの動作がおかしい場合にも、OCPのコンポーネントに問題があるのかユーザーのアプリの作り方が悪いのか、など原因の切り分けがスムーズになります。

インフラノードで稼働するコンポーネントの中でも、特にRouter Podは外部からの接続を受け入れるための重要なコンポーネントです。これが停止してしまうと、外部からアプリケーションへアクセスすることができなくなってしまいます。

そのため、インフラノードの中でもRouterは更に別の専用ノードを構築するケースもあります。

OpenShiftのライセンス費用の節約

OpenShiftはワーカーノードのvCPUに応じたライセンス費用がかかります。

ワーカーノードのみで構築した場合、OCPのコンポーネントとして動いているPodが使用するCPUに対しても課金されてしまうことになります。

インフラノードで稼働するPodについてはライセンス課金の対象外となるため、ライセンス費用を浮かすためにもインフラノードを構築する意義があります。

注意!

ライセンス体系の詳細、最新の状況についてはレッドハット社へ十分確認してください。

インフラノードの設定手順

大きな流れとしては

  1. インフラノードにラベルとtaintを付与
  2. インフラノードからPodをevict
  3. インフラノードの各コンポーネントにNodeSelectorを設定

となります。順に見ていきましょう。

インフラノードにラベルとtaintを付与する

インフラノードとしたいノードにラベルを付与します。<node-name>のところは各自読み替えてください。

oc label node <node-name> node-role.kubernetes.io/infra=

Taintを付与します。Taintを付与することで、Tolerations設定のない通常のPodはInfra Nodeに配置されなくなります。

-l オプションが付いているので、インフラノードのラベルがついているノードに一括で適用されます。

oc adm taint nodes -l node-role.kubernetes.io/infra infra=reserved:NoSchedule infra=reserved:NoExecute
インフラノードからPodをevictする

Taintは「配置されなく」なるだけなので、現状稼働しているPodが勝手に出ていってくれるわけではありません。

インフラノードからPodを追い出すためにevictを実行します。

oc adm drain -l node-role.kubernetes.io/infra --delete-local-data --ignore-daemonsets --force 

RouterにNodeSelectorとTolerationsを設定する

Routerの設定はIngressControllerというCustom Resourceで管理されています。

ここにNodeSelectorとTolerations設定を入れます。

oc patch ingresscontroller/default -n  openshift-ingress-operator  --type=merge -p '{"spec":{"nodePlacement": {"nodeSelector": {"matchLabels": {"node-role.kubernetes.io/infra": ""}},"tolerations": [{"effect":"NoSchedule","key": "infra","value": "reserved"},{"effect":"NoExecute","key": "infra","value": "reserved"}]}}}'

イメージレジストリーにNodeSelectorとTolerationsを設定する

イメージレジストリーの設定はconfigs.imageregistry.operator.openshift.ioというCustom Resourceで管理されています。

ここにNodeSelectorとTolerations設定を入れます。

oc patch configs.imageregistry.operator.openshift.io/cluster --type=merge -p '{"spec":{"nodeSelector": {"node-role.kubernetes.io/infra": ""},"tolerations": [{"effect":"NoSchedule","key": "infra","value": "reserved"},{"effect":"NoExecute","key": "infra","value": "reserved"}]}}'
モニタリングにNodeSelectorとTolerationsを設定する

モニタリングの設定は、ConfigMapで管理します。以下のyamlファイルを作成し、oc applyで適用してください。

apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |+
    alertmanagerMain:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    prometheusK8s:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    prometheusOperator:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    grafana:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    k8sPrometheusAdapter:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    kubeStateMetrics:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    telemeterClient:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    openshiftStateMetrics:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    thanosQuerier:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute

既に保持期間やPVCの設定をConfigMapに入れている場合は、うまいことマージしたyamlを作成した上でoc applyしてください。でないと前の設定が消えてしまいます。

バージョン4.6からは、ユーザー定義のプロジェクトをモニタリングする機能(User workload monitoring)が追加されています。

User workload monitoringのコンポーネントをインフラノードへ動かすには、以下のようなyamlを作ってoc applyします。既存のConfigMapが存在する場合は、いい感じにマージしてください。

apiVersion: v1
kind: ConfigMap
metadata:
  name: user-workload-monitoring-config
  namespace: openshift-user-workload-monitoring
data:
  config.yaml: |
    prometheusOperator:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    prometheus:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    thanosRuler:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
ロギングにNodeSelectorとTolerationsを設定する

ロギングはClusterLoggingというCustom Resourceで管理されています。

ClusterLoggingの定義に以下のような感じでNodeSelectorとTolerationsを追加します。

※FluentdはDaemonSetなので本来入れなくても良いはずですが、念の為入れてます

apiVersion: logging.openshift.io/v1
kind: ClusterLogging

....

spec:
  collection:
    logs:
      fluentd:
        resources: null
      type: fluentd
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
  curation:
    curator:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
      resources: null
      schedule: 30 3 * * *
    type: curator
  logStore:
    elasticsearch:
      nodeCount: 3
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
      redundancyPolicy: SingleRedundancy
      resources:
        limits:
          cpu: 500m
          memory: 16Gi
        requests:
          cpu: 500m
          memory: 16Gi
      storage: {}
    type: elasticsearch
  managementState: Managed
  visualization:
    kibana:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
      proxy:
        resources: null
      replicas: 1
      resources: null
    type: kibana
...

インフラノードのサイジング

以下を参考にしてください。

メモリ64GB〜となっていますが、これはElasticsearchが大量のメモリーを使用するためです。

Worker Nodeが3台などごく小規模であればメモリ32GBでも十分賄えると思いますが、手元の環境と相談の上検討となります。Elasticsearchが最低でもメモリ16GBを使用するため、32GB未満とする場合はロギングを諦めるなどする必要があります。(30GBなら、24GBなら、などギリギリを攻めることもできなくはないですが・・・)

ロギングはOpenShiftの導入後に手動で導入するコンポーネントであるため導入する・しないの選択が可能です。

参考リンク