OpenShift Origin v3.9 の環境構築とアプリケーションのデプロイ(前編)

[後編はこちら](https://qiita.com/t-eno/items/fd9329369478b8dd818e)

# はじめに
OpenShift Origin v3.9 で環境を構築し、自分で作成したアプリケーションをGitHub からデプロイするところまでできましたので、その手順を書きます。
構築するにあたって色々検索してみましたが、Master 1台、Node 2台の最小構成だったり、
Hello World を表示するだけだったりと実用的でない例しか見つからなかったので、
もう少し実用的で体系的な例として書くことにしました。
長いですが、大部分はOpenShift インストール前のサーバーのセットアップですので難しくは無いです。
前編はOpenShift のインストールまで。後編はアプリケーションのデプロイから。

# 1. 構成と前提
- KVM 上の仮想マシーンにOpenShift の環境を構築
- Master, Infra Node, application Node それぞれ3台ずつ
- GlusterFS で内部レジストリー、アプリケーション用データを保全
- 物理マシーン、仮想マシーン全てCentOS7
- 物理マシーンにVlan Interface, Bridge Interface それぞれvlan205, br205 を作成
- 仮想マシーンはks ファイルから作成
- 仮想マシーン構築にはCentOS-7-x86_64-DVD-1804.iso を使用
- 仮想マシーンのdefault-zone はinternal を指定
- 構築作業は全てroot で行うものとする
- **[マシーン名]** と書いてあったらそのマシーンで作業するという意味

![outline.png](https://qiita-image-store.s3.amazonaws.com/0/147025/d4857782-a314-d3e5-0c2a-5796b5461f03.png)

| ホスト名 | 役割 |
| ---: | :--- |
| lb-01 | ロードバランサー(HA Proxy) |
| master-0[1:3] | Master 用 |
| infra-0[1:3] | Infra Node 用 |
| node-0[1:3] | Application Node 用 |
| gfs-0[1:3] | 内部レジストリー用GlusterFS |
| gfs-0[4:6] | アプリケーション用GlusterFS |
| ansible-01 | インストール作業サーバー |
| dns-01 | 環境内のDNS サーバー |
| repo-01 | origin パッケージ用のローカルリポジトリ(任意) |
| ntp-01 | NTP サーバー(任意) |

# 2. 準備
## 2-1. DNS 登録
ドメイン取得して、DNS 登録する。
ここではexample.com というドメインを取得して*.example.com というワイルドカードでDNS 登録したとする。実際に構築するときは以降全てのexample.com の部分を自分の環境のものに読み替える。

## 2-2. ファイアウォールのポート転送設定
外部からtcp port=80, 443, 8443 宛のアクセスをlb-01 にポートをそのままに転送する設定をする。

## 2-3. 物理マシーンの構築
**[物理マシーン]**
CentOS7 を最小構成でインストールしてKVM をインストール。

```
yum -y update
yum -y groupinstall "Virtualization Host"
yum -y install virt-install virt-top virt-clone
systemctl start libvirtd
systemctl enable libvirtd
``` 

vlan とbridge の作成。bond0 の部分は自分の環境に合わせて読み替える。

```
nmcli c add type bridge ifname br205 con-name br205
nmcli c mod br205 bridge.stp no
nmcli c mod br205 ipv4.method disabled ipv6.method ignore
nmcli c add type vlan ifname vlan205 con-name vlan205 dev bond0 id 205
nmcli c mod vlan205 connection.master br205 connection.slave-type bridge
```

CentOS-7-x86_64-DVD-1804.iso をダウンロードして/opt/Linux に保存しておく。

## 2-4. 内部用DNS サーバーの構築
**[物理マシーン]**
ks ファイルの作成。

```text:dns-01.ks
cmdline
install
lang ja_JP.UTF-8
keyboard jp106

network --device eth0 --onboot yes --bootproto=static --ip=192.168.205.6 --netmask=255.255.255.224 --gateway=192.168.205.30 --nameserver=8.8.8.8 --noipv6
network --hostname=dns-01

zerombr
bootloader --location=mbr --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8"

clearpart --linux --drives=vda
part /boot --fstype xfs --size=1024 --ondisk=vda
part pv.1 --size=1024 --grow --ondisk=vda
volgroup centos pv.1
logvol swap --fstype swap --name=swap --vgname=centos --size=1024
logvol /    --fstype xfs  --name=root --vgname=centos --size=1024 --grow

rootpw --plaintext rootpassword
user --groups=wheel --name=user-01 --password=user-01password --plaintext
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
firstboot --disabled
timezone --utc Asia/Tokyo
reboot

%packages --nobase
%end
```

ディスクイメージの作成。

```
qemu-img create -f qcow2 /var/lib/libvirt/images/dns-01.qcow2 8G
```

仮想マシーンの作成。

```
virt-install --connect=qemu:///system \
 --name=dns-01 \
 --vcpus=1 \
 --ram=1024 \
 --accelerate \
 --hvm \
 --disk /var/lib/libvirt/images/dns-01.qcow2,size=8,format=qcow2,bus=virtio \
 --location='/opt/Linux/CentOS-7-x86_64-DVD-1804.iso' \
 --network bridge=br205,model=virtio \
 --nographics \
 --initrd-inject=./dns-01.ks \
 --extra-args='ks=file:/dns-01.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \
 --os-type=linux \
 --os-variant=centos7.0 \
 --arch=x86_64
```

**[dns-01]**
firewalld の設定とdnsmasq のインストール。

```
yum -y update

nmcli c mod eth0 connection.zone internal
firewall-cmd --set-default-zone=internal
firewall-cmd --zone=internal --add-service=dns --permanent
firewall-cmd --zone=internal --remove-service=mdns --permanent
firewall-cmd --zone=internal --remove-service=samba-client --permanent
firewall-cmd --zone=internal --remove-service=dhcpv6-client --permanent

yum -y install dnsmasq

reboot
```

hosts ファイルに追記。

```text:/etc/hosts
192.168.205.1  lb-01     lb-01.example.com console console.example.com
192.168.205.3  ansible   ansible.example.com
192.168.205.6  dns-01    dns-01.example.com
192.168.205.8  repo-01   repo-01.example.com
192.168.205.9  ntp-01    ntp-01.example.com
192.168.205.11 master-01 master-01.example.com
192.168.205.12 master-02 master-02.example.com
192.168.205.13 master-03 master-03.example.com
192.168.205.14 infra-01  infra-01.example.com
192.168.205.15 infra-02  infra-02.example.com
192.168.205.16 infra-03  infra-03.example.com
192.168.205.17 node-01   node-01.example.com
192.168.205.18 node-02   node-02.example.com
192.168.205.19 node-03   node-03.example.com
192.168.205.21 gfs-01    gfs-01.example.com
192.168.205.22 gfs-02    gfs-02.example.com
192.168.205.23 gfs-03    gfs-03.example.com
192.168.205.24 gfs-04    gfs-04.example.com
192.168.205.25 gfs-05    gfs-05.example.com
192.168.205.26 gfs-06    gfs-06.example.com
```

dnsmasq 設定ファイルの編集と起動。

```config:/etc/dnsmasq.conf
port=53
domain-needed
bogus-priv
resolv-file=/etc/dnsmasq.resolv.conf
strict-order
local=/example.com/
expand-hosts
domain=example.com
conf-dir=/etc/dnsmasq.d,.rpmnew,.rpmsave,.rpmorig
```

```config:/etc/dnsmasq.resolv.conf
nameserver 8.8.8.8
```

```
systemctl start dnsmasq
systemctl enable dnsmasq
```

以降hosts ファイルを編集したらdnsmasq をrestart


## 2-5. ローカルリポジトリの作成
無くても良いが、origin 関連のパッケージのダウンロードに1時間以上かかったりすることがあり、
最初のうちは環境を作っては壊し作っては壊しを繰り返すと思うのでorigin 関連のパッケージだけのローカルリポジトリを作成しておくと時間の節約になる。

**[物理マシーン]**
ks ファイルの作成。

```text:repo-01.ks
cmdline
install
lang ja_JP.UTF-8
keyboard jp106

network --device eth0 --onboot yes --bootproto=static --ip=192.168.205.8 --netmask=255.255.255.224 --gateway=192.168.205.30 --nameserver=192.168.205.6 --noipv6
network --hostname=repo-01

zerombr
bootloader --location=mbr --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8"

clearpart --linux --drives=vda
part /boot --fstype xfs --size=1024 --ondisk=vda
part pv.1 --size=1024 --grow --ondisk=vda
volgroup centos pv.1
logvol swap --fstype swap --name=swap --vgname=centos --size=1024
logvol /    --fstype xfs  --name=root --vgname=centos --size=1024 --grow

rootpw --plaintext rootpassword
user --groups=wheel --name=user-01 --password=user-01password --plaintext
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
firstboot --disabled
timezone --utc Asia/Tokyo
reboot

%packages --nobase
%end
```

ディスクイメージの作成。

```
qemu-img create -f qcow2 /var/lib/libvirt/images/repo-01.qcow2 8G
```

仮想マシーンの作成。

```
virt-install --connect=qemu:///system \
 --name=repo-01 \
 --vcpus=1 \
 --ram=1024 \
 --accelerate \
 --hvm \
 --disk /var/lib/libvirt/images/repo-01.qcow2,size=8,format=qcow2,bus=virtio \
 --location='/opt/Linux/CentOS-7-x86_64-DVD-1804.iso' \
 --network bridge=br205,model=virtio \
 --nographics \
 --initrd-inject=./repo-01.ks \
 --extra-args='ks=file:/repo-01.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \
 --os-type=linux \
 --os-variant=centos7.0 \
 --arch=x86_64
```

**[repo-01]**
firewalld の設定とローカルリポジトリに必要なパッケージのインストール。

```
yum -y update

nmcli c mod eth0 connection.zone internal
firewall-cmd --set-default-zone=internal
firewall-cmd --zone=internal --add-service=http --permanent
firewall-cmd --zone=internal --remove-service=mdns --permanent
firewall-cmd --zone=internal --remove-service=samba-client --permanent
firewall-cmd --zone=internal --remove-service=dhcpv6-client --permanent

yum install -y httpd yum-utils createrepo centos-release-openshift-origin39 
systemctl enable httpd

reboot
```

origin 関連のパッケージのダウンロードとリポジトリの作成。

```
mkdir /var/www/html/repo
createrepo --database /var/www/html/repo
yum install -y --downloadonly --downloaddir=/var/www/html/repo origin origin-clients origin-master origin-node origin-sdn-ovs
createrepo --update /var/www/html/repo
```

## 2-6. NTP サーバー
無くても動作はするが、作成する場合は一般的な方法で作成する。
作成方法は他の記事に任せる。
以降の手順は作成した場合のもの。

# 3. OpenShift 動作仮想マシーンの作成
## 3-1. lb-01
**[物理マシーン]**
ks ファイルの作成。

```text:lb-01.ks
cmdline
install
lang ja_JP.UTF-8
keyboard jp106

network --device eth0 --onboot yes --bootproto=static --ip=192.168.205.1 --netmask=255.255.255.224 --gateway=192.168.205.30 --nameserver=192.168.205.6 --noipv6
network --hostname=lb-01

zerombr
bootloader --location=mbr --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8"

clearpart --linux --drives=vda
part /boot --fstype xfs --size=1024 --ondisk=vda
part pv.1 --size=1024 --grow --ondisk=vda
volgroup centos pv.1
logvol swap --fstype swap --name=swap --vgname=centos --size=1024
logvol /    --fstype xfs  --name=root --vgname=centos --size=1024 --grow

rootpw --plaintext rootpassword
user --groups=wheel --name=user-01 --password=user-01password --plaintext
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
firstboot --disabled
timezone --utc Asia/Tokyo
reboot

%packages --nobase
%end
```

ディスクイメージの作成。

```
qemu-img create -f qcow2 /var/lib/libvirt/images/lb-01.qcow2 8G
```

仮想マシーンの作成。

```
virt-install --connect=qemu:///system \
 --name=lb-01 \
 --vcpus=2 \
 --ram=2048 \
 --accelerate \
 --hvm \
 --disk /var/lib/libvirt/images/lb-01.qcow2,size=8,format=qcow2,bus=virtio \
 --location='/opt/Linux/CentOS-7-x86_64-DVD-1804.iso' \
 --network bridge=br205,model=virtio \
 --nographics \
 --initrd-inject=./lb-01.ks \
 --extra-args='ks=file:/lb-01.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \
 --os-type=linux \
 --os-variant=centos7.0 \
 --arch=x86_64
```

## 3-2. master-01
**[物理マシーン]**
ks ファイルの作成。

```text:master-01.ks
cmdline
install
lang ja_JP.UTF-8
keyboard jp106

network --device eth0 --onboot yes --bootproto=static --ip=192.168.205.11 --netmask=255.255.255.224 --gateway=192.168.205.30 --nameserver=192.168.205.6 --noipv6
network --hostname=master-01

zerombr
bootloader --location=mbr --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8"

clearpart --linux --drives=vda
part /boot --fstype xfs --size=1024 --ondisk=vda
part pv.1 --size=65536 --ondisk=vda
volgroup centos pv.1
logvol / --fstype xfs  --name=root --vgname=centos --size=1024 --grow

rootpw --plaintext rootpassword
user --groups=wheel --name=user-01 --password=user-01password --plaintext
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
firstboot --disabled
timezone --utc Asia/Tokyo
reboot

%packages --nobase
%end
```

ディスクイメージの作成。

```
qemu-img create -f qcow2 /var/lib/libvirt/images/master-01.qcow2 128G
```

仮想マシーンの作成。

```
virt-install --connect=qemu:///system \
 --name=master-01 \
 --vcpus=8 \
 --ram=24576 \
 --accelerate \
 --hvm \
 --disk /var/lib/libvirt/images/master-01.qcow2,size=128,format=qcow2,bus=virtio \
 --location='/opt/Linux/CentOS-7-x86_64-DVD-1804.iso' \
 --network bridge=br205,model=virtio \
 --nographics \
 --initrd-inject=./master-01.ks \
 --extra-args='ks=file:/master-01.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \
 --os-type=linux \
 --os-variant=centos7.0 \
 --arch=x86_64
```

ホスト名とIP Address を変えてmaster-02, 03 の仮想マシーンも作成する。

## 3-3. infra-01
**[物理マシーン]**
ks ファイルの作成。

```text:infra-01.ks
cmdline
install
lang ja_JP.UTF-8
keyboard jp106

network --device eth0 --onboot yes --bootproto=static --ip=192.168.205.14 --netmask=255.255.255.224 --gateway=192.168.205.30 --nameserver=192.168.205.6 --noipv6
network --hostname=infra-01

zerombr
bootloader --location=mbr --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8"

clearpart --linux --drives=vda
part /boot --fstype xfs --size=1024 --ondisk=vda
part pv.1 --size=32768 --ondisk=vda
volgroup centos pv.1
logvol / --fstype xfs  --name=root --vgname=centos --size=1024 --grow

rootpw --plaintext rootpassword
user --groups=wheel --name=user-01 --password=user-01password --plaintext
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
firstboot --disabled
timezone --utc Asia/Tokyo
reboot

%packages --nobase
%end
```

ディスクイメージの作成。

```
qemu-img create -f qcow2 /var/lib/libvirt/images/infra-01.qcow2 96G
```

仮想マシーンの作成。

```
virt-install --connect=qemu:///system \
 --name=infra-01 \
 --vcpus=8 \
 --ram=16384 \
 --accelerate \
 --hvm \
 --disk /var/lib/libvirt/images/infra-01.qcow2,size=96,format=qcow2,bus=virtio \
 --location='/opt/Linux/CentOS-7-x86_64-DVD-1804.iso' \
 --network bridge=br205,model=virtio \
 --nographics \
 --initrd-inject=./infra-01.ks \
 --extra-args='ks=file:/infra-01.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \
 --os-type=linux \
 --os-variant=centos7.0 \
 --arch=x86_64
```

ホスト名とIP Address を変えてinfra-02, 03, node-01, 02, 03 の仮想マシーンも作成する。

## 3-4. gfs-01
**[物理マシーン]**
ks ファイルの作成。

```text:gfs-01.ks
cmdline
install
lang ja_JP.UTF-8
keyboard jp106

network --device eth0 --onboot yes --bootproto=static --ip=192.168.205.21 --netmask=255.255.255.224 --gateway=192.168.205.30 --nameserver=192.168.205.6 --noipv6
network --hostname=gfs-01

zerombr
bootloader --location=mbr --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8"

clearpart --linux --drives=vda
part /boot --fstype xfs --size=1024 --ondisk=vda
part pv.1 --size=8192 --ondisk=vda
volgroup centos pv.1
logvol / --fstype xfs  --name=root --vgname=centos --size=1024 --grow

rootpw --plaintext rootpassword
user --groups=wheel --name=user-01 --password=user-01password --plaintext
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
firstboot --disabled
timezone --utc Asia/Tokyo
reboot

%packages --nobase
%end
```

ディスクイメージの作成。

```
qemu-img create -f qcow2 /var/lib/libvirt/images/gfs-01.qcow2 200G
```

仮想マシーンの作成。

```
virt-install --connect=qemu:///system \
 --name=gfs-01 \
 --vcpus=2 \
 --ram=8192 \
 --accelerate \
 --hvm \
 --disk /var/lib/libvirt/images/gfs-01.qcow2,size=200,format=qcow2,bus=virtio \
 --location='/opt/Linux/CentOS-7-x86_64-DVD-1804.iso' \
 --network bridge=br205,model=virtio \
 --nographics \
 --initrd-inject=./gfs-01.ks \
 --extra-args='ks=file:/gfs-01.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \
 --os-type=linux \
 --os-variant=centos7.0 \
 --arch=x86_64
```

ホスト名とIP Address を変えてgfs-02, 03, 04, 05, 06 の仮想マシーンも作成する。

# 4. 作業サーバーの作成とセットアップ
## 4-1. ansible-01 の作成
**[物理マシーン]**
ks ファイルの作成。

```text:ansible-01.ks
cmdline
install
lang ja_JP.UTF-8
keyboard jp106

network --device eth0 --onboot yes --bootproto=static --ip=192.168.205.3 --netmask=255.255.255.224 --gateway=192.168.205.30 --nameserver=192.168.205.6 --noipv6
network --hostname=ansible-01

zerombr
bootloader --location=mbr --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8"

clearpart --linux --drives=vda
part /boot --fstype xfs --size=1024 --ondisk=vda
part pv.1 --size=1024 --grow --ondisk=vda
volgroup centos pv.1
logvol swap --fstype swap --name=swap --vgname=centos --size=1024
logvol /    --fstype xfs  --name=root --vgname=centos --size=1024 --grow

rootpw --plaintext rootpassword
user --groups=wheel --name=user-01 --password=user-01password --plaintext
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
firstboot --disabled
timezone --utc Asia/Tokyo
reboot

%packages --nobase
%end
```

ディスクイメージの作成。

```
qemu-img create -f qcow2 /var/lib/libvirt/images/ansible-01.qcow2 8G
```

仮想マシーンの作成。

```
virt-install --connect=qemu:///system \
 --name=ansible-01 \
 --vcpus=1 \
 --ram=1024 \
 --accelerate \
 --hvm \
 --disk /var/lib/libvirt/images/ansible-01.qcow2,size=8,format=qcow2,bus=virtio \
 --location='/opt/Linux/CentOS-7-x86_64-DVD-1804.iso' \
 --network bridge=br205,model=virtio \
 --nographics \
 --initrd-inject=./ansible-01.ks \
 --extra-args='ks=file:/ansible-01.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \
 --os-type=linux \
 --os-variant=centos7.0 \
 --arch=x86_64
```

**[ansible-01]**
firewalld の設定と必要パッケージのインストール。

```
yum -y update

nmcli c mod eth0 connection.zone internal
firewall-cmd --set-default-zone=internal
firewall-cmd --zone=internal --remove-service=mdns --permanent
firewall-cmd --zone=internal --remove-service=samba-client --permanent
firewall-cmd --zone=internal --remove-service=dhcpv6-client --permanent

yum install -y git epel-release python2-passlib httpd-tools java-1.8.0-openjdk-headless patch
yum install -y --enablerepo=epel ansible pyOpenSSL

reboot
```

## 4-2. OpenShift 動作仮想マシーンのセットアップ
**[ansible-01]**
パスフレーズ無しの鍵を作成。

```
ssh-keygen
```

各サーバーへ鍵の送付。

```
ssh-copy-id -i ~/.ssh/id_rsa.pub lb-01
ssh-copy-id -i ~/.ssh/id_rsa.pub master-01
ssh-copy-id -i ~/.ssh/id_rsa.pub master-02
ssh-copy-id -i ~/.ssh/id_rsa.pub master-03
ssh-copy-id -i ~/.ssh/id_rsa.pub infra-01
ssh-copy-id -i ~/.ssh/id_rsa.pub infra-02
ssh-copy-id -i ~/.ssh/id_rsa.pub infra-03
ssh-copy-id -i ~/.ssh/id_rsa.pub node-01
ssh-copy-id -i ~/.ssh/id_rsa.pub node-02
ssh-copy-id -i ~/.ssh/id_rsa.pub node-03
ssh-copy-id -i ~/.ssh/id_rsa.pub gfs-01
ssh-copy-id -i ~/.ssh/id_rsa.pub gfs-02
ssh-copy-id -i ~/.ssh/id_rsa.pub gfs-03
ssh-copy-id -i ~/.ssh/id_rsa.pub gfs-04
ssh-copy-id -i ~/.ssh/id_rsa.pub gfs-05
ssh-copy-id -i ~/.ssh/id_rsa.pub gfs-06
```

### 4-2-1. lb-01 のセットアップ
**[ansible-01]**
yum update

```
for host in lb-01;
    do ssh ${host} 'yum -y update'
    done
```

firewalld, chrony, ifcfg-eth0 の設定。

```
for host in lb-01 ;
    do ssh ${host} 'nmcli c mod eth0 connection.zone internal; \
                    firewall-cmd --set-default-zone=internal; \
                    firewall-cmd --zone=internal --add-service=http --permanent; \
                    firewall-cmd --zone=internal --add-service=https --permanent; \
                    firewall-cmd --zone=internal --remove-service=mdns --permanent; \
                    firewall-cmd --zone=internal --remove-service=samba-client --permanent; \
                    firewall-cmd --zone=internal --remove-service=dhcpv6-client --permanent; \
                    sed -i -e "/server/s/^/#/" /etc/chrony.conf; \
                    sed -i -e "s/server 3\.centos\.pool\.ntp\.org iburst/server 3.centos.pool.ntp.org iburst\nserver 192.168.205.9 iburst\nport 0/" /etc/chrony.conf; \
                    sed -i -e "/HWADDR/s/^/#/" /etc/sysconfig/network-scripts/ifcfg-eth0; \
                    sed -i -e "/UUID/s/^/#/" /etc/sysconfig/network-scripts/ifcfg-eth0; \
                    sed -i -e "\$aDOMAIN=example.com" /etc/sysconfig/network-scripts/ifcfg-eth0;'
    done
```

再起動。

```
for host in lb-01;
    do ssh ${host} 'reboot'
    done
```

### 4-2-2. master, infra, node のセットアップ
**[ansible-01]**
yum update

```
for host in master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03;
    do ssh ${host} 'yum -y update'
    done
```

firewalld, chrony, ifcfg-eth0 の設定。

```
for host in master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03;
    do ssh ${host} 'nmcli c mod eth0 connection.zone internal; \
                    firewall-cmd --set-default-zone=internal; \
                    firewall-cmd --zone=internal --remove-service=mdns --permanent; \
                    firewall-cmd --zone=internal --remove-service=samba-client --permanent; \
                    firewall-cmd --zone=internal --remove-service=dhcpv6-client --permanent; \
                    sed -i -e "/server/s/^/#/" /etc/chrony.conf; \
                    sed -i -e "s/server 3\.centos\.pool\.ntp\.org iburst/server 3.centos.pool.ntp.org iburst\nserver 192.168.205.9 iburst\nport 0/" /etc/chrony.conf; \
                    sed -i -e "/HWADDR/s/^/#/" /etc/sysconfig/network-scripts/ifcfg-eth0; \
                    sed -i -e "/UUID/s/^/#/" /etc/sysconfig/network-scripts/ifcfg-eth0; \
                    sed -i -e "\$aDOMAIN=example.com" /etc/sysconfig/network-scripts/ifcfg-eth0;'
    done
```

必要パッケージのインストール。

```
for host in master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03;
    do ssh ${host} 'yum -y install wget git net-tools bind-utils yum-utils iptables-services bridge-utils bash-completion kexec-tools sos psacct'
    done
```

vda3 の作成。

```
for host in master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03;
    do ssh ${host} 'echo -e "n\np\n3\n\n\nt\n3\n8e\nw\n" | fdisk /dev/vda'
    done
```

再起動。

```
for host in master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03;
    do ssh ${host} 'reboot'
    done
```

docker のインストール。

```
for host in master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03;
    do ssh ${host} 'vgcreate docker-vg /dev/vda3; \
                    yum -y install docker-1.13.1; \
                    rpm -V docker-1.13.1; \
                    echo "VG=docker-vg" > /etc/sysconfig/docker-storage-setup; \
                    docker-storage-setup; \
                    systemctl start docker; \
                    systemctl enable docker;'
    done
```

master のみ追加パッケージ。

```
for host in master-01 \
    master-02 \
    master-03;
    do ssh ${host} "yum -y install centos-release-gluster httpd-tools"
    done
```

ローカルリポジトリを構築した場合は以下も実行。

```
for host in master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03;
    do ssh ${host} 'yum -y install yum-plugin-priorities; \
                    echo -e "[local]\nname=Local Repo\nbaseurl=http://192.168.205.8/repo\ngpgcheck=0\npriority=1" > /etc/yum.repos.d/local.repo; \
                    yum clean all;'
    done
```

### 4-2-3. gfs のセットアップ
**[ansible-01]**
yum update

```
for host in gfs-01 \
    gfs-02 \
    gfs-03 \
    gfs-04 \
    gfs-05 \
    gfs-06;
    do ssh ${host} 'yum -y update'
    done
```

firewalld, chrony, ifcfg-eth0, SELinux の設定。

```
for host in gfs-01 \
    gfs-02 \
    gfs-03 \
    gfs-04 \
    gfs-05 \
    gfs-06;
    do ssh ${host} 'nmcli c mod eth0 connection.zone internal; \
                    firewall-cmd --set-default-zone=internal; \
                    firewall-cmd --permanent --zone=internal --add-rich-rule="rule family="ipv4" source address="192.168.205.0/27" accept"; \
                    firewall-cmd --zone=internal --remove-service=mdns --permanent; \
                    firewall-cmd --zone=internal --remove-service=samba-client --permanent; \
                    firewall-cmd --zone=internal --remove-service=dhcpv6-client --permanent; \
                    sed -i -e "/server/s/^/#/" /etc/chrony.conf; \
                    sed -i -e "s/server 3\.centos\.pool\.ntp\.org iburst/server 3.centos.pool.ntp.org iburst\nserver 192.168.205.9 iburst\nport 0/" /etc/chrony.conf; \
                    sed -i -e "/HWADDR/s/^/#/" /etc/sysconfig/network-scripts/ifcfg-eth0; \
                    sed -i -e "/UUID/s/^/#/" /etc/sysconfig/network-scripts/ifcfg-eth0; \
                    sed -i -e "\$aDOMAIN=example.com" /etc/sysconfig/network-scripts/ifcfg-eth0; \
                    setsebool -P virt_sandbox_use_fusefs on; \
                    setsebool -P virt_use_fusefs on;'
    done
```

GlusterFS のインストール。

```
for host in gfs-01 \
    gfs-02 \
    gfs-03 \
    gfs-04 \
    gfs-05 \
    gfs-06;
    do ssh ${host} 'yum -y install centos-release-gluster; \
                    yum -y install glusterfs-server gluster-block; \
                    systemctl enable glusterd; \
                    systemctl enable gluster-blockd;'
    done
```

logrotate の設定の編集。
一度GlusterFS のログが数GB で吐かれていて/ パーティションの使用率が100% に達していたことがあったので、とりあえず日単位でファイルを分けるようにする。

```
for host in gfs-01 \
    gfs-02 \
    gfs-03 \
    gfs-04 \
    gfs-05 \
    gfs-06;
    do ssh ${host} 'sed -i -e "s/weekly/daily/" /etc/logrotate.d/glusterfs;'
done
```

vda3 の作成。

```
for host in gfs-01 \
    gfs-02 \
    gfs-03 \
    gfs-04 \
    gfs-05 \
    gfs-06;
    do ssh ${host} 'echo -e "n\np\n3\n\n\nt\n3\n8e\nw\n" | fdisk /dev/vda'
    done
```

再起動。

```
for host in gfs-01 \
    gfs-02 \
    gfs-03 \
    gfs-04 \
    gfs-05 \
    gfs-06;
    do ssh ${host} 'reboot'
    done
```

### 4-2-4. 起動確認とバックアップ
**[ansible-01]**
全てactive と表示されるか確認。 

```
for host in master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03;
    do ssh ${host} "systemctl is-active docker;"
    done
```
```
for host in gfs-01 \
    gfs-02 \
    gfs-03 \
    gfs-04 \
    gfs-05 \
    gfs-06;
    do ssh ${host} "systemctl is-active glusterd; systemctl is-active gluster-blockd;"
    done
```

ここまでできたらOpenShift 動作仮想マシーンをshutdown してディスクイメージファイルのバックアップを取ること強く推奨する。
OpenShift をアンインストールして再インストールする場合、アンインストールが失敗してゴミが残ったり成功しても色々必要なものまで消してくれるので、仮想マシーンのディスクイメージファイルごと差し替えるのが一番確実。

一括shutdown する場合は以下を実行。

```
for host in lb-01 \
    master-01 \
    master-02 \
    master-03 \
    infra-01 \
    infra-02 \
    infra-03 \
    node-01 \
    node-02 \
    node-03 \
    gfs-01 \
    gfs-02 \
    gfs-03 \
    gfs-04 \
    gfs-05 \
    gfs-06;
    do ssh ${host} 'shutdown -h now'
    done
```

# 5. OpenShift のインストール
## 5-1. インストール
**[ansible-01]**

OpenShift のAnsible yaml をダウンロード。

```
git clone https://github.com/openshift/openshift-ansible
cd openshift-ansible
git checkout release-3.9
```

yaml ファイルの編集。
2018/10/12 に確認したところ修正されているようである。
したがって、ここでの修正は必要無いが念の為記事には残しておく。

```yaml:roles/openshift_storage_glusterfs/templates/v3.9/glusterfs-storageclass.yml.j2
resturl: "http://{% if glusterfs_heketi_is_native %}{{ glusterfs_heketi_route }}{% else %}{{ glusterfs_heketi_url }}:{{ glusterfs_heketi_port }}{% endif %}"
↓
resturl: "http://{% if glusterfs_heketi_is_native %}heketi-{{ glusterfs_name }}.{{ glusterfs_namespace }}.svc.cluster.local:8080{% else %}{{ glusterfs_heketi_url }}:{{ glusterfs_heketi_port }}{% endif %}"
```

```yaml:roles/openshift_storage_glusterfs/templates/v3.9/gluster-block-storageclass.yml.j2
resturl: "http://{% if glusterfs_heketi_is_native %}{{ glusterfs_heketi_route }}{% else %}{{ glusterfs_heketi_url }}:{{ glusterfs_heketi_port }}{% endif %}"
↓
resturl: "http://{% if glusterfs_heketi_is_native %}heketi-{{ glusterfs_name }}.{{ glusterfs_namespace }}.svc.cluster.local:8080{% else %}{{ glusterfs_heketi_url }}:{{ glusterfs_heketi_port }}{% endif %}"
```

inventory ファイルの作成。
内部レジストリーのサイズはopenshift_hosted_registry_storage_volume_size の値で変える。

```text:inventory/hosts
[masters]
master-0[1:3].example.com

[etcd]
master-0[1:3].example.com

[nodes]
master-0[1:3].example.com
infra-0[1:3].example.com openshift_node_labels="{'region': 'infra', 'zone': 'default', 'node-role.kubernetes.io/infra': 'true'}"
node-0[1:3].example.com openshift_node_labels="{'region': 'primary', 'zone': 'default'}"

[lb]
console.example.com

[glusterfs]
gfs-04.example.com glusterfs_ip=192.168.205.24 glusterfs_devices='[ "/dev/vda3" ]'
gfs-05.example.com glusterfs_ip=192.168.205.25 glusterfs_devices='[ "/dev/vda3" ]'
gfs-06.example.com glusterfs_ip=192.168.205.26 glusterfs_devices='[ "/dev/vda3" ]'

[glusterfs_registry]
gfs-01.example.com glusterfs_ip=192.168.205.21 glusterfs_devices='[ "/dev/vda3" ]'
gfs-02.example.com glusterfs_ip=192.168.205.22 glusterfs_devices='[ "/dev/vda3" ]'
gfs-03.example.com glusterfs_ip=192.168.205.23 glusterfs_devices='[ "/dev/vda3" ]'

[OSEv3:children]
masters
nodes
etcd
lb
glusterfs
glusterfs_registry

[OSEv3:vars]
ansible_user=root
ansible_become=yes
os_firewall_use_firewalld=true
openshift_deployment_type=origin
openshift_release=v3.9
openshift_master_default_subdomain=app.example.com
openshift_master_cluster_method=native
openshift_master_cluster_hostname=console.example.com
openshift_master_cluster_public_hostname=console.example.com
openshift_master_logging_public_url=https://kibana.example.com
openshift_disable_check=memory_availability,disk_availability,package_version,docker_image_availability
openshift_docker_options="--insecure-registry=172.30.0.0/16 --selinux-enabled --log-opt max-size=1M --log-opt max-file=3"
openshift_router_selector="region=infra"
openshift_enable_service_catalog=true
ansible_service_broker_install=false
debug_level=2
openshift_master_dynamic_provisioning_enabled=true

# registry
openshift_hosted_registry_replicas=3
openshift_hosted_registry_selector="region=infra"
openshift_hosted_registry_storage_kind=glusterfs
openshift_hosted_registry_storage_volume_size=64Gi

# CNS storage for applications
openshift_storage_glusterfs_is_native=false
openshift_storage_glusterfs_namespace=app-glusterfs
openshift_storage_glusterfs_name=storage
openshift_storage_glusterfs_storageclass=true
openshift_storage_glusterfs_block_deploy=false

openshift_storage_glusterfs_heketi_is_native=true
openshift_storage_glusterfs_heketi_executor=ssh
openshift_storage_glusterfs_heketi_ssh_port=22
openshift_storage_glusterfs_heketi_ssh_user=root
openshift_storage_glusterfs_heketi_ssh_sudo=false
openshift_storage_glusterfs_heketi_ssh_keyfile="/root/.ssh/id_rsa"

# CNS storage for OpenShift infrastructure 
openshift_storage_glusterfs_is_native=false 
openshift_storage_glusterfs_registry_namespace=infra-glusterfs
openshift_storage_glusterfs_registry_name=registry
openshift_storage_glusterfs_registry_block_deploy=true
openshift_storage_glusterfs_registry_block_storageclass=true
openshift_storage_glusterfs_registry_block_storageclass_default=true

openshift_storage_glusterfs_registry_heketi_is_native=true
openshift_storage_glusterfs_registry_heketi_executor=ssh
openshift_storage_glusterfs_registry_heketi_ssh_port=22
openshift_storage_glusterfs_registry_heketi_ssh_user=root
openshift_storage_glusterfs_registry_heketi_ssh_sudo=false
openshift_storage_glusterfs_registry_heketi_ssh_keyfile="/root/.ssh/id_rsa"
```

事前確認。
標準出力をログとして保存しながら行うことを推奨。
エラーが出たらログを見て該当箇所を修正する。
エラーが出なくなるまで繰り返す。

```
ansible-playbook -i inventory/hosts playbooks/prerequisites.yml -vvv
```

インストール。
標準出力をログとして保存しながら行うことを推奨。

```
ansible-playbook -i inventory/hosts playbooks/deploy_cluster.yml -vvv
```

エラーが出たらバックアップしたOpenShift 動作仮想マシーンに差し戻して問題箇所を修正し、prerequisites.yml の実行からやり直す。
差し戻さずにdeploy_cluster.yml をやり直してもうまくいかない。

## 5-2. ユーザー作成
**[master-01]**
アカウントを作成。

```
htpasswd -b -c /etc/origin/master/htpasswd <user> <password>
```

作成したユーザーに管理者権限を付ける。

```
oadm policy add-cluster-role-to-user cluster-admin <user>
```

## 5-3. HA Proxy の設定
**[lb-01]**
HA Proxy の設定を追記。
port = 80, 443 へのアクセスをinfra-01, 02, 03 に転送する設定の追記。

```config:/etc/haproxy/haproxy.cfg
frontend  router-http
    bind *:80
    default_backend router-http
    mode tcp
    option tcplog

backend router-http
    balance source
    mode tcp
    server      router1 192.168.205.14:80 check
    server      router2 192.168.205.15:80 check
    server      router3 192.168.205.16:80 check

frontend  router-https
    bind *:443
    default_backend router-https
    mode tcp
    option tcplog

backend router-https
    balance source
    mode tcp
    server      router1 192.168.205.14:443 check
    server      router2 192.168.205.15:443 check
    server      router3 192.168.205.16:443 check
```

HA Proxy を再起動

```
systemctl restart haproxy
```

## 5-4. 確認
https&#58;//console.example.com:8443
にアクセスして作成したアカウントでログインできるか確認。

## 5-5. metrics, logging のインストール
**[master-01]**
inventory ファイルにmetrics とlogging のインストール定義を追記。

```text:inventory/hosts
# metrics
openshift_metrics_install_metrics=true
openshift_metrics_hawkular_nodeselector={"region":"infra"}
openshift_metrics_cassandra_nodeselector={"region":"infra"}
openshift_metrics_heapster_nodeselector={"region":"infra"} 
openshift_metrics_cassandra_pvc_size=8Gi
openshift_metrics_storage_kind=dynamic
openshift_metrics_cassanda_pvc_storage_class_name=glusterfs-registry-block
openshift_metrics_hawkular_hostname=hawkular-metrics.example.com
openshift_metrics_image_version=latest

# logging
openshift_logging_install_logging=true
openshift_logging_es_cluster_size=3  
openshift_logging_es_nodeselector={"region":"infra"}
openshift_logging_kibana_nodeselector={"region":"infra"}
openshift_logging_curator_nodeselector={"region":"infra"}
openshift_logging_storage_kind=dynamic
openshift_logging_es_pvc_size=8Gi   
openshift_logging_es_pvc_dynamic=true
openshift_logging_es_pvc_storage_class_name=glusterfs-registry-block
openshift_logging_image_version=latest
```

metrics とlogging それぞれのインストール用Playbook を実行。

```
ansible-playbook -i inventory/hosts playbooks/openshift-metrics/config.yml -vvv
ansible-playbook -i inventory/hosts playbooks/openshift-logging/config.yml -vvv
```

metrics とlogging それぞれopenshift-infra, logging というプロジェクトに専用のコンテナがデプロイされる。
しかし、本記事の内容の最終確認のために投稿直前に全てのインストール作業を実施してみたところ両方共コンテナのデプロイに失敗してしまった。少し前はmetrics は成功したのだが。
この2つは無くても自前のアプリケーションのデプロイと動作には影響無い。

アンインストールする場合は以下を実施する。

```
ansible-playbook -i inventory/hosts playbooks/openshift-metrics/config.yml -e openshift_metrics_install_metrics=false
ansible-playbook -i inventory/hosts playbooks/openshift-logging/config.yml -e openshift_logging_install_logging=false
```

# まとめ
KVM 上のCentOS7 の仮想マシーンという枯れたインフラ上にOpenShift をインストールできた。
metrics とlogging の確実なインストール方法は不明だが、無くても動くのでこのまま自作アプリケーションのデプロイを続ける。
metrics とlogging の正しいインストール方法がわかる人がいれば教えて欲しい。

[後編はこちら](https://qiita.com/t-eno/items/fd9329369478b8dd818e)

# 参考
[Prerequisites](https://docs.okd.io/3.9/install_config/install/prerequisites.html)
[Host Preparation](https://docs.okd.io/3.9/install_config/install/host_preparation.html)
[Advanced Installation](https://docs.okd.io/3.9/install_config/install/advanced_install.html)
[Persistent Storage Using GlusterFS](https://docs.okd.io/3.9/install_config/persistent_storage/persistent_storage_glusterfs.html#install-config-persistent-storage-persistent-storage-glusterfs)
[Container-native storage 3.9](https://redhatstorage.redhat.com/2018/03/28/container-native-storage-3-9/)
[Use service name for heketi url](https://github.com/openshift/openshift-ansible/pull/9122/commits/475bf46d7f6643c52fe5c4772e494b3bcd584945)
[Metrics for OpenShift Origin 3.9 fails due to incorrect image tags](https://github.com/openshift/origin/issues/19440)