> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cooree.co/llms.txt
> Use this file to discover all available pages before exploring further.

# VictoriaLogs 部署

> 在 Kubernetes 中部署 VictoriaLogs 日志存储与查询服务

VictoriaLogs 负责接收、存储和查询日志。本文使用单副本 StatefulSet 部署 VictoriaLogs,并通过 NodePort 暴露写入、查询和健康检查接口。

## 环境前提

* 已配置 `kubeconfig`,可以执行 `kubectl`
* 目标节点至少有 50 GiB 可用磁盘空间
* 目标节点可以拉取 VictoriaLogs 镜像

<Warning>
  本清单使用节点本地 `hostPath` 持久卷,并将 Pod 固定在 `worko1` 节点。应用清单前,请把节点名替换为实际值。生产环境请使用 NFS、Ceph、Longhorn 或云厂商 CSI 存储。
</Warning>

查看可用节点名:

```bash theme={null}
kubectl get nodes
```

## 部署参数

| 配置       | 默认值                                                             | 说明                      |
| -------- | --------------------------------------------------------------- | ----------------------- |
| 镜像       | `uhub.service.ucloud.cn/kubernetes_images/victoria-logs:latest` | 生产环境应固定版本               |
| 数据目录     | `worko1:/var/lib/observability/victorialogs`                    | 节点本地目录                  |
| 存储容量     | `50Gi`                                                          | 按日志量和保留周期调整             |
| 保留周期     | `30d`                                                           | 由 `-retentionPeriod` 控制 |
| NodePort | `30942`                                                         | 对外提供 HTTP 接口            |

## 部署清单

把以下内容保存为 `victorialogs.yaml`:

```yaml victorialogs.yaml theme={null}
apiVersion: v1
kind: Namespace
metadata:
  name: observability
  labels:
    app.kubernetes.io/part-of: observability
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: victorialogs-local-pv
  labels:
    app.kubernetes.io/name: victorialogs
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ""
  hostPath:
    path: /var/lib/observability/victorialogs
    type: DirectoryOrCreate
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - worko1
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: victorialogs-data
  namespace: observability
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ""
  volumeName: victorialogs-local-pv
  resources:
    requests:
      storage: 50Gi
---
apiVersion: v1
kind: Service
metadata:
  name: victorialogs
  namespace: observability
  labels:
    app.kubernetes.io/name: victorialogs
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: victorialogs
  ports:
    - name: http
      port: 9428
      targetPort: http
      nodePort: 30942
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: victorialogs
  namespace: observability
  labels:
    app.kubernetes.io/name: victorialogs
spec:
  serviceName: victorialogs
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: victorialogs
  template:
    metadata:
      labels:
        app.kubernetes.io/name: victorialogs
    spec:
      nodeSelector:
        kubernetes.io/hostname: worko1
      containers:
        - name: victorialogs
          image: uhub.service.ucloud.cn/kubernetes_images/victoria-logs:latest
          imagePullPolicy: IfNotPresent
          args:
            - -storageDataPath=/victoria-logs-data
            - -retentionPeriod=30d
            - -httpListenAddr=:9428
          ports:
            - name: http
              containerPort: 9428
          readinessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 30
            periodSeconds: 20
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
            limits:
              cpu: "2"
              memory: 2Gi
          volumeMounts:
            - name: data
              mountPath: /victoria-logs-data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: victorialogs-data
```

## 应用并验证

```bash theme={null}
kubectl apply -f victorialogs.yaml
kubectl -n observability rollout status statefulset/victorialogs --timeout=180s
kubectl -n observability get pod,pvc,service -l app.kubernetes.io/name=victorialogs
```

把 `<节点IP>` 替换为集群节点地址,检查服务健康状态:

```bash theme={null}
curl http://<节点IP>:30942/health
```

预期返回 `OK`。

## 写入与查询测试

写入一条测试日志:

```bash theme={null}
curl -X POST http://<节点IP>:30942/insert/jsonline \
  -H 'Content-Type: application/stream+json' \
  --data-binary '{"_time":"2026-09-10T03:00:00Z","_msg":"observability test","level":"info","service":"demo"}'
```

查询最近 1 小时日志和指定服务日志:

```bash theme={null}
curl --get 'http://<节点IP>:30942/select/logsql/query' --data-urlencode 'query=_time:1h'
curl --get 'http://<节点IP>:30942/select/logsql/query' --data-urlencode 'query=service:demo'
```

## 常见故障

| 现象             | 排查方法                                                                |
| -------------- | ------------------------------------------------------------------- |
| Pod 一直 Pending | 检查 `worko1` 节点名、PV 的 nodeAffinity 和 PVC 绑定状态                        |
| Pod 镜像拉取失败     | 执行 `kubectl -n observability describe pod victorialogs-0`,检查镜像仓库连通性 |
| 健康检查失败         | 查看 `kubectl -n observability logs victorialogs-0`,确认数据目录可写          |
| 查询不到日志         | 先手工写入测试日志,再检查 Vector 的 sink 状态                                      |

## 删除组件

```bash theme={null}
kubectl -n observability delete statefulset victorialogs
kubectl -n observability delete service victorialogs
kubectl -n observability delete pvc victorialogs-data
```

<Warning>
  PV 的回收策略是 `Retain`。删除 PVC 不会删除 PV 和节点数据。确认数据不再需要后,再删除 `victorialogs-local-pv` 并清理节点目录。
</Warning>

## 下一步

* [部署 Vector](/observability/vector-victorialogs/vector):采集 Kubernetes 容器日志
* [部署 Grafana](/observability/vector-victorialogs/grafana):查询和展示日志
