zaki work log

作業ログやら生活ログやらなんやら

マルチノードOpenShift Origin(OKD) 3.11 with NFSをmetrics/logging込みでCentOS7へインストール

検証用なので軽めの構成になってます。
本当はRed Hat Forum Tokyo 2019終わってすぐ、遅くとも12月中旬にはまとめたかったけどずいぶん遅くなってしまった。。

バージョン3.11なので旬は過ぎてますが、仕事(Enterprise版だけど)で3.11お守してるのと、tech nightで「OKD 3.11の情報を探している」とおっしゃってた方とお話する機会もあったので、遅くなったけど何かお役に立てればなと。。

メニュー

構成

openshift-ansible release-3.11 (2020-01-17 19時(JST)時点)

host addr node_group vCPU RAM Disk
manager 192.168.0.70 N/A 2 2GB 20GB
master 192.168.0.71 node-config-master-infra 4 20GB 60GB
node1 192.168.0.75 node-config-compute 2 8GB 40GB
node2 192.168.0.76 node-config-compute 2 8GB 40GB
  • managerは、openshift-ansible実行ノード兼NFS/DNSサーバ
  • master(master/infra共用)はElasticsearch用に20GB (request 16Giなので16GBだと足りない / ただしdeploymentconfigイジって8Giとかに再設定することで、もっと少ないリソースでもデプロイは可能)

OSは全てCentOS 7(18.04)です。

システム要件とホストの準備

外部要件

  • DNS (dnsmasq使用)
  • PVのNFS (インベントリ的にはexternal NFS)

ホストの準備について

基本的な流れは以下の通り

  • 管理用ユーザ作成 (OSインストール時に作成のため省略)
  • 基本パッケージのインストール
  • openshift-ansibleのclone
  • Dockerのインストール (OverlayFS/ストレージ/ログの設定をカスタムする場合)
  • GlusterFSパッケージのインストール (省略)

Dockerのインストールは、マニュアル設定が不要であればprerequisites.ymlのAnsible実行時にインストールされるので、事前に入れておかなくてもOK

その他手動で構築が必要な部分は、以下Playbookにしてる。

Ansible 2.6

まずAnsibleのインストール。 手順には"epel-release-latest-7"をyum installしてAnsibleをインストールするようになっており、これだと2010年1月時点で2.9がインストールされるが、(経験上)2.6でないと動作しないroleがいくつかあるため、2.6を入れて進めた方がトラブルが少ない。…気がする。

zaki-hmkc.hatenablog.com

CentOS7へAnsible2.6を入れるには

$ sudo yum install -y centos-release-ansible26
$ sudo yum install -y ansible
[zaki@okd-manager ~]$ ansible --version
ansible 2.6.20
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/zaki/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
[zaki@okd-manager ~]$

準備用Ansibleのインベントリ

openshift-ansibleとは別に準備用Ansibleのために作成

[manager]
okd-manager.esxi.jp-z.jp ansible_host=192.168.0.70

[node]
okd-master.esxi.jp-z.jp ansible_host=192.168.0.71
okd-node1.esxi.jp-z.jp ansible_host=192.168.0.75
okd-node2.esxi.jp-z.jp ansible_host=192.168.0.76

ssh公開鍵とsudo設定

このプレイブックをssh-sudo.ymlとして$ ansible-playbook -i inventory.ini ssh-sudo.yml -kKを実行。

---
- hosts: localhost
  tasks:
  - name: create directory for ssh keypair
    file:
      path: "{{ lookup('env','HOME') }}/.ssh/"
      state: directory
      mode: 0700

  - name: check exists ssh privatekey
    shell: test -f $HOME/.ssh/id_rsa
    register: exist_key
    ignore_errors: True
    check_mode: False
    changed_when: False
  - name: create ssh privatekey
    shell: ssh-keygen -t rsa -f $HOME/.ssh/id_rsa -N ""
    when: exist_key.rc != 0

- hosts: all
  tasks:
  - name: publickey copy to target-nodes
    authorized_key:
      user: "{{ ansible_env.USER }}"
      key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/id_rsa.pub' )}}"

- hosts: all
  become: True
  tasks:
  - name: configure non-password sudo
    copy:
      dest: /etc/sudoers.d/nopass
      mode: 0600
      content: |
        %wheel ALL=(ALL) NOPASSWD: ALL

DNS (dnsmasq)

インストールが楽なdnsmasqを使用。クラスタ内ノードの名前解決。
DNSが既存ネットワークにあるならそれを使った方が多分良い。

---
- hosts: manager
  become: True
  gather_facts: False
  tasks:
  - name: install DNS server
    yum:
      name: dnsmasq
      state: present
  - copy:
      content: |
        domain-needed
        bogus-priv
        address=/okd-apps.esxi.jp-z.jp/192.168.0.71
      dest: /etc/dnsmasq.d/openshift.conf
      mode: 0644
  - template:
      src: hosts.j2
      dest: /etc/hosts
      mode: 0644
  - systemd:
      name: dnsmasq
      state: restarted
      enabled: yes
  - firewalld:
      service: dns
      permanent: yes
      state: enabled
      zone: public
  - systemd:
      name: firewalld
      state: restarted

NFSサーバ

コンテナレジストリ、metrics、loggingのpv用に用意。

---
- hosts: manager
  become: True
  gather_facts: False
  tasks:
  - name: create NFS directories
    file:
      path: "/exports/{{ item }}"
      state: directory
      mode: 0775
    with_items:
      - registry
      - metrics
      - logging
  - name: install NFS server
    yum:
      name: nfs-utils
      state: present
  - copy:
      content: |
        /exports/ *(rw,sync,no_wdelay,no_root_squash,insecure)
      dest: /etc/exports.d/nfs-pv.exports
      mode: 0644
  - shell: exportfs -ar
  - systemd:
      name: nfs-server
      state: restarted
      enabled: yes
  - firewalld:
      service: nfs
      permanent: yes
      state: enabled
      zone: public
  - systemd:
      name: firewalld
      state: restarted

基本パッケージのインストール

see: Preparing your hosts / Installing base packages

なお、ドキュメントに記載されてるパッケージだけだと、metricsとloggingのデプロイに失敗するため、以下のパッケージを追加している。

---
- hosts: all
  become: True
  gather_facts: False
  tasks:
  - name: install required packages
    yum:
      name:
        - wget
        - git
        - net-tools
        - bind-utils
        - yum-utils
        - iptables-services
        - bridge-utils
        - bash-completion
        - kexec-tools
        - sos
        - psacct
        - httpd-tools
        - java-1.8.0-openjdk-headless
        - python-passlib
      state: present

openshift-ansible

git clone

ドキュメントはrootで実施するような感じになってるけど、個人的にrootでの作業は気持ち悪いので作業用ユーザで実施。 作業するホストはインストール用Ansibleを実行するホスト(manager)

$ cd ~
$ git clone https://github.com/openshift/openshift-ansible
$ cd openshift-ansible
$ git checkout release-3.11

OKDでなくEnterprise版であれば、git cloneでなくyum install openshift-ansibleでインストールできる。(その場合のパスは/usr/share/ansible/opneshift-ansibleのはず)

インベントリファイルの用意

インベントリファイルのサンプルはinventoryディレクトリ以下にあるので、inventory/hosts.exampleをベースにするのが初回は楽。

$ mkdir ~/install-inventory
$ cp inventory/hosts.example ~/install-inventory/

ノード設定

master/infra共用ノードが1台、computeノードが2台、NFSは自前で構築済みなので使用せず、master/infraが1台なのでLBも使用しないという構成。

[masters]
okd-master.esxi.jp-z.jp

[etcd]
okd-master.esxi.jp-z.jp

[nodes]
okd-master.esxi.jp-z.jp openshift_node_group_name="node-config-master-infra"
okd-node[1:2].esxi.jp-z.jp openshift_node_group_name="node-config-compute"

#[nfs]
#ose3-master1.test.example.com

#[lb]
#ose3-lb.test.example.com

[OSEv3:children]
masters
nodes
etcd
#lb
#nfs

Ansible実行ユーザ

デフォルトはrootになってるけど、作業用ユーザに設定・become(sudoのこと)の指定を記入。

# SSH user, this user should allow ssh based auth without requiring a
# password. If using ssh key based auth, then the key should be managed by an
# ssh agent.
ansible_user=zaki

# If ansible_user is not root, ansible_become must be set to true and the
# user must be configured for passwordless sudo
ansible_become=yes

deployemntタイプ

OKDなのでorigin

# Specify the deployment type. Valid values are origin and openshift-enterprise.
openshift_deployment_type=origin
#openshift_deployment_type=openshift-enterprise

ライセンスがあればopenshift-enterpriseが使える。
最もわかりやすい違いは、デプロイされるコンテナイメージが、OKDだとdocker.ioやquay.ioのフリーでアクセスできるところからpullされるか、認証が必要なRed Hatのコンテナレジストリからpullされるか、あたり、かな?

アプリ用サブドメイン

Routeへの割り振り先になるドメイン
ワイルドカードDNSを使って*.okd-apps.esxi.jp-z.jpがinfraノードに名前解決するように設定する。
これはdnsmasqの設定のaddress=/okd-apps.esxi.jp-z.jp/192.168.0.71の部分で行っている。
今回は冗長構成を取っていないのでinfraロールを割り当てているmasterへ直接名前解決するようにしているが、HA構成にする場合は80/TCPと443/TCPを複数のinfraノードへロードバランスするLBに名前解決するように構成する。

# default subdomain to use for exposed routes, you should have wildcard dns
# for *.apps.test.example.com that points at your infra nodes which will run
# your router
openshift_master_default_subdomain=okd-apps.esxi.jp-z.jp

(図を描きたい)

LB

上記アプリ用サブドメインと同様に、冗長構成でないのでmasterサーバを直接指定している。
HA構成であれば、8443/TCPを複数のmasterノードへロードバランスするLBを指定する。

#Set cluster_hostname to point at your load balancer
openshift_master_cluster_hostname=okd-master.esxi.jp-z.jp

(こっちも図を描きたい)

OpenShiftユーザ

oc loginやwebコンソールにログインするクラスタ操作用ユーザをデプロイ時に作成する。
ユーザ管理のプロバイダは色々あるが、検証用としては単純なhtpasswdを使ったファイルによるユーザ管理を使用する。
htpasswd -nb <username> <password>を実行した出力がそのまま使える。

$ htpasswd -nb user user
user:$apr1$dWZrK5Cl$DKGb58Txa24GcYJT4UI/k0

これを:でバラシて

# htpasswd auth
openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]
# Defining htpasswd users
openshift_master_htpasswd_users={'user': '$apr1$dWZrK5Cl$DKGb58Txa24GcYJT4UI/k0'}

このように記述する。
JSONなので複数ユーザ定義可能。

openshift_master_htpasswd_users={'admin': '$apr1$3okJisBZ$0Dho15qcoE.5RD/RJO1Ph0', 'user': '$apr1$dWZrK5Cl$DKGb58Txa24GcYJT4UI/k0'}

ただしroleの割り当てはクラスタデプロイ時に行えないっぽいので、デプロイ完了後にoc adm policy add-role-to-useroc adm policy add-cluster-role-to-userする。

パスワードの部分に、:でバラす前の文字列を指定するミスをよくやらかす。…やらかすよね?

RegistryのボリュームにNFSのpvを使う設定

設定例がコメントにあるのでインベントリ変数を有効にしていけばOK
下記設定であれば、okd-manager.esxi.jp-z.jp:/exports/registryがマウント先となる。
アプリケーションpodのビルド等を行えば、NFSサーバの/exports/registryへビルドされたコンテナイメージがpushされる。

# External NFS Host
# NFS volume must already exist with path "nfs_directory/_volume_name" on
# the storage_host. For example, the remote volume path using these
# options would be "nfs.example.com:/exports/registry".  "exports" is
# is the name of the export served by the nfs server.  "registry" is
# the name of a directory inside of "/exports".
openshift_hosted_registry_storage_kind=nfs
openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
openshift_hosted_registry_storage_host=okd-manager.esxi.jp-z.jp
# nfs_directory must conform to DNS-1123 subdomain must consist of lower case
# alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character
openshift_hosted_registry_storage_nfs_directory=/exports
openshift_hosted_registry_storage_volume_name=registry
openshift_hosted_registry_storage_volume_size=10Gi

なお、NFSを使おうとすると、デプロイ完了後のINSTALL STATUSに警告が表示される。

INSTALLER STATUS ***************************************************************
Initialization               : Complete (0:00:07)
Health Check                 : Complete (0:00:32)
Node Bootstrap Preparation   : Complete (0:03:11)
etcd Install                 : Complete (0:00:19)
Master Install               : Complete (0:07:50)
Master Additional Install    : Complete (0:00:18)
Node Join                    : Complete (0:00:23)
Hosted Install               : Complete (0:00:27)
        The use of NFS for the core OpenShift Container Platform components is not recommended, as NFS (and the NFS Protocol) does not provide the proper consistency needed for the applications that make up the OpenShift Container Platform infrastructure.
Cluster Monitoring Operator  : Complete (0:00:37)
Web Console Install          : Complete (0:00:46)
Console Install              : Complete (0:00:19)
metrics-server Install       : Complete (0:00:24)
Service Catalog Install      : Complete (0:03:07)

ちなみにRegistryはhostpathを使ったpvも、クラスタデプロイ時に指定できた。
openshift_hosted_registry_storage_kind=hostpathの部分。

metrics server

HorizontalPodAutoscaler(HPA)を設定するにはこれが必要。
インストールするとopenshift-metrics-serverネームスペースにmetrics-serverがデプロイされる。

# metrics-server deployment
# By default, metrics-server is not automatically deployed, unless metrics is also
# deployed.  Deploying metrics-server is necessary to use the HorizontalPodAutoscaler.
# Set this to enable it.
openshift_metrics_server_install=true

HPAを使うためにはこのmetrics-serverがあれば良く、後述のhawkular関連は不要。

metrics (cassandra/hawkular/heapster)

# Metrics deployment
# See: https://docs.openshift.com/container-platform/latest/install_config/cluster_metrics.html
#
# By default metrics are not automatically deployed, set this to enable them
openshift_metrics_install_metrics=true

これをデプロイするには、httpd-tools,java-1.8.0-openjdk-headless,python-passlibパッケージを入れておく必要がある。

無いと、以下のエラーがそれぞれ発生する。

TASK [openshift_metrics : fail] ************************************************
Tuesday 07 January 2020  00:18:04 +0900 (0:00:00.140)       0:14:14.515 ******* 
fatal: [okd-master.esxi.jp-z.jp]: FAILED! => {"changed": false, "msg": "'htpasswd' is unavailable. Please install httpd-tools on the control node"}

PLAY RECAP *********************************************************************
[snip]

INSTALLER STATUS ***************************************************************
[snip]

Failure summary:

  1. Hosts:    okd-master.esxi.jp-z.jp
     Play:     OpenShift Metrics
     Task:     openshift_metrics : fail
     Message:  'htpasswd' is unavailable. Please install httpd-tools on the control node
TASK [openshift_metrics : fail] ************************************************
Tuesday 07 January 2020  01:12:38 +0900 (0:00:00.139)       0:28:09.412 ******* 
fatal: [okd-master.esxi.jp-z.jp]: FAILED! => {"changed": false, "msg": "'keytool' is unavailable. Please install java-1.8.0-openjdk-headless on the control node"}

PLAY RECAP *********************************************************************
[snip]

INSTALLER STATUS ***************************************************************
[snip]

Failure summary:

  1. Hosts:    okd-master.esxi.jp-z.jp
     Play:     OpenShift Metrics
     Task:     openshift_metrics : fail
     Message:  'keytool' is unavailable. Please install java-1.8.0-openjdk-headless on the control node
TASK [openshift_metrics : generate htpasswd file for hawkular metrics] *********
Tuesday 07 January 2020  00:29:30 +0900 (0:00:00.161)       0:06:39.260 ******* 
fatal: [okd-master.esxi.jp-z.jp -> localhost]: FAILED! => {"changed": false, "msg": "This module requires the passlib Python library"}

PLAY RECAP *********************************************************************
[snip]

INSTALLER STATUS ***************************************************************
[snip]

Failure summary:

  1. Hosts:    okd-master.esxi.jp-z.jp
     Play:     OpenShift Metrics
     Task:     generate htpasswd file for hawkular metrics
     Message:  This module requires the passlib Python library

cassandraのボリュームのpv設定をExternal NFSにするには以下の設定を追加しておく。

# Option B - External NFS Host
# NFS volume must already exist with path "nfs_directory/_volume_name" on
# the storage_host. For example, the remote volume path using these
# options would be "nfs.example.com:/exports/metrics".  "exports" is
# is the name of the export served by the nfs server.  "metrics" is
# the name of a directory inside of "/exports".
openshift_metrics_storage_kind=nfs
openshift_metrics_storage_access_modes=['ReadWriteOnce']
openshift_metrics_storage_host=okd-manager.esxi.jp-z.jp
openshift_metrics_storage_nfs_directory=/exports
openshift_metrics_storage_volume_name=metrics
openshift_metrics_storage_volume_size=10Gi
openshift_metrics_storage_labels={'storage': 'metrics'}

# [中略]

# Enable unsupported configurations, things that will yield a partially
# functioning cluster but would not be supported for production use
openshift_enable_unsupported_configurations=true

openshift_enable_unsupported_configurations=trueが無いと、prerequisites.ymlの実行で以下のエラーになる。

PLAY [Verify Requirements] *****************************************************
TASK [Run variable sanity checks] **********************************************
Wednesday 08 January 2020  06:56:58 +0900 (0:00:00.175)       0:00:11.349 ***** 
fatal: [okd-master.esxi.jp-z.jp]: FAILED! => {"msg": "last_checked_host: okd-master.esxi.jp-z.jp, last_checked_var: openshift_metrics_storage_kind;nfs is an unsupported type for openshift_metrics_storage_kind. openshift_enable_unsupported_configurations=True must be specified to continue with this configuration."}

logging (Elasticsearch/Fluentd/Kibana)

# Logging deployment
#
# Currently logging deployment is disabled by default, enable it by setting this
openshift_logging_install_logging=true
openshift_logging_es_nodeselector={"node-role.kubernetes.io/infra":"true"}

openshift_logging_es_nodeselectorはexampleには無いが必須。

github.com

無いとデプロイ対象ノード未定義となり、以下のエラーになる。

TASK [assert] ******************************************************************
Monday 06 January 2020  22:13:42 +0900 (0:00:00.362)       0:22:45.152 ******** 
fatal: [okd-master.esxi.jp-z.jp]: FAILED! => {
    "assertion": "openshift_logging_es_nodeselector is defined", 
    "changed": false, 
    "evaluated_to": false, 
    "msg": "A node selector is required for Elasticsearch pods, please specify one with openshift_logging_es_nodeselector"
}

PLAY RECAP *********************************************************************
[snip]

INSTALLER STATUS ***************************************************************
[snip]

Failure summary:

  1. Hosts:    okd-master.esxi.jp-z.jp
     Play:     Verify and collect ES hosts
     Task:     assert
     Message:  A node selector is required for Elasticsearch pods, please specify one with openshift_logging_es_nodeselector

また、java-1.8.0-openjdk-headlessパッケージ(に含まれるkeytoolコマンド)も必要。

TASK [openshift_logging : Run JKS generation script] ***************************
Monday 06 January 2020  22:25:29 +0900 (0:00:00.294)       0:06:48.688 ******** 
fatal: [okd-master.esxi.jp-z.jp -> localhost]: FAILED! => {"changed": true, "msg": "non-zero return code", "rc": 127, "stderr": "+ '[' 4 -lt 1 ']'\n+ dir=/tmp/openshift-logging-ansible-jF6I67\n+ SCRATCH_DIR=/tmp/openshift-logging-ansible-jF6I67\n+ PROJECT=openshift-logging\n+ MORE_ES_NAMES=\n+ escomma=\n+ '[' -n es.okd-apps.esxi.jp-z.jp ']'\n+ echo es.okd-apps.esxi.jp-z.jp\n+ egrep -q '^[0-9]|[.][0-9]'\n+ MORE_ES_NAMES=es.okd-apps.esxi.jp-z.jp\n+ escomma=,\n+ MORE_ES_OPS_NAMES=\n+ esopscomma=\n+ '[' -n es-ops.okd-apps.esxi.jp-z.jp ']'\n+ echo es-ops.okd-apps.esxi.jp-z.jp\n+ egrep -q '^[0-9]|[.][0-9]'\n+ MORE_ES_OPS_NAMES=es-ops.okd-apps.esxi.jp-z.jp\n+ esopscomma=,\n+ [[ ! -f /tmp/openshift-logging-ansible-jF6I67/system.admin.jks ]]\n+ generate_JKS_client_cert system.admin\n+ NODE_NAME=system.admin\n+ ks_pass=kspass\n+ ts_pass=tspass\n+ dir=/tmp/openshift-logging-ansible-jF6I67\n++ date -u '+%Y/%m/%d %H:%M:%S'\n+ startdate='2020/01/06 13:25:29'\n+ echo Generating keystore and certificate for node system.admin\n+ keytool -genkey -alias system.admin -keystore /tmp/openshift-logging-ansible-jF6I67/system.admin.jks -keyalg RSA -keysize 2048 -validity 712 -startdate '2020/01/06 13:25:29' -keypass kspass -storepass kspass -dname 'CN=system.admin, OU=OpenShift, O=Logging'\n/home/zaki/.ansible/tmp/ansible-tmp-1578317129.52-277025140157510/generate-jks.sh: 行 92: keytool: コマンドが見つかりません\n", "stderr_lines": ["+ '[' 4 -lt 1 ']'", "+ dir=/tmp/openshift-logging-ansible-jF6I67", "+ SCRATCH_DIR=/tmp/openshift-logging-ansible-jF6I67", "+ PROJECT=openshift-logging", "+ MORE_ES_NAMES=", "+ escomma=", "+ '[' -n es.okd-apps.esxi.jp-z.jp ']'", "+ echo es.okd-apps.esxi.jp-z.jp", "+ egrep -q '^[0-9]|[.][0-9]'", "+ MORE_ES_NAMES=es.okd-apps.esxi.jp-z.jp", "+ escomma=,", "+ MORE_ES_OPS_NAMES=", "+ esopscomma=", "+ '[' -n es-ops.okd-apps.esxi.jp-z.jp ']'", "+ echo es-ops.okd-apps.esxi.jp-z.jp", "+ egrep -q '^[0-9]|[.][0-9]'", "+ MORE_ES_OPS_NAMES=es-ops.okd-apps.esxi.jp-z.jp", "+ esopscomma=,", "+ [[ ! -f /tmp/openshift-logging-ansible-jF6I67/system.admin.jks ]]", "+ generate_JKS_client_cert system.admin", "+ NODE_NAME=system.admin", "+ ks_pass=kspass", "+ ts_pass=tspass", "+ dir=/tmp/openshift-logging-ansible-jF6I67", "++ date -u '+%Y/%m/%d %H:%M:%S'", "+ startdate='2020/01/06 13:25:29'", "+ echo Generating keystore and certificate for node system.admin", "+ keytool -genkey -alias system.admin -keystore /tmp/openshift-logging-ansible-jF6I67/system.admin.jks -keyalg RSA -keysize 2048 -validity 712 -startdate '2020/01/06 13:25:29' -keypass kspass -storepass kspass -dname 'CN=system.admin, OU=OpenShift, O=Logging'", "/home/zaki/.ansible/tmp/ansible-tmp-1578317129.52-277025140157510/generate-jks.sh: 行 92: keytool: コマンドが見つかりません"], "stdout": "Generating keystore and certificate for node system.admin\n", "stdout_lines": ["Generating keystore and certificate for node system.admin"]}

PLAY RECAP *********************************************************************
[snip]

Elasticsearchのボリュームのpv設定をExternal NFSにするには以下の設定を追加する。
openshift_logging_es_pvc_dynamicの設定追加に注意。

# Option B - External NFS Host
# NFS volume must already exist with path "nfs_directory/_volume_name" on
# the storage_host. For example, the remote volume path using these
# options would be "nfs.example.com:/exports/logging".  "exports" is
# is the name of the export served by the nfs server.  "logging" is
# the name of a directory inside of "/exports".
openshift_logging_storage_kind=nfs
openshift_logging_storage_access_modes=['ReadWriteOnce']
openshift_logging_storage_host=okd-manager.esxi.jp-z.jp
openshift_logging_storage_nfs_directory=/exports
openshift_logging_storage_volume_name=logging
openshift_logging_storage_volume_size=10Gi
openshift_logging_storage_labels={'storage': 'logging'}
openshift_logging_es_pvc_dynamic=False

# [中略]

# Enable unsupported configurations, things that will yield a partially
# functioning cluster but would not be supported for production use
openshift_enable_unsupported_configurations=true

openshift_logging_es_pvc_dynamicの設定は既存のexampleにはないが、以下のように指定が無いとpvcのテンプレート処理に失敗してしまう。

  1. Hosts:    aio3-node1.esxi.jp-z.jp
     Play:     OpenShift Aggregated Logging
     Task:     Creating ES storage template - static
     Message:  The conditional check 'not openshift_logging_elasticsearch_pvc_dynamic | bool' failed. The error was: An unhandled exception occurred while templating '{{ openshift_logging_es_pvc_dynamic }}'.
     Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ openshift_logging_elasticsearch_pvc_dynamic | default(False) }}'.
     Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ openshift_logging_es_pvc_dynamic }}'.

     [..snip..]

               The error appears to have been in '/home/zaki/openshift-ansible/roles/openshift_logging_elasticsearch/tasks/main.yaml': line 424, column 5, but may
               be elsewhere in the file depending on the exact syntax problem.

               The offending line appears to be:

                 # storageclasses with the storageClassName set to "" in pvc.j2
                 - name: Creating ES storage template - static
                   ^ here

失敗の仕方が変数定義の整合性が取れてない感じの結果未定義によるJinja2テンプレートの処理失敗なので、role側の記述ミスっぽいけどnfs/static provisioningは非推奨環境なので修正されるか微妙な感じ。

あと、openshift_enable_unsupported_configurations=trueが無いと、metrics同様prerequisites.ymlの実行で以下のエラーになる。

PLAY [Verify Requirements] *****************************************************
TASK [Run variable sanity checks] **********************************************
Tuesday 07 January 2020  19:49:51 +0900 (0:00:00.174)       0:00:11.207 ******* 
fatal: [okd-master.esxi.jp-z.jp]: FAILED! => {"msg": "last_checked_host: okd-master.esxi.jp-z.jp, last_checked_var: openshift_logging_storage_kind;nfs is an unsupported type for openshift_logging_storage_kind. openshift_enable_unsupported_configurations=True must be specified to continue with this configuration."}

変更点全体

--- /home/zaki/openshift-ansible/inventory/hosts.example 2020-01-06 19:13:02.346609154 +0900
+++ /home/zaki/install-inventory/hosts.example    2020-01-08 22:29:27.635225430 +0900
@@ -5,31 +5,30 @@
 # should use an external load balancing solution that itself is highly available.
 
 [masters]
-ose3-master[1:3].test.example.com
+okd-master.esxi.jp-z.jp
 
 [etcd]
-ose3-master[1:3].test.example.com
+okd-master.esxi.jp-z.jp
 
 [nodes]
 # openshift_node_group_name must be provided for each node
 # See 'Node Group Definition and Mapping' in the project README for more details
-ose3-master[1:3].test.example.com openshift_node_group_name="node-config-master"
-ose3-infra[1:2].test.example.com openshift_node_group_name="node-config-infra"
-ose3-node[1:2].test.example.com openshift_node_group_name="node-config-compute"
+okd-master.esxi.jp-z.jp openshift_node_group_name="node-config-master-infra"
+okd-node[1:2].esxi.jp-z.jp openshift_node_group_name="node-config-compute"
 
-[nfs]
-ose3-master1.test.example.com
+#[nfs]
+#ose3-master1.test.example.com
 
-[lb]
-ose3-lb.test.example.com
+#[lb]
+#ose3-lb.test.example.com
 
 # Create an OSEv3 group that contains the masters and nodes groups
 [OSEv3:children]
 masters
 nodes
 etcd
-lb
-nfs
+#lb
+#nfs
 
 [OSEv3:vars]
 ###############################################################################
@@ -38,11 +37,11 @@
 # SSH user, this user should allow ssh based auth without requiring a
 # password. If using ssh key based auth, then the key should be managed by an
 # ssh agent.
-ansible_user=root
+ansible_user=zaki
 
 # If ansible_user is not root, ansible_become must be set to true and the
 # user must be configured for passwordless sudo
-#ansible_become=yes
+ansible_become=yes
 
 # Specify the deployment type. Valid values are origin and openshift-enterprise.
 openshift_deployment_type=origin
@@ -58,10 +57,10 @@
 # default subdomain to use for exposed routes, you should have wildcard dns
 # for *.apps.test.example.com that points at your infra nodes which will run
 # your router
-openshift_master_default_subdomain=apps.test.example.com
+openshift_master_default_subdomain=okd-apps.esxi.jp-z.jp
 
 #Set cluster_hostname to point at your load balancer
-openshift_master_cluster_hostname=ose3-lb.test.example.com
+openshift_master_cluster_hostname=okd-master.esxi.jp-z.jp
 
 
 
@@ -200,9 +199,9 @@
 #osm_etcd_image=registry.example.com/rhel7/etcd
 
 # htpasswd auth
-#openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]
+openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]
 # Defining htpasswd users
-#openshift_master_htpasswd_users={'user1': '<pre-hashed password>', 'user2': '<pre-hashed password>'}
+openshift_master_htpasswd_users={'admin': '$apr1$3okJisBZ$0Dho15qcoE.5RD/RJO1Ph0', 'user': '$apr1$dWZrK5Cl$DKGb58Txa24GcYJT4UI/k0'}
 # or
 #openshift_master_htpasswd_file=<path to local pre-generated htpasswd file>
 
@@ -507,14 +506,14 @@
 # options would be "nfs.example.com:/exports/registry".  "exports" is
 # is the name of the export served by the nfs server.  "registry" is
 # the name of a directory inside of "/exports".
-#openshift_hosted_registry_storage_kind=nfs
-#openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
-#openshift_hosted_registry_storage_host=nfs.example.com
+openshift_hosted_registry_storage_kind=nfs
+openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
+openshift_hosted_registry_storage_host=okd-manager.esxi.jp-z.jp
 # nfs_directory must conform to DNS-1123 subdomain must consist of lower case
 # alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character
-#openshift_hosted_registry_storage_nfs_directory=/exports
-#openshift_hosted_registry_storage_volume_name=registry
-#openshift_hosted_registry_storage_volume_size=10Gi
+openshift_hosted_registry_storage_nfs_directory=/exports
+openshift_hosted_registry_storage_volume_name=registry
+openshift_hosted_registry_storage_volume_size=10Gi
 #
 # Openstack
 # Volume must already exist.
@@ -584,13 +583,13 @@
 # See: https://docs.openshift.com/container-platform/latest/install_config/cluster_metrics.html
 #
 # By default metrics are not automatically deployed, set this to enable them
-#openshift_metrics_install_metrics=true
+openshift_metrics_install_metrics=true
 #
 # metrics-server deployment
 # By default, metrics-server is not automatically deployed, unless metrics is also
 # deployed.  Deploying metrics-server is necessary to use the HorizontalPodAutoscaler.
 # Set this to enable it.
-#openshift_metrics_server_install=true
+openshift_metrics_server_install=true
 #
 # Storage Options
 # If openshift_metrics_storage_kind is unset then metrics will be stored
@@ -619,13 +618,13 @@
 # options would be "nfs.example.com:/exports/metrics".  "exports" is
 # is the name of the export served by the nfs server.  "metrics" is
 # the name of a directory inside of "/exports".
-#openshift_metrics_storage_kind=nfs
-#openshift_metrics_storage_access_modes=['ReadWriteOnce']
-#openshift_metrics_storage_host=nfs.example.com
-#openshift_metrics_storage_nfs_directory=/exports
-#openshift_metrics_storage_volume_name=metrics
-#openshift_metrics_storage_volume_size=10Gi
-#openshift_metrics_storage_labels={'storage': 'metrics'}
+openshift_metrics_storage_kind=nfs
+openshift_metrics_storage_access_modes=['ReadWriteOnce']
+openshift_metrics_storage_host=okd-manager.esxi.jp-z.jp
+openshift_metrics_storage_nfs_directory=/exports
+openshift_metrics_storage_volume_name=metrics
+openshift_metrics_storage_volume_size=10Gi
+openshift_metrics_storage_labels={'storage': 'metrics'}
 #
 # Option C - Dynamic -- If openshift supports dynamic volume provisioning for
 # your cloud platform use this.
@@ -688,7 +687,9 @@
 # Logging deployment
 #
 # Currently logging deployment is disabled by default, enable it by setting this
-#openshift_logging_install_logging=true
+openshift_logging_install_logging=true
+openshift_logging_es_nodeselector={"node-role.kubernetes.io/infra":"true"}
+
 #
 # Logging storage config
 # Option A - NFS Host Group
@@ -711,13 +712,14 @@
 # options would be "nfs.example.com:/exports/logging".  "exports" is
 # is the name of the export served by the nfs server.  "logging" is
 # the name of a directory inside of "/exports".
-#openshift_logging_storage_kind=nfs
-#openshift_logging_storage_access_modes=['ReadWriteOnce']
-#openshift_logging_storage_host=nfs.example.com
-#openshift_logging_storage_nfs_directory=/exports
-#openshift_logging_storage_volume_name=logging
-#openshift_logging_storage_volume_size=10Gi
-#openshift_logging_storage_labels={'storage': 'logging'}
+openshift_logging_storage_kind=nfs
+openshift_logging_storage_access_modes=['ReadWriteOnce']
+openshift_logging_storage_host=okd-manager.esxi.jp-z.jp
+openshift_logging_storage_nfs_directory=/exports
+openshift_logging_storage_volume_name=logging
+openshift_logging_storage_volume_size=10Gi
+openshift_logging_storage_labels={'storage': 'logging'}
+openshift_logging_es_pvc_dynamic=False
 #
 # Option C - Dynamic -- If openshift supports dynamic volume provisioning for
 # your cloud platform use this.
@@ -1108,4 +1110,4 @@
 
 # Enable unsupported configurations, things that will yield a partially
 # functioning cluster but would not be supported for production use
-#openshift_enable_unsupported_configurations=false
+openshift_enable_unsupported_configurations=true

インストール

インストールは2段階のansible-playbook実行。
また、git cloneしたopenshift-ansible直下(インストール用にカスタマイズされたansible.cfgのあるディレクトリ)で実施する。

prerequisites

$ ansible-playbook -i ~/install-inventory/hosts.example playbooks/prerequisites.yml

これは数分で完了する。

deploy_cluster

$ time ansible-playbook -i ~/install-inventory/hosts.example playbooks/deploy_cluster.yml

問題無ければデプロイは正常に完了するはず。

PLAY RECAP *********************************************************************
localhost                  : ok=11   changed=0    unreachable=0    failed=0   
okd-master.esxi.jp-z.jp    : ok=1081 changed=395  unreachable=0    failed=0   
okd-node1.esxi.jp-z.jp     : ok=109  changed=36   unreachable=0    failed=0   
okd-node2.esxi.jp-z.jp     : ok=109  changed=36   unreachable=0    failed=0   


INSTALLER STATUS ***************************************************************
Initialization               : Complete (0:00:08)
Health Check                 : Complete (0:00:32)
Node Bootstrap Preparation   : Complete (0:02:46)
etcd Install                 : Complete (0:00:22)
Master Install               : Complete (0:03:29)
Master Additional Install    : Complete (0:00:19)
Node Join                    : Complete (0:00:26)
Hosted Install               : Complete (0:00:31)
        The use of NFS for the core OpenShift Container Platform components is not recommended, as NFS (and the NFS Protocol) does not provide the proper consistency needed for the applications that make up the OpenShift Container Platform infrastructure.
Cluster Monitoring Operator  : Complete (0:00:37)
Web Console Install          : Complete (0:00:58)
Console Install              : Complete (0:00:21)
Metrics Install              : Complete (0:01:07)
metrics-server Install       : Complete (0:00:26)
Logging Install              : Complete (0:01:49)
Service Catalog Install      : Complete (0:05:00)
Wednesday 08 January 2020  22:51:19 +0900 (0:00:00.021)       0:19:08.315 ***** 
=============================================================================== 
openshift_service_catalog : Wait for API Server rollout success ------- 153.67s
openshift_control_plane : Wait for all control plane pods to come up and become ready - 102.58s
openshift_node : Install node, clients, and conntrack packages --------- 84.95s
openshift_web_console : Verify that the console is running ------------- 51.77s
openshift_service_catalog : Wait for Controller Manager rollout success -- 50.71s
template_service_broker : Verify that TSB is running ------------------- 45.18s
Run health checks (install) - EL --------------------------------------- 31.43s
openshift_cluster_monitoring_operator : Wait for the ServiceMonitor CRD to be created -- 30.70s
openshift_node : Check status of node image pre-pull ------------------- 30.44s
openshift_ca : Install the base package for admin tooling -------------- 27.29s
openshift_console : Waiting for console rollout to complete ------------ 17.14s
openshift_manage_node : Wait for sync DS to set annotations on all nodes -- 11.08s
openshift_node_group : Wait for the sync daemonset to become ready and available -- 10.64s
openshift_service_catalog : oc_process --------------------------------- 10.28s
openshift_hosted : Create OpenShift router ------------------------------ 6.71s
openshift_manageiq : Configure role/user permissions -------------------- 3.89s
openshift_logging : Annotate Operations Projects for data prefix -------- 3.63s
openshift_logging : Run JKS generation script --------------------------- 3.45s
openshift_excluder : Install docker excluder - yum ---------------------- 2.93s
openshift_control_plane : Wait for APIs to become available ------------- 2.74s

real    19m10.883s
user    3m46.074s
sys     1m12.823s

サンプルアプリのデプロイ

偶然にも昔作ったminishiftなOpenShiftで動くmaven-webapp on WildFly + MySQLなアプリケーションがあるのでデプロイしてみる。

qiita.com

project作成

$ oc new-project samplepj

pv作成

動的プロビジョニング設定じゃないので、DB用のpvを作る。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: memoapp-pv
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi
  nfs:
    path: /exports/memoapp-db
    server: okd-manager.esxi.jp-z.jp
  persistentVolumeReclaimPolicy: Retain

このファイルを適当に保存して、oc apply -f <filename>する。
また、podのデプロイ前にNFSサーバ上にpathに指定している/exports/memoapp-dbをrootの775で作成する。

DB

$ oc new-app mysql-persistent -p DATABASE_SERVICE_NAME=memoapp-db -p MYSQL_USER=memoapp -p MYSQL_PASSWORD=memoapp -p MYSQL_DATABASE=memoapp_db -p VOLUME_CAPACITY=10Gi

これでpvのデータ領域になっているNFSサーバ上にDBのデータが作成され、MySQLのpodがデプロイされるはず。

[zaki@okd-master ~]$ oc get pod
NAME                 READY     STATUS    RESTARTS   AGE
memoapp-db-1-hgncr   1/1       Running   0          14s

app

S2Iでビルドする。要インターネット接続。

$ oc new-app openshift/wildfly~https://github.com/zaki-lknr/javaee-memoapp2.git

これでgit cloneからmvnビルド・コンテナイメージビルドからデプロイまで全自動で動く。

[zaki@okd-master ~]$ oc get pod
NAME                      READY     STATUS    RESTARTS   AGE
javaee-memoapp2-1-build   1/1       Running   0          31s
memoapp-db-1-hgncr        1/1       Running   0          2m

アクセス

Routeは作ってくれないので、手動で。

$ oc expose svc/javaee-memoapp2 
route.route.openshift.io/javaee-memoapp2 exposed
$ oc get route
NAME              HOST/PORT                                        PATH      SERVICES          PORT       TERMINATION   WILDCARD
javaee-memoapp2   javaee-memoapp2-samplepj.okd-apps.esxi.jp-z.jp             javaee-memoapp2   8080-tcp                 None

このドメインでwebアクセスする。 と思ったけど、アプリの仕様でコンテキストルートじゃなかったので、http://javaee-memoapp2-samplepj.okd-apps.esxi.jp-z.jp/memoapp2/へアクセス。

f:id:zaki-hmkc:20200108233612p:plain

f:id:zaki-hmkc:20200108233621p:plain

データ入力すればちゃんと保存された。


補足

NFSをpvに使ってるのはあくまで検証用です。DBとかのストレージにブロックストレージでなくファイルストレージを使うのはよくないと、つよつよな方はみんなおっしゃっているので注意。(VM上にDBを構築したとして、その生データがNFS経由で別のホストにあるような感じなので、そりゃあよろしくない)

speakerdeck.com