Ansible
kubernetes
centos7
kubespray

CentOS7 kubespray で kubernetes(1.9) cluster を作る - その1 -

Overview

kubernetes のインストールにはKops, kubeadm など様々なツールがありますが
単にyum install kubeadmだけ叩けばよい、ような物でない。

私はAnsible使いなので、この手の類いをコマンド一発、みたいなことを試みるならば
kubespray を使うのが良さそう。ということでkubesprayを使った環境作りの記録を残します。

既にQiitaにも先人の知恵があり、こちらなどがそうなのですが
1年以上前の記事と言うことで大分勝手が変わっている様子。

https://qiita.com/albatross/items/7f472a973d0c04041a4d

ちなみに私もインストール環境は vSpere ESXiの上にCentOS(ただし、7.4) を入れてインストール環境を用意しました。

Scope of Work

  1. kubesprayを使ったkubernetes のインストール
  2. kube-dashboard の表示
  3. 後片付け

インストール環境

ホスト名 IPアドレス 別名 役割
k8master01.localdomain 192.168.240.175 k8master01 Master + Node + Etcd
k8master02.localdomain 192.168.240.169 k8master02 Master + Node + Etcd
k8node01.localdomain 192.168.240.160 k8node01 Node + Etcd
k8node02.localdomain 192.168.240.168 k8node02 Node
kargo.localdomain 192.168.240.185 N/A kubespray 実行ホスト

IPアドレスが連番では無いのは、用意した環境でIPアドレスが連番では無かったから。

基本方針

1. kubesprayを使ったkubernetes のインストール

Install host構築

下記、基本パッケージインストールと、python3(4)のインストールは
拙速のansible playbookを使うと一通りそろえるようになっている。
特にswap offは罠なので忘れるとインストールできないので注意が必要。
なお、まだREADMEもろくに書いていないがhostsファイルに対象が書いてあるので
そちらについては適宜修正のこと。

基本パッケージインストール

ansible をインストールすると jinja2は依存関係を解決してインストールされるとは思うが
CentOS7 の Jinja2 は 2.9より古いため、そのままではkubesprayのインストール段階でコケてしまう。
従ってここはpipでjinja2の最新を入れ直す。

# yum install -y epel-release
# yum install -y ansible git gcc python-pip python-devel python-netaddr libffi-devel openssl-devel
# pip install pip --upgrade
# pip install jinja2

python3 系のインストール

https://github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md#starting-custom-deployment

直接、ansible のInventoryファイルを理解した上で、編集できるのであれば不要だが、inventory generatorを使うのであれば
python3が必要なので、こちらを入れておく。

# yum install python34

kubespray の取得

自分向けに編集するならば以下を元に、編集しupstreamを取り込めるようにするとよい、とあるが
pushすると公開されちゃうから、込み入った情報は書くな!ともある他、一度作成したplaybookをupstramから
更にアップデート取得することはあまり考えられないので、単純にcheckoutとする。
https://github.com/kubernetes-incubator/kubespray/blob/master/docs/integration.md

 # git https://github.com/kubernetes-incubator/kubespray.git

inventory ファイルの編集

先ほどのIPアドレスに合わせてinventoryファイルを修正する。
直接編集してもよいが、自分用のinventoryを作るときは copy して my_inventoryを作れ、とあるので
そこはおとなしく従う。

 # cd kubespray-cli
 # cp -r inventory my_inventory
 # vi my_inventory/inventory.cfg

inventory.cfg

[all]
k8master01       ansible_host=192.168.240.169 ip=192.168.240.169
k8master02       ansible_host=192.168.240.175 ip=192.168.240.175
k8node01         ansible_host=192.168.240.160 ip=192.168.240.160
k8node02         ansible_host=192.168.240.168 ip=192.168.240.168

[kube-master]
k8master01
k8master02

[kube-node]
k8master01
k8master02
k8node01
k8node02

[etcd]
k8master01
k8master02
k8node01

[k8s-cluster:children]
kube-node
kube-master

[calico-rr]

[vault]
k8master01
k8master02
k8node01

[all:vars]
ansible_ssh_port=22
ansible_ssh_user=root
ansible_ssh_pass=ssh_password
ansible_sudo_pass=root_password

ssh はあらかじめキーを登録し、ログインできるようにしておく。
ansible playbook を見るとわかるが become が入っているので root 化は必須。
rootログインで入ってしまってもよいが、 sudo を仕込む方が本来は正しいと思う。
最後の4行はその辺りのおまじない。

kubenetes インストール

環境ファイルのIPアドレス修正が終わったら以下を実行するのみ。

 # ansible-playbook -i my_inventory/inventory.cfg cluster.yaml -v

以下のように全て通ればOK。

PLAY RECAP **********************************************************************************************************************************************************************************
k8master01                 : ok=349  changed=111  unreachable=0    failed=0   
k8master02                 : ok=307  changed=105  unreachable=0    failed=0   
k8node01                   : ok=269  changed=85   unreachable=0    failed=0   
k8node02                   : ok=226  changed=65   unreachable=0    failed=0   
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

Tuesday 30 January 2018  06:24:09 +0900 (0:00:00.035)       0:59:00.958 ******* 
=============================================================================== 
download : container_download | Download containers if pull is required or told to always pull (all nodes) ------------------------------------------------------------------------ 1034.29s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ------------------------------------------------------------------------- 484.70s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ------------------------------------------------------------------------- 262.40s
kubernetes/preinstall : Update package management cache (YUM) ---------------------------------------------------------------------------------------------------------------------- 228.95s
docker : ensure docker packages are installed -------------------------------------------------------------------------------------------------------------------------------------- 151.51s
download : container_download | Download containers if pull is required or told to always pull (all nodes) -------------------------------------------------------------------------- 99.80s
download : container_download | Download containers if pull is required or told to always pull (all nodes) -------------------------------------------------------------------------- 96.86s
download : container_download | Download containers if pull is required or told to always pull (all nodes) -------------------------------------------------------------------------- 73.80s
download : container_download | Download containers if pull is required or told to always pull (all nodes) -------------------------------------------------------------------------- 67.56s
download : container_download | Download containers if pull is required or told to always pull (all nodes) -------------------------------------------------------------------------- 65.78s
download : container_download | Download containers if pull is required or told to always pull (all nodes) -------------------------------------------------------------------------- 65.08s
download : container_download | Download containers if pull is required or told to always pull (all nodes) -------------------------------------------------------------------------- 56.23s
kubernetes/preinstall : Install packages requirements ------------------------------------------------------------------------------------------------------------------------------- 56.05s
etcd : Configure | Join member(s) to cluster one at a time -------------------------------------------------------------------------------------------------------------------------- 20.34s
etcd : Configure | Join member(s) to cluster one at a time -------------------------------------------------------------------------------------------------------------------------- 20.32s
kubernetes/secrets : Check certs | check if a cert already exists on node ----------------------------------------------------------------------------------------------------------- 18.30s
kubernetes/master : Master | wait for the apiserver to be running ------------------------------------------------------------------------------------------------------------------- 14.32s
kubernetes/node : install | Copy kubelet from hyperkube container ------------------------------------------------------------------------------------------------------------------- 12.19s
etcd : reload etcd ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 11.25s
docker : Docker | pause while Docker restarts --------------------------------------------------------------------------------------------------------------------------------------- 10.40s

kubernetes インストール後

kubernetes 環境の確認

セットアップが完了すると kubectl コマンドで様々な事ができる
まずは、状況の確認。

 # ssh k8master01
  • Version の確認
# kubectl version
Client Version: version.Info{Major:"", Minor:"", GitVersion:"v1.9.0+coreos.0", GitCommit:"1b69a2a6c01194421b0aa17747a8c1a81738a8dd", GitTreeState:"clean", BuildDate:"2017-12-19T02:52:15Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"", Minor:"", GitVersion:"v1.9.0+coreos.0", GitCommit:"1b69a2a6c01194421b0aa17747a8c1a81738a8dd", GitTreeState:"clean", BuildDate:"2017-12-19T02:52:15Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
  • Cluster info
 # kubectl cluster-info
Kubernetes master is running at https://192.168.240.169:6443
KubeDNS is running at https://192.168.240.169:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

[kubernetes の tutorial[(https://kubernetes.io/docs/tutorials/kubernetes-basics/cluster-interactive/)
を実行すると dashborad, grafana そして influxdb が動いていたりするので、kubespray の default は最小限で動作しているようだ

  • get node(s)
 # kubectl get nodes

NAME         STATUS    ROLES         AGE       VERSION
k8master01   Ready     master,node   56m       v1.9.0+coreos.0
k8master02   Ready     master,node   56m       v1.9.0+coreos.0
k8node01     Ready     node          56m       v1.9.0+coreos.0
k8node02     Ready     node          56m       v1.9.0+coreos.0

get node でも get nodes でも動作するようだ。

  • get namespace
 # kubectl get namespaces

NAME          STATUS    AGE
default       Active    57m
kube-public   Active    57m
kube-system   Active    57m
  • get pods all-namespaces
 # kubectl get pods --all-namespaces

NAMESPACE     NAME                                    READY     STATUS    RESTARTS   AGE
kube-system   kube-apiserver-k8master01               1/1       Running   0          56m
kube-system   kube-apiserver-k8master02               1/1       Running   0          56m
kube-system   kube-controller-manager-k8master01      1/1       Running   0          57m
kube-system   kube-controller-manager-k8master02      1/1       Running   0          57m
kube-system   kube-dns-6444ff8d8b-qdksn               3/3       Running   0          55m
kube-system   kube-dns-6444ff8d8b-xfhtp               3/3       Running   0          55m
kube-system   kube-flannel-4kf8n                      2/2       Running   0          56m
kube-system   kube-flannel-cfzjc                      2/2       Running   0          56m
kube-system   kube-flannel-gf584                      2/2       Running   0          56m
kube-system   kube-flannel-wk7cd                      2/2       Running   0          56m
kube-system   kube-proxy-k8master01                   1/1       Running   0          56m
kube-system   kube-proxy-k8master02                   1/1       Running   0          56m
kube-system   kube-proxy-k8node01                     1/1       Running   0          56m
kube-system   kube-proxy-k8node02                     1/1       Running   0          56m
kube-system   kube-scheduler-k8master01               1/1       Running   0          57m
kube-system   kube-scheduler-k8master02               1/1       Running   0          57m
kube-system   kubedns-autoscaler-58d9fbcbf6-lmm8c     1/1       Running   0          55m
kube-system   kubernetes-dashboard-75c5ff6844-wnnjv   1/1       Running   0          55m
kube-system   nginx-proxy-k8node01                    1/1       Running   0          56m
kube-system   nginx-proxy-k8node02                    1/1       Running   0          56m

テストサービスの作成

master ホストにログインし、実際にpodを建ててみる。
幸い、ちょうど良いサンプルが公開されているので sock-shopを使ってやってみる。

  • Create namespace
    • 後述のyamlを見るとわかるがnamespace指定があるので事前にnamespaceを作っておく
 # kubectl create namespace sock-shop
 # $ kubectl get namespace
NAME          STATUS    AGE
default       Active    1h
kube-public   Active    1h
kube-system   Active    1h
sock-shop     Active    4s
  • service pod の作成
 # kubectl create -f "https://github.com/microservices-demo/microservices-demo/blob/master/deploy/kubernetes/complete-demo.yaml?raw=true"
deployment "carts-db" created
service "carts-db" created
deployment "carts" created
service "carts" created
deployment "catalogue-db" created
service "catalogue-db" created
deployment "catalogue" created
service "catalogue" created
deployment "front-end" created
service "front-end" created
deployment "orders-db" created
service "orders-db" created
deployment "orders" created
service "orders" created
deployment "payment" created
service "payment" created
deployment "queue-master" created
service "queue-master" created
deployment "rabbitmq" created
service "rabbitmq" created
deployment "shipping" created
service "shipping" created
deployment "user-db" created
service "user-db" created
deployment "user" created
  • 進捗確認
 # kubectl get pod --namespace=sock-shop                                                                                                                                  
NAME                            READY     STATUS              RESTARTS   AGE
carts-74f4558cb8-d75ps          0/1       ContainerCreating   0          1m
carts-db-7fcddfbc79-6mk2z       0/1       ContainerCreating   0          1m
catalogue-676d4b9f7c-qzjpf      0/1       ContainerCreating   0          1m
catalogue-db-5c67cdc8cd-tqgtc   0/1       ContainerCreating   0          1m
front-end-977bfd86-6g49s        0/1       ContainerCreating   0          1m
orders-787bf5b89f-wdpvb         0/1       ContainerCreating   0          59s
orders-db-775655b675-jmm4l      0/1       ContainerCreating   0          59s
payment-75f75b467f-js97s        0/1       ContainerCreating   0          59s
queue-master-5c86964795-4pnn8   0/1       ContainerCreating   0          59s
rabbitmq-96d887875-vvx78        0/1       ContainerCreating   0          59s
shipping-5bd69fb4cc-tzw2f       0/1       ContainerCreating   0          59s
user-5bd9b9c468-jqs6s           0/1       ContainerCreating   0          59s
user-db-5f9d89bbbb-xz7s5        0/1       ContainerCreating   0          59s

これはまだ作成中。 STATUS が 全て Running になるまで待つ。

 # kubectl get pod --namespace=sock-shop
NAME                            READY     STATUS    RESTARTS   AGE
carts-74f4558cb8-d75ps          1/1       Running   0          20m
carts-db-7fcddfbc79-6mk2z       1/1       Running   0          20m
catalogue-676d4b9f7c-qzjpf      1/1       Running   0          20m
catalogue-db-5c67cdc8cd-tqgtc   1/1       Running   0          20m
front-end-977bfd86-6g49s        1/1       Running   0          20m
orders-787bf5b89f-wdpvb         1/1       Running   0          20m
orders-db-775655b675-jmm4l      1/1       Running   0          20m
payment-75f75b467f-js97s        1/1       Running   0          20m
queue-master-5c86964795-4pnn8   1/1       Running   0          20m
rabbitmq-96d887875-vvx78        1/1       Running   0          20m
shipping-5bd69fb4cc-tzw2f       1/1       Running   0          20m
user-5bd9b9c468-jqs6s           1/1       Running   0          20m
user-db-5f9d89bbbb-xz7s5        1/1       Running   0          20m

こうなったらOK。

  • フロントエンドのIPアドレス確認
 # kubectl describe service front-end -n sock-shop                                                                                                                        
Name:                     front-end
Namespace:                sock-shop
Labels:                   name=front-end
Annotations:              <none>
Selector:                 name=front-end
Type:                     NodePort
IP:                       10.233.33.80
Port:                     <unset>  80/TCP
TargetPort:               8079/TCP
NodePort:                 <unset>  30001/TCP
Endpoints:                10.233.111.195:8079
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
  • これでどのポートが公開されているのかがわかる。
    • NodePort -- 30001 がそれ

従って以下へアクセスすれば、sock-shopのデモが動いているのが確認できる。

http://192.168.240.175:30001

2. kube-dashboard の表示

kube-dashboard 状態確認

kubespray をインストールするとdashboardもインストールされる。
とはいえ、下記の通り内部にしかListenしていないのでそのままではアクセスできない。

 # kubectl -n kube-system get service kubernetes-dashboard
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes-dashboard   ClusterIP   10.233.24.184   <none>        443/TCP   19h

kube proxy の起動

kubernetes の状況を確認するツールとして Dashboard がある。
インストールされた時点で利用は可能でアクセスもできるのだが、
以下のような画面になり利用できない。

https://192.168.240.175:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login

kubernetes-dashboad-6443.png

API経由で表示しているだけなので、dashboardアクセスとは異なる様子。
従って proxy を起動して dashboard そのものを表示してやる。
下のコマンドよりは上のコマンドの方がよさそう。
accept-hosts でドメインやIPアドレスが指定できるならば細かく書いてやる方が良い。

 # kubectl proxy --address 0.0.0.0 --accept-hosts '.*'
  OR
 # kubectl proxy --address 0.0.0.0  --disable-filter=true

これで以下のURLを叩くとdash boardを見ることができる。

http://192.168.240.175:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login

kubernetes-dashboard-02.png

ちなみに accept-hosts や disable-filter を書けないと
アクセスはできてもやはり auth fail として何も表示されない。

kubernetes-dashboard-01.png

フルコントロールの付与

ただし、これでもまた権限不足で情報表示ができないため、以下の設定を入れてあけてやる。

 # kubectl create -f dashboard-admin.yaml

dashboard-admin.yaml は、以下の通り 公式ドキュメントをコピペして作る。
https://github.com/kubernetes/dashboard/wiki/Access-control#bearer-token

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
  labels:
    k8s-app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system

これを叩いてやるとログインの最初に出る以下の場所で SKIP としても
全ての情報が表示されるようになる。

kubernetes-dashboard-03.png

3. 後片付け

kubenetes master / node の削除

とりあえず一通り動いたと言うことで、環境の削除。
なぜならばサービスホストのIPアドレス空間など、インストール時に設定しておかなければ
後から修正できないような項目があるため。

 # ansible-playbook -i my_inventory/inventory.cfg reset.yaml -v

ハマりどころ

  • ansible がホストの環境パラメータを持ってしまう
    • /tmp/ として gather_info が記録されている。 これがあると、ホストの収集情報が更新されず、パラメータ不良を直しても幾度となくコケることになる。 retryの際には必ず、消してからやり直しましょう。

続き

今回はあくまで、インストールだけを主眼に置いているため
これさえやれば動く。というところしか書いていない。

Dashboardへのアクセス制御も極めてずさんなため、
次回以降で、細かくパラメータを見ていくことにする。