如何在 K3s 中使用网络策略

news2024/11/28 20:56:09

本文将介绍如何在示例项目中使用网络策略,并解释它在 K3s 中的工作原理,从而帮助用户提高部署的安全性。

关于 K3s 对网络策略的支持存在一个普遍的误解,因为 K3s 默认使用 Flannel CNI,而 Flannel CNI 不支持网络策略。其实,K3s 使用 Kube-router 网络策略控制器为网络策略提供支持,所以网络策略也可以在 K3s 中使用,就像在其他 Kubernetes 发行版中一样。

正常的 Pod 相互通信

默认情况下,在 K3s 中,一个特定命名空间中的所有 services/Pod 都可以被任何其他命名空间中的所有其他 Pod 访问。

为了举例说明 Pod 如何相互通信,让我们在两个不同的命名空间(sample1 和 sample2)中使用简单的 nginx deployment 和 service 来测试,如下所示:

nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: ngnix-service
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

创建测试命名空间并将 nginx 部署到对应命名空间中:

# 在 sample1 中创建第一个示例应用
kubectl create ns sample1
kubectl apply -f nginx.yaml -n sample1

# 在 sample2 中创建第二个示例应用
kubectl create ns sample2
kubectl apply -f nginx.yaml -n sample2

接下来可以尝试在 Pod 中使用 curl 来检查 Pod 间的通信。

sample1 中的 pod -> sample2 命名空间中的 service:

# 从 sample1 访问 sample2
kubectl exec -n sample1 $(kubectl get po -n sample1 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample2.svc.cluster.local

# 从 sample1 访问 sample1
kubectl exec -n sample1 $(kubectl get po -n sample1 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample1.svc.cluster.local:80

sample2 中的 pod -> sample1 命名空间中的 service:

# 从 sample2 访问 sample1
kubectl exec -n sample2 $(kubectl get po -n sample2 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample1.svc.cluster.local:80

# 从 sample2 访问 sample2
kubectl exec -n sample2 $(kubectl get po -n sample2 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample2.svc.cluster.local:80

可以看到,以上命令均可以访问到对应目的地址,也就代表相互都可以通信。

使用 NetworkPolicy 限制 Pod 相互通信

NetworkPolicy Editor(https://editor.cilium.io/)是一个很好的 UI 工具,可以用于生成 Networkploicy,下面是一个示例。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: my-namespace
spec:
  podSelector:
    matchLabels:
      role: db <1>
  policyTypes:
  - Ingress
  ingress: <2>
  - from:
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379

<1> 这会选择当前命名空间中的特定 Pod 来匹配该策略。<2> 白名单入口规则列表。每个规则都允许与 from 部分匹配的流量。

可以在 ingress from 部分中指定四种选择器:

  • ipBlock: 会选择特定的 IP CIDR 范围以允许作为入口源。通常这是集群外部 IP,因为 Pod IP 是临时的。

  • podSelector: 会在与 NetworkPolicy 相同的命名空间中选择特定的 Pod,这些 Pod 应该被允许作为入口源或出口目的地。

  • namespaceSelector: 会选择特定的命名空间,所有 Pod 都应该被允许作为入口源或出口目的地。

  • namespaceSelector** 和 podSelector**: 指定 namespaceSelector 和 podSelector 的单个 from 条目选择特定命名空间内的特定 Pod。

使用 NetworkPolicy 配置多租户隔离

现在让我们使用 NetworkPolicy 来配置隔离。

下面的 yaml 将在不同命名空间的服务之间建立隔离,只允许同一命名空间的 Pod 相互通信,同时也允许从 ingress 和监控 Pod 传入通信:

networkPolicy.yaml

# 阻止所有传入流量
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-by-default
spec:
  podSelector: {}
  ingress: []
---
# 允许所有 Pod 在同一命名空间内的所有流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-same-namespace
spec:
  podSelector: {}
  ingress:
  - from:
    - podSelector: {}
---
# 允许 ingress Pod “traefik” 与该命名空间中的所有 Pod 通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-svclbtraefik-ingress
spec:
  podSelector:
    matchLabels:
      svccontroller.k3s.cattle.io/svcname: traefik
  ingress:
  - {}
  policyTypes:
  - Ingress
---
# 允许 ingress Pod “traefik” 与该命名空间中的所有 Pod 通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-traefik-v121-ingress
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: traefik
  ingress:
  - {}
  policyTypes:
  - Ingress
---
# 允许监控系统 Pod 与该命名空间中的所有 Pod 通信(以允许抓取指标)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-cattle-monitoring-system
spec:
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: cattle-monitoring-system
  podSelector: {}
  policyTypes:
  - Ingress

现在将策略应用于两个示例命名空间中:

kubectl apply -f networkPolicy.yaml -n sample1
kubectl apply -f networkPolicy.yaml -n sample2

应用上述 networkPolicy.yaml 后,你需要设置好 ingress Pod 或 监控 Pod 的白名单。

现在让我们再次尝试之前的 curl 来检查 Pod 之间的通信:

# 从 sample1 访问 sample2
kubectl exec -n sample1 $(kubectl get po -n sample1 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample2.svc.cluster.local

# 从 sample1 访问 sample1
kubectl exec -n sample1 $(kubectl get po -n sample1 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample1.svc.cluster.local:80

# 从 sample2 访问 sample1
kubectl exec -n sample2 $(kubectl get po -n sample2 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample1.svc.cluster.local:80

# 从 sample2 访问 sample2
kubectl exec -n sample2 $(kubectl get po -n sample2 -l app=nginx -o name) -- curl --max-time 2 http://ngnix-service.sample2.svc.cluster.local:80

现在你应该看到,不同命名空间之间的通信被阻止了,但同一命名空间内是可以正常通信的。

调试 NetworkPolicy 通信

NetworkPolicy 能够看到由于匹配的 NetworkPolicy 而丢弃的数据包。由于网络规则是通过 KUBE-BWPLCY 链中的 iptables 部署的,我们可以在当前运行 Pod 的节点上看到这些规则。因此,让我们检查生成的 iptables。

首先,我们需要检查 Pod 是在哪个节点上运行。

kubectl get po -o wide -n sample1
NAMESPACE             NAME                                                  READY   STATUS    RESTARTS      AGE    IP              NODE       NOMINATED NODE   READINESS GATES
sample1               nginx-6c8b449b8f-hhwhv                                1/1     Running   0             3d6h   192.168.248.2   node2

登录到 node2,并获取 iptables 的 KUBE-NWPLCY 链:

node2# iptables -L | grep KUBE-NWPLCY -B 2

iptables -L | grep KUBE-NWPLCY -B 2
target     prot opt source               destination

Chain KUBE-NWPLCY-6MLFY7WSIVQ6X74S (1 references)
target     prot opt source               destination

Chain KUBE-NWPLCY-6ZMDCAWFW6IG7Y65 (0 references)
--
RETURN     all  --  anywhere             anywhere             /* rule to ACCEPT traffic from all sources to dest pods selected by policy name: allow-all-svclbtraefik-ingress namespace sample1 */ match-set KUBE-DST-AZLS65URBWHIM4LV dst mark match 0x10000/0x10000

Chain KUBE-NWPLCY-CMW66LXPRKANGCCT (1 references)
--
RETURN     all  --  anywhere             anywhere             /* rule to ACCEPT traffic from specified ipBlocks to dest pods selected by policy name: allow-from-cattle-monitoring-system namespace sample1 */ match-set KUBE-SRC-RCIDLRVZOORE5IEC src match-set KUBE-DST-T5UTRUNREWDWGD44 dst mark match 0x10000/0x10000

Chain KUBE-NWPLCY-DEFAULT (2 references)
--
MARK       all  --  anywhere             anywhere             /* rule to mark traffic matching a network policy */ MARK or 0x10000

Chain KUBE-NWPLCY-EM64V3NXOUG2TAJZ (1 references)
--
RETURN     all  --  anywhere             anywhere             /* rule to ACCEPT traffic from specified ipBlocks to dest pods selected by policy name: allow-same-namespace namespace sample1 */ match-set KUBE-SRC-DSEC5V52VOYVVZ4H src match-set KUBE-DST-5TPLTTXGTPDHQ2AH dst mark match 0x10000/0x10000

Chain KUBE-NWPLCY-IF5LSB2QJ2HY5MD6 (0 references)
--
...
省略...
...

--
ACCEPT     all  --  anywhere             anywhere             /* rule for stateful firewall for pod */ ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             192.168.248.2        /* rule to permit the traffic traffic to pods when source is the pod's local node */ ADDRTYPE match src-type LOCAL
KUBE-NWPLCY-DEFAULT  all  --  192.168.248.2        anywhere             /* run through default egress network policy  chain */
KUBE-NWPLCY-CMW66LXPRKANGCCT  all  --  anywhere             192.168.248.2        /* run through nw policy allow-from-cattle-monitoring-system */
KUBE-NWPLCY-EM64V3NXOUG2TAJZ  all  --  anywhere             192.168.248.2        /* run through nw policy allow-same-namespace */
KUBE-NWPLCY-RJITOIYNFGLSMNHT  all  --  anywhere             192.168.248.2        /* run through nw policy deny-by-default */

现在我们观察链 KUBE-NWPLCY-EM64V3NXOUG2TAJZ(在你的环境中会有不同的名称),它是 allow-same-namespace namespace sample1,同时再次运行 curl 测试:

watch -n 2 -d iptables -L KUBE-NWPLCY-EM64V3NXOUG2TAJZ -nv

Every 2.0s: iptables -L KUBE-NWPLCY-EM64V3NXOUG2TAJZ -nv                                                                                                                         node2: Mon Mar  6 20:18:38 2023
Chain KUBE-NWPLCY-EM64V3NXOUG2TAJZ (1 references)
 pkts bytes target     prot opt in     out     source               destination
    4   240 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* rule to ACCEPT traffic from source pods to dest pods selected by policy name allow-same-namespace namespace sample1 */
match-set KUBE-SRC-OPGXQ4TCHJJUUOWB src match-set KUBE-DST-5TPLTTXGTPDHQ2AH dst MARK or 0x10000
    4   240 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* rule to ACCEPT traffic from source pods to dest pods selected by policy name allow-same-namespace namespace sample1 */
match-set KUBE-SRC-OPGXQ4TCHJJUUOWB src match-set KUBE-DST-5TPLTTXGTPDHQ2AH dst mark match 0x10000/0x10000
    0     0 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* rule to ACCEPT traffic from specified ipBlocks to dest pods selected by policy name: allow-same-namespace namespace sample1 */ match-set KUBE-SRC-DSEC5V52VOYVVZ4H src match-set KUBE-DST-5TPLTTXGTPDHQ2AH dst MARK or 0x10000
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* rule to ACCEPT traffic from specified ipBlocks to dest pods selected by policy name: allow-same-namespace namespace sample1 */ match-set KUBE-SRC-DSEC5V52VOYVVZ4H src match-set KUBE-DST-5TPLTTXGTPDHQ2AH dst mark match 0x10000/0x10000

你会看到在运行 curl 测试期间,计数器不断变化,显示已接受和已丢弃的数据包。

被网络策略丢弃的数据包也可以被记录下来。被丢弃的数据包被发送到 iptables NFLOG,它显示了数据包的详细信息,包括阻止它的网络策略。

要将 NFLOG 转换为日志条目,可以安装 ulogd2/ulogd 包并将 [log1] 配置为在 group=100 上读取。然后,重新启动 ulogd2 服务提交新配置。

要将所有这些数据包记录到文件中,ulogd2 需要在 /etc/ulogd.conf 中进行配置,示例如下:

[global]
logfile="syslog"
loglevel=3
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2STR.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2BIN.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_PRINTPKT.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_HWHDR.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_LOGEMU.so"


# 这是一个堆栈,用于记录系统通过 LOGEMU 发送的数据包
stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU

[log1]
group=100

[emu1]
file="/var/log/ulog/syslogemu.log"
sync=1

修改配置文件后,重启 ulogd:

systemctl restart ulogd2.service

如果数据包被网络策略规则阻止,日志消息将出现在 /var/log/ulog/syslogemu.log 中:

# cat /var/log/ulog/syslogemu.log

Mar  7 09:35:43 cluster-k3s-masters-a3620efa-5qgpt  IN=cni0 OUT=cni0 MAC=da:f6:6e:6e:f9:ce:ae:66:8d:d5:f8:d1:08:00 SRC=10.42.0.59 DST=10.42.0.60 LEN=60 TOS=00 PREC=0x00 TTL=64 ID=50378 DF PROTO=TCP SPT=47750 DPT=80 SEQ=3773744693 ACK=0 WINDOW=62377 SYN URGP=0 MARK=20000

如果有大量的流量,日志文件可能增长得非常快。为了控制这种情况,通过在相关的网络策略中添加以下注释,适当地设置 "limit "和 "limit-burst "iptables 参数:

# 默认值是limit=10/分钟和limit-burst=10。
kube-router.io/netpol-nflog-limit=<LIMIT-VALUE>
kube-router.io.io/netpol-nflog-limit-burst=<LIMIT-BURST-VALUE>

参考:

  • Kubernetes Network Policies:https://kubernetes.io/docs/concepts/services-networking/network-policies
  • K3s:https://github.com/k3s-io/k3s/blob/master/README.md
  • 强化指南 – NetworkPolicies:https://docs.k3s.io/security/hardening-guide#networkpolicies
  • K3s Network Policy:https://docs.k3s.io/advanced#additional-network-policy-logging

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/597663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker+Jenkins+Gitee+Pipeline部署项目

1.前言 Hello&#xff0c;各位小伙伴大家好。&#x1f604; 在上一篇文章【DockerJenkinsGitee自动化部署maven项目】中&#xff0c;咱们详细介绍了如何自动化部署maven项目&#xff0c;如果说你的项目仅仅为maven项目&#xff0c;那么这种部署方式是很契合的&#xff0c;如果…

超全,Selenium4自动化测试并行测试详解,进阶之路看这篇就够了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Selenium4 自动化测…

万字解析PELT算法!

Linux是一个通用操作系统的内核&#xff0c;她的目标是星辰大海&#xff0c;上到网络服务器&#xff0c;下至嵌入式设备都能运行良好。做一款好的linux进程调度器是一项非常具有挑战性的任务&#xff0c;因为设计约束太多了&#xff1a; 它必须是公平的快速响应系统的throughp…

如何学习R-Meta分析与【文献计量分析、贝叶斯、机器学习等】多技术融合?

专题一&#xff1a;Meta分析的选题与文献计量分析CiteSpace应用 1、Meta分析的选题与文献检索 1) 什么是Meta分析 2) Meta分析的选题策略 3) 文献检索数据库 4) 精确检索策略&#xff0c;如何检索全、检索准 5) 文献的管理与清洗&#xff0c;如何制定文献纳入排除标准 6…

第一行代码 第十四章 开发酷欧天气

第14章 开发酷欧天气 在本章将编写一个功能较为完整的天气预报程序。 功能需求及技术可行性分析 在开始编码之前&#xff0c;需要先对程序进行需求分析&#xff0c;想一想酷欧天气中应该具备哪些功能。将这些功能全部整理出来&#xff1a; 可以罗列出全国所有的省、市、县&…

英飞凌 AURIX-TC3XX:QSPI通信实验

目录 AURIX-TC3XX-QSPI通信实验1.QSP简介1.1、AURIX TC3XX QSPI个数1.2、QSPI功能特点1.2.1、QSPI外设的新特性1.2.2、一些独特的特性1.2.3、支持传统的SPI特性1.2.4、四种可供用户选择的传输模式 2、具体实验操作2.1、新建工程2.2、实验一 3、域控制器中常见的SPI通信方式3.1、…

ble常见概念

0. 蓝牙一些常见概念 参考&#xff1a;https://www.bilibili.com/video/BV1ad4y1d7AM 基于ESP32来了解蓝牙协议的一些东西 蓝牙广播 包组成结构 低功耗蓝牙一共有40个信道&#xff0c;频段范围从2402Mhz-2480Mhz&#xff0c;每2Mhz一个信道&#xff0c;37 38 39 是广播信道…

基于linux的程序库文件打包和调用的实现(一)——静态库文件打包和调用

随着技术的发展&#xff0c;基于linux项目的软件代码越发复杂&#xff0c;原来一个人可以完成的软件项目&#xff0c;现在可能需要多个人合作、多个部门合作、多个企业合作&#xff0c;每个人、每个部门、每个企业可能负责部分软件模块的开发。各个软件模块在调试过程由于涉及企…

DeFi 发展沃土,Uniswap 成功“登陆” Moonbeam

作者&#xff1a;OneBlock 去年 3 月底&#xff0c;Uniswap 社区发布一项全新治理提案&#xff0c;旨在通过社区授权于 Polkadot 生态智能合约平台 Moonbeam 上部署 Uniswap V3&#xff0c;将 Uniswap 扩展至 Polkadot 生态。在这项提案中&#xff0c;Uniswap 计划除了提供流动…

极兔抢滩IPO,李杰不止缺一个丰网

&#xff08;图片来源于网络&#xff0c;侵删&#xff09; 来源 | 螳螂观察 文 | 叶小安 物流业打响了上市“抢滩战”。 5月&#xff0c;顺丰控股传出2023年在香港二次上市消息&#xff1b;紧接着极兔也传出将于下半年赴港上市消息&#xff1b;另一边&#xff0c;阿里主席张…

最新自助建站系统源码 一键建站系统源码 含700+精美网站模板和搭建教程

分享一款最新自助建站系统源码&#xff0c;一键建站系统源码&#xff0c;傻瓜式一键建站含700精美网站模板&#xff0c;网站全是自适应响应式&#xff0c;含完整代码程序包和详细搭建教程。 系统模板页面图&#xff1a; 系统功能特色一览&#xff1a; 1、一次性打包&#xff0…

chatgpt接口返回参数分析

接口请求使用二进制请求&#xff0c;数据流式返回&#xff0c;即分块&#xff08;分批次&#xff09;返回。 问题&#xff1a;一周有几天 请求头 参数详解 参数名称 说明 role 消息发送者的角色&#xff0c;这里为 "assistant"。 id 消息的唯一标识符。 pare…

图的基本概念和存储

基本概念 基本概念 图的定义&#xff1a;图&#xff08;Graph&#xff09;一般由两个集合共同构成&#xff0c;一个是非空但是有限的顶点集合V&#xff08;Vertex&#xff09;&#xff0c;另一个是描述顶点之间连接关系的边集合E&#xff08;Edge)&#xff0c;边集合可以为…

4.信息安全之数据恢复

1.数据容灾数据备份 RPO(recovery point object)数据恢复点目标 数据丢掉多少可接受 RTO(recovery time object)数据恢复时间目标 恢复数据需要多少时间 2.系统灾难原因 1.硬件 2.人为 3.软件 4.病毒 5.自然灾害 3.容灾级别 数据级别(数据出错)<应用(某个功能不能使用)<业…

运维小白必学篇之基础篇第二集:文件系统结构和目录管理

文件系统结构和目录管理实验 实验者&#xff1a;胡 阳 目录 一、将虚拟机主机名改为自己的名字 二、完成以下操作&#xff1a; 一、将虚拟机主机名改为自己的名字 例如&#xff1a;hostname liangyuntong 关闭该终端后&#xff0c;重新打开即可 二、完成以下操作&#…

【AIGC】CPM-BEE 开源大模型介绍、部署以及创建接口服务

终于! 中文基座模型CPM-Bee开源了 # CPM-Bee 百亿参数的开源中英文双语基座大模型 ✨ 模型介绍 CPM-Bee是一个完全开源、允许商用的百亿参数中英文基座模型&#xff0c;也是CPM-Live训练的第二个里程碑。它采用Transformer自回归架构&#xff08;auto-regressive&#xff0…

直播预告丨SaaS+CG?UE影视级场景渲染与科学制片全流程揭秘!

余热不减&#xff01;在第二届瑞云3D渲染动画创作大赛赛果公布 后&#xff0c;小瑞紧锣密鼓在安排获奖选手的系列专场直播。在上期的“ 泛CG 聚未来 ” 第四届实用技术线上分享会中,咱们邀请到大赛专业组冠亚军“3ds Max老法师”彼尔德和“Maya大神”Shuiguo 分享了自己的创作历…

cplex基础入门(一)

这边文章会以纯新手小白的视角&#xff0c;教会大家如何快速的搭建自己的cplex模型&#xff0c;做到求解模型不求人。 目录 一、引言 1、掌握数据类型及数据结构 2、常规Cplex编程方法 3、Cplex编程步骤 4、cplex 程序框架 5、创建模型 二、规划建模的入门求解案例 1、…

代码随想录训练营Day57| 647. 回文子串 516.最长回文子序列 动态规划总结篇

目录 学习目标 学习内容 647. 回文子串 516.最长回文子序列 学习目标 647. 回文子串 516.最长回文子序列 动态规划总结篇 学习内容 647. 回文子串 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/palindromic-substrings/ class S…

3.部署 Stable Diffusion(SD)

部署Stable Diffusion webui方式: 本地部署:在自己的电脑上安装(官方脚本部署、懒人包部署(文末自取)) 云端部署:在远程服务上运行(免费有时长限制、可付费租用GPU) 两种部署方式哪种都可以,看需选择。如果有性能比较不错的的显卡,那么可以考虑本地部署。如果是没…