[01] オンプレ環境で VM 2台を使って 1マスタ・1ノードの kubernetes を構築してみる (VM構築)

# 概要

下表の構成で、オンプレ上に k8s を構築したときの記録である.
本記事では「**k8s を導入するための事前準備として 仮想PC (以降 VM) の構築まで**」を記す.

基本的には、https://github.com/takara9/vagrant-kubernetes にて
Ansible で実行していた処理を、手動で実行しているのみです.
(若干マニフェストを変更しています)

|No|用途|ノード名|形態|公開IP|内部IP|OS|備考|
|:--|:--|:--|:--|:--|:--|:--|:--|
|1|k8sマスタ|master01|VM|192.168.1.91|172.24.20.11|Ubuntu18.04||
|2|k8sノード|node01|VM|192.168.1.92|172.24.20.12|Ubuntu18.04||


# 参考にしたサイトおよび書籍

|URL|備考|
|:--|:--|
|[実践 Vagrant](https://www.oreilly.co.jp/books/9784873116655/)||
|[15Stepで習得 Dockerから入るKubernetes](http://www.ric.co.jp/book/contents/book_1161.html)|K8s だけでなく、Ansible, Vagrant, GlusterFS のことなども学べる.|
|https://github.com/takara9/vagrant-k8s|[『15Stepで習得 Dockerから入るKubernetes』](http://www.ric.co.jp/book/contents/book_1161.html)の著者が公開されている GitHub.<br/>Vagrant や Ansible コードを公開してくださっている.|
|https://github.com/takara9/vagrant-kubernetes|同上|
|https://github.com/takara9/codes_for_lessons|同上|
|https://nextpublishing.jp/book/12197.html|『解体kubeadm　フェーズから読み解くKubernetesクラスタ構築ツールの全貌』を参考にして 1マスタ・1ノードを構築した.|



# 環境

## 物理PC および 仮想PC の OS

```bash
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
```

## 物理PC

下記ソフトを導入済みであること.

- Vagrant 
- VirtualBox


# 手順

## 1. Vagrant と Ansible のファイルを配置する

Vagrant および Ansible のファイルは、
書籍『[15Stepで習得 Dockerから入るKubernetes](http://www.ric.co.jp/book/contents/book_1161.html)』を参考にさせてもらいました.
ありがとうございます.

```
.
|-- Vagrantfile
|-- ansible.cfg
|-- hosts
`-- playbook
    |-- install_master.yml
    |-- install_node.yml
    `-- kubernetes
        |-- defaults
        |   `-- main.yml
        `-- tasks
            `-- main.yml
```


### ファイルの中身


#### ./playbook/install_node.yml

```yaml
---
- name: Kubernetes base
  hosts: nodes
  gather_facts: true
  become: true
  roles:
    - kubernetes
```

#### ./playbook/install_master.yml

```yaml
---
- name: Kubernetes base
  hosts: master01
  gather_facts: true
  become: true
  roles:
    - kubernetes
```

#### ./playbook/kubernetes/tasks/main.yml

```yaml
# Master と Workerで共通のタスク
#- debug: msg="{{ ansible_facts }}"

##################################################
##  Docker CE のインストール
##################################################
################################################## Ubuntu
- name: Add Docker GPG key
  apt_key: url=https://download.docker.com/linux/ubuntu/gpg
  when:
    - ansible_facts.distribution == "Ubuntu"
- name: Add Docker APT repository
  apt_repository:
    repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ansible_distribution_release}} stable
  when:
    - ansible_facts.distribution == "Ubuntu"
- name: Install a list of packages
  apt:
    name: "{{ packages }}"
    state: present
    update_cache: yes
  vars:
    packages:
    - apt-transport-https
    - ca-certificates
    - curl
    - software-properties-common
    - nfs-common
    - docker-ce{{ docker_version_ubuntu }}
  when:
    - ansible_facts.distribution == "Ubuntu"
################################################### Ubuntu & CentOS    
- name: Add the user 'vagrant' with a specific uid and a primary group of 'docker'
  user:
    name: vagrant
    comment: docker exection user
    group: docker
- name: Start dockerd
  systemd:
    name: docker
    state: started
    enabled: yes
```

#### ./playbook/kubernetes/defaults/main.yml

```yaml
# default var file
---
# Docker Package Version
docker_version_ubuntu: =18.06.1~ce~3-0~ubuntu
```

#### ./hosts

```ini
master01   ansible_connection=local
node01     ansible_connection=local

[nodes]
node01
```

#### ./ansible.cfg

```ini
[defaults]
inventory = /home/vagrant/playbook/hosts
host_key_checking = no
log_path = ansible.log
interpreter_python = auto

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes
```

#### ./Vagrantfile

```ruby
# coding: utf-8
# -*- mode: ruby -*-
# vi: set ft=ruby :

linux_os = "ubuntu/bionic64"   # Ubuntu 18.04
#linux_os  = "generic/centos7"  # CentOS 7.7
bridge_if = "en0: Wi-Fi (Wireless)"

vm_spec = [
  { name: "master01", cpu: 2, memory: 2048,
    box: linux_os,
    private_ip: "172.24.20.11",
    public_ip: "192.168.1.91",
    storage: [], playbook: "install_master.yml",
    comment: "Master node" },

  { name: "node01", cpu: 4, memory: 8192,
    box: linux_os,
    private_ip: "172.24.20.12",
    public_ip: "192.168.1.92",
    storage: [], playbook: "install_node.yml",
    comment: "Worker node #1" },
]


Vagrant.configure("2") do |config|
  vm_spec.each do |spec|
    config.vm.define spec[:name] do |v|
      v.vm.box = spec[:box]
      v.vm.hostname = spec[:name]
      v.vm.network :private_network,ip: spec[:private_ip]
      #v.vm.network :public_network,ip:  spec[:public_ip], bridge: bridge_if
      v.vm.provider "virtualbox" do |vbox|
        vbox.gui = false
        vbox.cpus = spec[:cpu]
        vbox.memory = spec[:memory]
        i = 1
        spec[:storage].each do |vol|
          vdisk = "vdisks/sd-" + spec[:name] + "-" + i.to_s + ".vdi"
          if not File.exist?(vdisk) then
            if i == 1 then
              vbox.customize [
                'storagectl', :id,
                '--name', 'SATA Controller',
                '--add', 'sata',
                '--controller', 'IntelAHCI']
            end            
            vbox.customize [
              'createmedium', 'disk',
              '--filename', vdisk,
              '--format', 'VDI',
              '--size', vol * 1024 ]
          end
          vbox.customize [
            'storageattach', :id,
            '--storagectl', 'SATA Controller',
            '--port', i,
            '--device', 0,
            '--type', 'hdd',
            '--medium', vdisk]
          i = i + 1
        end
      end
      v.vm.synced_folder ".", "/vagrant", owner: "vagrant",
                            group: "vagrant", mount_options: ["dmode=700", "fmode=700"]

      v.vm.provision "ansible_local" do |ansible|
        ansible.playbook       = "playbook/" + spec[:playbook]
        ansible.verbose        = false #!
        ansible.install        = true
        ansible.limit          = spec[:name] 
        ansible.inventory_path = "hosts"
      end
    
      # v.vm.provision "shell", inline: <<-SHELL
      #   apt-get update
      #   apt-get install -y apache2
      # SHELL
    end
    config.ssh.forward_x11 = true
  end
end
```

## 2. VM を起動させる

```bash
$ vagrant up
```

VM 2台が running 状態であることを確認する

```bash
$ vagrant status
```

以上.