概要
Kubernetesを使ってDockerのクラスタを構築します。Kubernetesを使うことで以下のような本番環境を意識したシステムを構築できます。
- フェイルオーバー(コンテナが異常終了したことを検知し再起動させる)
- スケーリング(起動しているコンテナの数を自由に変更できる)
- ロードバランス(複数のコンテナにリクエストを振り分けて負荷分散する)
- サービスディスカバリ(サービスへのルーティングを自動で提供する)
この構築は長いので記事自体も複数に分けて進めます。
アーキテクチャ
コンポーネント名 | 説明 |
---|---|
apiserver | kubernetesを操作するためのAPIを提供する |
controller-manager | コンテナの状態管理やノードの管理と言った各種管理作業を行う |
kube-proxy | コンテナへのネットワークルーティングおよび負荷分散を行う |
scheduler | 各ノードに対しコンテナの割り当てなどを行う |
kubelet | 各ノード上でのコンテナ作成/削除やボリュームの割り当てなどを行う |
kubectl | API経由でKubenetesを操作するためのクライアントツール |
図に表すと以下です。
ref: Introduction to Kubernetes Architecture
また各ホストは以下の役割とします。
ホスト名 | IP | 役割 |
---|---|---|
master | 192.168.33.10 | マスターノード |
node1 | 192.168.33.100 | 子ノード |
node2 | 192.168.33.101 | 子ノード |
環境
今回は各ツールのパッケージが全て提供されているCentOS7で構築します。
事前準備
簡単のため各サーバのファイアウォールとSELinuxを無効化します。
# systemctl disable firewalld
SELinuxの修正
# vim /etc/sysconfig/selinux ・・・ SELINUX=permissive ・・・
また各ホスト名もユニークである必要があるので、/etc/hostname
を上記の表の通りに変更します。
最後に/etc/hosts
にホスト名とIPを紐付けます。そうでないとkubeletがホスト名からIPを取得できません。
完了したら再起動します。
# reboot
マスターノードの設定
主に必要なパッケージは以下です。
- docker
- kubernetes-master
- kubernetes-client
- etcd
- flannel
上記のパッケージを以下のコマンドでインストールします。
# yum install etcd kubernetes flannel
dockerサービスの自動起動化をします。
# systemctl start docker # systemctl enable docker
etcdの設定
/etc/etcd/etcd.conf
ETCD_NAME=default ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="http://localhost:2380" ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_LISTEN_CLIENT_URLS
、ETCD_ADVERTISE_CLIENT_URLS
がlocalhostのままだと他のノードがアクセス出来ないので変更します。
起動&自動起動設定をします。
# systemctl start etcd # systemctl enable etcd
Kubernetesの設定
/etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=0" KUBE_ALLOW_PRIV="--allow-privileged=false" KUBE_MASTER="--master=http://192.168.33.10:8080"
KUBE_MASTER
をマスターサーバのIPにします。
/etc/kubernetes/apiserver
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0" KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.33.10:2379" KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota" KUBE_API_ARGS=""
KUBE_API_ADDRESS
を0.0.0.0に設定、KUBE_ETCD_SERVERS
をマスターサーバのIPに変更します。
完了したらサービスを起動します。
# for SERVICES in kube-apiserver kube-controller-manager kube-scheduler; do \ systemctl restart $SERVICES && \ systemctl enable $SERVICES; done
動作確認します。
# curl -s -L http://192.168.33.10:8080/version { "major": "1", "minor": "2", "gitVersion": "v1.2.0", "gitCommit": "738b7603b042dcda7a5ba419ab0e7f40a617080c", "gitTreeState": "clean" }
ポートも確認します。
# ss -untlp | grep -E "kube|etcd" tcp LISTEN 0 128 192.168.33.10:2379 *:* users:(("etcd",pid=2466,fd=6)) tcp LISTEN 0 128 127.0.0.1:2380 *:* users:(("etcd",pid=2466,fd=5)) tcp LISTEN 0 128 192.168.33.10:8080 *:* users:(("kube-apiserver",pid=2514,fd=31)) tcp LISTEN 0 128 :::10251 :::* users:(("kube-scheduler",pid=2568,fd=13)) tcp LISTEN 0 128 :::10252 :::* users:(("kube-controller",pid=2541,fd=10))
kube-apiserverとetcdがLISTENしてます。大丈夫ですね。
子ノードの設定
主に必要なパッケージは以下です。
- docker
- kubernetes-node
- kubernetes-client
- flannel
上記のパッケージを以下のコマンドでインストールします。
# yum install kubernetes-node flannel
dockerサービスの自動起動化をします。
# systemctl start docker # systemctl enable docker
kubernetesの設定
/etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=0" KUBE_ALLOW_PRIV="--allow-privileged=false" KUBE_MASTER="--master=http://192.168.33.10:8080"
KUBE_MASTER
にマスターのIPを指定します。
/etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=0.0.0.0" KUBELET_API_SERVER="--api-servers=http://192.168.33.10:8080" KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest" KUBELET_ARGS="--register-node=true"
KUBELET_ADDRESS
を0.0.0.0に設定、KUBELET_API_SERVER
をマスターに。KUBELET_ARGS
にオプションを追記します。
完了したら各サービスを再起動します。
# for SERVICES in kubelet kube-proxy; do \ systemctl restart $SERVICES && \ systemctl enable $SERVICES; done
サービスが動いているか確認します。
# ss -untlp | grep kube tcp LISTEN 0 128 127.0.0.1:10248 *:* users:(("kubelet",pid=24082,fd=4)) tcp LISTEN 0 128 127.0.0.1:10249 *:* users:(("kube-proxy",pid=24110,fd=10)) tcp LISTEN 0 128 :::10250 :::* users:(("kubelet",pid=24082,fd=8)) tcp LISTEN 0 128 :::10255 :::* users:(("kubelet",pid=24082,fd=22)) tcp LISTEN 0 128 :::4194 :::* users:(("kubelet",pid=24082,fd=14))
ノードからマスターのetcdにアクセスできるか確認します。
# curl -s -L http://192.168.33.10:2379/version {"etcdserver":"2.2.5","etcdcluster":"2.2.0"}
大丈夫ですね。
動作確認
全部の設定が完了するとマスターからノードが確認できます。
# kubectl get node NAME STATUS AGE node1 Ready 6m node2 Ready 25s
次回はflannelを使ってマルチホストでDockerコンテナが通信できるovarlay networkを構築します。