前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linkerd服务网格安装部署

Linkerd服务网格安装部署

作者头像
王先森sec
发布2023-10-17 15:22:08
2620
发布2023-10-17 15:22:08
举报
文章被收录于专栏:王先森

Linkerd服务网格安装部署

王先森2023-04-242023-04-24

Linkerd 介绍

Linkerd 是 Kubernetes 的一个完全开源的服务网格实现。它通过为你提供运行时调试、可观测性、可靠性和安全性,使运行服务更轻松、更安全,所有这些都不需要对你的代码进行任何更改。

Linkerd 通过在每个服务实例旁边安装一组超轻、透明的代理来工作。这些代理会自动处理进出服务的所有流量。由于它们是透明的,这些代理充当高度仪表化的进程外网络堆栈,向控制平面发送遥测数据并从控制平面接收控制信号。这种设计允许 Linkerd 测量和操纵进出你的服务的流量,而不会引入过多的延迟。为了尽可能小、轻和安全,Linkerd 的代理采用 Rust 编写。

功能概述

  • 自动 mTLS:Linkerd 自动为网格应用程序之间的所有通信启用相互传输层安全性 (TLS)。
  • 自动代理注入:Linkerd 会自动将数据平面代理注入到基于 annotations 的 pod 中。
  • 容器网络接口插件:Linkerd 能被配置去运行一个 CNI 插件,该插件自动重写每个 pod 的 iptables 规则。
  • 仪表板和 Grafana:Linkerd 提供了一个 Web 仪表板,以及预配置的 Grafana 仪表板。
  • 分布式追踪:您可以在 Linkerd 中启用分布式跟踪支持。
  • 故障注入:Linkerd 提供了以编程方式将故障注入服务的机制。
  • 高可用性:Linkerd 控制平面可以在高可用性 (HA) 模式下运行。
  • HTTP、HTTP/2 和 gRPC 代理:Linkerd 将自动为 HTTP、HTTP/2 和 gRPC 连接启用高级功能(包括指标、负载平衡、重试等)。
  • Ingress:Linkerd 可以与您选择的 ingress controller 一起工作。
  • 负载均衡:Linkerd 会自动对 HTTP、HTTP/2 和 gRPC 连接上所有目标端点的请求进行负载平衡。
  • 多集群通信:Linkerd 可以透明且安全地连接运行在不同集群中的服务。
  • 重试和超时:Linkerd 可以执行特定于服务的重试和超时。
  • 服务配置文件:Linkerd 的服务配置文件支持每条路由指标以及重试和超时。
  • TCP 代理和协议检测:Linkerd 能够代理所有 TCP 流量,包括 TLS 连接、WebSockets 和 HTTP 隧道。
  • 遥测和监控:Linkerd 会自动从所有通过它发送流量的服务收集指标。
  • 流量拆分(金丝雀、蓝/绿部署):Linkerd 可以动态地将一部分流量发送到不同的服务。

架构

整体上来看 Linkerd 由一个控制平面和一个数据平面组成。

  • 控制平面是一组服务,提供对 Linkerd 整体的控制。
  • 数据平面由在每个服务实例旁边运行的透明微代理(micro-proxies)组成,作为 Pod 中的 Sidecar 容器运行,这些代理会自动处理进出服务的所有 TCP 流量,并与控制平面进行通信以进行配置。

此外 Linkerd 还提供了一个 CLI 工具,可用于控制平面和数据平面进行交互。

架构
架构

控制平面(control plane)

Linkerd 控制平面是一组在专用 Kubernetes 命名空间(默认为 linkerd)中运行的服务,控制平面有几个组件组成:

  • 目标服务(destination):数据平面代理使用 destination 服务来确定其行为的各个方面。它用于获取服务发现信息;获取有关允许哪些类型的请求的策略信息;获取用于通知每条路由指标、重试和超时的服务配置文件信息和其它有用信息。
  • 身份服务(identity):identity 服务充当 TLS 证书颁发机构,接受来自代理的 CSR 并返回签名证书。这些证书在代理初始化时颁发,用于代理到代理连接以实现 mTLS。
  • 代理注入器(proxy injector):proxy injector 是一个 Kubernetes admission controller,它在每次创建 pod 时接收一个 webhook 请求。 此 injector 检查特定于 Linkerd 的 annotation(linkerd.io/inject: enabled)的资源。 当该 annotation 存在时,injector 会改变 pod 的规范, 并将 proxy-init 和 linkerd-proxy 容器以及相关的启动时间配置添加到 pod 中。

数据平面(data plane)

Linkerd 数据平面包含超轻型微代理,这些微代理部署为应用程序 Pod 内的 sidecar 容器。 由于由 linkerd-init(或者,由 Linkerd 的 CNI 插件)制定的 iptables 规则, 这些代理透明地拦截进出每个 pod 的 TCP 连接。

  • 代理(Linkerd2-proxy):Linkerd2-proxy 是一个用 Rust 编写的超轻、透明的微代理。Linkerd2-proxy 专为 service mesh 用例而设计,并非设计为通用代理。代理的功能包括:
    • HTTP、HTTP/2 和任意 TCP 协议的透明、零配置代理。
    • HTTP 和 TCP 流量的自动 Prometheus 指标导出。
    • 透明、零配置的 WebSocket 代理。
    • 自动、延迟感知、第 7 层负载平衡。
    • 非 HTTP 流量的自动第 4 层负载平衡。
    • 自动 TLS。
    • 按需诊断 Tap API。
    • 代理支持通过 DNS 和目标 gRPC API 进行服务发现。
  • Linkerd init 容器:linkerd-init 容器作为 Kubernetes 初始化容器添加到每个网格 Pod 中,该容器在任何其他容器启动之前运行。它使用 iptables 通过代理将所有 TCP 流量,路由到 Pod 和从 Pod 发出。

Linkerd 安装部署

Linkerd命令安装

我们可以通过在本地安装一个 Linkerd 的 CLI 命令行工具,通过该 CLI 可以将 Linkerd 的控制平面安装到 Kubernetes 集群上。

所以首先需要在本地运行 kubectl 命令,确保可以访问一个可用的 Kubernetes 集群,如果没有集群,可以使用 KinD 在本地快速创建一个。

代码语言:javascript
复制
kubectl version --short
Client Version: v1.23.6
Server Version: v1.23.6

可以使用下面的命令在本地安装 Linkerd 的 CLI 工具:

代码语言:javascript
复制
$ curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh

如果是 Mac 系统,同样还可以使用 Homebrew 工具一键安装:

代码语言:javascript
复制
brew install linkerd

同样直接前往 Linkerd Release 页面 https://github.com/linkerd/linkerd2/releases/ 下载安装即可。

安装后使用下面的命令可以验证 CLI 工具是否安装成功:

代码语言:javascript
复制
 linkerd  version
Client version: stable-2.13.1
Server version: unavailable

正常我们可以看到 CLI 的版本信息,但是会出现 Server version: unavailable 信息,这是因为我们还没有在 Kubernetes 集群上安装控制平面造成的,所以接下来我们就来安装 Server 端。

Kubernetes 集群可以通过多种不同的方式进行配置,在安装 Linkerd 控制平面之前,我们需要检查并验证所有配置是否正确,要检查集群是否已准备好安装 Linkerd,可以执行下面的命令:

代码语言:javascript
复制
$ linkerd check --pre      
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version

pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
√ can create non-namespaced resources
√ can create ServiceAccounts
√ can create Services
√ can create Deployments
√ can create CronJobs
√ can create ConfigMaps
√ can create Secrets
√ can read Secrets
√ can read extension-apiserver-authentication configmap
√ no clock skew detected

linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date

Status check results are √

如果一切检查都 OK 则可以开始安装 Linkerd 的控制平面了,直接执行下面的命令即可一键安装:

代码语言:javascript
复制
# 新版需要先安装crd资源,才能执行安装linkerd
linkerd install --crds |kubectl apply -f -

linkerd install |kubectl apply -f -

在此命令中,linkerd install 会生成一个 Kubernetes 资源清单文件,其中包含所有必要的控制平面资源,然后使用 kubectl apply 命令即可将其安装到 Kubernetes 集群中。

可以看到会将 Linkerd 控制面安装到一个名为 linkerd 的命名空间之下,安装完成后会有如下几个 Pod 运行:

代码语言:javascript
复制
$ kubectl get pods -n linkerd
NAME                                      READY   STATUS    RESTARTS   AGE
linkerd-destination-7fcf6649dd-h2ztv      4/4     Running   0          92s
linkerd-identity-68d57d5-5trt8            2/2     Running   0          93s
linkerd-proxy-injector-759c487549-lqvjm   2/2     Running   0          92s

安装完成后通过运行以下命令等待控制平面准备就绪,并可以验证安装结果是否正常:

代码语言:javascript
复制
$ linkerd check
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version

linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ control plane pods are ready
√ cluster networks contains all pods
√ cluster networks contains all services

linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist
√ proxy-init container runs as root user if docker container runtime is used

linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor

linkerd-webhooks-and-apisvc-tls
-------------------------------
√ proxy-injector webhook has valid cert
√ proxy-injector cert is valid for at least 60 days
√ sp-validator webhook has valid cert
√ sp-validator cert is valid for at least 60 days
√ policy-validator webhook has valid cert
√ policy-validator cert is valid for at least 60 days

linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date

control-plane-version
---------------------
√ can retrieve the control plane version
√ control plane is up-to-date
√ control plane and cli versions match

linkerd-control-plane-proxy
---------------------------
√ control plane proxies are healthy
√ control plane proxies are up-to-date
√ control plane proxies and cli versions match

Status check results are √

当出现上面的 Status check results are √ 信息后表示 Linkerd 的控制平面安装成功了。

Helm安装

除了使用 CLI 工具的方式安装控制平面之外,我们也可以通过 Helm Chart 的方式来安装,如下所示:

代码语言:javascript
复制
$ helm repo add linkerd https://helm.linkerd.io/stable
$ exp=$(date -d '+8760 hour' +"%Y-%m-%dT%H:%M:%SZ")
#$ exp=$(date -v+8760H +"%Y-%m-%dT%H:%M:%SZ") set expiry date one year from now, in Mac:
helm install linkerd2 \
  --set-file identityTrustAnchorsPEM=ca.crt \
  --set-file identity.issuer.tls.crtPEM=issuer.crt \
  --set-file identity.issuer.tls.keyPEM=issuer.key \
  --set identity.issuer.crtExpiry=$exp \
  linkerd/linkerd2

此外该 chart 包含一个 values-ha.yaml 文件, 它覆盖了一些默认值,以便在高可用性场景下进行设置, 类似于 linkerd install 中的 --ha 选项。我们可以通过获取 chart 文件来获得 values-ha.yaml

采用哪种方式进行安装均可,到这里我们现在就完成了 Linkerd 的安装,重新执行 linkerd version 命令就可以看到 Server 端版本信息了:

代码语言:javascript
复制
$ linkerd version
Client version: stable-2.13.1
Server version: stable-2.13.1

Linkerd Viz 扩展安装部署

另外还有一个需要注意的是 viz 插件,在最新版本中已经没有内置 grafana 了,由于新版本已经没有内置 Grafana 了,我们安装的使用可以通过 --set grafana.url 来指定外部的 Grafana 地址(如果是集群外的地址可以通过 grafana.externalUrl 参数指定)。通过dashboard.enforcedHostRegexp来指定允许那些域名、IP进行访问dashboard。 **官方参数介绍**:https://github.com/linkerd/linkerd2/blob/main/viz/charts/linkerd-viz/README.md

代码语言:javascript
复制
linkerd viz install --set grafana.externalUrl=http://grafana.od.com,dashboard.enforcedHostRegexp='^(localhost|127\\.0\\.0\\.1|web\\.linkerd-viz\\.svc\\.cluster\\.local|web\\.linkerd-viz\\.svc|viz\\.od\\.com|\\[::1\\])(:\d+)?$'|kubectl apply -f -

安装完成后通过运行以下命令等待Viz 扩展平面准备就绪,并可以验证安装结果是否正常:

代码语言:javascript
复制
$ linkerd check
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API

kubernetes-version
------------------
√ is running the minimum Kubernetes API version

linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ control plane pods are ready
√ cluster networks contains all pods
√ cluster networks contains all services

linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist
√ proxy-init container runs as root user if docker container runtime is used

linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor

linkerd-webhooks-and-apisvc-tls
-------------------------------
√ proxy-injector webhook has valid cert
√ proxy-injector cert is valid for at least 60 days
√ sp-validator webhook has valid cert
√ sp-validator cert is valid for at least 60 days
√ policy-validator webhook has valid cert
√ policy-validator cert is valid for at least 60 days

linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date

control-plane-version
---------------------
√ can retrieve the control plane version
√ control plane is up-to-date
√ control plane and cli versions match

linkerd-control-plane-proxy
---------------------------
√ control plane proxies are healthy
√ control plane proxies are up-to-date
√ control plane proxies and cli versions match

linkerd-viz
-----------
√ linkerd-viz Namespace exists
√ can initialize the client
√ linkerd-viz ClusterRoles exist
√ linkerd-viz ClusterRoleBindings exist
√ tap API server has valid cert
√ tap API server cert is valid for at least 60 days
√ tap API service is running
√ linkerd-viz pods are injected
√ viz extension pods are running
√ viz extension proxies are healthy
√ viz extension proxies are up-to-date
√ viz extension proxies and cli versions match
√ prometheus is installed and configured correctly
√ viz extension self-check

Status check results are √

此外我们也可以通过 Ingress 来暴露 viz 服务,创建如下所示的资源对象:

代码语言:javascript
复制
cat > viz-ing.yaml <<EOF
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: websocket
  namespace: linkerd-viz
spec:
  headers: # 配置websocket访问
    customRequestHeaders:
      Connection: keep-alive, Upgrade
      Upgrade: WebSocket
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: linkerd-dashboard
  namespace: linkerd-viz
  annotations:
    ingress.kubernetes.io/custom-request-headers: l5d-dst-override:web.linkerd-viz.svc.cluster.local:8084
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`viz.od.com`)  # 指定域名
    kind: Rule
    services:
    - name: web
      port: 8084
  - match: Host(`viz.od.com`) && Path(`/api/tap`)
    middlewares:
      - name: websocket
        namespace: linkerd-viz
    kind: Rule
    services:
    - name: web
      port: 8084
EOF

浏览器打开https://viz.od.com/

在对应的资源后面包含一个 Grafana 的图标,点击可以自动跳转到 Grafana 的监控页面。

grafana部署yaml

官方文档https://linkerd.io/2.13/tasks/grafana/index.html

代码语言:javascript
复制
cat > grafana.yaml <<EOF
# Source: grafana/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
  name: grafana
  namespace: infra
---
# Source: grafana/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana
  namespace: infra
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
data:
  grafana.ini: |
    [analytics]
    check_for_updates = false
    [auth]
    disable_login_form = true
    [auth.anonymous]
    enabled = true
    org_role = Editor
    [auth.basic]
    enabled = false
    [grafana_net]
    url = https://grafana.net
    [log]
    mode = console
    [log.console]
    format = text
    level = info
    [panels]
    disable_sanitize_html = true
    [paths]
    data = /var/lib/grafana/
    logs = /var/log/grafana
    plugins = /var/lib/grafana/plugins
    provisioning = /etc/grafana/provisioning
    [server]
    domain = ''
    root_url = %(protocol)s://%(domain)s:/grafana/
    serve_from_sub_path = true
  datasources.yaml: |
    apiVersion: 1
    datasources:
    - access: proxy
      editable: true
      isDefault: true
      jsonData:
        timeInterval: 5s
      name: prometheus
      orgId: 1
      type: prometheus
      url: http://prometheus.linkerd-viz.svc.cluster.local:9090
  dashboardproviders.yaml: |
    apiVersion: 1
    providers:
    - disableDeletion: false
      editable: true
      folder: ""
      name: default
      options:
        path: /var/lib/grafana/dashboards/default
      orgId: 1
      type: file
  download_dashboards.sh: |
    #!/usr/bin/env sh
    grafana_dir="/var/lib/grafana/dashboards/default"
    
    if [ ! -d "\$grafana_dir" ]; then
      mkdir -p "\$grafana_dir"
    fi

    download_dashboard() {
      local url="\$1"
      local file="\$2"
      if [ ! -f "\$file" ]; then
        echo "Downloading \$url..."
        curl -skf --connect-timeout 60 --max-time 60 \
          -H "Accept: application/json" \
          -H "Content-Type: application/json;charset=UTF-8" \
          "\$url" | sed '/-- .* --/! s/"datasource":.*,/"datasource": "prometheus",/g' \
          > "\$file"
      else
        echo "File \$file already exists"
      fi
    }

    # Download dashboards 如果文件存在而不会下载,不存在就会下载
    download_dashboard "https://grafana.com/api/dashboards/15482/revisions/2/download" \
      "\$grafana_dir/authority.json"
    download_dashboard "https://grafana.com/api/dashboards/15483/revisions/2/download" \
      "\$grafana_dir/cronjob.json"
    download_dashboard "https://grafana.com/api/dashboards/15484/revisions/2/download" \
      "\$grafana_dir/daemonset.json"
    download_dashboard "https://grafana.com/api/dashboards/15475/revisions/5/download" \
      "\$grafana_dir/deployment.json"
    download_dashboard "https://grafana.com/api/dashboards/15486/revisions/2/download" \
      "\$grafana_dir/health.json"
    download_dashboard "https://grafana.com/api/dashboards/15487/revisions/2/download" \
      "\$grafana_dir/job.json"
    download_dashboard "https://grafana.com/api/dashboards/15479/revisions/2/download" \
      "\$grafana_dir/kubernetes.json"
    download_dashboard "https://grafana.com/api/dashboards/15488/revisions/2/download" \
      "\$grafana_dir/multicluster.json"
    download_dashboard "https://grafana.com/api/dashboards/15478/revisions/2/download" \
      "\$grafana_dir/namespace.json"
    download_dashboard "https://grafana.com/api/dashboards/15477/revisions/2/download" \
      "\$grafana_dir/pod.json"
    download_dashboard "https://grafana.com/api/dashboards/15489/revisions/2/download" \
      "\$grafana_dir/prometheus.json"
    download_dashboard "https://grafana.com/api/dashboards/15490/revisions/2/download" \
      "\$grafana_dir/prometheus-benchmark.json"
    download_dashboard "https://grafana.com/api/dashboards/15491/revisions/2/download" \
      "\$grafana_dir/replicaset.json"
    download_dashboard "https://grafana.com/api/dashboards/15492/revisions/2/download" \
      "\$grafana_dir/replicationcontroller.json"
    download_dashboard "https://grafana.com/api/dashboards/15481/revisions/2/download" \
      "\$grafana_dir/route.json"
    download_dashboard "https://grafana.com/api/dashboards/15480/revisions/2/download" \
      "\$grafana_dir/service.json"
    download_dashboard "https://grafana.com/api/dashboards/15493/revisions/2/download" \
      "\$grafana_dir/statefulset.json"
    download_dashboard "https://grafana.com/api/dashboards/15474/revisions/3/download" \
      "\$grafana_dir/top-line.json"
---
# Source: grafana/templates/dashboards-json-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-dashboards-default
  namespace: infra
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
    dashboard-provider: default
data:
  {}
---
# Source: grafana/templates/clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
  name: grafana-clusterrole
rules: []
---
# Source: grafana/templates/clusterrolebinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: grafana-clusterrolebinding
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
subjects:
  - kind: ServiceAccount
    name: grafana
    namespace: infra
roleRef:
  kind: ClusterRole
  name: grafana-clusterrole
  apiGroup: rbac.authorization.k8s.io
---
# Source: grafana/templates/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: grafana
  namespace: infra
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
rules: []
---
# Source: grafana/templates/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: grafana
  namespace: infra
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: grafana
subjects:
- kind: ServiceAccount
  name: grafana
  namespace: infra
---
# Source: grafana/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: infra
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
spec:
  type: ClusterIP
  ports:
    - name: service
      port: 80
      protocol: TCP
      targetPort: 3000
  selector:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
---
# Source: grafana/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: infra
  labels:
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "9.4.7"
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/name: grafana
      app.kubernetes.io/instance: grafana
  template:
    metadata:
      labels:
        app.kubernetes.io/name: grafana
        app.kubernetes.io/instance: grafana
      annotations:
        linkerd.io/inject: enabled
    spec:
      nodeName: k8s-node1
      serviceAccountName: grafana
      automountServiceAccountToken: true
      securityContext:
        runAsUser: 0
      initContainers: # 通过初始化认为下载所需要的dashboards
        - name: download-dashboards
          image: "docker.io/curlimages/curl:7.85.0"
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh"]
          args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh -x /etc/grafana/download_dashboards.sh" ]
          volumeMounts:
            - name: config
              mountPath: "/etc/grafana/download_dashboards.sh"
              subPath: download_dashboards.sh
            - name: storage
              mountPath: "/var/lib/grafana"
      enableServiceLinks: true
      containers:
        - name: grafana
          image: "docker.io/grafana/grafana:9.4.7"
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: config
              mountPath: "/etc/grafana/grafana.ini"
              subPath: grafana.ini
            - name: storage
              mountPath: "/var/lib/grafana"
            - name: config
              mountPath: "/etc/grafana/provisioning/datasources/datasources.yaml"
              subPath: "datasources.yaml"
            - name: config
              mountPath: "/etc/grafana/provisioning/dashboards/dashboardproviders.yaml"
              subPath: "dashboardproviders.yaml"
          ports:
            - name: grafana
              containerPort: 3000
              protocol: TCP
          env:
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: GF_PATHS_DATA
              value: /var/lib/grafana/
            - name: GF_PATHS_LOGS
              value: /var/log/grafana
            - name: GF_PATHS_PLUGINS
              value: /var/lib/grafana/plugins
            - name: GF_PATHS_PROVISIONING
              value: /etc/grafana/provisioning
          livenessProbe:
            failureThreshold: 10
            httpGet:
              path: /api/health
              port: 3000
            initialDelaySeconds: 60
            timeoutSeconds: 30
          readinessProbe:
            httpGet:
              path: /api/health
              port: 3000
      volumes:
        - name: config
          configMap:
            name: grafana
        - name: dashboards-default
          configMap:
            name: grafana-dashboards-default
        - name: storage  # 挂载到本地
          hostPath:
            path: /data/volumes/grafana
EOF

通过traefik实现外部访问

代码语言:javascript
复制
cat > k8s-yaml/grafana/ing.yaml <EOF
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: grafana-web
  namespace: infra
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`grafana.od.com`)  # 指定域名
    kind: Rule
    services:
    - name: grafana
      port: 80
EOF
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Linkerd服务网格安装部署
  • Linkerd 介绍
    • 功能概述
      • 架构
      • Linkerd 安装部署
        • Linkerd命令安装
          • Helm安装
          • Linkerd Viz 扩展安装部署
            • grafana部署yaml
              • 通过traefik实现外部访问
              相关产品与服务
              服务网格
              服务网格(Tencent Cloud Mesh, TCM),一致、可靠、透明的云原生应用通信网络管控基础平台。全面兼容 Istio,集成腾讯云基础设施,提供全托管服务化的支撑能力保障网格生命周期管理。IaaS 组网与监控组件开箱即用,跨集群、异构应用一致发现管理加速云原生迁移。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档