KVM 上で Kubernetes を構築

KVM 上で Kubernetes を構築

kubernetes istio calico bird BGP

#####● Kubernetes で何をしたいのか。
特に何をしたいということではありません。
インフラ系の技術者として、 Kubernetes に対する知見を身に着けておきたいということで始めました。
実行環境は、自宅 PC の KVM 上です。

OS は、ホストを含め、すべて下記の OS を使いました。
CentOS Linux release 7.6.1810 (Core)

KVM 上に下記のゲストを作成します。
Desktop            2cpu  4GB memory  50GB HDD
Kubernetes master  2cpu  4GB memory  50GB HDD  192.168.122.100  master.testk.jp
Kubernetes node01  2cpu  4GB memory  20GB HDD  192.168.122.101  node01.testk.jp
Kubernetes node02  2cpu  4GB memory  20GB HDD  192.168.122.102  node02.testk.jp

ちなみに KVM関連のパッケージはすべて yum でインストールしたものです。

#####● 導入手順概要
以下の順に導入していきます。
1. OS セットアップ
2. Docker インストール
3. Kubernetes インストール
4. Kubernetes Master セットアップ
5. Calico インストール
6. Kubernetes Node 参加
7. kiali Secret 作成
8. Istio インストール

今回の構築は、ここまでと考えています。
下記の図のような構成になるということになります。
![Kubernetes-Kubernetes02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136267/9a625586-3418-0c5b-c4e6-e062ecefa1b9.png)
図1 初期構成

実行ユーザは、コマンド表記時の先頭で区別します。
\# root ユーザ
$ kubernetes User ( kuberus )

Kubernetes インストール までは、 master node01 node02 共に実施します。

#####1. OS セットアップ
Kubernetes を導入する上で必要な設定を行います。

```
パッケージのアップデート
# yum -y update
hosts 登録
# cat << EOF >> /etc/hosts

192.168.122.100    master.testk.jp
192.168.122.101    node01.testk.jp
192.168.122.102    node02.testk.jp
EOF

グループ追加
# groupadd -g 3000 kubergr

ユーザ追加
# useradd -g 3000 -u 3001 kuberus
# passwd kuberus

sudo 実行可能に
# gpasswd -a kuberus wheel

● SELinux を無効化
# sed -i -e "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
# setenforce 0

firewalld を無効化
# systemctl disable firewalld && systemctl stop firewalld
```

#####2. Docker インストール
Docker CE をインストールします。

```
Docker CE リポジトリ 設定
# curl -L https://download.docker.com/linux/centos/docker-ce.repo \
-o /etc/yum.repos.d/docker-ce.repo
# sed -i -e "s/^enabled=1/enabled=0/" /etc/yum.repos.d/docker-ce.repo

Docker CE インストール
# yum -y install docker-ce --enablerepo=docker-ce-stable

Docker CE バージョン確認
# docker --version
```

Docker CE のセットアップ

```
Docker グループへユーザの追加
# gpasswd -a kuberus docker

サービス設定ファイルのコピー
# cp /usr/lib/systemd/system/docker.service /etc/systemd/system

Docker 自動起動設定
# systemctl enable docker && systemctl start docker

Docker bridge 無効化
# cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

# sysctl --system
```

Kubernetes の Cgroup Driver が、 systemd を推奨ということで、
Docker Cgroup Driver systemdへ変更します。

```
# cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

# systemctl daemon-reload
# systemctl restart docker

# docker info | grep -i cgroup
Cgroup Driver: systemd
```

#####3. Kubernetes インストール
Istio 1.2 が対応するバージョンで Kubernetes をインストール します。
現在の最新版はまだテストしてないようです。
[Installing on Kubernetes](https://istio.io/docs/setup/kubernetes/)

```
kubernetes のリポジトリ登録
# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=0
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

Kubernetes のインストール Istio が対応するバージョン
# yum install -y kubelet-1.14.3 kubeadm-1.14.3 kubectl-1.14.3 --enablerepo=kubernetes

kubelet の自動起動設定
# cp /usr/lib/systemd/system/kubelet.service /etc/systemd/system
# systemctl enable kubelet
```

ここまでの作業を Master Node 共に実施します。

#####4. Kubernetes Master セットアップ
kubeadm を使って、Kubernetes をセットアップします。

```
Kubernetes Master セットアップ
$ sudo kubeadm init \
--apiserver-advertise-address=192.168.122.100 \
--pod-network-cidr=10.100.0.0/16
```

Kubernetes Master セットアップ時のログに kubeadm join で始まる部分があります。
Kubernetes Node 参加で使用するコマンドになります。

```
管理ユーザの設定
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
$ kubectl get node
```

#####5. Calico インストール
Calico のインストールと calicoctl のセットアップを行います。

```
Calico 用yamlファイルのダウンロード
$ mkdir calico
$ cd calico
$ curl -OL https://docs.projectcalico.org/v3.7/manifests/calico.yaml

Calico 用yamlファイルの編集
$ grep -n -A1 CALICO_IPV4POOL_IPIP calico.yaml
$ grep -n -A1 CALICO_IPV4POOL_CIDR calico.yaml

$ sed -i -e "600 s/Always/off/" calico.yaml
$ sed -i -e "611 s/192.168.0.0/10.100.0.0/" calico.yaml

$ grep -n -A1 CALICO_IPV4POOL_IPIP calico.yaml
$ grep -n -A1 CALICO_IPV4POOL_CIDR calico.yaml

Calico のインストール
$ kubectl apply -f calico.yaml

calicoctl のダウンロード
$ cd /usr/local/bin/
$ sudo curl -O -L  \
https://github.com/projectcalico/calicoctl/releases/download/v3.7.3/calicoctl

$ sudo chmod +x calicoctl

calicoctl の環境設定
$ cat << EOF >> ~/.bash_profile

export DATASTORE_TYPE=kubernetes
export KUBECONFIG=~/.kube/config
EOF

$ calicoctl get node
```

#####6. Kubernetes Node 参加
node01 , node02 双方で下記のコマンドを実行します。

```
# kubeadm join 192.168.122.100:6443 --token xxxxxxxxxxxxxx \
    --discovery-token-ca-cert-hash sha256:yyyyyyyyyyyyyyyyyyyy
```

#####7. Kiali Secret 作成
master で実行します。
管理ユーザの設定が master だけになっているので master での作業になります。
Kiali のUIへ接続しようとするとき、先に行うのがいいみたいです。
なぜかまでは分かっていません。

```
Kiali Secret の作成
$ KIALI_USERNAME=$(read -p 'Kiali Username: ' uval && echo -n $uval | base64)
$ KIALI_PASSPHRASE=$(read -sp 'Kiali Passphrase: ' pval && echo -n $pval | base64)
$ NAMESPACE=istio-system
$ kubectl create namespace $NAMESPACE
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: kiali
  namespace: $NAMESPACE
  labels:
    app: kiali
type: Opaque
data:
  username: $KIALI_USERNAME
  passphrase: $KIALI_PASSPHRASE
EOF
```

#####8. Istio インストール
Helm , Tiller をインストールし、 Helm を使ってインストール用 YAML ファイルを作成し、インストールします。

```
Istio ダウンロード
$ mkdir istio
$ cd istio/
$ curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.2.2 sh -
$ sudo cp  istio-1.2.2/bin/istioctl /usr/local/bin/
```

```
Helm インストール
$ mkdir ~/helm
$ cd ~/helm
$ curl -OL \
https://storage.googleapis.com/kubernetes-helm/helm-v2.14.1-linux-amd64.tar.gz

$ tar zxf helm-v2.14.1-linux-amd64.tar.gz

$ sudo cp linux-amd64/helm /usr/local/bin/

$ helm version
```

```
Tillerのインストール
$ kubectl apply -f \
/home/kuberus/istio/istio-1.2.2/install/kubernetes/helm/helm-service-account.yaml

$ helm init --service-account tiller

$ helm install /home/kuberus/istio/istio-1.2.2/install/kubernetes/helm/istio-init \
--name istio-init --namespace istio-system

$ helm repo add istio.io \
https://storage.googleapis.com/istio-release/releases/1.2.2/charts/
```

```
Istio のインストール
$ helm template /home/kuberus/istio/istio-1.2.2/install/kubernetes/helm/istio \
--set kiali.enabled=true \
--set "kiali.dashboard.jaegerURL=http://jaeger-query:16686" \
--set "kiali.dashboard.grafanaURL=http://grafana:3000" \
--set gateways.istio-ingressgateway.type=NodePort \
--set gateways.istio-egressgateway.type=NodePort \
--name istio --namespace istio-system \
> /home/kuberus/istio/kiali.yaml

$ kubectl apply -f /home/kuberus/istio/kiali.yaml
```

これで意図した構成にすることができました。
Desktop で Kiali の UI に接続するためには、 service/kiali を NodePort にする必要があります。
下記のように実施しました。

```
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  labels:
    app: kiali
    chart: kiali
    heritage: Tiller
    release: istio
  name: kiali
  namespace: istio-system
spec:
  ports:
  - name: http-kiali
    port: 20001
    protocol: TCP
    targetPort: 20001
    nodePort: 32001
  selector:
    app: kiali
  sessionAffinity: None
  type: NodePort
EOF
```

192.168.122.100:32001 へ接続して、 Kiali のUIへ無事アクセスできました。