Grafana install for k8s

准备

k8s 集群: version >= 1.19.7

Yaml 编写

Namespace

创建 grafana 运行所需的命名空间

apiVersion: v1  
kind: Namespace  
metadata:  
  name: grafana-system

存储

创建 grafana 运行所需的存储

---  
apiVersion: storage.k8s.io/v1  
kind: StorageClass  
metadata:  
  name: grafana-sc  
  namespace: grafana-system  
provisioner: kubernetes.io/no-provisioner  
volumeBindingMode: WaitForFirstConsumer  
---  
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: grafana-pv  
  namespace: grafana-system  
spec:  
  storageClassName: grafana-sc  
  capacity:  
    storage: 1Gi  
  accessModes:  
    - ReadWriteOnce  
  hostPath:  
    path: /tmp/grafana  
---  
apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
  name: grafana-pvc  
  namespace: grafana-system  
spec:  
  storageClassName: grafana-sc  
  accessModes:  
    - ReadWriteOnce  
  resources:  
    requests:  
      storage: 1Gi

Deployment

创建 grafana 运行所需的工作负载

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  labels:  
    app: grafana  
  name: grafana  
  namespace: grafana-system  
spec:  
  selector:  
    matchLabels:  
      app: grafana  
  template:  
    metadata:  
      labels:  
        app: grafana  
    spec:  
      securityContext:  
        fsGroup: 472  
        supplementalGroups:  
          - 0  
      containers:  
        - name: grafana  
          image: grafana/grafana:9.1.0  
          imagePullPolicy: IfNotPresent  
          ports:  
            - containerPort: 3000  
              name: http-grafana  
              protocol: TCP  
          readinessProbe:  
            failureThreshold: 3  
            httpGet:  
              path: /robots.txt  
              port: 3000  
              scheme: HTTP  
            initialDelaySeconds: 10  
            periodSeconds: 30  
            successThreshold: 1  
            timeoutSeconds: 2  
          livenessProbe:  
            failureThreshold: 3  
            initialDelaySeconds: 30  
            periodSeconds: 10  
            successThreshold: 1  
            tcpSocket:  
              port: 3000  
            timeoutSeconds: 1  
          resources:  
            requests:  
              cpu: 250m  
              memory: 750Mi  
          volumeMounts:  
            - mountPath: /var/lib/grafana  
              name: grafana-pv  
      volumes:  
        - name: grafana-pv  
          persistentVolumeClaim:  
            claimName: grafana-pvc

修改挂载目录权限

如果就这样部署,会发生错误:

➜  ~ kubectl logs -f grafana-xxx -n grafana-system
GF_PATHS_DATA='/var/lib/grafana' is not writable.
You may have issues with file permissions, more information here: http://docs.grafana.org/installation/docker/#migration-from-a-previous-version-of-the-docker-container-to-5-1-or-later
mkdir: cannot create directory '/var/lib/grafana/plugins': Permission denied

可以看出是由于没有目录权限引起的,我们可以通过修改目录权限来解决这个问题,我们可以了利用一个 Job 来帮我们解决这个问题:

apiVersion: batch/v1  
kind: Job  
metadata:  
  name: grafana-chown  
  namespace: grafana-system  
spec:  
  template:  
    spec:  
      restartPolicy: Never  
      containers:  
        - name: grafana-chown  
          command: ["chown", "-R", "472:472", "/var/lib/grafana"]  
          image: busybox  
          imagePullPolicy: IfNotPresent  
          volumeMounts:  
            - name: grafana-pvc  
              mountPath: /var/lib/grafana  
      volumes:  
        - name: grafana-pvc  
          persistentVolumeClaim:  
            claimName: grafana-pvc

Service

创建 grafana 访问所需的 service, 可以根据自己需求自行修改,我这里因为我的集群部署了 Ingress 控制器,所以使用 ClusterIP。

apiVersion: v1  
kind: Service  
metadata:  
  name: grafana  
  namespace: grafana-system  
spec:  
  ports:  
    - port: 3000  
      protocol: TCP  
      targetPort: http-grafana  
  selector:  
    app: grafana  
  sessionAffinity: None  
  type: ClusterIP

Ingress

创建 grafana 访问所需的 ingress。

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: grafana  
  namespace: grafana-system  
  annotations:  
    nginx.ingress.kubernetes.io/proxy-buffer-size: "32k"  
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"  
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"  
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"  
    nginx.ingress.kubernetes.io/proxy-body-size: "512m"  
    nginx.ingress.kubernetes.io/ingress.class: 'nginx'  
spec:  
  ingressClassName: nginx  
  rules:  
    - host: grafana.test.com  
      http:  
        paths:  
          - path: /  
            pathType: Prefix  
            backend:  
              service:  
                name: grafana  
                port:  
                  number: 3000

完整 yaml

deploy.yaml

---  
apiVersion: v1  
kind: Namespace  
metadata:  
  name: grafana-system  
---  
apiVersion: storage.k8s.io/v1  
kind: StorageClass  
metadata:  
  name: grafana-sc  
  namespace: grafana-system  
provisioner: kubernetes.io/no-provisioner  
volumeBindingMode: WaitForFirstConsumer  
---  
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: grafana-pv  
  namespace: grafana-system  
spec:  
  storageClassName: grafana-sc  
  capacity:  
    storage: 1Gi  
  accessModes:  
    - ReadWriteOnce  
  hostPath:  
    path: /tmp/grafana  
---  
apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
  name: grafana-pvc  
  namespace: grafana-system  
spec:  
  storageClassName: grafana-sc  
  accessModes:  
    - ReadWriteOnce  
  resources:  
    requests:  
      storage: 1Gi  
---  
apiVersion: batch/v1  
kind: Job  
metadata:  
  name: grafana-chown  
  namespace: grafana-system  
spec:  
  template:  
    spec:  
      restartPolicy: Never  
      containers:  
        - name: grafana-chown  
          command: ["chown", "-R", "472:472", "/var/lib/grafana"]  
          image: busybox  
          imagePullPolicy: IfNotPresent  
          volumeMounts:  
            - name: grafana-pvc  
              mountPath: /var/lib/grafana  
      volumes:  
        - name: grafana-pvc  
          persistentVolumeClaim:  
            claimName: grafana-pvc  
---  
apiVersion: apps/v1  
kind: Deployment  
metadata:  
  labels:  
    app: grafana  
  name: grafana  
  namespace: grafana-system  
spec:  
  selector:  
    matchLabels:  
      app: grafana  
  template:  
    metadata:  
      labels:  
        app: grafana  
    spec:  
      securityContext:  
        fsGroup: 472  
        supplementalGroups:  
          - 0  
      containers:  
        - name: grafana  
          image: grafana/grafana:9.1.0  
          imagePullPolicy: IfNotPresent  
          ports:  
            - containerPort: 3000  
              name: http-grafana  
              protocol: TCP  
          readinessProbe:  
            failureThreshold: 3  
            httpGet:  
              path: /robots.txt  
              port: 3000  
              scheme: HTTP  
            initialDelaySeconds: 10  
            periodSeconds: 30  
            successThreshold: 1  
            timeoutSeconds: 2  
          livenessProbe:  
            failureThreshold: 3  
            initialDelaySeconds: 30  
            periodSeconds: 10  
            successThreshold: 1  
            tcpSocket:  
              port: 3000  
            timeoutSeconds: 1  
          resources:  
            requests:  
              cpu: 250m  
              memory: 750Mi  
          volumeMounts:  
            - mountPath: /var/lib/grafana  
              name: grafana-pv  
      volumes:  
        - name: grafana-pv  
          persistentVolumeClaim:  
            claimName: grafana-pvc  
---  
apiVersion: v1  
kind: Service  
metadata:  
  name: grafana  
  namespace: grafana-system  
spec:  
  ports:  
    - port: 3000  
      protocol: TCP  
      targetPort: http-grafana  
  selector:  
    app: grafana  
  sessionAffinity: None  
  type: ClusterIP  
---  
apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: grafana  
  namespace: grafana-system  
  annotations:  
    nginx.ingress.kubernetes.io/proxy-buffer-size: "32k"  
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"  
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"  
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"  
    nginx.ingress.kubernetes.io/proxy-body-size: "512m"  
    nginx.ingress.kubernetes.io/ingress.class: 'nginx'  
spec:  
  ingressClassName: nginx  
  rules:  
    - host: grafana.test.com  
      http:  
        paths:  
          - path: /  
            pathType: Prefix  
            backend:  
              service:  
                name: grafana  
                port:  
                  number: 3000

部署

# 部署 grafana
➜  ~ kubectl apply -f grafana-deploy.yaml

观察服务

查看存储绑定状态

➜  ~ kubectl get -n grafana-system sc
NAME         PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
grafana-sc   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                  3h21m
➜  ~ kubectl get -n grafana-system pv
NAME         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                        STORAGECLASS   REASON   AGE
grafana-pv   1Gi        RWO            Retain           Bound    grafana-system/grafana-pvc   grafana-sc              3h22m
➜  ~ kubectl get -n grafana-system pvc
NAME          STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
grafana-pvc   Bound    grafana-pv   1Gi        RWO            grafana-sc     3h22m

查看POD运行状态

➜  ~ kubectl get -n grafana-system pod
NAME                       READY   STATUS      RESTARTS   AGE
grafana-58445b6986-wx8tn   1/1     Running     1          3h23m
grafana-chown-x99bh        0/1     Completed   0          3h23m

查看 Serveice + Ingress

➜  ~ kubectl get -n grafana-system svc
NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
grafana   ClusterIP   10.98.141.112   <none>        3000/TCP   3h24m
➜  ~ kubectl get -n grafana-system ing
NAME      CLASS   HOSTS              ADDRESS       PORTS   AGE
grafana   nginx   grafana.test.com   10.99.6.241   80      3h20m

访问 grafana

配置host

windows

文件路径:C:\Windows\System32\drivers\etc

# 修改 hosts 文件
master ip grafana.test.com

linux & mac

sudo echo "master ip grafana.test.com" >> /etc/hosts

浏览器访问: http://grafana.test.com

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容