KubernetesをCentOS7 複数台(AWS EC2)へインストール

kubernetesをAWS EC2のCentOS7にインストールしてみた。

Master１台、Worker(Minion)２台の計３台構成パターン。

※AWS用のセットアップスクリプトが提供されている(http://kubernetes.io/v1.1/docs/getting-started-guides/aws.html) が、ここでは手動でトライ。

※１台のみにインストールする方法は以下参照
http://qiita.com/suzukihi724/items/4e120fdc66b014cfa972

参考
http://qiita.com/HommaHomma/items/3b83c6cc5a09980e0d85


##1.AWS EC2でCentOS7インスタンス起動
CentOS7インスタンスは、AWS Marketplaceから指定する
https://www.youtube.com/watch?v=_tWa5cIhO-k

CentOS7インスタンスは、ユーザ名がec2-userではなくcentosになっているので注意。
t2-micro1の場合メモリ不足の可能性があるため、t2-largeにしてみた。

##2.kubernetes/docker/etcd/flannelをインストール

`sudo yum update -y`

`sudo yum install -y docker`

dockerを起動

`sudo systemctl start docker`

以下のようなエラーが出た場合は、libdevmapperをインストール後再実行

```
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
```

`sudo yum -y install libdevmapper.so.1.02`


次にkubernetesなどをインストール

`sudo yum install -y kubernetes etcd flannel`

※etcdはmaster nodeのみでOK

##3.hostsファイル修正（全クラスタ共通）

`sudo vi /etc/hosts`


```
172.31.25.XX master
172.31.25.XX minion1
172.31.25.XX minion2
```
※IPアドレスは適宜変更。今回はMaster１台、Minion２台の計３台構成パターン


##4.Master Nodeの設定

(1)/etc/kubernetes/configの編集

`sudo vi /etc/kubernetes/config`

KUBE_MASTER=に、hostsファイルで定義したmaster nodeのホスト名を記載

`KUBE_MASTER="--master=http://master:8080"`


(2)kube-apiserver設定（/etc/kubernetes/apiserverの編集）

`sudo vi /etc/kubernetes/apiserver`


```
KUBE_API_ADDRESS="--address=0.0.0.0"
KUBE_API_PORT="--port=8080"
KUBE_ETCD_SERVERS="--etcd_servers=http://master:2379"
```
※KUBE_ETCD_SERVERS=に、hostsファイルで定義したmaster nodeのホスト名を記載

※KUBE_ADMISSION_CONTROL=のServiceAccountを削除


例

```
###
# kubernetes system config
#
# The following values are used to configure the kube-apiserver
#

# The address on the local server to listen to.
KUBE_API_ADDRESS="--address=0.0.0.0"

# The port on the local server to listen on.
KUBE_API_PORT="--port=8080"

# Port minions listen on
# KUBELET_PORT="--kubelet_port=10250"

# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd_servers=http://master:2379"

# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"

# default admission control policies
KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"

# Add your own!
KUBE_API_ARGS=""
```




(3)controller-manager設定（/etc/kubernetes/controller-manager を編集）
`sudo vi /etc/kubernetes/controller-manager`

以下を追記
`KUBELET_ADDRESSES="--machines=master,minion1,minion2"`
※machine名はhostsファイルで規定したホスト名

(4)ETCD設定（/etc/etcd/etcd.conf を編集）

`sudo vi /etc/etcd/etcd.conf`

```
ETCD_LISTEN_PEER_URLS="http://localhost:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
```

(5)Flannel設定
Flannelは、ホストを跨いでのコンテナ間通信を可能にする仮想ネットワーク(サブネット)を形成する。単一ホスト上でのクラスタ形成では不要。
Config情報の格納場所としてetcdを利用する。
https://github.com/coreos/flannel/blob/master/README.md

①/etc/sysconfig/flanneldを編集

`sudo vi /etc/sysconfig/flanneld`

```
# Flanneld configuration options

# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD="http://master:2379"

# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_KEY="/flannel/network"

# Any additional options that you want to pass
FLANNEL_OPTIONS="eth0"
```

②configファイルを作成

`sudo vi /root/flannel-config.json`

```
{
 "Network": "10.100.0.0/16",
 "SubnetLen": 24,
 "SubnetMin": "10.100.50.0",
 "SubnetMax": "10.100.199.0",
 "Backend": {
 "Type": "vxlan",
 "VNI": 1
 }
}
```

etcdにflannel設定（jsonファイル）を反映する（etcdのapiで）
まずはetcdを起動
`sudo systemctl start etcd`

`sudo curl -L http://master:2379/v2/keys/flannel/network/config -XPUT --data-urlencode value@/root/flannel-config.json`


etcd apiで設定が反映されていることを確認できる

`http://<etcdノードIP：port>/v2/keys/<key名>`

例）
`curl -L http://master:2379/v2/keys/flannel/network`

https://coreos.com/etcd/docs/0.4.7/etcd-api/

(6) 各種サービスの起動

```
#!/sh/bin

for SERVICES in docker etcd kube-apiserver kube-controller-manager kube-scheduler flanneld; do  
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES 
done
```


##5.Minion Nodeの設定

(1) docker kubernetes flannelをインストール

`sudo yum update -y`

`sudo yum -y install docker kubernetes flannel`


(2) /etc/hostsファイルを編集
※全ノード共通

(3) flannelファイルを編集

`sudo vi /etc/sysconfig/flanneld`

Master設定 4(5)と同じ

```
# Flanneld configuration options

# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD="http://master:2379"

# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_KEY="/flannel/network"

# Any additional options that you want to pass
FLANNEL_OPTIONS="eth0"
```

(4) kubelet設定

`sudo vi /etc/kubernetes/kubelet`

```
###
# kubernetes kubelet (minion) config

# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=0.0.0.0"

# The port for the info server to serve on
KUBELET_PORT="--port=10250"

# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME=""

# location of the api-server
KUBELET_API_SERVER="--api_servers=http://master:8080"

# Add your own!
KUBELET_ARGS=""
```

(5) 各種サービス起動

```
#!/sh/bin

for SERVICES in kube-proxy kubelet docker flanneld; do 
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES 
done
```

(6) Minion Nodeを増やす
この設定をしたNodeを作成して各サービスを実行すると、ETCDを通じてMasterノード側でMinionを検知してくれる。

１台Minionの設置アップをしたらAMIイメージを作成しておき、そのAMIを元にインスタンスを作成すると、Minionの量産が容易。

①全ノードのhostsファイルの更新
②Masterノードでcontroller-manager設定（新minion追加）
③新規追加したノードで各サービスを起動


##6.動作確認

正常にkuberクラスタが起動され、ホスト間の連携ができていれば、masterにて以下のコマンドを実行すると、minionノードを認識できる。
何も表示されない場合は、上記設定を再度見直すか、AWSのEC2のセキュリティポリシー等の設定を確認する。

```
$ kubectl get nodes
NAME              LABELS                                   STATUS    AGE
ip-172-31-28-50   kubernetes.io/hostname=ip-172-31-28-50   Ready     30s
```
(1)masterノードでサンプルpodを作成する

`$kubectl create -f sample.yaml`

サンプルpod(sample.yaml)

```
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
      ports:
      - containerPort: 80
```

(2)podの稼働状況確認

```
$ kubectl get pod
NAME        READY     STATUS    RESTARTS   AGE
nginx-pod   1/1       Running   0          3h
```

podの稼働ノードを調べる
※get podの引数にpod NAMEと-oを指定。出力形式はyamlかjsonで指定可能

```
$ kubectl get pod nginx-pod -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: 2016-02-15T07:32:25Z
  name: nginx-pod
  namespace: default
  resourceVersion: "7101"
  selfLink: /api/v1/namespaces/default/pods/nginx-pod
  uid: 426e8595-d3b6-11e5-a2a4-066cb91d9daf

　（省略）

    lastState: {}
    name: nginx-container
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2016-02-15T07:32:45Z
  hostIP: 172.31.31.79
  phase: Running
  podIP: 172.17.0.1
  startTime: 2016-02-15T07:32:25Z
```

podIPのIPアドレスと、pod作成時のyamlで指定したポート(80)で稼働している。
上記では、hostIP172.31.31.79のminion上で、
`curl http://172.17.0.1:80/`
を実行すると、レスポンスが返ってくる。

別なpodを新たに作成すると、複数のMinionノードが有る場合、1Podづつ分散実行される。