0%

KubeEdge中的数据结构设计

Device

字段 类型 说明
ID string 设备唯一编码
Name string 设备名称
Description string 设别描述
State string 设备状态
LastOnline DateTime 最后在线时间
Attributes Map<string,MsgAttr> 设备属性(上报属性)
Twin Map<string,MsgTwin> 设备孪生属性(可控制属性)

MsgAttr

字段 类型 说明
Value string 属性名称
Optional bool 是否可为空
Metadata TypeMetadata 属性类型元数据

MsgTwin

字段 类型 说明
Expected TwinValue 期望值
Actual TwinValue 实际值
Optional bool 是否可为空
Metadata TypeMetadata 属性类型元数据
ExpectedVersion TwinVersion 期望值版本
ActualVersion TwinVersion 实际值版本

数据库表设计

Device

字段 类型 说明
ID 设备实例唯一ID
Name 设备实例名称
Description 设备描述
State 设备状态
LastOnline 最后在线时间

DeviceAttr

字段 类型 说明
ID 属性实例唯一ID
DeviceId 设备实例唯一ID
Name 设备名称
Description 设备描述
Value 设备属性值
Optional bool 是否可空
AttrType 属性类型
Metadata 属性元数据

DeviceTwin

字段 类型 说明
ID
DeviceID
Name
Description
Expected
Actual
ExpectedMeta
ActualMeta
ExpectedVersion
ActualVersion
Optional
AttrType
Metadata

DEVICE

字段 类型 说明
ID int 自增ID
SN varchar(20) 设备唯一编码
NAME varchar(20) 设备名称
MARKED BOOL 设备是否标记
IP varchar(15) 设备IP地址
LOCATION varchar(200) 设备安装位置

DEVICE_ATTR

字段 类型 说明
ID int 自增ID
KEY varchar(20) 属性名
CHANNEL
VALUE int 属性值
DEVICE_ID int 属性所属设备ID
SCALE int 缩放倍率,当数值有小数时可用倍率缩放
UNIT varchar(20) 数值单位

DEVICE_STATE

字段 类型 说明
ID int 自增ID
DEVICE_ID int 属性所属设备ID
PORT int 设备接收端口
VALUE int 数值
UNIT varchar(20) 数值单位

DEVICE_LINKAGE

字段 类型 说明
ID int 自增ID
CAT
DEVICE_ID int 属性所属设备ID
PORT int 设备接收端口
TARGET 联动目标
TRIGGER 联动触发器
TRIGGER_ALARM 联动触发告警
ACTION 联动动作
PARAM 参数

DEVICE_ALARM

字段 类型 说明
ID 自增ID
APP_ID 固件ID
CAT
REPORTER
PORT 端口
CODE 编码
MSG 消息
ALARM_TYPE 告警类型
SEVERITY
STATUS 状态

启用Dashboard

K3s (≥1.21)默认没有启用 Traefik Dashboard。如果要在 K3s 中启用 Dashborad,我们可以借助 HelmChartConfig 来自定义由 Helm 部署的 Traefik 并启用 Dashboard。

不建议手动编辑 /var/lib/rancher/K3s/server/manifests/traefik.yaml 来修改 Traefik 配置文件,因为 K3s 重启后会覆盖修改的内容。

建议通过在 /var/lib/rancher/K3s/server/manifests 中创建一个额外的 HelmChartConfig 清单来自定义 Traefik 配置,请参考:http://docs.rancher.cn/docs/K3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat >> /var/lib/rancher/K3s/server/manifests/traefik-config.yaml << EOF
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
dashboard:
enabled: true
ports:
traefik:
expose: true
logs:
access:
enabled: true
EOF

K8s 修改 traefik-vlues.yaml 中ingressRoute.dashboard并应用配置

1
2
helm upgrade traefik traefik/traefik \
--namespace traefik -f traefik-vlues.yaml

配置Service及路由规则

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
cat >> traefik-dashboard.yaml << EOF
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: kube-system
spec:
allocateLoadBalancerNodePorts: true
ports:
- name: web
nodePort: 80
port: 80
protocol: TCP
targetPort: web
- name: websecure
nodePort: 443
port: 443
protocol: TCP
targetPort: websecure
selector:
app.kubernetes.io/instance: traefik-kube-system
app.kubernetes.io/name: traefik
type: LoadBalancer

---

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-web
spec:
entryPoints:
- web
routes:
- kind: Rule
match: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
services:
- name: api@internal
kind: TraefikService

---

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-websecure
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
services:
- name: api@internal
kind: TraefikService
tls:
secretName: traefik-dashboard-tls
EOF
1
kubectl apply -f traefik-dashboard.yaml

访问Dashboard需要在最后加一个/ 否则可能出现page not found

配置IngressRoute

1
2
3
# 搭建测试环境
kubectl create deploy whoami --image=traefik/whoami --replicas=2
kubectl expose deploy whoami --port=80

HTTP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#whoami-no-tls-ingress-route.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-ingress-web
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`192.168.0.2`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: whoami
port: 80

HTTPS

1
2
3
4
# 用 openssl 来创建一个自签名的证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=domain.example.com"

kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# whoami-tls-ingress-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-ingress-websecure
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`192.168.0.2`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls

证书生成参考k3s证书管理

TCP/UDP
默认配置文件下,只有traefik(9000)、web(80)、websecure(443)以及metrics(9100)开放,如果想要反代MySQL tcp又想自定义端口的话,需要单独在配置文件中进行配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP #IngressRouteUDP
metadata:
name: redis
namespace: devops
spec:
entryPoints:
- redis
routes:
- match: HostSNI(`*`)
services:
- name: redis
port: 6379

TCP Routers与HTTP Routers的routes有所不同:

  • TCP Routers match采用HostSNI,而HTTP Routers match直接匹配Host。
  • TCP Routers只能定位TCP服务(不能定位HTTP服务)。
  • 如果HTTP Routers和TCP Routers都侦听相同的入口点,则TCP Routers将在HTTP Routers之前应用。如果找不到与TCP Routers匹配的路由,则HTTP Routers将接管。

参考

K3s版本 > v.121(Traefik 2.x)

K3S 中 Traefik v2 安装及采坑纪实 - 知乎 (zhihu.com)

k3s开启traefik的dashboard网页-CSDN博客

Step by Step!教你如何在k3s集群上使用Traefik 2.x - k3s中文社区 - 博客园 (cnblogs.com)

traefik系列之一 | 简介、部署和配置-腾讯云开发者社区-腾讯云 (tencent.com)

还不会Traefik?看这篇文章就够了! - 知乎 (zhihu.com)

k3s 使用 Letsencrypt 和 Traefik 完成 https 入口部署-腾讯云开发者社区-腾讯云 (tencent.com)

[Kubernetes环境Traefik部署与应用 - Tiscs - 博客园 (cnblogs.com)](https://www.cnblogs.com/tiscs/p/notes-k8s-traefik.html#:~:text=安装Traefik 1 配置 Helm Repo helm repo add, … 3 其他准备工作 获取 traefik 服务的负载均衡器地址。 )

Traefik - Kubernetes 配置TCP/HTTP服务-腾讯云开发者社区-腾讯云 (tencent.com)

cert-manager管理内网k8s开发环境证书 - hueidou163 - 博客园 (cnblogs.com)

Kubernetes (K8S)中Traefik路由(ingressRoute)-腾讯云开发者社区-腾讯云 (tencent.com)

Dashboard无法访问问题参考

如何在 K3s 中启用 Traefik Dashborad - RancherLabs - 博客园 (cnblogs.com)

How to Expose and Enable K3s with Traefik Dashboard (thriveread.com)

kubernetes - How to expose traefik v2 dashboard in k3d/k3s via configuration? - Stack Overflow

kubernetes - 云原生 07:改用 K3s,并使用 K3s 内置的 Traefik 做 Ingress 网关 - 小鲜 - SegmentFault 思否

K8s中使用traefik(基础) - AGou’s Blog

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();
}
}

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 # 安装nfs服务
sudo apt install nfs-common nfs-kernel-server portman -y

# 创建共享目录
sudo mkdir -p /mnt/share/
sudo chmod 777 /mnt/share

# 编辑映射文件
sudo vim /etc/exports

# 共享目录
/mnt/share *(rw,sync)

# 设置ACL赋予nfsnobody权限
sudo setfacl -m u:nfsbody:rw /mnt/share

# 启动NFS服务
sudo /etc/init.d/nfs-kernel-server start
sudo /etc/init.d/nfs-common start

# 检查服务启动
sudo showmount -e

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装nfs
sudo apt install nfs-common

# 新建本地文件夹
sudo mkdir /mnt/nfs

# sudo mount [nfs_server]:[server_dir] [local_mount_point]
# [nfs_server] nfs服务器ip
# [server_dir] 服务器共享路径
# [local_mount_point] 本地挂载路径
sudo mount [nfs_server]:[server_dir] [local_mount_point]
# 示例
sudo mount 192.168.1.100:/mnt/share /mnt/nfs

# 查看挂载是否成功
df -Th

编辑fstab 配置自动挂载

1
2
3
sudo vim /etc/fstab
# 在最后一行添加
[nfs_server]:/mnt/share /mnt/nfs nfs defaults 0 0

卸载

1
2
3
sudo umount [local_mount_point] 
#示例
sudo umount /mnt/nfs

需要认证参考为 Linux 客户端设置具有基于 Kerberos 的身份验证的 NFS 服务器 (linux-console.net)

安全相关参考如何确保NFS服务安全-腾讯云开发者社区-腾讯云 (tencent.com)

用户身份映射参考NFS服务的用户身份映射 - wangmo - 博客园 (cnblogs.com)

本地路径映射(HostPath)

HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。 当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# 宿主机上目录位置
path: /data
# 此字段为可选
type: Directory

支持的 type 值如下:

取值 行为
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
Directory 在给定路径上必须存在的目录。
FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
File 在给定路径上必须存在的文件。
Socket 在给定路径上必须存在的 UNIX 套接字。
CharDevice 在给定路径上必须存在的字符设备。
BlockDevice 在给定路径上必须存在的块设备。
1
2
3
4
5
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-vol-default
provisioner: vendor-name.example

local

local 卷只能用作静态创建的持久卷。不支持动态配置。

hostPath 卷相比,local 卷能够以持久和可移植的方式使用,而无需手动将 Pod 调度到节点。系统通过查看 PersistentVolume 的节点亲和性配置,就能了解卷的节点约束。

使用 local 卷时,你需要设置 PersistentVolume 对象的 nodeAffinity 字段。 Kubernetes 调度器使用 PersistentVolume 的 nodeAffinity 信息来将使用 local 卷的 Pod 调度到正确的节点。

PersistentVolume 对象的 volumeMode 字段可被设置为 “Block” (而不是默认值 “Filesystem”),以将 local 卷作为原始块设备暴露出来。

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: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node

NFS映射

1

Minio

1

Ceph

1

准备环境

证书

[[../杂项/OpenSSL生成自签名证书|OpenSSL生成自签名证书]]

k3s证书管理

默认配置文件

1
helm show values harbor/harbor > harbor-values.yaml

安装

配置清单

harbor-value.yaml

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
38
39
40
41
42
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: "example.io"
notarySecretName: "example.io"
ingress:
hosts:
core: harbor.example.io
notary: notary.example.io
controller: default
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/proxy-body-size: "0"
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure

externalURL: https://harbor.example.io

harborAdminPassword: "Harbor123456"

logLevel: info

chartmuseum:
enabled: true

database:
type: external
external:
host: "postgres.devops.svc.cluster.local"
port: "5432"
username: "harbor"
password: "harbor"
redis:
type: external
external:
addr: "redis.devops.svc.cluster.local:6379"
password: "passwd"

harbor-ingress.yaml

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-http
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/`)
kind: Rule
services:
- name: harbor-portal
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-api
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/api/`)
kind: Rule
services:
- name: harbor-core
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-service
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/service/`)
kind: Rule
services:
- name: harbor-core
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-v2
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/v2`)
kind: Rule
services:
- name: harbor-core
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-chartrepo
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/chartrepo/`)
kind: Rule
services:
- name: harbor-core
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: kube-ops
name: harbor-c
spec:
entryPoints:
- websecure
tls:
secretName: all-xxxx-com
routes:
- match: Host(`harbor.example.com`) && PathPrefix(`/c/`)
kind: Rule
services:
- name: harbor-core
port: 80

安装Harbor

1
2
3
4
5
6
7
# 添加Harbor仓库
helm repo add harbor https://helm.goharbor.io

# 使用部署或升级Harbor
helm upgrade harbor harbor/harbor --namespace harbor \
--install --create-namespace \
-f harbor-values.yaml

配置

配置library仓库源

1
2
3
4
5
6
7
kubectl edit configmap harobr-registry -n harbor

# 在auth: 后边添加新节点
proxy:
remoteurl: "https://registry-1.docker.io"


使用Harbor

配置镜像缓存

参考

Harbor 搭建镜像代理 | Northes

Kubernetes ≥ 1.25 Containerd配置Harbor私有镜像仓库_containerd登录镜像仓库-CSDN博客

结合Cert-Manager完成Harbor的Https证书自动签发 | 风格 | 风起于青萍之末 (lusyoe.github.io)

Containerd容器镜像管理-腾讯云开发者社区-腾讯云 (tencent.com)

通过helm在k8s上搭建Harbor - 简书 (jianshu.com)

Kubernetes 集群仓库 harbor Helm3 部署-腾讯云开发者社区-腾讯云 (tencent.com)

containerd基本使用命令 - 杨梅冲 - 博客园 (cnblogs.com)

Kubernetes1.21搭建harbor-腾讯云开发者社区-腾讯云 (tencent.com)