<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Linux on 涯余的博客</title><link>https://hangyan.github.io/tags/linux/</link><description>Recent content in Linux on 涯余的博客</description><generator>Hugo</generator><language>zh</language><managingEditor>hang.yan@hotmail.com (涯余)</managingEditor><webMaster>hang.yan@hotmail.com (涯余)</webMaster><lastBuildDate>Sat, 18 Dec 2021 19:29:35 +0800</lastBuildDate><atom:link href="https://hangyan.github.io/tags/linux/index.xml" rel="self" type="application/rss+xml"/><item><title>TC 的一些有趣功能</title><link>https://hangyan.github.io/post/2021-tc-ebpf/</link><pubDate>Sat, 18 Dec 2021 19:29:35 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2021-tc-ebpf/</guid><description>&lt;p&gt;最近在看 TC 和 eBPF 相关的一些介绍。TC 本身的概念比较复杂，想要理清并不容易。加上 eBPF 的引入就更复杂了。本文用来记录与此相关的一些发现。&lt;/p&gt;
&lt;h2 id="clsact"&gt;clsact&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;clsact&lt;/code&gt; 即是用来给 TC + eBPF 是使用的一个 &lt;code&gt;qdisc&lt;/code&gt;. &lt;code&gt;qdisc&lt;/code&gt; 可以简单理解为使用某种算法(FIFO)的 Queue. &lt;code&gt;clsact&lt;/code&gt; 的特点是:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不用排队&lt;/li&gt;
&lt;li&gt;主要就是为了 attach ebpf 用的&lt;/li&gt;
&lt;li&gt;在 ingress/egress 都提供了 hook&lt;/li&gt;
&lt;li&gt;lock free&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ingress-与-egress-的不同"&gt;ingress 与 egress 的不同&lt;/h2&gt;
&lt;p&gt;不太确定直接的原因是啥，目前的 qdisc 只在 egress 方向上有。一般的 rate-limiting 都是在 egress 上实现， ingress上的比较困难。一个原因是难以对源头进行限速。&lt;/p&gt;
&lt;h2 id="multiple-qdisc"&gt;multiple qdisc&lt;/h2&gt;
&lt;p&gt;多个 qdisc 在 egress 上是很常见的。加了 clasact 之后就更常见了。那么 clsact 和他们什么关系？&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://hangyan.github.io/images/2021-tc-ebpf/clsact-qdisc.png"&gt;&lt;/p&gt;
&lt;p&gt;这是我从另一个 Topic 摘过来的图。可以看出来， clsact 是在普通的 qdisc 之前的。&lt;/p&gt;
&lt;h2 id="direct-action-mode"&gt;direct-action mode&lt;/h2&gt;
&lt;p&gt;请参考: &lt;a href="https://qmonnet.github.io/whirl-offload/2020/04/11/tc-bpf-direct-action/"&gt;Understanding tc “direct action” mode for BPF&lt;/a&gt;&lt;/p&gt;</description></item><item><title>eBPF Loop</title><link>https://hangyan.github.io/post/2021-ebpf-loop/</link><pubDate>Fri, 03 Dec 2021 15:54:37 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2021-ebpf-loop/</guid><description>&lt;p&gt;eBPF Loop 是个老大难问题，只要实际开发大概率都会遇到。Kernel 版本越高，loop 的支持也越多。最近在 LWN 上又看到一篇关于 bpf loop 的新实现，如果能合并进去，那么就有三种 loop 得方式了:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;bounded loop: 跟传统编程模式很像，但loop的count必须是已知的&lt;/li&gt;
&lt;li&gt;map iterator: 针对 bpf map 的迭代器，可以用来遍历 map&lt;/li&gt;
&lt;li&gt;bpf_loop 函数: 最新的提议，能让 verifier 处理的更快&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;目前的 verifier 的策略是比较激进的，因为它没法验证所有的场景，所以有可能会对一些实际正确的程序验证不通过。&lt;code&gt;bpf_loop&lt;/code&gt; 主要就是从这个角度来考虑问题，相当于对最开始的 bounded loop 做的一个优化。下面将详细介绍。&lt;/p&gt;
&lt;h2 id="bounded-loop"&gt;Bounded Loop&lt;/h2&gt;
&lt;p&gt;Kernel 5.3 之前, eBPF 不支持 loop. 要想实现类似功能，而且前提是明确 loop 的次数，那么基本上只能靠 &lt;code&gt;unroll&lt;/code&gt; 来实现。示例如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#pragma clang loop unroll(full)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/* Do stuff ... */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;相当于把 loop 展开。5.3 及之后，就不用这样了。&lt;/p&gt;
&lt;h2 id="map-iterator"&gt;MAP Iterator&lt;/h2&gt;
&lt;p&gt;Bounded Loop 只能解决一部分的问题。总会有 unbounded loop 的场景。5.13 引入了 map iterator, 支持对 bpf map做遍历。考虑到 bpf map 在 eBPF 程序中的普遍性，算是一个比较好的解决方案了.&lt;/p&gt;</description></item><item><title>如何生成 vmlinux.h</title><link>https://hangyan.github.io/post/2021-vmlinux/</link><pubDate>Wed, 25 Aug 2021 13:28:21 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2021-vmlinux/</guid><description>&lt;p&gt;eBPF 的一些开发方案里涉及到 vmlinux.h, 它包含了kernel里所有用到的data structure等等。有了它可以方便地替代其他一大堆杂七杂八的头文件。网上基本上都提到了如何用 &lt;code&gt;vmlinux&lt;/code&gt; 来生成 &lt;code&gt;vmlinux.h&lt;/code&gt;, 但最开始的
&lt;code&gt;vmlinux&lt;/code&gt; 怎么来的并没有找到比较明确的文档。本来将提供一个比较全面的如何生成 &lt;code&gt;vmlinux.h&lt;/code&gt; 的文档.&lt;/p&gt;
&lt;h2 id="环境说明"&gt;环境说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OS: ubuntu 20.04.1&lt;/li&gt;
&lt;li&gt;Kernel: 5.4.0-70&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="安装-vmlinux"&gt;安装 vmlinux&lt;/h2&gt;
&lt;p&gt;需要添加 ddeb 的源&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb http://ddebs.ubuntu.com &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;lsb_release -cs&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; main restricted universe multiverse&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee -a /etc/apt/sources.list.d/ddebs.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;deb http://ddebs.ubuntu.com &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;lsb_release -cs&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-updates main restricted universe multiverse\ndeb http://ddebs.ubuntu.com &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;lsb_release -cs&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-proposed main restricted universe multiverse&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee -a /etc/apt/sources.list.d/ddebs.list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;repo key相关的&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install ubuntu-dbgsym-keyring
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安装&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install linux-image-&lt;span class="k"&gt;$(&lt;/span&gt;uname -r&lt;span class="k"&gt;)&lt;/span&gt;-dbgsym
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后安装好的文件在 &lt;code&gt;/usr/lib/debug/boot/&lt;/code&gt; 目录下。&lt;/p&gt;</description></item><item><title>卸载UOS</title><link>https://hangyan.github.io/post/2021-uninstall-uos/</link><pubDate>Tue, 25 May 2021 10:34:33 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2021-uninstall-uos/</guid><description>&lt;p&gt;用了大半年，最近卸载了。整体来说，不如最开始的期待。优点仍在，但缺点对于重度使用者来说，难以忍受。&lt;/p&gt;
&lt;p&gt;将常见应用做到开箱即用，这是个很大的贡献，也是目前所有 Linux 发行版里做的最好的一个，这点不可抹杀。但正如其他的一些本地化分支一样，稳定性都相比于 Debian/Ubuntu 大幅度降低了。这点在长期使用中会逐渐暴露出来，并且抵消掉前者带来的优势。如果UOS想继续好好做下去，后面的着力点也应该是这个。&lt;/p&gt;
&lt;p&gt;就我的体验来说，问题主要是以下几个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;电脑发热明显，最开始是非夏天用的感觉还不明显，到了夏天非常严重。而换了ubuntu之后好转。&lt;/li&gt;
&lt;li&gt;移除了添加repo的一些命令，让开发者很难受&lt;/li&gt;
&lt;li&gt;界面稳定性差，基本上难以做到经常不关机&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里面部分是 Deepin 的问题，部分是 UOS 的问题了。其他的国内的发行版总体来说都是更差。&lt;/p&gt;
&lt;p&gt;从产品角度来说，用户想要什么以及该怎么做其实是很明显的。既然有这个人力物力了，就应该定好优先级，把这些核心的问题解决好，这样才能普及开来。&lt;/p&gt;
&lt;p&gt;另外从美观程度上来讲，不算差，但也不算太好。很多方面也不如 Ubuntu 的 Unity. 如何用统一美观的设计语言去做出一个美观好用的界面，应该就是下一阶段的重点了。&lt;/p&gt;</description></item><item><title>io_uring 介绍</title><link>https://hangyan.github.io/post/2020-11-27-io_uring/</link><pubDate>Fri, 27 Nov 2020 11:18:00 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2020-11-27-io_uring/</guid><description>&lt;p&gt;这几年内核带来了很多革命性的新特性。一个是 ebpf, 现在主要被广泛应用于网络处理，性能分析等领域。另一个是 io_uring, 带来了真正的全异步IO。本文将对 io_uring 做简要介绍。&lt;/p&gt;
&lt;h2 id="总览"&gt;总览&lt;/h2&gt;
&lt;p&gt;在 io_uring 之前，只有 aio 这个异步框架。为什么要重新弄一套，是因为 aio 自身限制比较多，比如:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只支持 &lt;code&gt;direct_io&lt;/code&gt;.而O_DIRECT要求bypass缓存和size对齐等，直接影响了很多场景的使用。而对buffered IO，其表现为同步。&lt;/li&gt;
&lt;li&gt;即使满足了所有异步IO的约束，有时候还是可能会被阻塞，例如，等待元数据IO，或者存储设备的请求槽位都正在使用等等。&lt;/li&gt;
&lt;li&gt;存在额外的开销，每个IO提交需要拷贝64+8字节，每个IO完成需要拷贝32字节，这在某些场景下影响很可观。在使用完成event的时候需要非常小心，否则容易丢事件。IO总是需要至少2个系统调用（submit + wait-for-completion)，在spectre/meltdown开启下性能下降非常严重。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;aio本身扩展性也很差，很多基于aio的开发也经常需要用dirty hack的方式来满足自己的需求。Linux 自己对它的评价也不好:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;So I think this is ridiculously ugly.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;AIO is a horrible ad-hoc design, with the main excuse being “other, less gifted people, made that design, and we are implementing it for compatibility because database people — who seldom have any shred of taste — actually use it”.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>ARM指针的一些安全功能</title><link>https://hangyan.github.io/post/arm-pointer/</link><pubDate>Mon, 19 Oct 2020 13:12:59 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/arm-pointer/</guid><description>&lt;p&gt;伴随着 ARM 平台的越来越普及，Linux 内核对其的支持也逐渐丰富。而且 ARM 的设计也有很多独特的优点，本文将介绍在 ARM 平台关于指针操作的一些安全方面的设计。&lt;/p&gt;
&lt;h2 id="pointer-authentication"&gt;Pointer Authentication&lt;/h2&gt;
&lt;p&gt;很多攻击都是通过骇客设计的不安全指针进行的。比如 &lt;code&gt;buffer-overflow&lt;/code&gt; 和 &lt;code&gt;return-oriented programming&lt;/code&gt;, 都是通过在返回地址放置一个指针来进行的。内核已经针对这个问题做了很多改善，ARM 提供了 &lt;code&gt;pointer authentication&lt;/code&gt; 来检测和拒绝这种插入的非法指针。&lt;/p&gt;
&lt;p&gt;简单来说，就是在指针上附加一个签名，要想使用一个指针，先得签名验证通过。如果是外部的攻击者，它没法伪造这种签名，那么自己就不能制造指针来进行攻击了。&lt;/p&gt;
&lt;p&gt;目前一般指针都是64位，但一般都不是所有bit都是用了。ARM64的系统，如果是三级页表，那么只有低位的40bit用来存放地址，那么其他的bit就可以用来干其他事情。 签名一般是通过以下几个参数确定:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pointer 本身&lt;/li&gt;
&lt;li&gt;process context 里的一个 secret key, kernel生成 这个肯定是攻击者无法获取到的&lt;/li&gt;
&lt;li&gt;current stack pointer。防止签名过的pointer泄露被复用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用的话，需要先重新计算一下签名，确保二者对的上，然后把签名部署的数据清理掉，这时候就是一个正常的指针了。不然的话，就认为其非法。&lt;/p&gt;
&lt;h2 id="memory-tagging"&gt;Memory Tagging&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Memory Tagging&lt;/code&gt;的做法与&lt;code&gt;Pointer Authentication&lt;/code&gt;类似，都是利用指针里未利用的 bits 去存储一些信息。&lt;code&gt;Memory Tagging&lt;/code&gt; 是利用 4bit 的信息存储了一个 key, 同时在 pointer 指向的内存地址里也存储了同样的 key. 当对指针进行解引用操作时，需要对比 pointer 里的 key 与实际内存地址里的 key 是否一致。如果不一致将会报错。这个功能有以下用处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;被释放的内存可以修改其 key, 防止被二次引用&lt;/li&gt;
&lt;li&gt;每个 stack frame 分配一个 key, 越界访问也会报错&lt;/li&gt;
&lt;li&gt;野指针也能检测到&lt;/li&gt;
&lt;li&gt;&amp;hellip;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些 keys 可以用应用层来管理，也可以用 CPU 来随机生成。当用应用层来管理的时候，可以提前检测出内存方便的 bug.&lt;/p&gt;</description></item><item><title>统信 UOS 究竟咋样</title><link>https://hangyan.github.io/post/2020-09-10-uos/</link><pubDate>Thu, 10 Sep 2020 16:01:54 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2020-09-10-uos/</guid><description>&lt;p&gt;统信 UOS 是今年国产化浪潮中比较出风头的一个做国产操作系统的公司。这几天换掉了我的 Manjaro 装上了 UOS 体验了一下。总体来说，可以打七八十分吧。&lt;/p&gt;
&lt;p&gt;单说这个分数可能不是很好度量它究竟是个什么水平。可以横向对比一下，分两个方面。一个是底座上，linux 发行版里, Deepin 团队做的很出色，现在基本上是排名第十左右的发行版(按流行程度)。UOS 是基于 Deepin 改的，底座上有了不错的保证。&lt;/p&gt;
&lt;p&gt;再跟国内这一众国产操作系统比的话，那简直是碾压。红旗之类的不用说，之前中国软件的麒麟，基于 Ubuntu 来改的( Deepin 的底座也是Ubuntu), 做了这么多年，了解 Linux 的基本上没啥好感，还不如 Ubuntu。因为国产操作系统向来上先往政企方面推，像麒麟这种大概率是拿到之后用户基本上就闲置不用了，继续用 Windows了。UOS 终于让人看到一点希望，至少，看起来让人有想尝试一直用用的念头了。&lt;/p&gt;
&lt;p&gt;国产操作系统怎么做的问题，其实就是 Linux 桌面版怎么做的问题，虽然我们也自有国情在此。从操作系统内核来讲， Linux 比 Windows/MAC 并不差，问题全出在软件生态上。主要原因有以下几个:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;非商业模式。只要商业公司才能做出像 Adobe / Oracle 这样的软件。有赚钱的目标，合理的分工及 KPI, 再卖出去软件形成一个正向循环。Linux 生态里有点像现在各家的 Andriod, 还更差，基本上连个统一付钱买软件的地方都没有，再说 Linux 用户普遍还没有养成这样的习惯&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开发者太容易分散人力开发类似的项目了。大家对项目有了争议，可以立马基于当前版本重新立一个新项目，分开开发。这就导致现在 Linux 已经有了几百个发行版，N 个桌面系统，每一类软件都有 N 个不同的产品。除了个别的项目之外，大部分都不好用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;没有领导，群龙无首。跟上面说的两个问题相关。内核发展的好，是因为有强有力的领导。但桌面系统，基本上就是百家争鸣，谁也不服谁&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这些问题杂糅起来，就形成了一个恶性循环。 Linux 桌面不好用 -&amp;gt; 用的人少 -&amp;gt; Linux 桌面发展缓慢，程序员各自魔改 -&amp;gt; 用的人更少。所以导致现在的局面就是，你想要一个方便使用的 Linux 桌面，如果没有一点编程背景，总会有一天栽在一个无法解决的最基本的硬件问题上。蓝牙坏了，网络连不上，显示器连不上，显卡配置不好等等在 MAC/WIN 上很少碰到的问题上。&lt;/p&gt;
&lt;p&gt;假设硬件的问题解决了，那么更难的来了: 软件。国内因为更加封闭的互联网生态这个问题更加严重。让用户苹果/Wechat 二选一，大部分人会放弃苹果，Linux 也类似，没有微信这些软件，没有正常用户会喜欢用 Linux。问题摆在这，那么国产操作系统怎么做的答案也就呼之欲出了:&lt;/p&gt;</description></item><item><title>给 Kubernetes Lens AppImage 添加 Desktop Entry</title><link>https://hangyan.github.io/post/2020-04-29-linux-lens-icon/</link><pubDate>Wed, 29 Apr 2020 22:13:02 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2020-04-29-linux-lens-icon/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;本文记录如何为 Kuberntes Lens 的 Linux 版本的 AppImage 手动创建一个 Desktop Entry 以及生成 Icon&lt;/p&gt;
&lt;h2 id="手动创建-desktop-entry"&gt;手动创建 Desktop Entry&lt;/h2&gt;
&lt;p&gt;创建一个 &lt;code&gt;desktop&lt;/code&gt; 文件，任意位置均可。假设名字为 &lt;code&gt;lens.desktop&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Desktop Entry]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Lens&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Comment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;A full-featured Kubernetes IDE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Exec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/home/yayu/Soft/AppImage/Lens-3.3.1.AppImage&amp;#34; %U&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Terminal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Application&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;kube-lens&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;StartupWMClass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Lens&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;X-AppImage-Version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1.4.1.271&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Categories&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Network;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;X-AppImage-BuildId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1N3OgzauYTeCvM55WzKgL7MIQe0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;X-Desktop-File-Install-Version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0.24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;X-AppImage-Comment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Create By HangYan&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;TryExec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/home/yayu/Soft/AppImage/Lens-3.3.1.AppImage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中 &lt;code&gt;Exec&lt;/code&gt; 以及 &lt;code&gt;TryExec&lt;/code&gt; 是 AppImage 的位置，应相应更改&lt;/p&gt;
&lt;h2 id="生成-icon"&gt;生成 ICON&lt;/h2&gt;
&lt;p&gt;这里我下载了一个黑色的 Kubernetes ICON, 背景透明，webp 格式&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://hangyan.github.io/images/kube/kube.png"&gt;&lt;/p&gt;
&lt;p&gt;这里我已经转为 png 格式，转换命令为:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dwebp &amp;lt;origin&amp;gt;.webp -o kube.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后，生成相应的 Icon, 并安装到系统中&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xdg-icon-resource install --theme Moka --size &lt;span class="m"&gt;48&lt;/span&gt; kube.png kube-lens
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安装的 icon 可以在 &lt;code&gt;~/.icons&lt;/code&gt; 目录中看到。&lt;/p&gt;</description></item></channel></rss>