Kubernetes1.6のkubeadmでのデプロイをメモっておく

コンテナはDockerで、ネットワークはCalicoで組んでいる。

全台

名前解決できるようにしておく必要がある

まず/etc/hostsとか設定しておく。

パッケージインストー

# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://yum.kubernetes.io/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
        https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

# setenforce 0
# sed -i 's/enforcing/permissive/g' /etc/selinux/config

# systemctl stop firewalld
# systemctl disable firewalld

# yum install -y docker ebtables kubeadm kubectl kubelet kubernetes-cni

cgroupのドライバ的なものを指定

# systemctl enable docker && systemctl start docker

# mkdir /var/log/kubelet
# CGROUP_DRIVER=$(docker info 2>/dev/null | grep "Cgroup Driver" | awk '{print $3}')
# echo $CGROUP_DRIVER
    systemd
# sed -i "s|KUBELET_KUBECONFIG_ARGS=|KUBELET_KUBECONFIG_ARGS=--cgroup-driver=$CGROUP_DRIVER --enable-cri=false --logtostderr=false --log-dir=/var/log/kubelet |g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

DNSサーバのIPをデフォルト値から変更

# sed -i 's/10.96.0.10/10.3.3.10/g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

オーバーレイFSのモジュールをロード

# sudo tee /etc/modules-load.d/overlay.conf <<-'EOF'
overlay
EOF

# sed -e '$ a STORAGE_DRIVER="overlay"' -i /etc/sysconfig/docker-storage-setup

# reboot
# lsmod | grep overlay

カーネルパラメータをいじる

# sysctl -w net.bridge.bridge-nf-call-iptables=1

# sed -e '$ a net.bridge.bridge-nf-call-iptables=1' -i /etc/sysctl.conf

kubeletサービス起動

# systemctl enable kubelet && systemctl start kubelet

このタイミングでは下記のエラーでkubeletが起動できず、再起動を繰り返す状態になるらしい。
kubeadmがkubeletを起動するので、問題ないとのこと。

error: failed to run Kubelet: invalid kubeconfig: stat /etc/kubernetes/kubelet.conf: no such file or directory


マスター

クラスタを初期化

# kubeadm init --pod-network-cidr=10.1.0.0/16 --service-cidr=10.3.3.0/24 --apiserver-advertise-address=192.168.66.26  

--pod-network-cidr
→各ミニオンに払い出されるIPネットワークのプール。
   各ミニオンは、払い出されたセグメントの中から各PodへIPを払い出す。

--service-cidr
→VIP用を払い出す為にキープされるセグメント。

--apiserver-advertise-address
→kube-apiserverがAPIを待ち受けるIP。
  このオプションがないと、デフォゲのインタフェースでkube-apiserverを待機させてしまうらしい。  

処理の最後に下記みたいな表示が出るので、メモっておく。

kubeadm join --token <token> <master-ip>:<master-port>

確認してみる。

# sudo cp /etc/kubernetes/admin.conf $HOME/
# sudo chown $(id -u):$(id -g) $HOME/admin.conf
# export KUBECONFIG=$HOME/admin.conf
# kubectl get nodes

# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: https://192.168.66.26:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

ネットワーク設定

CNIという抽象化レイヤが用意されている。
ここに、使いたいプラグインを食わせて、Podのネットワークを構成する。


Calicoを単体で使う

# wget http://docs.projectcalico.org/v2.1/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml

# sed -i "s@192.168.0.0/16@10.1.0.0/16@" calico.yaml
# sed -i "s@10.96.232.136@10.3.3.100@" calico.yaml

# kubectl apply -f calico.yaml


マスターとミニオンを一台で済ませる場合

デフォルトでは、セキュリティ上の理由から、クラスタはマスター上にポッドをスケジュールしないようになっている。
オールインワンで使いたいときは、マスターマシン上でポッドをスケジュールされるように設定する。

# kubectl taint nodes --all node-role.kubernetes.io/master-

出力は次のような感じ。

node "test-01" tainted
taint key="dedicated" and effect="" not found.
taint key="dedicated" and effect="" not found.


マスターと別個にミニオンノードをインストールする場合

マスターの手順と同様に、dockerとkubeletの起動までやったら、下記を実行。

[root@kube-minion16-1 ~]# kubeadm join --token トークン 192.168.66.26:6443 ←マスターのIP
[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.
[preflight] Running pre-flight checks
[discovery] Trying to connect to API Server "192.168.66.26:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.66.26:6443"
[discovery] Cluster info signature and contents are valid, will use API Server "https://192.168.66.26:6443"
[discovery] Successfully established connection with API Server "192.168.66.26:6443"
[bootstrap] Detected server version: v1.6.0
[bootstrap] The server supports the Certificates API (certificates.k8s.io/v1beta1)
[csr] Created API client to obtain unique certificate for this node, generating keys and certificate signing request
[csr] Received signed certificate from the API server, generating KubeConfig...
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"

Node join complete:
* Certificate signing request sent to master and response
  received.
* Kubelet informed of new secure connection details.

Run 'kubectl get nodes' on the master to see this machine join.
[root@kube-minion16-1 ~]#

Ansibleでmasterノードが冗長化されたKubernetes1.5環境をデプロイする

masterノードが冗長化されたKubernetes環境をデプロイするためのAnsibleプレイブックを書いた。

github.com

一応ローカルの環境では動いたので、大丈夫だと思う。。。


インベントリファイルhostsに複数masterホストを指定してmngipと一緒に書いておけば、それらで冗長化される。
フロントにNginxをロードバランサとして置く。
masterにはetcdクラスタとflanneldとkube-apiserverとkube-schedulerとkube-controller-managerが入る。


本当はKubernetes1.6でやりたかったけど、kubeadmから入れるとetcdの設定とかが見張られてて、いじれなかった。
kubeadmを使わずに入れれば良かったのかもしれないけど。。。 今後、ロールベースのシステムを管理していくのに、kubeadmが推奨されていくっぽいので、 kubeadmから無理に逸脱するのもあまり旨くないかなぁ、と思ってやめた。
いずれは1.6用に直そうと思う。


次は、Nginxを冗長化させるか、KubernetesのバックエンドにKeystoneを使うようにするか、Playbookを直していく。

Stateファイル配置場所について

確認バージョン:

マスター、ミニオンともに
# salt --version
  salt 2016.11.3 (Carbon)

gitでStateファイルを公開した場合、どうやってcloneしてきて使うのが良いのかよくわからなかった。


下記のように設定されているとして、

# tail /etc/salt/master
  log_level_logfile: info
  default_include: master.d/*.conf
  file_roots:
    base:
      - /srv/salt    ←ここ
  pillar_roots:
    base:
      - /srv/pillar


下記のようにデプロイして実行してみようとする。

# pwd
/srv/salt/

# git clone https://github.com/YasuhiroOsajima/salt_kubernetes.git

# cd salt_kubernetes

# pwd
/srv/salt/salt_kubernetes

# ls -l
total 16
-rw-r--r--. 1 root root 268 Apr  1 14:35 deploy_kube-master.sls
-rw-r--r--. 1 root root 231 Apr  1 14:36 deploy_kube-minion.sls
drwxr-xr-x. 2 root root  26 Apr  1 14:32 kube-defaults
drwxr-xr-x. 3 root root 130 Apr  1 14:20 kube-master
drwxr-xr-x. 3 root root 114 Apr  1 14:20 kube-minion
-rw-r--r--. 1 root root 138 Apr  1 14:20 README.md
-rw-r--r--. 1 root root 347 Apr  1 14:20 top.sls

この状態でStateを実行すると怒られる。

# salt -N 'kube-minion' state.sls deploy_kube-minion
kube-minion1:
    Data failed to compile:
----------
    No matching sls found for 'deploy_kube-minion' in env 'base'

調べたてみたけど、/etc/salt/masterに「default_top: xxx」の設定(だけでいいのか自信はない)が入ってない場合、Saltはデフォルトで「base」という環境へのデプロイだと判断してStateを解析し始めるっぽい。

/etc/salt/masterに書いた「file_roots:base:- /srv/salt」の部分が、/srv/saltの直下にあるファイルが「base」環境へのデプロイに使えることを示してるっぽい。

そして、file_rootsに定義した以外のディレクトリにあるStateファイルを実行しようとすると、 エラーになる。

# salt -N 'kube-minion' state.sls deploy_kube-minion
kube-minion1:
    Data failed to compile:
----------
    No matching sls found for 'deploy_kube-minion' in env 'base'  ←この部分

slsモジュールが、このStateファイルが「base」環境として実行していいものなのか、わからなかったのだと思われる。

で、いくつか試したところ下記のどちらかで対応できそう。

  1. file_rootsで定義したディレクトリの直下にシンボリックリンクを作る。

    # pwd
      /srv/salt/
    # ln -s salt_kubernetes/deploy_kube-master.sls deploy_kube-master.sls
    # ls -l
      total 4
      lrwxrwxrwx. 1 root root  38 Apr  1 14:37 deploy_kube-master.sls -> salt_kubernetes/deploy_kube-master.sls
      drwxr-xr-x. 6 root root 169 Apr  1 14:36 salt_kubernetes
      -rw-r--r--. 1 root root  43 Apr  1 14:23 top.sls
    
    # salt -N 'kube-minion' state.sls deploy_kube-master
    
  2. 環境を指定してslsモジュールを実行する。

    # pwd
      /srv/salt/
    
    # salt -N 'kube-minion' state.sls salt_kubernetes/deploy_kube-master saltenv=base
    

本来ならどんな使い方がいいのか、まだ良くわからないけれども、なんとか動かすことはできそう。

Saltマスターの鍵の削除忘れについて

確認バージョン:

マスター、ミニオンともに
# salt --version
  salt 2016.11.3 (Carbon)


Saltはマスター、ミニオンともに公開鍵を交換して認証する。
ミニオンを再インストールした時は鍵の再登録が必要。

# salt-key -d ミニオン名

このことは知ってたけれど、マスターの鍵のことを忘れてて、
マスターを再インストールした際にミニオンがジョブを受け付けてくれなくなってビビった。

salt-masterを再インストールした時に必要なこと

マスターを作り直すと下記のようにミニオンが応答しなくなる

# salt 'minion1' test.ping
  minion1:
      Minion did not return. [No response]


ミニオンで下記のログが出てる。

# tail /var/log/salt/minion  
   2017-03-28 02:36:12,418 [salt.crypt       ][ERROR   ][10371] The master key has changed, the salt master could have been subverted, verify salt master's public key
   2017-03-28 02:36:12,418 [salt.crypt       ][CRITICAL][10371] The Salt Master server's public key did not authenticate!
   The master may need to be updated if it is a version of Salt lower than 2015.5.10, or
   If you are confident that you are connecting to a valid Salt Master, then remove the master public key and restart the Salt Minion.
   The master public key can be found at:
   /etc/salt/pki/minion/minion_master.pub   ←これ消して再起動しろとのこと


ミニオンがマスターの公開鍵をキャッシュしてるので、それをいっぺん消してやる必要がある。
その後、 ミニオンを再起動する。

 salt-minionで
 # rm /etc/salt/pki/minion/minion_master.pub  ←マスターの鍵を削除
 # systemctl restart salt-minion


改めてジョブを発行してみる。

 salt-masterで
 # salt 'minion1' test.ping
   minion1:
       True

Saltについていまいまわかってること

いろいろ構築し始める前に、いまいまわかってる範囲でSalt(SaltStack)についてまとめる。

確認バージョン:

マスター、ミニオンともに
# salt --version
  salt 2016.11.3 (Carbon)


概要(なんとなくわかったこと)

  • Pythonで動いてる。

  • マスター上のtcp4505でZeroMQが待ってて、そこにミニオンが常時接続する。
    ミニオンはジョブをこのキューから受け取って実行する。
    ミニオンからの返答を受け取る為にマスターはtcp4506で待っている。
    ミニオンは結果を報告するときにこのポートに送信する。

  • Stateというものに対象ミニオンの状態の定義する。
    Pillarというものに変数を定義する。
    おのおのの保存場所のデフォルト値は /etc/salt/master
    file_roots:」と「pillar_roots:」という項目で場所を設定する。
    なんかお約束では /srv/saltと /srv/pillarらしい。

  • マスターと ミニオンは公開鍵認証している。
    ミニオンのプロセス起動時に マスターに対して公開鍵が送信される。
    マスター側がこの公開鍵を承認すると接続可能になる。
    ミニオンに対してジョブが送られたときに、マスターの公開鍵が送信されてミニオンに格納される。


とりあえず動かす

  • salt masterの作業

    # yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-1.el7.noarch.rpm
    # yum install salt-master
    # vim /etc/salt/master
      file_roots:
          base:
              - /srv/salt
      pillar_roots:
          base:
              - /srv/pillar
    
      default_include:
          master.d/*.conf   ← 今後はここに個別に設定ファイルを作る
    
    # systemctl start salt-master
    # systemctl enable salt-master
    
  • salt minionの作業

    # yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-1.el7.noarch.rpm
    # yum install salt-minion
    # vim /etc/salt/minion
      master: salt1   ← Saltマスターを指定
    
    # systemctl start salt-minion
    # systemctl enable salt-minion
    
  • Saltマスター側でミニオンの鍵の受諾

    # salt-key -L   ←マスターが認識している鍵の一覧
      Accepted Keys:
      Denied Keys:
      Unaccepted Keys:
      salt2        ←Unacceptedに入ってる
      Rejected Keys:
    
    # salt-key -A
      The following keys are going to be accepted:
      Unaccepted Keys:
      salt2
      Proceed? [n/Y] y
      Key for minion salt2 accepted.
    
    # salt-key -L
      Accepted Keys:
      salt2
      Denied Keys:
      Unaccepted Keys:
      Rejected Keys:
    
    # salt "*" test.ping   ←動作確認
      salt2:
          True
    


使い方

大きく二種類の使い方がある。

  1. モジュールを指定して実行。
    Saltに用意されているモジュールを単発で実行する場合は下記のようなコマンドを実行する。

     # salt '対象ミニオン' モジュール名.ファンクション名  
    


    ちなみに対象の指定方法は何パターンかある。

    • 「salt-key」コマンドで出てくるミニオン全部に対してジョブ発行。

       # salt '*' モジュール名.ファンクション名
      
    • ミニオンの内、名前がパターンに合っているものにジョブ発行。

       # salt 'hoge*' モジュール名.ファンクション名
      
    • SaltにはGrainsというミニオンから構成情報を収集して保持しておく為のモジュールがある。
      その構成情報から対象を絞り込んで対象ミニオンを指定する。

       # salt -G 'os:CentOS' モジュール名.ファンクション名
      
    • 正規表現で指定

       # salt -E 'hoge[0-9]' モジュール名.ファンクション名
      
    • 対象をリスト形式で指定

       # salt -L 'hoge1,hoge2' モジュール名.ファンクション名
      
    • AND条件とかもできる

       # salt -C 'G@os:CentOS and E@hoge[1-5]' モジュール名.ファンクション名
      

    例:ロードアベレージを確認

     # salt -L 'salt2' status.loadavg  ←対象をリスト形式で指定
       salt2:
           ----------
           1-min:
               0.0
           15-min:
               0.05
           5-min:
               0.01
    


2. SLSモジュールを指定してStateの内容を実行
 下の方の「シンプルなStateファイルの使い方 」以降を参照。


下記のコマンドで使えるモジュールを一覧表示できる。

# salt '*' sys.doc


ミニオンのグループ化の設定

Saltの対象ミニオンをいくつかにまとめてグループ名をつける。

# mkdir /etc/salt/master.d
# vim /etc/salt/master.d/nodegroups.conf
  nodegroups:
    group01: 'L@salt1,salt2'
    group02: 'E@salt[1-5]'
    group03: 'G@os:CentOS'

# systemctl restart salt-master
# salt -N 'group02' firewalld.list_services  ←こんな感じで「-N」で指定できる


シンプルなStateファイルの使い方

Stateファイルの拡張子は「.sls」。

# mkdir /srv/salt
# vim /srv/salt/default.sls
  install_wget:        ←wgetをインストールするジョブ
    pkg.installed:
      - name: wget

# salt "salt2" state.sls default    ←「state.sls」と Stateファイルを指定して実行する
  salt2:
  ----------
            ID: install_wget
      Function: pkg.installed
          Name: wget
        Result: True
       Comment: Package wget is already installed.
       Started: 04:40:00.117065
      Duration: 535.179 ms
       Changes:

  Summary
  ------------
  Succeeded: 1
  Failed:    0
  ------------
  Total states run:     1

確認してみる。

# salt "salt2" cmd.run 'rpm -q wget'
  salt2:
      wget-1.14-13.el7.x86_64


環境を一発でデプロイしたい場合

こんな感じらしい。

# vim /srv/salt/top.sls   ←てっぺんのStateファイル。「top.sls」は固定値。
  base:           ←「/etc/salt/master」の「file_roots:」で指定したenvironment。
    '*':           ←対象の指定。「'kube-master*'」とかにもできる。マッチしたとこが全部実行される。
      - default

下記でtop.slsの内容を対象ミニオンすべてに適用できる。
「base」の階層から複数セット記載しておけば、「開発環境用」とかデプロイするミニオンをわけられる。

# salt "*" state.apply saltenv=base   ←「top.sls」の中に書かれている内容を適用。
  salt2:
      ----------
      pkg_|-install_wget_|-wget_|-installed:   ←実行されたコマンド
          ----------
          __run_num__:
              0
          changes:
              ----------
          comment:
              Package wget is already installed.
          duration:
              557.722
          name:
              wget
          result:
              True
          start_time:
              04:48:49.113817


階層構造

StateもPillarも、下記のようにディレクトリを階層構造にできる。

/srv/salt/mysql/files/    ←ミニオンに転送するファイルの置き場がよく用意される
/srv/salt/mysql/client.sls
/srv/salt/mysql/map.jinja
/srv/salt/mysql/python.sls
/srv/salt/mysql/server.sls

# vim /srv/salt/top.sls
  base:
    'web*':
      - mysql.client
      - mysql.python
    'db*':
      - mysql.server


Stateのインクルード

複数のディレクトリにわかれてるStateとかをまとめて呼び出したりする。
git cloneとかでもらってきたStateを使うときとか。

# pwd
  /srv/salt

# ls -l
  drwxr-xr-x. 2 root root 40 Apr  1 12:46 testdir
  -rw-r--r--. 1 root root 45 Apr  1 12:47 test.sls

# cat testdir/test2.sls
  test_cmd1:
    cmd.run:
      - name: 'uname -n'

# cat testdir/test3.sls
  test_cmd2:
    cmd.run:
      - name: 'who -r'

# cat test.sls
  include:       ←ここでインクルードできる
    - testdir.test2
    - testdir.test3

# salt 'kube-minion1' state.sls test  ←てっぺんだけ呼び出せば全部実行される


Pillar

変数の定義の機能。AnsibleみたいにJINJA2を使ってるらしい。
定義の仕方は、Stateによく似ている。

# vim /srv/pillar/top.sls
  base:
    '*':
      - packages

# vim /srv/pillar/apache.sls
  {% if grains['os'] == 'CentOS' %}
  apache: httpd           ←キー:バリュー
  {% elif grains['os'] == 'Debian' %}
  apache: apache2
  {% endif %}

上みたいに定義した上で、Stateファイル中でこんな感じで使える。

# vim /srv/salt/top.sls
  base:
    '*':
      - packages

# vim /srv/salt/packages.sls
  apache:
    pkg.installed:
      - name: {{ pillar['apache'] }}   ←「pillar[キー]」でバリューを取り出せる

かなり手の込んだpillarオブジェクトを定義することもできる様子。 SALTSTACK社のベストプラクティスより。

# vim /srv/pillar/apache.sls
  apache:
    lookup:
      config:
        tmpl: salt://apache/files/httpd.conf ←「/srv/salt/apache/files/httpd.conf」に置いてあるファイル

# vim /srv/salt/apache/map.jinja
  {% set apache = salt['grains.filter_by']({ ←OSごとにまとめて「apache」の中に定義を入れる。
      'Debian': {
          'server': 'apache2',
          'service': 'apache2',
          'conf': '/etc/apache2/apache.conf',
      },
      'RedHat': {
          'server': 'httpd',
          'service': 'httpd',
          'conf': '/etc/httpd/httpd.conf',
      },
  }, merge=salt['pillar.get']('apache:lookup')) %}  ←apache.sls内の「lookup」の内容も読み込まれる。


# vim /srv/salt/apache/init.sls
  {% from "apache/map.jinja" import apache with context %} ←StateからJINJAファイルをインポート

  apache:
    pkg.installed:
      - name: {{ apache.server }}  ←ミニオンのOSを気にせずに指定できる。
    service.running:
      - name: {{ apache.service }}
      - enable: True

  apache_conf:
    file.managed:
      - name: {{ apache.conf }}  ←転送されてくるファイルの配置時の名前。
      - source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }} ←マスタ上のファイルが転送されてくる。
      - template: jinja
      - user: root
      - watch_in:
        - service: apache


ベストプラクティス

SALTSTACK社の提示してるもの。

https://docs.saltstack.com/en/latest/topics/best_practices.html


その他

なんかいろいろ便利コマンドがある様子。
使ったことはない。
SALTSTACK社のドキュメントにしこたま載ってる。
https://docs.saltstack.com/en/latest/contents.html

  • salt-cpコマンド
    ファイルを転送する

    # salt-cp '*' test1.txt /root/test1.txt
    
  • salt-cloudコマンド クラウドVMをつくる

    # vim /etc/salt/cloud.profiles
      fedora_rackspace:
        provider: my-rackspace-config
        image: Fedora 17
        size: 256 server
        script: bootstrap-salt
    
    # salt-cloud -p fedora_rackspace fedora_http_01
    

まずはKubernetesを立てる

とにもかくにもKubernetesを立てる。
自動化のためにSaltを選択。

いけるとこまで手元のALIENWAREノートPCで頑張る。
メモリ16GBでいけるとこまでいく。


確認バージョン:

# salt --version
  salt 2016.11.3 (Carbon)

# kubectl --version
  Kubernetes v1.5.2


まずはVagrant

PCにVirtualBoxを入れてVagrantを入れる。

作るVM下記。

名前 IPアドレス 備考
salt-master 192.168.66.21 Saltマスター用
kube-master1 192.168.66.22 Kubernetesマスター用
その内冗長構成にしたい
kube-minion1 192.168.66.24 Kubernetesミニオン
kube-minion2 192.168.66.25 Kubernetesミニオン


PCのどっかに下記のフォルダを作り、Vagrantfileを配置していく。

vagrant
  |- kube-master1
  |- kube-minion1
  |- kube-minion2
   - salt-master

下記のファイルを作っていく。

vagrant/salt-master/Vagrantfileファイル
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/centos-7.3"
  config.ssh.insert_key = false

  config.vm.provider "virtualbox" do |vb|
    vb.name = "salt-master"
    vb.memory = "1024"
  end

  config.vm.hostname = "salt-master"
  config.vm.network :forwarded_port, guest: 22, host: 2221, id: "ssh", auto_correct: true
  config.vm.network "private_network", ip: "192.168.66.21"
end

load "../yum_Vagrantfile" if File.exist?("../yum_Vagrantfile")
load "../cmd_Vagrantfile" if File.exist?("../cmd_Vagrantfile")
load "../salt_master_Vagrantfile" if File.exist?("../salt_master_Vagrantfile")
vagrant/kube-master1/Vagrantfileファイル
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/centos-7.3"
  config.ssh.insert_key = false

  config.vm.provider "virtualbox" do |vb|
    vb.name = "kube-master1"
    vb.memory = "2048"
  end

  config.vm.hostname = "kube-master1"
  config.vm.network :forwarded_port, guest: 22, host: 2222, id: "ssh", auto_correct: true
  config.vm.network "private_network", ip: "192.168.66.22"
end

load "../yum_Vagrantfile" if File.exist?("../yum_Vagrantfile")
load "../cmd_Vagrantfile" if File.exist?("../cmd_Vagrantfile")
load "../salt_minion_Vagrantfile" if File.exist?("../salt_minion_Vagrantfile")
vagrant/kube-minion1/Vagrantfileファイル

vagrant/kube-minion1/Vagrantfileもホスト名とIPアドレスとホストのポート以外は一緒)

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/centos-7.3"
  config.ssh.insert_key = false

  config.vm.provider "virtualbox" do |vb|
    vb.name = "kube-minion1"
    vb.memory = "2048"
  end

  config.vm.hostname = "kube-minion1"
  config.vm.network :forwarded_port, guest: 22, host: 2224, id: "ssh", auto_correct: true
  config.vm.network "private_network", ip: "192.168.66.24"
end

load "../yum_Vagrantfile" if File.exist?("../yum_Vagrantfile")
load "../cmd_Vagrantfile" if File.exist?("../cmd_Vagrantfile")
load "../salt_minion_Vagrantfile" if File.exist?("../salt_minion_Vagrantfile")
vagrant/yum_Vagrantfileファイル

好みでパッケージ入れる。

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: <<-SHELL
    yum update -y
    yum install -y net-tools sysstat iotop iftop vim tmux lsof bind-utils strace tcpdump psmisc wget git bash-completion
    cp /usr/share/doc/tmux-1.8/examples/vim-keys.conf /root/.tmux.conf
    sed -e '$ a set -g prefix C-g' -i /root/.tmux.conf
    sed -e '$ a unbind C-b' -i /root/.tmux.conf

    yum install -y epel-release
    yum clean all
  SHELL
end
vagrant/cmd_Vagrantfileファイル

叩いておきたいコマンドがあったらを書いておく。

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: <<-SHELL
    systemctl disable NetworkManager
  SHELL
end
vagrant/salt_master_Vagrantfileファイル
Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: <<-SHELL
    yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-1.el7.noarch.rpm
    yum clean all

    yum install -y salt-master
    sed -e '$ a log_level_logfile: info' -i /etc/salt/master

    sed -e '$ a default_include: master.d/*.conf' -i /etc/salt/master
    mkdir /etc/salt/master.d
    touch /etc/salt/master.d/nodegroups.conf
    echo -e "nodegroups:\\n  kube-master: 'kube-master*'\\n  kube-minion: 'kube-minion*'" > /etc/salt/master.d/nodegroups.conf

    sed -e "$ a file_roots:\\n  base:\\n    - /srv/salt" -i /etc/salt/master
    mkdir /srv/salt
    touch /srv/salt/top.sls
    touch /srv/salt/default.sls

    sed -e "$ a pillar_roots:\\n  base:\\n    - /srv/pillar" -i /etc/salt/master
    mkdir /srv/pillar
    touch /srv/pillar/top.sls
    touch /srv/pillar/default.sls

    systemctl start salt-master
    systemctl enable salt-master

    shutdown -r now
  SHELL
end
vagrant/salt_minion_Vagrantfileファイル
Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: <<-SHELL
    yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest-1.el7.noarch.rpm
    yum clean all

    yum install -y salt-minion
    sed -e '$ a master: salt-master' -i /etc/salt/minion
    sed -e '$ a 192.168.66.21 salt-master' -i /etc/hosts
    systemctl start salt-minion
    systemctl enable salt-minion
    shutdown -r now
  SHELL
end

salt-master -> kube-master1,kube-minion1,kube-minion2
の順で vagrant upして VM作る。


Kubernetes立てる

salt-masterで実行
salt-minionの公開鍵を承認。
# salt-key -L
# salt-key -A

# cat /etc/salt/master.d/nodegroups.conf
  nodegroups:
      kube-master: 'kube-master*'
      kube-minion: 'kube-minion*'

Saltでの疎通を確認
# salt -N 'kube-master' test.ping
  kube-master1:
      True


Stateファイルの配置

# cd /srv/salt/
# git clone https://github.com/YasuhiroOsajima/salt_kubernetes.git


デプロイ

# salt -N 'kube-master' state.sls salt_kubernetes/deploy_kube-master saltenv=base
# salt -N 'kube-minion' state.sls salt_kubernetes/deploy_kube-minion saltenv=base

デプロイされたか確認。
# salt "*" state.request


状況を確認

kube-master1で、

# kubectl get node
  NAME           STATUS     AGE
  kube-minion1   Ready      14m
  kube-minion2   Ready      13m

Saltを初めて使ったけど、Ansibleみたいに処理経過がコンソールに出てこないから、なんか怖い。
出るように設定できるのかもしれないけど、「Salt」で検索すると塩のことばかり引っかかってきて心が折れた。
「SaltStack」で検索しないといけないけど、ツール自体の名前は「Salt」なのよね、たしか。


次は Kubernetesに ReplicaSetを(また Saltから……)立てて、手始めに Tomcatの辺りから作っていきたいと思う。