Hyper-Vに作成したkubernetes環境(前回記事)にはLoadBalancerやIngressなどが用意されていない基本的な環境である。
今回、前回作成したkubernetes環境にLoadBalancerやIngress、DynamicVolumeProvisioningを導入する。
インストールするリソース
- LoadBalancer: metallb
- Volume: rook/ceph
- Registry: harbor
- ServiceMesh,Ingress: Istio
- DNS: ExternalDNS
0. control-planeのtaintを削除してpodがスケジュールされるようにする
ベアメタルのkubernetesだとcontrol-planeのmasterノードにはpodがスケジューリングされないが、
なるべく全ノードのリソースを活用したいためスケジューリングされるように設定を変更する。
設定はtaintという仕組みで行われているので、以下コマンドでtaintを外す。
kubectl taint nodes k8s0 node-role.kubernetes.io/control-plane-
1. Helmのインストール
kubernetes上で複数のpodにより構成されたシステムをデプロイしたいなど、
kubernetesリソースを組み合わせて管理したい場合にはhelmという
パッケージ管理ソフトウェアを使って行うことができる。
helmはリモートレジストリに多数のパッケージがすでに登録されており、
そちらを使うことですぐに自分のkubernetesにシステムをデプロイすることができる。
2. Metallbのインストール
kubernetesのpodに外部からアクセスできるようにするためにServiceを通してアクセスすることができる。
Serviceにはいくつか種類があるが、helmで導入するパッケージなどでもよく使われているLoadBalancerを導入する。
ufwを無効にする。
ufw disable
kube-proxyの設定を変更する。
> kubectl edit configmap -n kube-system kube-proxy
strictARP: true
公式サイトに従いインストールする。
Metallb公式
# helmリポジトリを追加する
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb
# metallb-systemにインストール
kubectl create ns metallb-system
helm install -n metallb-system metallb metallb/metallb -f values.yaml
LoadBalancerで使うIPアドレスの範囲を指定する。
以下ファイルでは172.20.0.200-172.20.0.254の範囲でLoadBalancerから
IPアドレスが配布される。
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default
namespace: metallb-system
spec:
addresses:
- 172.20.0.200-172.20.0.254
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
namespace: metallb-system
実際に以下コマンドを実行して、LoadBalancerからIPアドレスが配布されることを確認する。
# nginxのpodをデプロイしてLoadBalancerで外部に公開する
kubectl run --restart=Never nginx --image=nginx:alpine
kubectl expose pod/nginx --type=LoadBalancer --port=80
デプロイが完了すると、以下のようにExternal-IPにIPアドレスが割り振られていることが確認できる。
> kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d12h
nginx LoadBalancer 10.97.171.254 172.20.0.200 80:30379/TCP 61s
Rook/Cephをインストールする
kubernetesではpod内にデータを保存しておいて再利用することができない。
それは、podがいつのタイミングで作り直されるか保証されていないし、
pod内のデータは初期化されて前の起動時から引き継がれないためである。
そこで、kubernetesではpodの外部にデータを保存する方法がいくつか提供されている。
外部ストレージ領域をHyper-Vで用意して、これをkubernetesのデータの保存先として活用することを考える。
Rook/Cephを使えば簡単にノードに接続されている外部ストレージをkubernetesのデータ保存に活用することができる。
まず、外部ストレージをHyper-Vで作成してマシンのハードディスクとして設定する。
マシンの設定画面を開き、「SCSIコントローラー」にハードドライブを追加する。
どのマシンで作業を行ってもよく、また複数のノードにハードディスクを追加した場合、
各ハードディスクをまとめてRook/Cephから利用できる。
以下の例では3つのノードすべてにハードディスクが追加されている場合の例である。
データを保存する際に各ノードの障害にどれくらい耐久性があるかを設定するStorageClassに
3つのコピーを作成するように指定しているため(replicated)、最低3ノードが必要となるが、
こちらの値を変えることで必要なノードの数を変更できる。
ハードディスクを用意したら、(Rookの公式)[https://rook.io/]を確認してインストールを行う。
# リポジトリを任意のディレクトリにclone
git clone --single-branch --branch v1.13.5 https://github.com/rook/rook.git
# CRDなど必要な定義、設定をデプロイ
cd deploy/examples
kubectl create -f crds.yaml -f common.yaml -f operator.yaml
# インストール
kubectl create -f cluster.yaml
これでRook/Cephがkubernetesに導入できたが、kubernetesのpodからデータ保存領域として活用するためには、
StorageClassを定義する必要がある。
以下ファイルをデプロイすることで、「rook-ceph-block」という名前のStorageClassが作成できる。
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: replicapool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
annotations:
storageclass.kubernetes.io/is-default-class: "true"
# Change "rook-ceph" provisioner prefix to match the operator namespace if needed
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
# clusterID is the namespace where the rook cluster is running
clusterID: rook-ceph
# Ceph pool into which the RBD image shall be created
pool: replicapool
# (optional) mapOptions is a comma-separated list of map options.
# For krbd options refer
# https://docs.ceph.com/docs/master/man/8/rbd/#kernel-rbd-krbd-options
# For nbd options refer
# https://docs.ceph.com/docs/master/man/8/rbd-nbd/#options
# mapOptions: lock_on_read,queue_depth=1024
# (optional) unmapOptions is a comma-separated list of unmap options.
# For krbd options refer
# https://docs.ceph.com/docs/master/man/8/rbd/#kernel-rbd-krbd-options
# For nbd options refer
# https://docs.ceph.com/docs/master/man/8/rbd-nbd/#options
# unmapOptions: force
# RBD image format. Defaults to "2".
imageFormat: "2"
# RBD image features
# Available for imageFormat: "2". Older releases of CSI RBD
# support only the `layering` feature. The Linux kernel (KRBD) supports the
# full complement of features as of 5.4
# `layering` alone corresponds to Ceph's bitfield value of "2" ;
# `layering` + `fast-diff` + `object-map` + `deep-flatten` + `exclusive-lock` together
# correspond to Ceph's OR'd bitfield value of "63". Here we use
# a symbolic, comma-separated format:
# For 5.4 or later kernels:
#imageFeatures: layering,fast-diff,object-map,deep-flatten,exclusive-lock
# For 5.3 or earlier kernels:
imageFeatures: layering
# The secrets contain Ceph admin credentials.
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
# Specify the filesystem type of the volume. If not specified, csi-provisioner
# will set default as `ext4`. Note that `xfs` is not recommended due to potential deadlock
# in hyperconverged settings where the volume is mounted on the same node as the osds.
csi.storage.k8s.io/fstype: ext4
# Delete the rbd volume when a PVC is deleted
reclaimPolicy: Delete
# Optional, if you want to add dynamic resize for PVC.
# For now only ext3, ext4, xfs resize support provided, like in Kubernetes itself.
allowVolumeExpansion: true
実際に上記のStorageClassを使ってpodをデプロイしてみる。
公式で用意された以下のファイルをデプロイすることで、mysqlのデータを永続化してpodを使用できる。
cd deploy/example
kubectl apply -n rook-ceph -f mysql.yaml
4. istioのインストール
ServiceMeshをインストール。Ingressも導入。
以下公式を参考にインストール。
(公式サイト)[https://istio.io/latest/docs/setup/getting-started/]
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.20.3
istioctlコマンドをbashrcに追記
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo -y
kubectl label namespace default istio-injection=enabled
# sample
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
# kiali
kubectl apply -f samples/addons
kubectl rollout status deployment/kiali -n istio-system
5. Harborのインストール
helm repo add harbor https://helm.goharbor.io
helm show values harbor/harbor > values.yaml
value.yamlのingressをnodePortに変更する。
commonNameは適当に設定。
helm install -n harbor harbor -f values.yaml harbor/harbor
ブラウザからアクセスするとログイン画面がでるので、
admin/Harbor12345でログイン。
containerdでimageをpullできるように/etc/containerd/config.tomlを設定
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."172.20.0.101".tls]
insecure_skip_verify = true
[plugins."io.containerd.grpc.v1.cri".registry.configs."172.20.0.101".auth]
username = "admin"
password = "Harbor12345"
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."172.20.0.101"]
endpoint = ["http://172.20.0.101"]
また、dockerからpushできるようにinseruce_repositoriesにharborを追加する。