kubeadmでのk8sクラスタの構築　1/3

#はじめに
Kubernetes（に限らずだけど）を勉強するには、やはり実機環境でやってみると身につく。
minikubeだと簡単にできるけど色々制約あるし、クラウドのマネージドKubernetesサービスだと（無料枠もあるけど）お金がかかるので、PC上に仮想化環境を構築することにする。
今回は、Kubernetesを構築する環境の準備をする。

#構成概要
Windows PC（Windows10）上にVirtualboxで以下のVMを作ってk8sのクラスタを作っていく。
・master 2コア/3GBメモリ/20GB HDD
・worker01 2コア/3GBメモリ/20GB HDD
・worker02 2コア/3GBメモリ/20GB HDD
・gateway 1コア/2GBメモリ/10GB HDD

OSはすべてCentOS 7
色々半端な構成だけど、PCのスペック上これが限界。

master/workerはvirtualboxの内部ネットワークのみとして、gateway経由でインターネットと接続する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/9fb62af2-19a6-4137-07bf-ce6035f8119c.png)


gatewayにはvirtualboxのNATインターフェイスにポートフォワーディングの設定をしておいて、TeratermでSSH接続できるようにする。
各クラスタノードにはgatewayを経由して接続して操作することにする。

※まずはgatewayとmasterのみ構築して、workerノードはクローンで作ることにする。

#gatewayの設定
kubernetesとは直接関係ないけど、各クラスタのノードがリポジトリにアクセスするために、gatewayにDNSとルーティングを設定する。
##DNSの設定
###bindのインストール
sudoするのがめんどくさいので、rootで実行。

```
# yum install -y bind
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
・・・省略・・・
依存性関連をインストールしました:
  python-ply.noarch 0:3.4-11.el7

完了しました!
```
###bindの設定
/etc/named.confの編集
以下のように編集する。

```/etc/named.conf
//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
// See the BIND Administrator's Reference Manual (ARM) for details about the
// configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html

options {
#       listen-on port 53 { 127.0.0.1; };
#       listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { localhost; 10.20.30.0/24;};

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        recursion yes;

        dnssec-enable no;
        dnssec-validation no;

        /* Path to ISC DLV key */
        bindkeys-file "/etc/named.root.key";

        managed-keys-directory "/var/named/dynamic";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "my.net" IN {
        type master;
        file "my.net.zone";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
```
/var/named/my.net.zoneファイルの作成

```/var/named/my.net.zone
$TTL    86400

@       IN      SOA     my.net root.my.net    (
        2016050204
        3600
        900
        604800
        86400
)

@               IN      NS      k8s-client
k8s-client      IN      A       10.20.30.100
k8s-master      IN      A       10.20.30.10
k8s-worker01    IN      A       10.20.30.20
k8s-worker02    IN      A       10.20.30.30
```

###設定の確認

```
# named-checkconf
# named-checkzone my.net /var/named/my.net.zone
zone my.net/IN: loaded serial 2016050204
OK
```

###firewallの設定
```
# firewall-cmd --add-service=dns --permanent
success
# firewall-cmd --reload
success
```

###namedの起動
```
# systemctl enable named
Created symlink from /etc/systemd/system/multi-user.target.wants/named.service to /usr/lib/systemd/system/named.service.
# systemctl start named
```
###クラスタノード（master）の設定
nameserverとして、gatewayサーバのIPアドレスを指定する。

```/etc/resolv.conf
search my.net
nameserver 10.20.30.100
```


参考：https://www.hiroom2.com/2016/05/02/centos-7%E3%81%ABbind%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6%E5%86%85%E9%83%A8%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E5%90%91%E3%81%91%E3%81%ABdns%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%92%E3%82%8B/

#ルーティングの設定
gatewayサーバをルーターにして、masterと各workerノードからインターネットに接続できるようにする。
##/etc/hostsファイルの設定（全サーバ）
各サーバの名前解決ができるように/etc/hostsファイルに書いておく。

```factor:/etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

10.20.30.10 k8s-master
10.20.30.20 k8s-worker01
10.20.30.30 k8s-worker02

10.20.30.30 k8s-client
```

##デフォルトゲートウェイの設定（master）
デフォルトゲートウェイをgatewayにする。

```
# nmcli c modify enp0s3 ipv4.gateway 10.20.30.100
```
インターフェイスを再起動する。

```
# nmcli c down enp0s3
# nmcli c up enp0s3
```

念のため、ネットワークも再起動する。

```
# systemctl restart network
```

ルーティングテーブルの確認

```
# ip route
default via 10.20.30.100 dev enp0s3 proto static metric 100
10.20.30.0/24 dev enp0s3 proto kernel scope link src 10.20.30.10 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
```
##IPフォワードの設定（gateway）
/etc/sysctl.confに以下を追記する。

```
net.ipv4.ip_forward = 1
```
反映する。

```
# sysctl -p
net.ipv4.ip_forward = 1
```

##iptablesの設定（gateway）
以下のシェルスクリプトを作成して、実行権を付けてから実行する。

```iptables.sh
#!/bin/bash

/sbin/iptables -A FORWARD -i enp0s3 -o enp0s8 -s 10.20.30.0/255.255.255.0 -j ACCEPT
/sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -t nat -A POSTROUTING -o enp0s8 -s 10.20.30.0/255.255.255.0 -j MASQUERADE

/sbin/iptables -A INPUT -p tcp --dport 53 -j ACCEPT
/sbin/iptables -A INPUT -p udp --dport 53 -j ACCEPT
```
このままだと、再起動すると設定が消えるので、cronで起動時にこのスクリプトを実行するようにした。

```
# crontab -l
@reboot         /root/iptables.sh
```

##疎通確認（master）
masterサーバからインターネットに接続できることを確認する。

```
# ping yahoo.co.jp
PING yahoo.co.jp (183.79.135.206) 56(84) bytes of data.
64 bytes from f1.top.vip.kks.yahoo.co.jp (183.79.135.206): icmp_seq=1 ttl=46 time=25.7 ms
64 bytes from f1.top.vip.kks.yahoo.co.jp (183.79.135.206): icmp_seq=2 ttl=46 time=21.5 ms
64 bytes from f1.top.vip.kks.yahoo.co.jp (183.79.135.206): icmp_seq=3 ttl=46 time=25.7 ms
^C
--- yahoo.co.jp ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2170ms
rtt min/avg/max/mdev = 21.515/24.344/25.768/2.004 ms
```
マスターサーバからgatewayを経由して、インターネット（ここではyahoo）にpingが飛ぶことを確認。

参考：http://toriaezu-engineer.hatenablog.com/entry/2017/01/22/081545

#おまけ
このあと、マスターサーバのパッケージをアップデートしようとしたが、以下のメッセージが出て失敗。

```
# yum update
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was
14: curl#7 - "Failed to connect to 2604:1580:fe02:2::10: ネットワークに届きません"
・・・
```

色々調べたけど、不明なので最後はFirewallを無効化した。
本当は必要なポートのみを許可すべきなんだろうけど、この後のkubernetesのインストールでもポートを開けたりが必要になってくるので、無効化で対応。
このあたりは、後で復習しよう。。。

```
# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since 月 2020-02-24 14:15:26 JST; 3min 42s ago
     Docs: man:firewalld(1)
・・・
# systemctl stop firewalld.service
# systemctl disable firewalld.service
# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
```
Firewallを無効化し、パッケージをアップデート

```
# yum -y update
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.jaist.ac.jp
 * extras: ftp.jaist.ac.jp
 * updates: ftp.jaist.ac.jp
base                                                                                                                               | 3.6 kB  00:00:00
extras                                                                                                                             | 2.9 kB  00:00:00
updates                                                                                                                            | 2.9 kB  00:00:00
(1/4): base/7/x86_64/group_gz
・・・
```

#まとめ
結局、kubernetesの構築まで行かず事前準備だけでだいぶ長くなったので、続きは次回にする。
やっぱりネットワークは難しいなと。

#続き
[kubeadmでのk8sクラスタの構築　2/3](https://qiita.com/dingtianhongjie/items/a3707c3443d8f6b1d8f5)
[kubeadmでのk8sクラスタの構築　3/3](https://qiita.com/dingtianhongjie/items/c906b52154c6d501c107)