LoginSignup
5
5

More than 5 years have passed since last update.

AnsibleでIaaSにKubernetesを自動デプロイする

Last updated at Posted at 2018-05-28

はじめに

構成管理ツールとAPIを使ってIaaS環境にKubernetes環境一式を自動デプロイし、プライベート・クラウド環境を構築します。構成管理ツールは、Ansibleを使います。デプロイ先となるIaaSは、IBM Cloud IaaSとします。IBM Cloud IaaSは、APIが公開されていますので、SL API (SoftLayer API Python Client)を使ってIaaS部分の管理を自動化します。Kubernetesは、IBM版Kubernetesである、IBM Cloud Private(以下、ICP)のCommunity Edition(無料)を用います。ソースコードは、GithubのDeploy IBM Cloud Privateをご確認ください。AnsibleだけでなくVagrant、Terrraformといったバージョンもあります。

IaaS構成

システム構成は下図のとおりです。MacbookをICPのBoot Node(Ansibleベースのインストーラー)として、IaaS側の4台の仮想サーバーにMaster node (icp-master01)、Proxy node (icp-proxy01)、Worker node (icp-worker01, icp-worker02)をオーダーした上でICPを自動デプロイしています。インバウンド/アウトバウンド通信については、セキュリティ・グループの機能で必要なIPアドレスとポート番号を許可しておきます。

image.png

事前準備

MacbookのターミナルにIBM Cloud Privateのリポジトリーをクローンします。

$ git clone https://github.com/IBM/deploy-ibm-cloud-private.git

クローンしたリポジトリーに移動します。

$ cd deploy-ibm-cloud-private
$ ls
Cachefile       ansible.cfg     extensions      requirements.txt
LICENSE         camQuick.sh     hosts           terraform
README.md       cluster         images
Vagrantfile     docs            playbooks

pipコマンドでSL CLIとAnsibleをセットアップします。

$ sudo pip install -r requirements.txt
$ cat requirements.txt
softlayer
ansible

SL CLIのバージョンは以下のとおりです。

$ slcli --version
slcli (SoftLayer Command-line), version 5.3.1

Ansibleのバージョンは以下のとおりです。

$ ansible --version
ansible 2.5.3
...

SL CLIに資格情報をセットアップします。対話形式で必要な項目を入力していきます。

$ slcli config setup
Username [XXXXX@XX.ibm.com]:
API Key or Password [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]:
Endpoint (public|private|custom) [public]:
Timeout [0]:
:..............:..................................................................:
:         name : value                                                            :
:..............:..................................................................:
:     Username : XXXXX@jp.ibm.com                                              :
:      API Key : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX :
: Endpoint URL : https://api.softlayer.com/xmlrpc/v3.1/                           :
:      Timeout : not set                                                          :
:..............:..................................................................:
Are you sure you want to write settings to "/Users/asasaki/.softlayer"? [Y/n]:

仮想サーバーにパスワードなしでログインするためにSSH鍵を作成します。

$ ssh-keygen -f cluster/ssh_key -P ""
Generating public/private rsa key pair.
Overwrite (y/n)? y
Your identification has been saved in cluster/ssh_key
Your public key has been saved in cluster/ssh_key.pub

作成したSSH鍵をSoftLayerに追加します。

$ slcli sshkey add -f cluster/ssh_key.pub icp-key

icp-keyという名前のSSH鍵がIBM Cloud IaaSに登録されていることを確認します。

$ slcli sshkey list               
:........:....................:.................................................:.......:
:   id   :       label        :                   fingerprint                   : notes :
:........:....................:.................................................:.......:
: XXXXXXX :    icp-key     : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX :   -   :
:........:....................:.................................................:.......:

デプロイ先となるVLANのIDを確認します。

$ slcli vlan list
:.........:........:......................:..........:............:..........:.................:............:
:    id   : number :         name         : firewall : datacenter : hardware : virtual_servers : public_ips :
:.........:........:......................:..........:............:..........:.................:............:
: XXXXXXX :  XXXX  :                      :    No    :   tok02    :    0     :        0        :     0      :
:.........:........:......................:..........:............:..........:.................:............:

Ansibleによる仮想サーバーのデプロイ

Ansibleでは、Playbookと呼ばれるYAML形式のテキスト・ファイルに実行したいタスクを記述します。それをAnsibleで実行させることにより、インフラの構成管理を自動化することができます。ここでは、AnsibleのPlaybookを使用して、ICPのデプロイ先となるIBM Cloud IaaSの仮想サーバーをデプロイします。

デプロイ先のデータセンター名(ここではtok02)とさきほど確認したVLANのIDを使用して、Ansibleで利用するYAMLファイルcluster/config.yamlsl_datacentersl_vlanの2つの変数を構成ファイルにセットします。

cluster/config.yaml
$ cat cluster/config.yaml
network_type: calico
network_cidr: 192.168.0.0/16
service_cluster_ip_range: 192.168.0.0/24
ingress_enabled: true
ansible_user: root

mesos_enabled: false
install_docker_py: true

sl_datacenter: tok02
sl_ssh_key: XXXXXXX
sl_vlan: XXXXXXX

sl_icp_masters:
  - icp-master01

sl_icp_workers:
  - icp-worker01
  - icp-worker02

sl_icp_proxies:
  - icp-proxy01

次に、実際に仮想サーバーを作成するPlaybookcreate_sl_vms.ymlの内容を確認します。内部的にさきほど設定したcluster/config.yamlが呼び出されていることが分かります。cpus: 2 memory: 8192 disks: [100]といった変数で、ICPを構成する各ノードのスペックを指定することができます。

create_sl_vms.yml
$ cat playbooks/create_sl_vms.yml
---
- name: create servers
  hosts: localhost
  gather_facts: False

  tasks:
    - name: Include cluster vars
      include_vars:
        file: ../cluster/config.yaml
    - name: create master
      sl_vm:
        hostname: "{{ item }}"
        domain: example.com
        datacenter: "{{ sl_datacenter|default('dal09') }}"
        tags: "{{ item }},icp,master"
        hourly: True
        private: False
        dedicated: False
        local_disk: True
        cpus: 2
        memory: 8192
        disks: [100]
        os_code: UBUNTU_LATEST
        private_vlan: "{{ sl_vlan|default(omit) }}"
        wait: no
        ssh_keys: "{{ sl_ssh_key|default(omit) }}"
      with_items: " {{ sl_icp_masters }}"

    - name: create workers
      sl_vm:
        hostname: "{{ item }}"
        domain: example.com
        datacenter: "{{ sl_datacenter|default('dal09') }}"
        tags: "{{ item }},icp,worker"
        hourly: True
        private: False
        dedicated: False
        local_disk: True
        cpus: 2
        memory: 4096
        disks: [100]
        os_code: UBUNTU_LATEST
        private_vlan: "{{ sl_vlan|default(omit) }}"
        wait: no
        ssh_keys: "{{ sl_ssh_key|default(omit) }}"
      with_items: " {{ sl_icp_workers }}"

    - name: create proxies
      sl_vm:
        hostname: "{{ item }}"
        domain: example.com
        datacenter: "{{ sl_datacenter|default('dal09') }}"
        tags: "{{ item }},icp,proxy"
        hourly: True
        private: False
        dedicated: False
        local_disk: True
        cpus: 2
        memory: 4096
        disks: [100]
        os_code: UBUNTU_LATEST
        private_vlan: "{{ sl_vlan|default(omit) }}"
        wait: no
        ssh_keys: "{{ sl_ssh_key|default(omit) }}"
      with_items: " {{ sl_icp_proxies }}"

AnsibleからPlaybookplaybooks/create_sl_vms.ymlを実行してIBM Cloud IaaSに仮想サーバーをデプロイします。

$ ansible-playbook playbooks/create_sl_vms.yml

5-10分ほどで仮想サーバーのデプロイが完了します。

AnsibleによるOS構成

各仮想サーバーのOSにログインするためのSSH鍵を追加します。

$ ssh-add cluster/ssh_key

OSパラメータを設定するためのPlaybookprepare_sl_vms.ymlの内容を確認します。swapの無効化、Pythonなどのパッケージの追加、dnsmasq(プライベートDNSサーバ)の設定、Docker CEのインストールといったICPのインストールに必要な前提タスクが記述されていることを確認します。

prepare_sl_vms.yml
$ cat playbooks/prepare_sl_vms.yml
---
- name: ensure connectivity to all nodes
  hosts: all
  gather_facts: false
  pre_tasks:
    - name: Include cluster vars
      include_vars:
        file: ../cluster/config.yaml
    - name: check if python is installed
      raw: test -e /usr/bin/python
      register: python_installed
      changed_when: false
      failed_when: false
    - name: check if debian based OS
      raw: which apt-get
      register: is_ubuntu
      changed_when: false
      failed_when: false
    - name: install python
      raw: (apt-get -y update && apt-get install -y python)
      when: python_installed.rc != 0 and is_ubuntu.rc == 0
    - name: install python
      raw: (yum install -y python)
      when: python_installed.rc != 0 and is_ubuntu.rc != 0
  tasks:
    - name: ansible setup
      action: setup
      tags: ['ping']
  any_errors_fatal: true
  max_fail_percentage: 0

- name: bootstrap nodes
  hosts: all
  gather_facts: true
  tasks:
    - name: Include cluster vars
      include_vars:
        file: ../cluster/config.yaml

    - name: disable swap
      command: swapoff -a

    - name: install extra packages
      yum:
        name: "{{ item }}"
      with_items: [dnsmasq,vim, yum-utils,python-pip]
      when: ansible_os_family == 'RedHat'

    - name: install extra packages
      apt:
        name: "{{ item }}"
      with_items: [dnsmasq,vim,python-pip,nfs-common]
      when: ansible_os_family == 'Debian'

    - name: disable resolvconf updates
      command: resolvconf --disable-updates
      when: ansible_os_family == 'Debian'

    - name: add alternative dnsmasq resolv.conf
      lineinfile:
        line: "resolv-file=/etc/dnsmasq_resolv.conf"
        path: /etc/dnsmasq.conf
        regexp: "^#resolv-file="

    - name: add dns servers to /etc/dnsmasq_resolv.conf
      lineinfile:
        create: yes
        line: "nameserver {{ item }}"
        path: /etc/dnsmasq_resolv.conf
      with_items: [10.0.80.11, 10.0.80.12]

    - name: rewrite /var/run/resolvconf/resolv.conf
      lineinfile:
        create: yes
        line: "nameserver {{ item }}"
        path: /var/run/resolvconf/resolv.conf
        regexp: "nameserver {{ item }}"
        state: absent
      with_items: [10.0.80.11, 10.0.80.12, 127.0.0.1]

    - name: rewrite /var/run/resolvconf/resolv.conf
      lineinfile:
        line: "nameserver {{ primaryBackendIpAddress }}"
        path: /var/run/resolvconf/resolv.conf
        regexp: "nameserver {{ primaryBackendIpAddress }}"

    - name: remove /etc/hosts
      file:
        dest: /etc/hosts
        state: absent

    - name: add localhost to /etc/hosts
      lineinfile:
        create: yes
        line: 127.0.0.1 localhost
        path: /etc/hosts

    - name: add host to /etc/hosts
      lineinfile:
        line: "{{ hostvars[item]['primaryBackendIpAddress'] }} {{ hostvars[item]['hostname'] }} {{ hostvars[item]['ansible_fqdn'] }}"
        path: /etc/hosts
      with_items: "{{ groups['all'] }}"

    - name: enable / start dnsmasq
      service:
        name: dnsmasq
        state: started
        enabled: true

    - name: wait 60 seconds then restart dnsmasq
      shell: sleep 60; systemctl restart dnsmasq

    - block:
      - name: get Docker CE repo
        shell: yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
        args:
          creates: /etc/yum.repos.d/docker-ce.repo

      - name: install Docker CE
        yum:
          name: docker-ce
      when: ansible_os_family == "RedHat"

    - block:
      - name: Import Docker CE repository gpg key
        apt_key:
          url: https://download.docker.com/linux/ubuntu/gpg
          state: present
          id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
      - name: Add Docker CE repository
        apt_repository:
          repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
          state: present

      - name: Install Docker CE
        apt:
          name: docker-ce
          state: present
          update_cache: yes
      when: ansible_os_family == "Debian"

  any_errors_fatal: true
  max_fail_percentage: 0

- name: install icp
  hosts: master[0]
  gather_facts: true
  tasks:
    - name: Include cluster vars
      include_vars:
        file: ../cluster/config.yaml

    - name: create icp install dir
      file:
        dest: /root/cluster
        state: directory

    - name: Copy icp files up
      copy:
        src: ../cluster
        dest: /root/

    - name: set perms on hosts script
      file:
        dest: /root/cluster/hosts
        mode: 0755

    - name: Build installer image
      command: docker build -t icp-on-sl /root/cluster

    - name: Run the following command to deploy IBM Cloud Private
      debug:
        msg: "ssh {{ ansible_user }}@{{ hostvars[groups['master'][0]]['primaryIpAddress'] }} docker run -e SL_USERNAME=<SL_USERNAME> -e SL_API_KEY=<SL_API_KEY> -e LICENSE=accept --net=host --rm -t -v /root/cluster:/installer/cluster icp-on-sl install"

Playbook (prepare_sl_vms.yml)を実行します。

$ ansible-playbook -i hosts playbooks/prepare_sl_vms.yml

※dnsmasqが原因でエラーになることがありますが、Playbookを再度実行すると通常は解決されます。もしくはマスター・ノードでdnsmasqを再起動することで解決されることもあります。

ICPコンテナのインストール

仮想サーバーにログインして、Dockerコマンドを使いICPコンテナicp-on-slをインストールします。

$ cat ~/.softlayer

$ ssh root@XXX.XXX.XXX.XXX docker run -e SL_USERNAME=XXXXX -e SL_API_KEY=XXXXX -e LICENSE=accept --net=host \
   --rm -t -v /root/cluster:/installer/cluster icp-on-sl install
...

10分ほどでICPコンテナのインストールが完了します。

ICPコンソールへのアクセス

ProxyノードのパブリックIPアドレスを確認し、ブラウザからhttps://<Proxy Node Public IP>:8443/にアクセスしてコンソールが表示されることを確認します。

Screen Shot 2018-05-27 at 00.54.29-fullpage.png

Screen Shot 2018-05-27 at 00.56.42-fullpage.png

IBM Cloud Privateのコンソールが表示されることを確認します。

ICP初期設定

[Menu] > [Tools] > [Command line]をオープンします。右側にある[Download For Mac OS X]よりThe IBM Cloud Private CLIをダウンロードします。

Screen Shot 2018-05-29 at 10.31.18-fullpage.png

MacbookでIBM Cloud CLI (bxコマンド)がインストールされていることを確認します。

$ bx --version
bx version 0.6.7+283a906f-2018-05-14T23:39:23+00:00

IBM Cloud CLIがインストールされていない場合は、こちらを参考に別途インストールしてください。

bx plugin installコマンドでダウンロードしたicp-darwin-amd64をインストールします。

$ bx plugin install /<path_to_installer>/icp-darwin-amd64
バイナリーをインストールしています...
OK
プラグイン 'icp 2.1.239' は /Users/asasaki/.bluemix/plugins/icp に正常にインストールされました。 'bx plugin show icp' を使用して詳細を表示してください。

The IBM Cloud Private CLI (以下、ICP CLI)がインストールされていることを確認します。

$ bx pr help
名前:
   bx pr - IBM Cloud Private Service
使用法:
   bx pr command [arguments...] [command options]

コマンド:
   api                View the API endpoint and API version for the service.
   cluster-config     Download the Kubernetes configuration and configure kubectl for a specified cluster.
   cluster-get        クラスターの詳細を表示します
   clusters           List all the clusters in your account.
...

デプロイしたICPのマスター・ノードにログインします。

$ bx pr login -a https://<master_ip_address>:8443 --skip-ssl-validation
 Login method invokedAPI endpoint: https://169.56.28.254:8443

Username> admin

Password>
Authenticating...
OK

Select an account:
1. ICP Account (3c43bf7207a6932a043f2eabc6002d70)
Enter a number> 1
Targeted account: ICP Account (3c43bf7207a6932a043f2eabc6002d70)

MacbookのプラグインリストにICP CLIがインストールされていることを確認します。

$ bx plugin list
インストール済みプラグインをリストしています...

プラグイン名         バージョン
IBM-Containers       1.0.1028
container-registry   0.1.292
container-service    0.1.488
icp                  2.1.239

サービスのAPIエンドポイントとAPIバージョンを表示します。

$ bx pr api

API エンドポイント:   https://<Master Node IP Address>:8443/api
API バージョン:       v1
SSL 検証のスキップ:   tru

Kubernetes設定をダウンロードし、指定されたクラスタに対してkubectlを設定します。

$ bx pr cluster-config mycluster
Configuring kubectl: /Users/asasaki/.bluemix/plugins/icp/clusters/mycluster/kube-config
Cluster "master.cfc" set.
Context "master.cfc-context" modified.
User "master.cfc-user" set.
Context "master.cfc-context" modified.
Switched to context "master.cfc-context".

OK
Cluster mycluster configured successfully.

クラスタの詳細を表示します。

$ bx pr cluster-get mycluster
Retrieving cluster mycluster...
OK

Name:           mycluster
ID:         00000000000000000000000000000001
State:          deployed
Created:        2018-05-29T01:46:29+0000
Datacenter:     default
Master URL:     https://<Master Node IP Address>:8001
Masters:        1
Workers:        3

アカウント内のすべてのクラスタを一覧表示します。

$ bx pr clusters
OK
Name        ID                                 State      Created                    Masters   Workers   Datacenter
mycluster   00000000000000000000000000000001   deployed   2018-05-29T01:46:29+0000   1         3         default

以上

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5