はじめに
Dockerのオーケストレーションである[kubenetes]を使用してDockerのクラスタ化を行います。過去バージョンのものはいくつかあったのですが新バージョンはなかった気がするので備忘録で上げておきます。
環境
AWSで以下の構成を作ります
| VPC | Subnet | ホスト名 | 役割 | インスタンスタイプ | AMI | AMI |
|---|---|---|---|---|---|---|
| 10.2.0.0/16 | 10.2.1.0/24 | k8b-mster | マスター | t2.middle | centos 7.0 | work-sg |
| 10.2.0.0/16 | 10.2.1.0/24 | k8b-node01 | ノード1号機 | t2.middle | centos 7.0 | work-sg |
| 10.2.0.0/16 | 10.2.1.0/24 | k8b-node02 | ノード2号機 | t2.middle | centos 7.0 | work-sg |
■[work-sg]内容
※非推奨(全開放しています)
Inbound : 0-65536 0.0.0.0
Outbound : すべて 0.0.0.0
準備
root ssh パスワード認証
別にやらなくても構いませんが筆者は鍵認証よりパスワード認証でsudo -s で切り替えるのが面倒だったためにこの設定を入れました
対象:全台
<$:centos>
sudo -s
passwd root
※以降root
sed -ri "s/#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
sed -ri "s/PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
systemctl restart sshd
ssh パスワード認証なし
これは必須ではありません。何となくおまじないでやっています
<<#:Master>>
ssh-keygen -t rsa
(途中入力するプロンプトはすべてEnter)
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
vi ~/.ssh/authorized_keys
<<#:node01,node02>>
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub
(master側の「authorized_keys」に内容をコピペ)
<<#:Master>>
cat .ssh/authorized_keys
<<#:node01,node02>>
vi ~/.ssh/authorized_keys
(マスター側の[authorized_keys]の内容をすべてコピペ)
(known_hostsの作成)
for ip in 10.2.1.62 10.2.1.141 10.2.1.21; do ssh $ip uname -a; done
for ip in k8b-master k8b-node01 k8b-node02; do ssh $ip uname -a; done
EC2hostname変更とhosts設定
これは必須です。クラスタ間の通信の際に使ってると思います
<<#:master>>
hostnamectl set-hostname 'k8b-master'
<<#:node01>>
hostnamectl set-hostname 'k8b-node01'
<<#:node02>>
hostnamectl set-hostname 'k8b-node02'
vi /etc/hosts
10.2.1.62 k8b-master
10.2.1.141 k8b-node01
10.2.1.21 k8b-node02
scp /etc/hosts root@k8b-master:/etc/hosts
scp /etc/hosts root@k8b-node01:/etc/hosts
scp /etc/hosts root@k8b-node02:/etc/hosts
selinux 停止
クラスタの際のエラーを回避するために停止させます
<<#:master>>
for host in k8b-master k8b-node01 k8b-node02 ;do ssh $host sed -ri "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config && cat /etc/selinux/config | grep SELINUX; done
for i in k8b-master k8b-node01 k8b-node02; do ssh $i sed -i 's/^SELINUX=permissive$/SELINUX=disabled/' /etc/selinux/config;done
<<#:master,node01,node02>>
reboot
<<#:master>>
for i in k8b-master k8b-node01 k8b-node02; do ssh $i sestatus;done
Docker install
これから[kubenetes]のインストール作業に入ります。まずは前提となる[Docker]をインストールします
下記コマンドを実行するとすべてのサーバに[1.13.1]が導入されます
<<#:master>>
# Dockerリポジトリの追加
for i in k8b-master k8b-node01 k8b-node02; do ssh $i yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && ls -l /etc/yum.repos.d/; done
# yumの更新
for i in k8b-master k8b-node01 k8b-node02; do ssh $i yum update all; done
# Docker install
for i in k8b-master k8b-node01 k8b-node02; do ssh $i yum install -y docker; done
# Docker install check
for i in k8b-master k8b-node01 k8b-node02; do ssh $i echo $hostname && echo "------" && docker -v && echo "-----"; done
<<#:master,node01,node02>>
# Docker サービス設定
systemctl enable docker && systemctl start docker && systemctl status docker
kubernetesのリポジトリ追加
<<#:master>>
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/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
scp /etc/yum.repos.d/kubernetes.repo root@k8b-node01:/etc/yum.repos.d/
scp /etc/yum.repos.d/kubernetes.repo root@k8b-node02:/etc/yum.repos.d/
for i in k8b-master k8b-node01 k8b-node02; do ssh $i ls -l /etc/yum.repos.d/; done
kubenetes インストール
for文使って各サーバに対して一気に実行することも可能だと思いますが、ここは確認しながら進めたかったので
個別に実行しています
<<#:master,node01,node02>>
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
kubenetes マスター初期化
「kubenetes」のマスターを初期化しています。
サービス設定
systemctl enable kubelet && systemctl start kubelet
※この時点ではサービスは起動していない
net.bridge.bridge-nf-call-iptablesの確認
1であればよい
sysctl -n net.bridge.bridge-nf-call-iptables
cgroup 確認
Dockerの設定と[10-kubeadm.conf]の[cgroupdriver]が一致しているか確認する
「systemd」になっていない場合変更する
(Centosの場合は基本的に[systemd])
※現バージョンにはそもそも入っていないのでスルーで可。以下は一応確認した結果
docker info | grep -i cgroup
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
[root@k8b-master ~]# docker info | grep -i cgroup
WARNING: You're not using the default seccomp profile
Cgroup Driver: systemd
[root@k8b-master ~]# cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
[root@k8b-master ~]#
kubenetes マスター初期化
「kubenetes」のマスターを初期化します。実行結果の最後に出てくるメッセージはメモ帳等に保存してください。ノード追加の時に使用します
<<#:master>>
kubeadm init --pod-network-cidr=10.244.0.0/16
※IPは使ってなければいいだけのようです。
[root@k8b-master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16
[init] using Kubernetes version: v1.12.3
[preflight] running pre-flight checks
<中略>
[addons] Applied essential addon: kube-proxy
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
※↓をすべてテキストなどに保存しておく
kubeadm join 10.2.1.9:6443 --token 4mlbar.6g75q47pg3vodb8t --discovery-token-ca-cert-hash sha256:5d62c6cc1061fb5aac0c17e21d744e164eef734611146693ca45959d9ac857c5
admin.confのパス設定
rootで行う場合は以下のコマンドでパスを通します
<<#:master>>
export KUBECONFIG=/etc/kubernetes/admin.conf
n/w 設定
[calico]を使用してPodのネットワーク設定を行います
<<#:master>>
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml
ノード追加
マスター以外に作った2台のサーバをクラスタに追加させる
<<#:k8b-node01,k8b-node02>>
※(Masterで[kubeadm init]を実行した際の最後に表示されたコマンドをそのまま実行する
kubeadm join 10.2.1.9:6443 --token 4mlbar.6g75q47pg3vodb8t --discovery-token-ca-cert-hash sha256:5d62c6cc1061fb5aac0c17e21d744e164eef734611146693ca45959d9ac857c5
稼働確認
kubectl get nodes
ノード追加
先ほどinitを実行したときのコマンドを使用してマスターにノードを追加します。やり方は保存済みのJoinコマンドをノードで実行するだけです
<<#:node01,node02>>
kubeadm join 10.2.1.9:6443 --token 4mlbar.6g75q47pg3vodb8t --discovery-token-ca-cert-hash sha256:5d62c6cc1061fb5aac0c17e21d744e164eef734611146693ca45959d9ac857c5
<<#:master>>
kubectl get nodes
[root@k8b-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8b-master Ready master 16m v1.12.3
k8b-node01 Ready <none> 2m5s v1.12.3
k8b-node02 Ready <none> 2m1s v1.12.3
[root@k8b-master ~]#
コンテナ作成
ここでは[apache]と[nginx]を起動させて本当にクラスタになっているかを確認します。作成するフォルダは任意となります。今回は[~/kubeimg]の下に作成していきます。
mkdir ~/kubeimg
vi ~/kubeimg/apache.yaml
vi ~/kubeimg/apache-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache
spec:
selector:
matchLabels:
app: apache
replicas: 2
template:
metadata:
labels:
app: apache
spec:
containers:
- name: apache
image: httpd:2.4
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: apache
spec:
type: NodePort
selector:
app: apache
ports:
- protocol: TCP
port: 80
targetPort: 80
mkdir ~/kubeimg
vi ~/kubeimg/nginx.yaml
vi ~/kubeimg/nginx-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.12.1
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
apacheとnginxの起動
cd ~/kubeimg
kubectl apply -f nginx.yaml
kubectl apply -f nginx-svc.yaml
kubectl apply -f apache.yaml
kubectl apply -f apache-svc.yaml
kubectl get deployment,replicasets,pods
kubectl get svc
[root@k8b-master kubeimg]# kubectl get deployment,replicasets,pods
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.extensions/apache 2 2 2 2 37m
deployment.extensions/nginx 2 2 2 2 14m
NAME DESIRED CURRENT READY AGE
replicaset.extensions/apache-5954cc7465 2 2 2 37m
replicaset.extensions/nginx-7f97d5f456 2 2 2 8m6s
NAME READY STATUS RESTARTS AGE
pod/apache-5954cc7465-bdrpg 1/1 Running 0 37m
pod/apache-5954cc7465-dhwpd 1/1 Running 0 37m
pod/nginx-7f97d5f456-442l5 1/1 Running 0 8m6s
pod/nginx-7f97d5f456-bcm2j 1/1 Running 0 8m5s
[root@k8b-master kubeimg]#
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apache NodePort 10.103.43.210 <none> 80:32130/TCP 38m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 132m
nginx NodePort 10.100.254.122 <none> 80:32240/TCP 9m30s
[root@k8b-master kubeimg]#
※Portsに指定された番号にアクセスすることになります
(コンテナポート:リモートポート)
web起動
AWSなのでPublicIPにバインディングしたポートを指定し
ブラウザアクセス。node1IP:,node2IP:で同じ画面が見えていることが正解です
■apache
AWSでやっているのでパブリックIPを使用してアクセス
TeraTermでポートフォワーディングしているのでURLはすべてlocalhostになります
Local "localhost" port 80 to remote "node01のプライベートIP" port 32130
Local "localhost" port 80 to remote "node02のプライベートIP" port 32130
■nginx
Local "localhost" port 80 to remote "node01のプライベートIP" port 32240
Local "localhost" port 80 to remote "node02のプライベートIP" port 32240
補足)
podが使用しているIPを知りたい場合
[root@appmaster apache]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apache NodePort 10.98.130.184 <none> 80:32455/TCP 4h54m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h6m
nginx NodePort 10.99.201.47 <none> 80:30587/TCP 4h54m
[root@appmaster apache]#
namespeceの情報を取得する
[root@appmaster apache]# kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default apache-5954cc7465-cztk9 1/1 Running 0 4h55m
default apache-5954cc7465-ntsk7 1/1 Running 0 4h55m
default nginx-7f97d5f456-57dl2 1/1 Running 0 4h55m
default nginx-7f97d5f456-hxw2n 1/1 Running
[root@appmaster apache]#
究極の手段リセット
[root@appmaster apache]# kubeadm reset
[reset] WARNING: changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted.
[reset] are you sure you want to proceed? [y/N]: y
[preflight] running pre-flight checks
[reset] stopping the kubelet service
[reset] unmounting mounted directories in "/var/lib/kubelet"
[reset] deleting contents of stateful directories: [/var/lib/kubelet /etc/cni/net.d /var/lib/dockershim /var/run/kubernetes /var/lib/etcd]
[reset] deleting contents of config directories: [/etc/kubernetes/manifests /etc/kubernetes/pki]
[reset] deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]
[root@appmaster apache]#
終わりに
ここまでやるのに結構苦労しました。今現在は[dashbord]を頑張っています。次に各種コマンドを一通りやってみて最終的に[kubernetes]の備忘録にするつもりです。それにしてもDocker関連は面白いですね。

