Elastic:運用Elastic Stack對Kubernetes進行監控 (一)

在本文中,我們將學習如何爲您的Kubernetes環境(簡稱k8s)設置監視堆棧。 這種解決方案使您的團隊可以在幾乎不影響現有資源的情況下獲得對基礎架構和每個應用程序的可見性。

可觀測性的目的是向負責生產的操作員提供工具,以檢測不良行爲(服務停機,錯誤,響應速度慢),並提供可操作的信息以查找問題的根本原因。 它通常分爲三個支柱:

  • 指標:提供有關係統每個組件的時間序列信息,例如CPU,內存,磁盤和網絡消耗,並且通常顯示整體前景以及在特定時間檢測異常行爲的第一步。
  • 日誌:爲操作員提供了一種工具,可以將機器,服務和應用程序日誌集中在同一可搜索數據庫中,以分析和了解系統上的意外行爲。
  • 跟蹤或APM(應用程序監視性能):提供了對應用程序的更深入的瞭解,其中記錄了服務執行中的每個請求和步驟(http調用,數據庫查詢等)。 使用跟蹤,我們可以檢測到性能低下或調試低級別的特定用戶,並相應地改進或修復我們的系統。

出處:Peter Bourgon

360可觀察性的概念與devop和敏捷原則完全一致,可以隨着時間的推移不斷觀察,檢測和改進系統。

在本文中,我們將在Kubernetes環境中使用由Elasticsearch,Kibana,Filebeat,Metricbeat和APM-Server組成的Elastic堆棧(版本7.6.2)監視和記錄生產環境。 本系列文章將逐步介紹標準的Kubernetes部署,在我看來,它可以更好地全面瞭解安裝和配置的每個步驟。 當然,還存在其他方法來在Kubernetes上使用Helm或Elastic Cloud之類的工具來安裝和配置某些服務,但是本文的目的是使讀者充分了解這種``相當''複雜的體系結構中的每個組件,以幫助他們進行調整 適用於自己的系統,有時會受到自動安裝程序的限制。

前提條件

本教程使用minikube創建本地k8s環境,並部署一個簡單的應用程序,該應用程序由Spring-Boot服務和MongoDB數據庫組成,將用作示例來監視和跟蹤系統及應用程序的行爲。

因此,爲了開始使用,需要以下工具:

  • Docker:容器引擎
  • minikube:用於開發和測試的本地kubernetes
  • kubectl:Kubernetes命令行工具
  • Elasticsearch要求增加主機上的nmapfs(虛擬內存)(請參閱詳細信息)針對Linux系統我們需要運行如下的命令:
$ sudo sysctl -w vm.max_map_count=262144

如果你還沒沒有安裝好自己的Minikube的話,那麼請參照我之前的文章“Elastic Cloud Kubernetes (ECK) 部署”。

配置minikube 內存大小

首先,我們將分配給minikube主機的默認內存大小(2GB)增加到8GB。 在終端中運行以下命令:

minikube config set memory 8192
$ minikube config set memory 8192
❗  These changes will take effect upon a minikube delete and then a minikube start

啓動minikube

現在,使用以下命令啓動minikube。 可能要花幾分鐘...。針對中國的情況,我們使用如下命令來啓動minikube:

minikube start --driver=virtualbox --cpus 3 --memory 8196  --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'
$ minikube start --driver=virtualbox --cpus 3 --memory 8196  --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'
😄  minikube v1.9.2 on Darwin 10.15.4
✨  Using the virtualbox driver based on existing profile
✅  Using image repository registry.cn-hangzhou.aliyuncs.com/google_containers
👍  Starting control plane node m01 in cluster minikube
🏃  Updating the running virtualbox "minikube" VM ...
🐳  Preparing Kubernetes v1.18.0 on Docker 19.03.8 ...
🌟  Enabling addons: default-storageclass, storage-provisioner
🏄  Done! kubectl is now configured to use "minikube"

❗  /usr/local/bin/kubectl is v1.15.5, which may be incompatible with Kubernetes v1.18.0.
💡  You can also use 'minikube kubectl -- get pods' to invoke a matching versio

檢查Minikube的狀態

我們可以檢查minikube的狀態:

 minikube status
$ minikube status
m01
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
kubectl get nodes
$ kubectl get nodes
NAME       STATUS   ROLES    AGE   VERSION
minikube   Ready    master   23m   v1.18.0

我們可以看到我們有一個master,並且Kubernetes的版本是1.18。

部署樣本應用程序

現在,我們將部署一個簡單的應用程序(Spring-Boot)及其數據庫(MongoDB)。

MongoDB

我們首先在k8s環境中部署MongoDB,並公開端口27017。

mongo.yml

---
apiVersion: v1
kind: Service
metadata:
  namespace: default
  name: mongo
  labels:
    app: mongo
spec:
  ports:
  - port: 27017
    protocol: TCP
  selector:
    app: mongo
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: default
  name: mongo
  labels:
    app: mongo
spec:
  serviceName: "mongo"
  replicas: 1
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongo
        image: mongo
        ports:
        - containerPort: 27017
        volumeMounts:
        - name: mongo-persistent-storage
          mountPath: /data/db
  volumeClaimTemplates:
  - metadata:
      name: mongo-persistent-storage
      annotations:
        volume.beta.kubernetes.io/storage-class: "standard"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: standard
      resources:
        requests:
          storage: 1Gi

使用以下命令部署MongoDB:

kubectl apply -f mongo.yml

我們等一下直到它運行起來:

 kubectl get pods
$ kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
mongo-0   1/1     Running   0          114s
kubectl get all -l app=mongo
$ kubectl get all -l app=mongo
NAME          READY   STATUS    RESTARTS   AGE
pod/mongo-0   1/1     Running   0          2m31s


NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)     AGE
service/mongo   ClusterIP   10.104.205.22   <none>        27017/TCP   14m


NAME                     READY   AGE
statefulset.apps/mongo   1/1     2m31s

spring-boot-simple

現在讓我們部署我們的Spring-Boot API。 它將API內部部署在端口8080上,但是type = NodePort也可以從節點靜態IP在另一個端口上進行訪問。

spring-boot-simple.yml

# spring-boot-simple.yml
---
apiVersion: v1
kind: Service
metadata:
  namespace: default
  name: spring-boot-simple
  labels:
    app: spring-boot-simple
spec:
  type: NodePort
  ports:
  - port: 8080
    protocol: TCP
  selector:
    app: spring-boot-simple
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  name: spring-boot-simple
  labels:
    app: spring-boot-simple
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-boot-simple
  template:
    metadata:
      labels:
        app: spring-boot-simple
    spec:
      containers:
      - image: gjeanmart/spring-boot-simple:0.0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-boot-simple
        env:
          - name: SPRING_DATA_MONGODB_HOST
            value: mongo
        ports:
        - containerPort: 8080

運行命令以部署spring-boot-simple:

kubectl apply -f spring-boot-simple.yml

然後等它部署好:

kubectl get all -l app=spring-boot-simple
$ kubectl get all -l app=spring-boot-simple
NAME                                      READY   STATUS    RESTARTS   AGE
pod/spring-boot-simple-84c965c78c-xknw9   1/1     Running   0          5m31s


NAME                         TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/spring-boot-simple   NodePort   10.110.22.185   <none>        8080:30894/TCP   5m31s


NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/spring-boot-simple   1/1     1            1           5m31s

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/spring-boot-simple-84c965c78c   1         1         1       5m31s

注意節點上API的外部端口:30049,並使用$ minikube ip獲得節點靜態IP。

$ minikube  ip
192.168.99.118

我們也可以通過如下的方法來找到service的port號:

export NODE_PORT=$(kubectl get service/spring-boot-simple -o go-template='{{(index .spec.ports 0).nodePort}}')

echo $NODE_PORT
$ echo $NODE_PORT
30894

獲得所需的所有信息後,只需運行以下命令以測試我們的示例API(將<IP>:<PORT>替換爲您的值)。

Greetings

curl $(minikube ip):30894
$ curl $(minikube ip):30894
Greetings from Spring Boot!liuxg:minikube

Post 一個信息

curl -X POST $(minikube ip):30894/message -d 'hello world'
$ curl -X POST $(minikube ip):30894/message -d 'hello world'
{"id":"5eac196bcff47e0001297d16","message":"hello+world=","postedAt":"2020-05-01T12:43:23.944+0000"}

Get 所有信息

curl -X GET $(minikube ip):30894/message
$ curl -X GET $(minikube ip):30894/message
[{"id":"5eac196bcff47e0001297d16","message":"hello+world=","postedAt":"2020-05-01T12:43:23.944+0000"}]

創建 monitoring 的命名空間

最後,爲了在邏輯上將監視堆棧與應用程序分開(namespace default),我們將所有內容部署在稱爲monitoring的命名空間下。

要創建namespace,只需運行以下命令:

kubectl create namespace monitoring

你也可以通過如下的方式來創建。先創建一個yaml文件。

monitoring.namespace.yml

# monitoring.namespace.yml
---
apiVersion: v1
kind: Namespace
metadata:
   name: monitoring
---

讓後,使用如下的命令來創建:

kubectl apply -f monitoring.namespace.yml

在下一步,我們將安裝Elasticsearch及Kibana。請閱讀我的另外一篇文章。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章