Kubernetesクラスタ作成後にいれるアプリケーション

ClusterAPIで作成したクラスタだと、基本的なコンポーネントのみ動作しており実際に使うには不十分。いつも同じアプリを入れているので、その備忘録です。

概要

ClusterAPIで作成されたクラスタでは、基本的なコンポーネントのみが動いています。

$ kubectl get pod -A
NAMESPACE     NAME                                     READY   STATUS              RESTARTS   AGE
kube-system   coredns-74ff55c5b-4v6m9                  0/1     Pending             0          18h
kube-system   coredns-74ff55c5b-mdtlm                  0/1     Pending             0          18h
kube-system   etcd-k8s3-6x8gx                          1/1     Running             0          18h
kube-system   kube-apiserver-k8s3-6x8gx                1/1     Running             0          18h
kube-system   kube-controller-manager-k8s3-6x8gx       1/1     Running             0          18h
kube-system   kube-proxy-62h9p                         1/1     Running             0          18h
kube-system   kube-proxy-hhbbb                         1/1     Running             0          18h
kube-system   kube-proxy-sl9dk                         1/1     Running             0          18h
kube-system   kube-scheduler-k8s3-6x8gx                1/1     Running             0          18h
kube-system   kube-vip-k8s3-6x8gx                      1/1     Running             0          18h
kube-system   vsphere-cloud-controller-manager-88jpn   1/1     Running             0          18h
kube-system   vsphere-csi-controller-978c68bc4-76v97   0/5     Pending             0          18h
kube-system   vsphere-csi-node-79jt8                   0/3     ContainerCreating   0          18h
kube-system   vsphere-csi-node-kv7sg                   0/3     ContainerCreating   0          18h
kube-system   vsphere-csi-node-pvmdn                   0/3     ContainerCreating   0          18h

そのため、必須コンポーネントであるCNIをまずインストールするところから始まります。

使用ソフトウェア

  • clusterctl v0.3.19
  • cluster-api-provider-vsphere v0.7.8
  • kubernetes version photon3 v1.20.1
$ clusterctl version
clusterctl version: &version.Info{Major:"0", Minor:"3", GitVersion:"v0.3.19", GitCommit:"665d56652a787180dc36ecbfdf183b1e436fba75", GitTreeState:"clean", BuildDate:"2021-06-09T18:25:37Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"darwin/amd64"}
$ clusterctl upgrade plan
Checking cert-manager version...
Cert-Manager will be upgraded from "v0.11.0" to "v1.1.0"

Checking new release availability...

Management group: capi-system/cluster-api, latest release available for the v1alpha3 API Version of Cluster API (contract):

NAME                     NAMESPACE                           TYPE                     CURRENT VERSION   NEXT VERSION
bootstrap-kubeadm        capi-kubeadm-bootstrap-system       BootstrapProvider        v0.3.19           Already up to date
control-plane-kubeadm    capi-kubeadm-control-plane-system   ControlPlaneProvider     v0.3.19           Already up to date
cluster-api              capi-system                         CoreProvider             v0.3.19           Already up to date
infrastructure-vsphere   capv-system                         InfrastructureProvider   v0.7.8            Already up to date

You are already up to date!
 $ govc ls /Datacenter/vm/photon-3-kube-v1.20.1
/Datacenter/vm/photon-3-kube-v1.20.1

クラスタ作成用マニフェストの変更

PodとServiceのネットワーク変更に加え、vCenterが自己署名の証明書を使用しているのでinsecure-flag = "true"を追加。

--- cluster-org.yaml	2021-06-15 13:11:45.000000000 +0900
+++ cluster.yaml	2021-06-15 13:14:24.000000000 +0900
@@ -9,7 +9,10 @@
   clusterNetwork:
     pods:
       cidrBlocks:
-      - 192.168.0.0/16
+      - 172.16.0.0/16
+    services:
+      cidrBlocks:
+      - 172.30.0.0/16
   controlPlaneRef:
     apiVersion: controlplane.cluster.x-k8s.io/v1alpha3
     kind: KubeadmControlPlane
@@ -430,6 +433,7 @@
         user = "administrator@home.lab"
         password = "VMware1!"
         datacenters = "Datacenter"
+        insecure-flag = "true"

         [Network]
         public-network = "K8s"

その後、クラスタの作成

kubectl apply -f ./cluster.yaml

必須コンポーネント

CNI(Calico)のインストール

実績のあるCalicoをインストールしていきます。

参考 Calico Quickstart

まずは、Calicoのオペレーターをインストールします。

kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml

インストールが完了したことを確認します。

# kubectl -n tigera-operator get pod
NAME                               READY   STATUS    RESTARTS   AGE
tigera-operator-86c4fc874f-27ssw   1/1     Running   0          76s

次に、CalicoをデプロイするためにInstallationリソースを作成します。

wget https://docs.projectcalico.org/manifests/custom-resources.yaml

その際、クラスタ作成時に指定したPodのネットワークを指定します。

--- custom-resources.yaml	2021-06-15 13:34:39.000000000 +0900
+++ custom-resources-changed.yaml	2021-06-15 12:52:28.000000000 +0900
@@ -10,7 +10,7 @@
     # Note: The ipPools section cannot be modified post-install.
     ipPools:
     - blockSize: 26
-      cidr: 192.168.0.0/16
+      cidr: 172.16.0.0/16
       encapsulation: VXLANCrossSubnet
       natOutgoing: Enabled
       nodeSelector: all()

Calicoをインストールします。

# kubectl apply -f ./custom-resources.yaml
installation.operator.tigera.io/default created

インストールが完了すると全てのPodとNodeがREADYになります。

# kubectl get node
NAME                         STATUS   ROLES                  AGE   VERSION
k8s3-md-0-869b5f8c47-x7wvd   Ready    <none>                 10m   v1.20.1
k8s3-md-0-869b5f8c47-z5l96   Ready    <none>                 10m   v1.20.1
k8s3-sj2qh                   Ready    control-plane,master   12m   v1.20.1

# kubectl get pod -A
NAMESPACE         NAME                                      READY   STATUS    RESTARTS   AGE
calico-system     calico-kube-controllers-5dbb4b4cd-vwqzq   1/1     Running   0          4m43s
calico-system     calico-node-cf2bf                         1/1     Running   0          4m43s
calico-system     calico-node-pkbcr                         1/1     Running   0          4m43s
calico-system     calico-node-wz4kp                         1/1     Running   1          4m43s
calico-system     calico-typha-9cd8c7867-24fs8              1/1     Running   0          4m35s
calico-system     calico-typha-9cd8c7867-2rlbf              1/1     Running   0          4m35s
calico-system     calico-typha-9cd8c7867-nkdbh              1/1     Running   0          4m44s
kube-system       coredns-74ff55c5b-4h6hl                   1/1     Running   0          12m
kube-system       coredns-74ff55c5b-cxnsv                   1/1     Running   0          12m
kube-system       etcd-k8s3-sj2qh                           1/1     Running   0          12m
kube-system       kube-apiserver-k8s3-sj2qh                 1/1     Running   0          12m
kube-system       kube-controller-manager-k8s3-sj2qh        1/1     Running   0          12m
kube-system       kube-proxy-bjqnv                          1/1     Running   0          10m
kube-system       kube-proxy-spbth                          1/1     Running   0          12m
kube-system       kube-proxy-vm9pg                          1/1     Running   0          10m
kube-system       kube-scheduler-k8s3-sj2qh                 1/1     Running   0          12m
kube-system       kube-vip-k8s3-sj2qh                       1/1     Running   0          12m
kube-system       vsphere-cloud-controller-manager-45jc9    1/1     Running   0          12m
kube-system       vsphere-csi-controller-5456544dd5-ghj6r   5/5     Running   0          12m
kube-system       vsphere-csi-node-l7bwh                    3/3     Running   0          12m
kube-system       vsphere-csi-node-s8q4k                    3/3     Running   0          10m
kube-system       vsphere-csi-node-zhrkr                    3/3     Running   0          10m
tigera-operator   tigera-operator-86c4fc874f-8jvxc          1/1     Running   0          5m1s

Storage Classの作成

必須ではないですが、PersistentStorageを使ってEFKスタックを構築するので、StorageClassを設定します。StorageClass内で指定するdatastoreurlはUIから以下のように取得できます。

# k8s3-sc.yml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: k8s3-sc
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: csi.vsphere.vmware.com
allowVolumeExpansion: true
parameters:
  datastoreurl: "ds:///vmfs/volumes/60963522-77cad8f3-b98e-8cae4cdd1039/"

では、設定します。

kubectl apply -f ./k8s3-sc.yml

オペレーション関連

kube-prometheusのインストール

オペレーションに必要なコンポーネントをkube-prometheusよりまとめてインストールします。

参考 kube-prometheus Github

レポジトリには、本レポジトリにある全てが試験段階で、大幅な変更が起こる可能性があることが書かれています。

Note that everything is experimental and may change significantly at any time.

とはいえ、あれこれ別々にデプロイするのも大変なので、kube-prometheusを使用します。

git clone https://github.com/prometheus-operator/kube-prometheus.git
cd kube-prometheus/
kubectl create -f manifests/setup/
until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
kubectl create -f manifests/

デプロイ後に、Podの状態を確認します。

# kubectl -n monitoring get pod
NAME                                   READY   STATUS    RESTARTS   AGE
alertmanager-main-0                    2/2     Running   0          7m
alertmanager-main-1                    2/2     Running   0          7m
alertmanager-main-2                    2/2     Running   0          7m
blackbox-exporter-6c95587d7-t2vjv      3/3     Running   0          7m
grafana-849487dc74-dn5k4               1/1     Running   0          6m59s
kube-state-metrics-b545789dd-gxhhn     3/3     Running   0          6m59s
node-exporter-68wlm                    2/2     Running   0          6m59s
node-exporter-jzvql                    2/2     Running   0          6m59s
node-exporter-rsrr4                    2/2     Running   0          6m59s
prometheus-adapter-59df95d9f5-5gdmd    1/1     Running   0          6m59s
prometheus-adapter-59df95d9f5-vz25z    1/1     Running   0          6m59s
prometheus-k8s-0                       2/2     Running   1          7m
prometheus-k8s-1                       2/2     Running   1          7m
prometheus-operator-84dc795dc8-xhqd2   2/2     Running   0          7m25s

EFKスタックのインストール

ログ収集コンポーネントとして、EFK(Elastic Fluentd Kibana)をインストールします。

Elastic Cloud on Kubernetesをインストール

Elasticが提供しているオペレータを使って、Elastic SearchとKibanaをインストールします。

参考 Elastic Cloud on Kubernetes Quickstart

まず、CRDとオペレータをデプロイ。

kubectl apply -f https://download.elastic.co/downloads/eck/1.6.0/all-in-one.yaml

デプロイが完了すると、operatorが下記のように起動します。

# kubectl -n elastic-system get pod
NAME                 READY   STATUS    RESTARTS   AGE
elastic-operator-0   1/1     Running   0          16s

続いて、Elasticsearchをデプロイします。

cat <<EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: elasticsearch
  namespace: elastic-system
spec:
  version: 7.13.2
  nodeSets:
  - name: default
    count: 1
    config:
      node.store.allow_mmap: false
EOF

Kibanaをデプロイします。

cat <<EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: kibana
  namespace: elastic-system
spec:
  version: 7.13.2
  count: 1
  elasticsearchRef:
    name: elasticsearch
EOF

Fluentdのインストール

KibanaとElastic searchがインストールできたので、Fluentdをインストールしてログを転送します。

参考 Fluentd deployment on Kubernetes

公式のドキュメントにあるマニフェストを参考にデプロイします。

wget https://raw.githubusercontent.com/fluent/fluentd-kubernetes-daemonset/master/fluentd-daemonset-elasticsearch-rbac.yaml

今回CRIを使っているので、CRIのLogFormatを使うように変更が必要です。

# cri-tail-container-parse.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cri-tail-container-parse
  namespace: elastic-system
data:
  tail_container_parse.conf: |
    <parse>
      @type cri
    </parse>

@type CRIを使うように指定した設定ファイルをConfigMapとして作成します。

kubectl apply -f cri-tail-container-parse.yaml

続いて、デプロイされたElastic searchの宛先、パスワード、ネームスペースなどを変更します。
先程作成したConfigmapも既存の設定ファイルをオーバーライドするように変更します。

--- fluentd-daemonset-elasticsearch-rbac.yaml.org	2021-06-15 17:12:41.000000000 +0900
+++ fluentd-daemonset-elasticsearch-rbac.yaml	2021-06-16 10:28:41.000000000 +0900
@@ -3,14 +3,14 @@
 kind: ServiceAccount
 metadata:
   name: fluentd
-  namespace: kube-system
+  namespace: elastic-system

 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
   name: fluentd
-  namespace: kube-system
+  namespace: elastic-system
 rules:
 - apiGroups:
   - ""
@@ -34,13 +34,13 @@
 subjects:
 - kind: ServiceAccount
   name: fluentd
-  namespace: kube-system
+  namespace: elastic-system
 ---
 apiVersion: apps/v1
 kind: DaemonSet
 metadata:
   name: fluentd
-  namespace: kube-system
+  namespace: elastic-system
   labels:
     k8s-app: fluentd-logging
     version: v1
@@ -62,18 +62,18 @@
         effect: NoSchedule
       containers:
       - name: fluentd
-        image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch
+        image: fluent/fluentd-kubernetes-daemonset:v1.12.4-debian-elasticsearch7-1.1
         env:
           - name:  FLUENT_ELASTICSEARCH_HOST
-            value: "elasticsearch-logging"
+            value: "elasticsearch-es-http"
           - name:  FLUENT_ELASTICSEARCH_PORT
             value: "9200"
           - name: FLUENT_ELASTICSEARCH_SCHEME
-            value: "http"
+            value: "https"
           # Option to configure elasticsearch plugin with self signed certs
           # ================================================================
           - name: FLUENT_ELASTICSEARCH_SSL_VERIFY
-            value: "true"
+            value: "false"
           # Option to configure elasticsearch plugin with tls
           # ================================================================
           - name: FLUENT_ELASTICSEARCH_SSL_VERSION
@@ -83,7 +83,10 @@
           - name: FLUENT_ELASTICSEARCH_USER
             value: "elastic"
           - name: FLUENT_ELASTICSEARCH_PASSWORD
-            value: "changeme"
+            valueFrom:
+              secretKeyRef:
+                name: elasticsearch-es-elastic-user
+                key: elastic
         resources:
           limits:
             memory: 200Mi
@@ -101,6 +104,10 @@
         - name: dockercontainerlogdirectory
           mountPath: /var/log/pods
           readOnly: true
+        - name: tail-container-parse-config
+          mountPath: "/fluentd/etc/tail_container_parse.conf"
+          subPath: tail_container_parse.conf
+          readOnly: true
       terminationGracePeriodSeconds: 30
       volumes:
       - name: varlog
@@ -114,3 +121,6 @@
       - name: dockercontainerlogdirectory
         hostPath:
           path: /var/log/pods
+      - name: tail-container-parse-config
+        configMap:
+          name: cri-tail-container-parse

本設定を適用します。

kubectl apply -f ./fluentd-daemonset-elasticsearch-rbac.yaml

これにより、Kibanaからログが確認できれば設定が完了です。

ネットワーク関連

MetalLBのインストール

Service(LoadBalancer)が利用できるようにMetalLBをインストールします。

参考 MetalLB Installation

上記のページにならってインストールします。

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml

必要なコンポーネントがREADYになったか確認します。

# kubectl -n metallb-system get pod
NAME                          READY   STATUS    RESTARTS   AGE
controller-6b78bff7d9-wskh9   1/1     Running   0          25s
speaker-d7qs6                 1/1     Running   0          25s
speaker-n22gl                 1/1     Running   0          25s
speaker-pp82d                 1/1     Running   0          25s

続いて、LoadBalancerに割り当てるIPアドレスのレンジを指定します。

# metallb-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.11.81-192.168.11.90

こちらを適用します。

kubectl apply -f ./metallb-configmap.yaml

本設定が正しく動くことを確認するために、サンプルアプリケーションをデプロイします。

kubectl run nginx --image=nginx
kubectl expose pod nginx --port=80 --type=LoadBalancer

Serviceの情報を取得すると、External-IPがプールから付与されていることがわかります。

# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
kubernetes   ClusterIP      172.30.0.1      <none>          443/TCP        80m
nginx        LoadBalancer   172.30.215.51   192.168.11.81   80:31922/TCP   2m39s

サンプルアプリの削除

kubectl delete service/nginx pod/nginx

Ingress Controller(Contour)をインストール

Ingress ControllerとしてContourをインストールします。

参考 Contour Getting Started

特にカスタマイズする予定もないが、Operatorを使ってインストール。

kubectl apply -f https://projectcontour.io/quickstart/operator.yaml
kubectl apply -f https://projectcontour.io/quickstart/contour-custom-resource.yaml

動作確認のため、サンプルアプリケーションをデプロイ。

kubectl apply -f https://projectcontour.io/examples/kuard.yaml

デプロイ後IngressのIPアドレスにアクセスし、200 OKが返ってくれば完了。

# kubectl get ingress
NAME    CLASS    HOSTS   ADDRESS         PORTS   AGE
kuard   <none>   *       192.168.11.82   80      5m30s

# curl -s -v http://192.168.11.82/ > /dev/null
*   Trying 192.168.11.82...
* TCP_NODELAY set
* Connected to 192.168.11.82 (192.168.11.82) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.11.82
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-length: 1676
< content-type: text/html
< date: Tue, 15 Jun 2021 06:24:28 GMT
< x-envoy-upstream-service-time: 0
< vary: Accept-Encoding
< server: envoy
<
{ [1676 bytes data]
* Connection #0 to host 192.168.11.82 left intact
* Closing connection 0

サンプルアプリの削除

kubectl delete -f https://projectcontour.io/examples/kuard.yaml

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA