Chemmy's Blog

chengming0916@outlook.com

LibVLCSharp版本

1
2
3
<PackageReference Include="LibVLCSharp" version="3.6.6" />
<PackageReference Include="LibVLCSharp.WPF" version="3.6.6" />
<PackageReference Include="VideoLAN.LibVLC.Windows" version="3.0.16" />

现象播放RTSP视频流时在VideoView播放正常,但会弹出一个窗体同时播放,窗体名VLC (Direct3D11 output)

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public partial class MainWindow : Window
{
private LibVLC m_libVLC;

public MainWindow()
{
InitializeComponent();

this.Loaded += MainWindow_Loaded;

m_libVLC = new LibVLC();
}

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
VideoView.MediaPlayer = new LibVLCSharp.Shared.MediaPlayer(m_libVLC);
VideoView.MediaPlayer.Play(new Media(m_libVLC, new Uri(uri)));
}
}

故障原因

打断点调试发现,Loaded时间执行两次,第一次执行在VideoView播放正常,第二次执行弹出VLC (Direct3D11 output)

解决方法: 控制只初始化和播放一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public partial class MainWindow : Window
{
private LibVLC m_libVLC;

public MainWindow()
{
InitializeComponent();

this.Loaded += MainWindow_Loaded;

m_libVLC = new LibVLC();
}

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
VideoView.MediaPlayer ??= new LibVLCSharp.Shared.MediaPlayer(m_libVLC)
{
Media = new Media(m_libVLC, new Uri(uri))
};

if (!VideoView.MediaPlayer.IsPlaying)
VideoView.MediaPlayer.Play();
}
}

PostgreSQL作为一款高性能、开源的关系型数据库,在云原生场景中,常需与轻量级Kubernetes发行版K3s结合部署,以实现资源高效利用与灵活运维。本文将详细拆解基于K3s部署PostgreSQL的完整流程,涵盖存储配置、配置管理、服务暴露及部署编排等核心环节,助力开发者快速完成部署落地。

一、环境准备

部署前需确保K3s集群已正常运行,且kubectl工具已完成集群连接配置(可通过kubectl get nodes命令验证集群状态)。本文所有资源配置均部署在独立的postgres命名空间下,避免与其他应用资源冲突,需先执行以下命令创建该命名空间:

1
kubectl create namespace postgres

二、存储配置:PersistentVolume与PersistentVolumeClaim

PostgreSQL作为有状态应用,数据持久化是核心需求。本文提供两种存储配置方案,可根据集群规模(单节点/多节点)及实际存储需求灵活选择。

方案1:基于local-path存储类(单节点场景)

local-path是K3s默认集成的存储类,适用于单节点K3s集群,无需手动创建PersistentVolume(PV),仅需定义PersistentVolumeClaim(PVC),系统会自动创建PV并完成绑定。创建postgres-pvc-local-path.yaml配置文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
namespace: postgres
labels:
app: postgres
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 10Gi

该配置声明了10Gi的存储资源请求,访问模式为ReadWriteOnce(仅允许单个节点读写),完全适配单节点K3s的部署场景,配置简洁且无需额外运维。

方案2:基于hostPath的自定义存储类(多节点/自定义路径场景)

若需自定义存储路径,或集群为多节点架构,可手动创建PV并绑定PVC,实现更灵活的存储管理。创建postgres-pvc-host-path.yaml文件,包含PV与PVC的完整定义(修正原文中storge的拼写错误为storage):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
namespace: postgres
labels:
app: postgres
spec:
storageClassName: postgres-persistent-storage
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
hostPath:
path: /mnt/postgres/data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
labels:
app: postgres
spec:
storageClassName: postgres-persistent-storage
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi

需提前在集群节点上创建/mnt/postgres/data目录,并确保目录权限正确(建议设置为777或匹配Pod运行用户权限);访问模式ReadWriteMany支持多节点读写,可满足多节点K3s集群的部署需求。

执行以下命令创建对应存储资源:

1
2
3
4
# 方案1(单节点)
kubectl apply -f postgres-pvc-local-path.yaml
# 方案2(多节点/自定义路径)
kubectl apply -f postgres-pvc-host-path.yaml

三、配置管理:ConfigMap定义环境变量

PostgreSQL的核心初始化配置(如默认数据库名、管理员用户名、密码)可通过ConfigMap统一管理,便于后续配置修改与维护,无需重新构建镜像或重启Pod。创建postgres-config.yaml配置文件:

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-config
namespace: postgres
labels:
app: postgres
data:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres

本文为简化部署流程,使用ConfigMap存储密码;实际生产环境中,建议使用Secret存储敏感信息(如数据库密码),提升配置安全性。

执行以下命令创建ConfigMap资源:

1
kubectl apply -f postgres-config.yaml

四、服务暴露:Service与IngressRouteTCP

为实现PostgreSQL的可访问性,需根据访问场景(集群内/集群外)配置对应的服务暴露方式。K3s默认集成Traefik作为Ingress控制器,可通过Service实现集群内访问,通过IngressRouteTCP实现集群外访问。

1. ClusterIP类型Service(集群内访问)

创建postgres-service.yaml文件,定义ClusterIP类型的Service,监听PostgreSQL默认端口5432,实现集群内Pod间的访问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: postgres
labels:
app: postgres
spec:
ports:
- port: 5432
targetPort: 5432
protocol: TCP
selector:
app: postgres
type: ClusterIP

ClusterIP类型Service仅允许集群内Pod访问,集群内其他应用可通过服务域名postgres.postgres.svc.cluster.local:5432连接PostgreSQL数据库。

2. IngressRouteTCP(集群外访问)

若需从集群外访问PostgreSQL,可通过Traefik的IngressRouteTCP暴露TCP端口。创建postgres-ingress.yaml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: postgres-tcp
namespace: postgres
labels:
app: postgres
spec:
entryPoints:
- postgres
routes:
- match: HostSNI(`*`)
services:
- name: postgres
port: 5432

需先在Traefik控制器中配置postgres入口点(entryPoints),指定监听的主机端口(建议与PostgreSQL默认端口5432保持一致),否则IngressRouteTCP配置无法生效。

执行以下命令创建服务相关资源:

1
2
kubectl apply -f postgres-service.yaml
kubectl apply -f postgres-ingress.yaml

五、部署编排:StatefulSet部署PostgreSQL

PostgreSQL作为有状态应用,推荐使用StatefulSet而非Deployment部署,可确保Pod拥有稳定的网络标识和持久化存储,避免因Pod重启导致数据丢失或网络地址变更。创建postgres-statefulset.yaml文件(修正原文“deployment.yaml”命名偏差,贴合StatefulSet资源类型):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: postgres
labels:
app: postgres
spec:
selector:
matchLabels:
app: postgres
replicas: 1
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5432
envFrom:
- configMapRef:
name: postgres-config
volumeMounts:
- name: postgredb
mountPath: /var/lib/postgresql/data
volumes:
- name: postgredb
persistentVolumeClaim:
claimName: postgres-pvc

使用postgres:16.3稳定版本镜像,通过envFrom批量加载ConfigMap中的环境变量,将PVC挂载到PostgreSQL的数据存储目录/var/lib/postgresql/data,确保数据持久化;镜像拉取策略设为IfNotPresent,避免重复拉取镜像,提升部署效率。

执行以下命令部署PostgreSQL:

1
kubectl apply -f postgres-statefulset.yaml

六、验证部署结果

部署完成后,需通过一系列命令验证各资源状态,确保PostgreSQL正常运行。

  1. 检查PVC绑定状态:
1
kubectl get pvc -n postgres

正常情况下,PVC的STATUS列显示为Bound,表示存储绑定成功。

  1. 检查StatefulSet与Pod运行状态:
1
2
kubectl get statefulset -n postgres
kubectl get pods -n postgres

确保StatefulSet的READY列显示为1/1(副本数为1时),Pod的STATUS列显示为Running,无异常重启记录。

  1. 测试数据库连接:
1
2
3
4
# 进入PostgreSQL Pod内部
kubectl exec -it postgres-0 -n postgres -- bash
# 连接PostgreSQL数据库(使用ConfigMap中定义的用户名和数据库名)
psql -U postgres -d postgres

若能成功进入PostgreSQL命令行界面(显示postgres=#提示符),说明PostgreSQL部署成功且可正常使用。

总结

本文基于K3s原生资源(PVC/PV、ConfigMap、Service、StatefulSet),完成了PostgreSQL的全流程部署,覆盖了存储配置、配置管理、服务暴露、部署编排及结果验证等核心环节,流程清晰、可操作性强。在实际生产环境中,可根据业务需求灵活调整:如增加副本数实现高可用、使用Secret管理敏感信息、优化Ingress配置实现访问控制等,进一步提升部署的安全性与稳定性。

在K3s集群中部署MySQL,需结合Kubernetes资源编排特性,合理配置存储、网络、配置项等核心组件,确保数据库服务稳定、可访问且数据安全。本文将详细拆解基于K3s部署MySQL的完整流程,涵盖资源配置文件编写、部署操作及关键注意要点,助力开发者快速完成部署落地。

一、环境说明

本文基于K3s集群环境,通过Kubernetes各类核心资源对象(StatefulSet、Service、PVC/PV、ConfigMap、IngressRouteTCP),实现MySQL 5.7版本的规范化部署,重点保障数据持久化、集群内外网络可访问及配置灵活自定义。所有资源均部署在mysql命名空间下,需提前执行命令创建该命名空间:kubectl create namespace mysql

二、核心资源配置与部署

1. 配置自定义参数:ConfigMap

MySQL的核心运行参数通过ConfigMap进行统一管理,便于后续参数调整、维护及复用。创建mysql-config.yaml配置文件,明确定义字符集、最大连接数、绑定地址等关键参数,具体内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: mysql
labels:
app: mysql-config
data:
mysqld.cnf: |
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
skip-character-set-client-handshake = true
max_connections=2000
secure_file_priv=/var/lib/mysql
datadir=/var/lib/mysql
bind-address=0.0.0.0
symbolic-links=0

该配置已做针对性优化:将字符集统一设置为utf8mb4,彻底解决中文乱码及特殊字符存储问题;绑定地址设为0.0.0.0,确保MySQL可被K3s集群内所有节点访问;调整最大连接数至2000,满足中高并发业务场景需求。配置文件编写完成后,执行以下命令部署ConfigMap:

1
kubectl apply -f mysql-config.yaml

2. 数据持久化:PVC/PV配置

MySQL作为关系型数据库,数据持久化是核心需求,需通过PVC(持久化卷声明)和PV(持久化卷)配置,避免Pod重建、重启后数据丢失。本文提供两种存储方案,可根据实际部署场景灵活选择。

方案1:基于local-path存储类(推荐)

K3s集群默认内置local-path存储类,无需手动创建PV,仅需创建PVC即可自动完成PV绑定,部署高效便捷。创建mysql-pvc-local-path.yaml文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: mysql
labels:
app: mysql
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 10Gi

执行部署命令,完成PVC创建:

1
kubectl apply -f mysql-pvc-local-path.yaml

方案2:基于hostPath的PV/PVC(自定义存储路径)

若需指定K3s节点本地具体路径作为MySQL数据存储位置,可手动创建PV和PVC。需注意,原始配置文件mysql-pvc-host-path.yaml中存在笔误(storge应为storage),修正后完整配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
namespace: mysql
labels:
app: mysql
spec:
storageClassName: mysql-persistent-storage
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
hostPath:
path: /var/lib/mysql/data

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: mysql
labels:
app: mysql
spec:
storageClassName: mysql-persistent-storage
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi

执行部署命令,完成PV和PVC创建:

1
kubectl apply -f mysql-pvc-host-path.yaml

注意:hostPath存储方案仅适用于单节点K3s集群;多节点集群需使用NFS等共享存储方案,确保数据一致性和可访问性。

3. 部署MySQL实例:StatefulSet

采用StatefulSet部署MySQL实例,可保证Pod名称固定、存储挂载稳定,更适配数据库这类有状态应用的部署需求。创建mysql-deployment.yaml文件(实际为StatefulSet资源类型,命名仅为便于识别),具体配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: mysql
labels:
app: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: root
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
- name: mysql-config
mountPath: /etc/mysql/mysql.conf.d
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pvc
- name: mysql-config
configMap:
name: mysql-config

该配置核心说明:

  • 镜像选用mysql:5.7稳定版本,通过环境变量MYSQL_ROOT_PASSWORD直接设置root用户密码为root(注:生产环境需使用Secret存储密码,避免明文暴露);

  • 将PVC挂载至MySQL默认数据目录/var/lib/mysql,确保数据持久化;将ConfigMap挂载至MySQL配置文件目录,覆盖默认配置,应用自定义参数;

  • 暴露3306端口,为集群内访问提供基础。

执行部署命令,启动MySQL实例:

1
kubectl apply -f mysql-deployment.yaml

4. 集群内访问:Service配置

创建ClusterIP类型的Service,为MySQL实例提供稳定的集群内访问地址,避免因Pod IP变化导致访问失败。创建mysql-service.yaml文件,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: mysql
labels:
app: mysql
spec:
ports:
- name: tcp
port: 3306
protocol: TCP
targetPort: mysql
selector:
app: mysql
type: ClusterIP

部署完成后,K3s集群内其他Pod可通过固定域名mysql.mysql.svc.cluster.local:3306访问MySQL服务,无需关注具体Pod IP。执行部署命令:

1
kubectl apply -f mysql-service.yaml

5. 外部访问:IngressRouteTCP配置

若需从K3s集群外部访问MySQL服务,可结合K3s默认Ingress控制器(Traefik),配置IngressRouteTCP实现TCP流量转发。创建mysql-ingress.yaml文件,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: mysql-tcp
namespace: mysql
spec:
entryPoints:
- mysql
routes:
- match: HostSNI(`*`)
services:
- name: mysql
port: 3306

注意:需提前在Traefik中配置mysql入口点(entryPoints),并监听指定端口(如3306),确保外部流量可正常转发至MySQL Service,否则外部访问会失败。

执行部署命令,完成IngressRouteTCP配置:

1
kubectl apply -f mysql-ingress.yaml

三、部署验证

部署完成后,需通过一系列操作验证MySQL服务是否正常运行、配置是否生效,具体步骤如下:

  1. 检查所有相关资源状态,确认部署无异常: kubectl get all -n mysql kubectl get pvc,pv -n mysql kubectl get configmap -n mysql 若所有资源均处于Running、Bound等正常状态,说明部署基础无问题。

  2. 验证MySQL内部连接及配置生效情况: # 进入MySQL Pod内部 kubectl exec -it mysql-0 -n mysql -- mysql -uroot -proot # 执行SQL命令,验证字符集等配置是否生效 mysql> show variables like '%character%'; 若查询结果中字符集相关参数均为utf8mb4,说明配置已成功应用。

  3. 外部访问验证(若已配置IngressRouteTCP): mysql -h <K3s节点IP> -P <Traefik监听端口> -uroot -proot 若能成功登录MySQL,说明外部访问配置生效。

四、注意事项

  1. 生产环境安全规范:MYSQL_ROOT_PASSWORD严禁明文写在配置文件中,需通过Kubernetes的Secret资源存储,提升密码安全性。

  2. 多节点集群存储建议:多节点K3s集群中,应使用Longhorn等分布式存储替代hostPath,避免单节点故障导致数据丢失,保障数据库高可用。

  3. 架构扩展说明:本文部署的为MySQL单实例,若需实现主从复制、读写分离架构,需在ConfigMap中额外配置主从复制相关参数,并调整StatefulSet配置。

  4. 数据备份要求:需定期备份PVC挂载目录中的数据,可通过定时任务脚本或专业备份工具实现,防止存储故障、误操作导致数据丢失。

  5. 配置更新生效:修改ConfigMap中的MySQL参数后,需重启MySQL StatefulSet使配置生效,执行命令:kubectl rollout restart statefulset mysql -n mysql

通过以上步骤,可在K3s集群中快速、规范地部署一个配置可定制、数据可持久化、网络可访问的MySQL实例,满足开发测试或生产环境的基础数据库使用需求,同时为后续架构优化、性能调优提供基础。

0%