封尘网 - 让学习成为一种习惯! https://www.58jb.com golang,Linux运维,持续集成,jenkins,mysql,kubernetes zh-CN Tue, 19 Mar 2024 17:29:14 +0800 Caddy替换Nginx解决网站服务功能 https://www.58jb.com/html/use-caddy-replace-nginx.html

使用Nginx已经很多年了,但是也只是使用了它的一部分功能,虽然它安装也很方便,其它很多功能我也并没有使用到。在接触到Caddy后也有两年多了,发现这工具确实不错。于是趁着这个点,把Nginx换掉,使用Caddy实现博客需求。

个人博客比较简单也没用到什么,之前使用Nginx也只是做一个游量入口,把请求响应到后端的Go程序。

所以使用caddy也一样,只需要这样功能就行了。而且caddy会自动实现https功能。这个连证书都不需要去申请了。

 

博客服务器在2月15号就到期了,续费太贵了,只能从新购买一台。在新的机器上我选择了ubuntu系统,以前的服务器都是使用Centos系统,之所有换成ubuntu系统,也是因为我的笔记本也换成了ubuntu系统快三年了,一直使用也很方便。

 

安装caddy软件

  • ubuntu直接根据官方的提供的方式安装

    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/testing/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-testing-archive-keyring.gpg
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/testing/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-testing.list
    sudo apt update
    sudo apt install caddy
    
  • 为了方便处理我把配置文件Caddyfile放在了一个目录下

    mkdir .caddy
    cd .caddy
    touch Caddyfile
    
  • Caddyfile的内容如下(根据个人情况需要修改)

    www.58jb.com {
        root * /var/www/caddy
        file_server
    	@cachedFiles {
        	path *.jpg *.jpeg *.png *.gif *.ico *.css
    	}
        header {
            enable HSTS
            Strict-Transport-Security max-age=31536000;
            @cachedFiles Cache-Control "public, max-age=604800, must-revalidate"
            }
    
        @excludeDirs {
            not path /uploads*
        }
        reverse_proxy @excludeDirs 127.0.0.1:8000
    }
    
    • @cachedFiles 定义一个缓存文件列表,以空格分隔
    • header 表示网站响应头里的信息,这里启用了HSTS,它和Strict-Transport-Security配套使用,同时加入了上面的@cachedFiles 缓存表下,把这里文件添加一个缓存时间。
    • @excludeDirs 定义一个排除的目录,因为我的程序主要以Go实现的一个Web服务,而Caddy就是把请求代理到后端的Go程序中,而@excludeDirs中定义的目录是一些静态文件,并不是经过后端程序的,所以把它排除掉。而这个目录是存放在root目录下的。
    • reverse_proxy @excludeDirs 处理一个代理请求,把上面的排除目录加到里面,剩下的都需要经过后端处理。

 

  • 启动服务

    使用apt安装的方式就是简单方便,启动的时候也是很简单。我直接进入到.caddy目录下执行

    cd .caddy
    sudo caddy start           #这样就以后台方式启动,如果使用run的方式就是在当前窗口中启动,服务一直挂着,直到Ctrl+C结束。
    

 

目前来讲Caddy的功能丰富,配置也比较简单。但是更多的高级用法,需要自己去研究一下。用它来替代Nginx的话应该不是问题。感觉比较香的还是网站中的https证书不用管了。

 

本文链接:https://www.58jb.com/html/use-caddy-replace-nginx.html

]]>
2023-02-16 22:07:08 +0800 CST
ubuntu通过usb连接手机无法访问到手机硬盘 https://www.58jb.com/html/linux-connect-usb-error.html

最近发现一个问题,出现的几率还是挻大的。就是ubuntu系统中使用usb连接手机传输数据时(就是挂把手机硬盘挂载到系统中)会出现以下问题。

 

错误提示

点击手机硬盘时出现“无法处理的错误消息:The name:1.629 was not provided by any.service files” 但是其怪那个手机助手就可以了哦。

 

 

 

排查异常,既然已经发现了USB设备,图标都显示出来那在系统中就可以找到一些相关信息。

 swper@15IKBN  ~  lsusb |grep Huawei
Bus 001 Device 028: ID 12d1:107e Huawei Technologies Co., Ltd. LLD-AL20

 

由于手机硬盘不是直接通过mount挂载到系统中的,所以使用mount命令无法查看到。

swper@15IKBN  ~  journalctl -xe|grep -i android
6月 17 22:12:54 15IKBN gvfsd[460267]: Android device detected, assigning default bug flags

发现一个gvfsd工具,然后就发现了有以下命令。

 

使用命令gvfs-mount -l 可以查看到手机硬盘挂载到哪里了

 swper@15IKBN  /dev/disk/by-uuid  gvfs-mount -l    
This tool has been deprecated, use 'gio mount' instead.
See 'gio help mount' for more info.

Drive(2): Linux File-CD Gadget
  Type: GProxyDrive (GProxyVolumeMonitorUDisks2)
  Volume(0): 华为手机助手
    Type: GProxyVolume (GProxyVolumeMonitorUDisks2)
    Mount(0): 华为手机助手 -> file:///media/swper/%E5%8D%8E%E4%B8%BA%E6%89%8B%E6%9C%BA%E5%8A%A9%E6%89%8B
      Type: GProxyMount (GProxyVolumeMonitorUDisks2)
Volume(0): LLD AL20
  Type: GProxyVolume (GProxyVolumeMonitorMTP)
  Mount(0): LLD AL20 -> mtp://HUAWEI_LLD-AL20_37KNW18521008409/
    Type: GProxyShadowMount (GProxyVolumeMonitorMTP)
Mount(1): mtp -> mtp://HUAWEI_LLD-AL20_37KNW18521008409/
  Type: GDaemonMount

注意上面的mtp://HUAWEI_LLD-AL20_37KNW18521008409/ 这个后面的产品ID号各不相同。

 

那知道了这个硬盘目录,怎么进入呢?桌面系统肯定点图标就好了。当然也可以直接使用命令操作

gvfs-open mtp://HUAWEI_LLD-AL20_37KNW18521008409/   #这个来自上面查到的数据信息,回车即可看到文件目录打开。除非出面上面的错误提示。

 

知道了文件的目录但是并不知道挂载点呢,此时可以更详细的查看挂载目录的信息

注意 local path它就是挂载在系统中的位置了,甚至手机一些信息都有记录。

 ✘ swper@15IKBN  ~  gio info mtp://HUAWEI_LLD-AL20_37KNW18521008409/
显示名称:Honor 9i
名称:HUAWEI_LLD-AL20_37KNW18521008409
类型:directory
大小:  0
uri:mtp://HUAWEI_LLD-AL20_37KNW18521008409/
local path: /run/user/1000/gvfs/mtp:host=HUAWEI_LLD-AL20_37KNW18521008409
unix mount: gvfsd-fuse /run/user/1000/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=1000
属性:
  standard::type: 2
  standard::name: HUAWEI_LLD-AL20_37KNW18521008409
  standard::display-name: Honor 9i
  standard::icon: phone, phone-symbolic
  standard::content-type: inode/directory
  standard::size: 0
  standard::symbolic-icon: phone-symbolic, phone
  id::filesystem: mtp:host=HUAWEI_LLD-AL20_37KNW18521008409
  access::can-read: TRUE
  access::can-write: FALSE
  access::can-execute: TRUE
  access::can-delete: FALSE
  access::can-trash: FALSE
  access::can-rename: FALSE
  filesystem::size: 56943968256
  filesystem::free: 6172704768
  filesystem::type: mtpfs
  filesystem::remote: FALSE
  metadata::nautilus-list-view-sort-column: name
  metadata::nautilus-list-view-sort-reversed: false

 

注意最后两行,元数据信息通过nautilus工具管理,(我当时真的没办法,看哪个都像命令,一个在命令行中试过。)然后发现有它这么一个命令。

文件,又名“Nautilus”,是 GNOME 桌面环境的默认文件管理器。它提供简单集成的方式来管理文件和浏览文件系统。

“文件”不仅提供所有基本的文件管理功能,还支持搜索和管理本地和远程网络上的文件及文件夹,读写可移动存储上的数据,运行脚本和启动程序。它有三种视图:图标网格、图标列表、树列表。可以用插件和脚本扩展它的功能。

 

 swper@15IKBN  ~  nautilus -h
用法:
  org.gnome.Nautilus [选项…] [URI…]

帮助选项:
  -h, --help                 显示帮助选项
  --help-all                 显示全部帮助选项
  --help-gapplication        显示 GApplication 选项
  --help-gtk                 显示 GTK+ 选项

应用程序选项:
  -c, --check                执行一组快速自检测试。
  --version                  显示程序的版本。
  -w, --new-window           在浏览指定的 URI 时总是打开新窗口
  -q, --quit                 退出 Nautilus。
  -s, --select               在上级文件夹中选择指定的 URI。
  --display=显示             要使用的 X 显示

这里一个-q参数就是解决问题的方法了。执行它就等刷新了nautilus -q

 

所以最终解决方法就

nautilus -q

如果不执行这命令,你可以重启系统,选择权在你手里。我的目的就是不重启机器把问题解决就行了。

 

 

详细Nautilus命令说明可以参考:

man nautilus
https://wiki.gnome.org/Apps/Nautilus
https://apps.gnome.org/zh-CN/app/org.gnome.Nautilus/

 

关于gvfs的用法很多可以参考以下网页

https://manpages.ubuntu.com/manpages/bionic/man7/gvfs.7.html
https://manpages.ubuntu.com/manpages/trusty/man1/gvfs-info.1.html

 

本文链接:https://www.58jb.com/html/linux-connect-usb-error.html

]]>
2022-06-18 10:27:08 +0800 CST
ubuntu系统使用shotcut添加字幕时不能输入中文的解决方法 https://www.58jb.com/html/shotcut-use-in-ubuntu.html

由于shotcut软件启动时无法在编辑器里输入中文导致了添加字幕,或者对中文处理不方便。于是在网上找了很多资料,终于看到一个deepin朋友遇到的是一样的情况。但是我直接在ubuntu上不能同样操作。

 

 

于是就出现了下文的操作记录。

 

解决方法就是加一个文件到该目录下

找到系统中的文件:
/usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so

复制到以下目录下:
/snap/shotcut/692/Shotcut.app/lib/qt5/platforminputcontexts/

但是并没有所想那样顺利,于就是有一堆问题出来了。

遇到权限问题

root@15IKBN:/usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts# cp libfcitxplatforminputcontextplugin.so /snap/shotcut/692/Shotcut.app/lib/qt5/platforminputcontexts/libfcitxplatforminputcontextplugin.so cp: 无法创建普通文件'/snap/shotcut/692/Shotcut.app/lib/qt5/platforminputcontexts/libfcitxplatforminputcontextplugin.so': 只读文件系统

 

 

已经是root用户了,为何还是不能写入文件呢?

 

其实上面不容易看到问题。如果使用mv命令时就更加明白什么问题了,看下面,它提示了一个跨设备,linux中一切皆文件,所以设备也是文件。

root@15IKBN:/var/lib/snapd/snaps# mv /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so /snap/shotcut/692/Shotcut.app/lib/qt5/platforminputcontexts/libfcitxplatforminputcontextplugin.so
mv: 无法进行跨设备的移动:'/usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so' 至'/snap/shotcut/692/Shotcut.app/lib/qt5/platforminputcontexts/libfcitxplatforminputcontextplugin.so';无法删除目标: 只读文件系统

 

 

查看系统中的设备

root@15IKBN:/var/lib/snapd/snaps# lsblk |grep shotcut
loop1                 7:1    0  80.2M  0 loop /snap/shotcut/692

这个loop1设备是随机分配的。
root@15IKBN:/var/lib/snapd/snaps# df -lh|grep shotcut
/dev/loop1                 82M   82M     0  100% /snap/shotcut/692

 

核对文件格式

root@15IKBN:/var/lib/snapd/snaps# mount |grep shotcut
/var/lib/snapd/snaps/shotcut_692.snap on /snap/shotcut/692 type squashfs (ro,relatime)


root@15IKBN:/var/lib/snapd/snaps# file /var/lib/snapd/snaps/shotcut_692.snap
/var/lib/snapd/snaps/shotcut_692.snap: Squashfs filesystem, little endian, version 1024.0, compressed, -3416822521792561152 bytes, -1962213376 inodes, blocksize: 512 bytes, created: Mon Jun 29 13:06:42 2076

可以看到上面的提示squashfs filesystem 居然是用于 Linux 的压缩只读文件系统。详细可参考:

https://www.kernel.org/doc/html/latest/filesystems/squashfs.html

 

最后个人简单理解:因为ubuntu中使用了snap管理工具来安装的shotcut软件的,而snap安装的软件是以挂载的方式,添加到系统中。而这个挂载的方式正是使用了squashfs文件系统。这系统又是以只读方式压缩处理的,所以不能直接对文件修改。要对压缩文件修改就要先解压,再修改,然后重新打包即可。

 

上面差不多都是废话,现在真正解决问题的时候

  • 卸载已经挂载的shotcut

    umount /dev/loop1   #每台机器不同,根据mount|grep shotcut返回的来操作
    

     

  • 复制文件到/tmp目录下方便操作

    mkdir /tmp/te
    cp /var/lib/snapd/snaps/shotcut_692.snap /tmp/te/
    

     

  • 解压文件并对文件修改

    unsquashfs shotcut_692.snap
    cd squashfs-root/Shotcut.app/lib/qt5/platforminputcontexts/
    
    进入对应目录后,执行下面命令把系统中的文件复制到当前目录下。
    cp /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so .
    
    通过查看其它文件也是755的,所以就给它一样的权限
    chmod 755 libfcitxplatforminputcontextplugin.so
    

     

  • 打包修改过的文件

    mksquashfs squashfs-root/ shotcut_692.snap -comp xz  
    

     

  • 替换文件shotcut_692.snap

    cp shotcut_692.snap /var/lib/snapd/snaps/
    

     

  • 重新挂载即可使用

    mount /var/lib/snapd/snaps/shotcut_692.snap /snap/shotcut/692/
    
    这里注意一下,因为snap安装时shotcut编了一个号692不同机器不一样。但是它在上面检查时使用mount命令可以看到,所以这里挂载时要对应上不然点击图标时是不能打开的。
    

     

完成上面操作后就可以在shotcut里添加滤镜文本直接输入中文了。

 

参考:

Deepin系统下shotcut无法输入中文的一种有效的解决方法

https://www.bilibili.com/read/cv9524524

 

本文链接:https://www.58jb.com/html/shotcut-use-in-ubuntu.html

]]>
2022-06-08 16:33:16 +0800 CST
ubuntu使用微信开发者工具 https://www.58jb.com/html/use-wechat-on-ubuntu.html

 

鹅厂官方一直没有出一个给广大linux系统用户的微信开发者工具。最近也是因为要对小程序项目做一个修改更新,但是自己的电脑已经把windows系统换成ubuntu20.04了(快两年不用windows了),所以为了能正常开发微信小程序,所以搜索到网上的这种解决方法(能解决问题的就是好方法)。

 

下面记录一下安装工具和启动过程遇到的问题。

 

基础依赖wine

对于wine来讲,不需要对它太在乎,只要安装上能通过它跑起程序就差不多了。之前我已经通过它运行过魔兽争霸游戏,所以系统已经支持这环境了。

wine安装方法很简单

sudo apt-get install wine -y

我安装的版本,这个版本没有太高要求,网上资料看很多都是1.6左右的

wine-5.0 (Ubuntu 5.0-3ubuntu1)

 

安装开发者工具

Linux微信web开发者工具, 可在 linux 桌面环境跑起 微信开发者工具, 原理是 微信开发者工具 本质是 nw.js 程序, 把它移植到 linux 下没大问题. 负责编译 wxmlwxsswccwcsc (可能还有其他功能), 则利用 wine 来跑即可.

拉取代码

git clone https://github.com/cytle/wechat_web_devtools.git

执行安装

cd wechat_web_devtools
# 自动下载最新 `nw.js` , 同时部署目录 `~/.config/wechat_web_devtools/`
./bin/wxdt install

在安装过程中,我遇到错误提示了,解决方法就是把以下两个目录删除,再执行一次安装。

sudo rm -rf dist/           #它在wechat_web_devtools目录下安装时会自动生成
sudo rm -rf /tmp/wxdt_xsp/

启动开发者工具

./bin/wxdt

 

启动时会提示无法解析小程序,无法加载打开一些文件,会出现以下类似的错误

[279074:279096:0601/210017.890062:ERROR:data_store_impl.cc(131)] Failed to open Data Reduction Proxy DB: 3 [279074:279096:0601/210017.896658:ERROR:database.cc(1713)] Passwords sqlite error 14, errno -2: unable to open database file, sql: -- sqlite3_open() [279074:279096:0601/210017.896694:ERROR:login_database.cc(622)] Unable to open the password store database. [279074:279096:0601/210017.896703:ERROR:password_store_default.cc(43)] Could not create/open login database. [279074:279074:0601/210018.330844:ERROR:desktop_window_tree_host_x11.cc(1125)] Not implemented reached in virtual void views::DesktopWindowTreeHostX11::InitModalType(ui::ModalType) [279074:279146:0601/210023.641493:ERROR:leveldb_env.cc(115)] Failed to open LevelDB database from /home/swper/.config/wechat_web_devtools/Default/Storage/ext/hclkpbeckopaedokicifjgflpbaiehjk/B6040049D0F4/IndexedDB/chrome-extension_hclkpbeckopaedokicifjgflpbaiehjk_0.indexeddb.leveldb,IO error: /home/swper/.config/wechat_web_devtools/Default/Storage/ext/hclkpbeckopaedokicifjgflpbaiehjk/B6040049D0F4/IndexedDB/chrome-extension_hclkpbeckopaedokicifjgflpbaiehjk_0.indexeddb.leveldb/000028.log: Unable to create sequential file (ChromeMethodBFE: 7::NewSequentialFile::5) [279074:279146:0601/210023.646378:ERROR:database.cc(1713)] DatabaseTracker sqlite error 14, errno -2: unable to open database file, sql: -- sqlite3_open() [279074:279146:0601/210023.646515:ERROR:database.cc(1713)] DatabaseTracker sqlite error 14, errno -2: unable to open database file, sql: -- sqlite3_open() [279074:279146:0601/210023.647217:ERROR:database.cc(1713)] DatabaseTracker sqlite error 14, errno -2: unable to open database file, sql: -- sqlite3_open()

 

所以需要给目录授权,为了方便直接777吧

sudo chmod -R 777 ~/.config/wechat_web_devtools/

 

授权后启动时就看不到上面的报错信息了。但是小程序里面还会有一个错误提示。

 

详细的信息可以看到下方的提示在哪个文件或者目录。

原因说明

根据错误的信息找到对应目录下,其实文件是存在的,但是为什么还会有这样的错误呢?

其实程序在启动之前这里~/.config/wechat_web_devtools/WeappVendor 不应该存在该文件,所以一启动项目时就会报错,它是启动后生成的。解决方法就是执行./wxdt命令时先把上面目录的wcc.exe文件删除。

 

修改启动脚本文件wxdt ,添加几行,在启动时先检查是否存在wcc.exe文件,存在就删除

 

 

就是添加了3-8行的代码

  3 #delete wcc.exe
  4 wccFile="$HOME/.config/wechat_web_devtools/WeappVendor/wcc.exe"
  5 
  6 if [ -f "$wccFile" ]; then
  7   rm $wccFile
  8 fi

 

注意

这样每次执行wxdt时就不会再出现上面的错误提示了。不过这也有不足的地方,就是开发者工具不是直接关闭退出程序的,只是点击项目里的关闭当前项目来切换一个项目的话还是会存在上面的提示。

 

 

添加一个启动图标

给程序添加一个启动图标,这样就可以直接在应用程序列表里找到,点击一下就可以启动了。

注意以下代码修改一下执行文件和Icon图片(自己找一个)的图径

 

添加一个文件sudo vim /usr/share/applications/WechatDevtools.desktop 添加以下内容,保存即可。

 

  1 [Desktop Entry]
  2 Type=Application
  3 Name=微信开发者工具
  4 Icon=/opt/wechat_web_devtools/images/logo_miniprogram.png
  5 GenericName=WechatDevtools
  6 Comment=WechatDevtools
  7 Exec="/opt/wechat_web_devtools/bin/wxdt" -desktop
  8 Terminal=false
  9 Categories=Wechat;tencent;

 

这样就可以在ubuntu系统中使用微信开发者工具继续开发小程序了。

本文链接:https://www.58jb.com/html/use-wechat-on-ubuntu.html

]]>
2022-06-02 10:53:17 +0800 CST
笔记本使用ubuntu完成日常工具 https://www.58jb.com/html/use-ubuntu-on-notebook.html

这是一个随手的笔记,主要是为了方便日后再次遇到时容易找到方法。本人使用了一台联想拯救者R720,一个nvme m.2接口的SM961 128G作为系统盘,同时还有一个1TB的机械盘。由于Windows10 经常频繁的自动更新,而且越来越慢,实在受不了,最后决定把系统改成Linux的。

 

因为这已经不是第一次的冲动了,这笔记本在入手没多久后就已经有想法了,无耐当时在nvme m.2这个硬盘无法识别,还有后续的N次(独显问题,WIFI问题,蓝牙问题,触摸屏问题)等。在多次失败后,最后在今年5月份左右,安装上了Ubuntu 20.04 LTS

 

以下记录是在安装完这系统中的一些基本操作,及个人安装的一些软件,主要是解决了满足我的一个日常工作,生活等要求。其实Linux现在已经可以说满足大部分人正常的工作需要,特别是搞IT,程序员等。在编程开发这块可以说是很棒的,简单的来说在Windows10下跑个go程序要卡一下,但是在ubuntu下就刷一下就完了。

 

但是它也在不足的地方就是很多软件都可能没有Linux下的版本(比如微信),所以很多人不愿意使用,再说就是要有些技术基础,和学习成本。

 

安装过程很简单,基本下一步就完事了。这次的版本解决了我之前遇到的问题,基本满足了我的需求。这是在使用了三个多月后的一个使用感受,但是文中记录的只是在平时使用过程中遇到的一些点点滴滴。

 

 

笔记本配置

CPU: Intel 酷睿i5 7300HQ 四核心/四线程
主板芯片: Intel HM175
内存: 8G
机械硬盘: 1TB
固态: NVMe 128GB 三星

 

查看硬件信息(驱动正常都能看到)

swper@15IKBN:~/Desktop$ lspci 
00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (rev 05)
00:01.0 PCI bridge: Intel Corporation Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x16) (rev 05)
00:02.0 VGA compatible controller: Intel Corporation HD Graphics 630 (rev 04)
00:14.0 USB controller: Intel Corporation 100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller (rev 31)
00:14.2 Signal processing controller: Intel Corporation 100 Series/C230 Series Chipset Family Thermal Subsystem (rev 31)
00:16.0 Communication controller: Intel Corporation 100 Series/C230 Series Chipset Family MEI Controller #1 (rev 31)
00:17.0 SATA controller: Intel Corporation HM170/QM170 Chipset SATA Controller [AHCI Mode] (rev 31)
00:1c.0 PCI bridge: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #2 (rev f1)
00:1c.2 PCI bridge: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #3 (rev f1)
00:1c.3 PCI bridge: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #4 (rev f1)
00:1d.0 PCI bridge: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #9 (rev f1)
00:1f.0 ISA bridge: Intel Corporation HM175 Chipset LPC/eSPI Controller (rev 31)
00:1f.2 Memory controller: Intel Corporation 100 Series/C230 Series Chipset Family Power Management Controller (rev 31)
00:1f.3 Audio device: Intel Corporation CM238 HD Audio Controller (rev 31)
00:1f.4 SMBus: Intel Corporation 100 Series/C230 Series Chipset Family SMBus (rev 31)
01:00.0 3D controller: NVIDIA Corporation GP107M [GeForce GTX 1050 Mobile] (rev a1)
02:00.0 SD Host controller: O2 Micro, Inc. SD/MMC Card Reader Controller (rev 01)
03:00.0 Network controller: Qualcomm Atheros QCA9377 802.11ac Wireless Network Adapter (rev 31)
04:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 10)
05:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller SM961/PM961

 

 

 

下载系统,并创建一个USB安装盘

https://mirror.bjtu.edu.cn/ubuntu-releases/20.04.2.0/ubuntu-20.04.2.0-desktop-amd64.iso


# 制作USB安装工具很多,随便都可以。我这里直接使用Etcher
https://www.balena.io/etcher/

 

安装过程很简单这里就不做详细的记录了。我是把系统安装了固态硬盘上的,硬盘直接使用LVM 格式处理

 

以下记录Ubuntu安装完后的一些基本操作。主要是为了更方便,满足日常的工作需要做的一些软件安装,系统配置等。

 

默认安装完后只有一个普通用户,所以我们要对root用户做一个密码修改

sudo passwd root    #回车后输入两次密码即可完成root用户密码修改

 

更新软件源

在安装完成系统后先对系统做一个软件源的更新,为了下次更新或者安装软件更快。

  • 备份配置文件,并把地址改成阿里云的

    #备份配置文件
    cp /etc/apt/sources.list{,.bak}
    
    # 修改配置文件 vim /etc/apt/sources.list
    # 默认可能没有vim这需要先安装一下咯,或者直接使用vi即可。
    
    deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
    
    deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
    
    deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
    
    deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
    
    deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
    
    
  • 更新源

    apt update -y
    

 

 

sudo

为了方便不用每次安装及对系统作一些修改时都要输入密码认证,这里对sudo授权做一个免密授权。

sudo vim /etc/sudoers
#
swper   ALL=(ALL:ALL) NOPASSWD:ALL

 

git简单配置

现在不管是项目代码,还是个人笔记都使用了git来做一个版本管理,方便高效管理。

#为了不用每次拉取代码都要输入帐号密码,创建一个文件,并保存以下内容
vim ~/.gitconfig

[credential]
    helper = store
    
    
#配置一下用户的帐号和密码
git config --global user.name "swper"
git config --global user.email "hz328@qq.com"

 

安装五笔输入法

由于个人是使用五笔输入法,所以这里只记录五笔记的安装,其它的安装方法在网上搜索一下即可以了。

sudo apt-get install fcitx-table-wubi

 

安装sublime

主要是这工具我一直免费使用,功能非常强大,所以必须安装。

wget -qO - https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add -

sudo apt-get install apt-transport-https

echo "deb https://download.sublimetext.com/ apt/stable/" | sudo tee /etc/apt/sources.list.d/sublime-text.list

sudo apt-get update

 

有道翻译安装(依赖一些软件包)

有些时候面对一些英文文档查看不方便时可以翻译一下。

#下载地址,找到linux对应的版本下载
http://cidian.youdao.com/multi.html

#通过dpkg 命令安装
sudo dpkg -i youdao-dict_6.0.0-ubuntu-amd64.deb

#在把下载回来的安装执行安装时会提示一堆依赖的python包,所以执行一下这命令后再重新执行安装。
sudo apt-get --fix-broken install
sudo dpkg -i youdao-dict_6.0.0-ubuntu-amd64.deb

 

Typora—markdown写作工具

这个工具写markdown笔记非常好用,我也是一直在使用的,主要它还有linux版的,大赞。

wget -qO - https://typora.io/linux/public-key.asc | sudo apt-key add -
sudo add-apt-repository 'deb https://typora.io/linux ./'
sudo apt-get update
sudo apt-get install typora

 

wine安装和卸载软件

为什么要安装这个呢?因为我喜欢玩魔兽世界冰封王座(这玩游戏暴露了年龄),因为这游戏在ubuntu通过wine可以说运行得非常顺畅。

 

sudo apt-get install wine -y

#如果要用wine安装一些windows下的程序可以通过以下两个命令,不过我发现安装完总有一些问题。

wine control.exe  #安装
wine uninstaller  #卸载

 

安装xmind

这些一款思维导图工具,虽然是收费,不过也可以免费试用。想不到它有linux版本。

sudo snap install xmind

 

 

以下可能记录比较乱,因为一开始只是为了方便以后再次使用时做的笔记。

 

ubuntu清除卸载后的残留信息

#查看已经安装到系统的软件列表apt list#如果有卸载后的残留信息会有提示的,通过下面命令清除[rc|ic]dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P

 

修改ubuntu grub启动等待时间

如果不这样修改每次启动系统时在启动菜单里都会有30秒的等待时间 ,为了提高速度,这里把等待时间改成3秒。

  • 修改配置文件

    sudo vim /etc/default/grub
    # 默认启动的系统序号,显示在开机界面的,从0开始,这里一般不做修改保留
    GRUB_DEFAULT=0
    # grub页面选择等待的超时时间
    GRUB_RECORDFAIL_TIMEOUT=3
    GRUB_HIDDEN_TIMEOUT_QUIET=true
    GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
    GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
    GRUB_CMDLINE_LINUX=""
    
  • 可以能过查找文件方式发现两个文件其实是指向同一个文件的

    swper@15IKBN:~$ which update-grub|xargs file
    /usr/sbin/update-grub: POSIX shell script, ASCII text executable
    swper@15IKBN:~$ which update-grub2|xargs file
    /usr/sbin/update-grub2: symbolic link to update-grub           #update-grub2也是指向了update-grub
    

     

  • 上面修改完并不能生效

根据配置文件/etc/default/grub中记录的文件:/boot/grub/grub.cfg再次找到/etc/grub.d/00_header文件,在此文件中发现其实是参数:GRUB_RECORDFAIL_TIMEOUT 影响的。所以加上参数GRUB_RECORDFAIL_TIMEOUT = 5

 

  • 修改完配置文件记得更新
sudo update-grub

#重启机器即可 

 

 

ubuntu关机时间等待过长的问题

sudo apt-get install watchdog
sudo systemctl enable watchdog.service
sudo systemctl start watchdog.service

 

安装xmind

这是一款思维导图工具,用过都知道好。

sudo snap install xmind

 

 

安装postman工具

调试一些API非常实用的工具。

sudo snap install postman

 

ubuntu清除卸载后的残留信息

#查看已经安装到系统的软件列表
apt list
#如果有卸载后的残留信息会有提示的,通过下面命令清除[rc|ic]
dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P

 

挂载nfts硬盘

因为是从windows切换过来的,以前保留在机械硬盘里的数据还要继续使用的,所以通过把它挂载上来使用。

#创建一个目录用于机械硬盘的分区,多个分区就创建多个目录来挂载,类似下方的操作即可。
mkdir /disk2

#添加记录到/etc/fstab文件
/dev/sda2       /disk2  ntfs    defaults        0       0

#验证是否成功
sudo mount -a

 

 

开启双屏输出

这个主要是我使用笔记本的hdmi接口接到电视上时遇到的一个问题,可能并不一定要这样设置。在不能正常的情况下再考虑这样操作。

添加一个外接显示器时需要做以下几步

  • 检查系统中的多屏输出接口

    xrandr
    

    二.设置双屏幕显示:

     

  • 打开外接显示器,双屏幕显示相同的内容--克隆(auto为最高分辨率)

    xrandr --output HDMI-1-2 --same-as DP-1-1 --auto
    
  • 若要指定外接显示器的分辨率可以使用下面的命令(1280*1024)

    xrandr --output HDMI-1-2 --same-as DP-1-1 --mode 1920x1080
    
  • 打开外接显示器,设置为右侧扩展

    xrandr --output HDMI-1-2 --rivht-of DP-1-1 --auto
    
  • 关闭显示器

    xrandr --output HDMI-1-2 --off
    
  • 打开VGA-0接口显示器,关闭HDMI-1-2接口显示器

    xrandr --output DP-1-1 --auto --output DMI-1-2 --off
    
  • 如果输出的屏幕没有带声音的话,需要在声音那边选择输出

 

安装微信

在安装完ubuntu后的好几天,非常不爽啊,微信都不能用,后来发现了可以通过docker方式来运行一个微信,而且功能都不错。以下就是记录一下安装操作记录。

  • 安装docker

    #移除旧的软件包
    sudo apt-get remove docker docker-engine docker.io containerd runc
    #更新一下系统的源
    sudo apt-get update
    sudo apt-get install \
        apt-transport-https \
        ca-certificates \
        curl \
        gnupg \
        lsb-release
    #添加官方源    
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    
    #因为我的是64位系统
    echo \
      "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
      
    #安装docker
    sudo apt-get update
    sudo apt-get install docker-ce docker-ce-cli containerd.io
    
    #为了方便添加开机启动
    sudo systemctl docker enable --now
    

     

  • 拉取镜像

    sudo docker pull bestwu/wechat
    
  • 创建一个启动脚本weixin.sh

    cat >$HOME/weixin.sh<<-EOF
    #!/usr/bin/bash
    sudo docker rm -f wechat >/dev/null 2>&1
    sudo docker run -d --name wechat --device /dev/snd --ipc=host \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/WeChatFiles:/WeChatFiles \
    -e DISPLAY=unix$DISPLAY \
    -e XMODIFIERS=@im=fcitx \
    -e QT_IM_MODULE=fcitx \
    -e GTK_IM_MODULE=fcitx \
    -e AUDIO_GID=`getent group audio | cut -d: -f3` \
    -e GID=`id -g` \
    -e UID=`id -u` \
    bestwu/wechat
    EOF
    
  • 启动容器

    sh weixin.sh        
    

     

  • 查看系统中audio ID 值

    getent group audio | cut -d: -f3
    

    解决问题

    • 中文输入,把脚本中ibus改成fcitx
    • 微信中的音频问题,AUDIO_GID用于获取主机的声卡ID

 

因为直接执行上面脚本时,会每次都把上一次的容器删除,导致聊天记录也删除了,不方便,再者就是启动慢很多.所以在第一次启动后,我们直接以start方式启动停止的容器,更方便还能看到历史聊天记录.

 

创建另一个启动脚本wechat.sh

#!/usr/bin/bash
sudo docker start wechat

 

创建一个桌面图标Wechat.desktop

同样由于docker启动的微信没有图标,所以自己添加一个图标了方便打开。

[Desktop Entry]
Type=Application
Name=Wechat
Icon=/disk2/linuxSoft/wechat.png
GenericName=Wechat
Comment=Wechat
Exec="/disk2/linuxSoft/wechat.sh" -desktop
Terminal=false
Categories=Wechat;tencent;

 

为了方便我们会把快捷方式加到/usr/share/applications目录,这样就可以在应用程序列表中看到刚才创建的程序了.

 

 

 

 

 

安装Preload

Preload(预加载)会在后台工作,以「研究」您如何使用计算机并增强计算机的应用程序处理能力。安装好 Preload 后,您使用频率最高的应用程序的加载速度就会明显快于不经常使用的应用程序。具体这个没发现什么效果,所以自己看着办咯。

sudo apt install preload

 

 

正常要打开魔兽世界冰封王座的话可能要通过命令来启动,但是这样不方便,所以要创建一个图标来点击运行程序。

 

魔兽世界冰封王座桌面图标

由于魔兽世界是windows 应用程序,所以通过win方式来启动.创建一个Warcraft.desktop文件,内容如下:

[Desktop Entry]
Type=Application
Name=Warcraft III
Icon=/disk2/Warcraft/war3.ico
GenericName=Warcraft III
Comment=Warcraft
Exec=wine "/disk2/Warcraft/war3.exe" -opengl -desktop        #这里注意游戏的目录,我是在nfts分区上的,而它是挂载到disk2目录下
Terminal=false
Categories=Warcraft;GAME;

 

 

 

 

 

 

安装Vscode

如果是通过snap软件仓库安装的话会遇到无法输入中文,所以直接使用官方的安装包

参考:https://code.visualstudio.com/docs/setup/linux

sudo dpkg -i code_1.57.1-1623937013_amd64.deb

 

dpkg 安装和卸载软件

 

安装软件包

ubuntu下软件包的后缀后为 .deb ,手动安装可以通过dpkg命令来安装

dpkg -i 软件包名

 

卸载软件包

通过dpkg方式安装的话,可能有些软件安装后的程序名跟安装包的名称不一样,所以我们先通过搜索出来再卸载.当卸载完后会发现有些图标啊,或者程序还在运行中等.此时需要先程序退出,等待程序清理完.

dpkg -l|grep "软件包名"
dpkg -r name               #卸载包,卸载软件,保留配置文件
dpkg -P name               #清除包配置文件之类的,卸载软件,同时删除配置文件
dpkg -s name           #查看软件包信息
dpkg -L name           #查看软件包的安装路径`

 

 

Ubuntu忘记登陆密码的方法

1、关机,按住Esc 或者Shift键,重新开机,进入GNU GRUB启动菜单栏

2、选择Advanced option for Ubuntu,点击回车

3、选择带有(recovery mode),不要点击回车,按下E键,进入下一个界面

4、往下走几行找到以linux开头的行,找到ro recovery nomodeset删除,并在最后添加rw quiet splash rw init=/bin/bash 或者添加rw single init=/bin/bash

5、然后根据下方的提示按Ctrl+x进入系统重置密码

6、修改用户密码passwwd 用户名

7、关机,重新开机即可

 

 

查看并安装推荐的显卡驱动

#此命令系统会根据硬件推荐适合的显卡驱动
sudo ubuntu-drivers devices

#根据提示recommended安装
sudo apt-get install nvidia-352

#或者在Software && Updates 工具里找到附加驱动里安装

nv设置显卡

nvidia-settings

切换显卡

sudo prime-select nvidia #使用用nv独显
sudo prime-select intel   #使用集成

查看当前显卡的驱动

nvidia-smi

 

 

ubuntu关于sudoer编辑不正确但又已经保存了文件现在的异常

swper@virtual:~$ sudo vim /etc/sudoers

/etc/sudoers: 语法错误 near line 27 <<< sudo: /etc/sudoers 中第 27 行附近有解析错误 sudo: 没有找到有效的 sudoers 资源,退出 sudo: 无法初始化策略插件

解决方法:
pkexec visudo     #会提示输入密码,然后进入编辑器,只需要把错误那行删除并保存即可。

 

 

防火墙ufw简单操作

 

#默认都应该安装了ufw
apt-get install ufw

#启动
systemctl start ufw

# 关闭

systemct stop ufw

#查看状态
systemctl status ufw  或者  ufw status


#启动规则
ufw enable

#禁用规则
ufw disable


#重置规则
ufw reset


#放行规则

#服务名
ufw allow ssh
ufw allow https
ufw allow http

#端口
ufw allow 22
ufw allow 443
ufw allow 80

ufw allow 6000:6003/tcp

#禁止
ufw deny from 192.168.11.7

#查看规则列表
ufw status numbered

#删除规则,通过上面的列表看到序号
ufw delete 4

#通过服务名删除
ufw delete allow http

 

确认笔记本显示的型号

swper@15IKBN:~$ sudo lshw -numeric -C display|grep -A6 product
       product: GP107M [GeForce GTX 1050 Mobile] [10DE:1C8D]
       vendor: NVIDIA Corporation [10DE]
       physical id: 0
       bus info: pci@0000:01:00.0
       version: a1
       width: 64 bits
       clock: 33MHz
--
       product: HD Graphics 630 [8086:591B]
       vendor: Intel Corporation [8086]
       physical id: 2
       bus info: pci@0000:00:02.0
       version: 04
       width: 64 bits
       clock: 33MHz

 

 

关于笔记本显示的安装

swper@15IKBN:~$ ubuntu-drivers devices
WARNING:root:_pkg_get_support nvidia-driver-390: package has invalid Support Legacyheader, cannot determine support level
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00001C8Dsv000017AAsd000039D1bc03sc02i00
vendor   : NVIDIA Corporation
model    : GP107M [GeForce GTX 1050 Mobile]
driver   : nvidia-driver-390 - distro non-free
driver   : nvidia-driver-470 - distro non-free recommended           #推荐安装的版本,我这里也是安装了这个版本
driver   : nvidia-driver-460-server - distro non-free
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-460 - distro non-free
driver   : nvidia-driver-418-server - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin


#可以执行以下命令安装
sudo ubuntu-drivers autoinstall

#如果没有特别的话也可以直接使用图形工具安装

 

 

未知的问题

运行dmesg 查看内核启动日志时发现的

[    0.243844] platform MSFT0101:00: failed to claim resource 1: [mem 0xfed40000-0xfed40fff]
[    0.243848] acpi MSFT0101:00: platform device creation failed: -16


# 以下感觉是启动时间长的原因,在蓝牙模块初始化时耗时太久了
[   11.984497] Started bpfilter
[   12.033605] Initializing XFRM netlink socket
[   12.228638] rfkill: input handler disabled
[  894.842882] Bluetooth: RFCOMM TTY layer initialized
[  894.842890] Bluetooth: RFCOMM socket layer initialized
[  894.842894] Bluetooth: RFCOMM ver 1.11
[  894.995672] rfkill: input handler enabled
[  900.518178] rfkill: input handler disabled
[  900.798111] audit: type=1400 audit(1626959530.057:43): apparmor="DENIED" operation="capable" profile="/snap/snapd/12398/usr/lib/snapd/snap-confine" pid=60704 comm="snap-confine" capability=4  capname="fsetid"


#查看蓝牙服务状态时有这样的提示
swper@15IKBN:~$ sudo systemctl status bluetooth.service 
● bluetooth.service - Bluetooth service
     Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2021-07-22 20:57:14 CST; 1h 16min ago
       Docs: man:bluetoothd(8)
   Main PID: 764 (bluetoothd)
     Status: "Running"
      Tasks: 1 (limit: 9327)
     Memory: 2.1M
     CGroup: /system.slice/bluetooth.service
             └─764 /usr/lib/bluetooth/bluetoothd

7月 22 20:57:14 15IKBN systemd[1]: Starting Bluetooth service...
7月 22 20:57:14 15IKBN bluetoothd[764]: Bluetooth daemon 5.53
7月 22 20:57:14 15IKBN systemd[1]: Started Bluetooth service.
7月 22 20:57:14 15IKBN bluetoothd[764]: Starting SDP server
7月 22 20:57:14 15IKBN bluetoothd[764]: Bluetooth management interface 1.17 initialized
7月 22 20:57:14 15IKBN bluetoothd[764]: Failed to set mode: Blocked through rfkill (0x12)
7月 22 20:57:21 15IKBN bluetoothd[764]: Failed to set mode: Blocked through rfkill (0x12)
7月 22 21:12:04 15IKBN bluetoothd[764]: Endpoint registered: sender=:1.73 path=/MediaEndpoint/A2DPSink/sbc
7月 22 21:12:04 15IKBN bluetoothd[764]: Endpoint registered: sender=:1.73 path=/MediaEndpoint/A2DPSource/sbc



#查看设备的状态
swper@15IKBN:~$ rfkill 
ID TYPE      DEVICE                 SOFT      HARD
 0 wlan      ideapad_wlan      unblocked unblocked
 1 bluetooth ideapad_bluetooth   blocked unblocked
 2 bluetooth hci0                blocked unblocked
 3 wlan      phy0              unblocked unblocked


#禁止
swper@15IKBN:~$ rfkill block bluetooth
#执行完操作后,重启机器再看dmesg日志发现在初始化蓝牙时的耗时很短了
[   12.475783] Initializing XFRM netlink socket
[   12.775701] rfkill: input handler disabled
[   23.657272] Bluetooth: RFCOMM TTY layer initialized
[   23.657276] Bluetooth: RFCOMM socket layer initialized
[   23.657279] Bluetooth: RFCOMM ver 1.11
[   23.807611] rfkill: input handler enabled
[   29.147037] rfkill: input handler disabled



#解除
swper@15IKBN:~$ rfkill unblock bluetooth

 

最后还是要说明一下,ubuntu在使用过程中还是会有多次提示提交bug或者异常的提示框,至少比蓝屏的好多了。可选择不发送,继续使用,本文暂时就记录到此,以后有新问题或者记录会继续关注。

本文链接:https://www.58jb.com/html/use-ubuntu-on-notebook.html

]]>
2021-08-29 21:14:53 +0800 CST
安装kubernetes v1.20.0版本时遇到的一个异常 https://www.58jb.com/html/k8s_v1.20_coredns_error.html

在没有安装网络插时的情况下

在v1.18.0版本中就是没有安装网络插件时都是NotReady状态的;这次发现有点奇怪了;

[root@k8s-master ~]# kubectl get nodes
NAME        STATUS     ROLES                  AGE     VERSION
k8s-node1   Ready      <none>                 110m    v1.21.0
k8s-node2   Ready      <none>                 110m    v1.21.0
node        NotReady   control-plane,master   3h46m   v1.21.0       #这是master节点

通过kubectl describe nodes node查看该节点,看到这样的信息

container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

再查看相应Pod时可以看到是coredns启动创建成功,那么其它节点为什么是Ready状态呢?

[root@k8s-master ~]# kubectl get po -n kube-system  -o wide
NAME                           READY   STATUS              RESTARTS   AGE     IP              NODE        NOMINATED NODE   READINESS GATES
coredns-558bd4d5db-gsq4m       0/1     ContainerCreating   0          70m     <none>          k8s-node1   <none>           <none>
coredns-558bd4d5db-wjmc4       0/1     ContainerCreating   0          33m     <none>          k8s-node1   <none>           <none>
etcd-node                      1/1     Running             0          5h37m   192.168.18.71   node        <none>           <none>
kube-apiserver-node            1/1     Running             0          5h37m   192.168.18.71   node        <none>           <none>
kube-controller-manager-node   1/1     Running             0          5h37m   192.168.18.71   node        <none>           <none>
kube-flannel-ds-clv8p          1/1     Running             0          11m     192.168.18.73   k8s-node2   <none>           <none>
kube-flannel-ds-rdphh          1/1     Running             0          11m     192.168.18.72   k8s-node1   <none>           <none>
kube-flannel-ds-zlg5w          1/1     Running             0          11m     192.168.18.71   node        <none>           <none>
kube-proxy-9hr59               1/1     Running             0          5h36m   192.168.18.71   node        <none>           <none>
kube-proxy-pbsht               1/1     Running             0          3h41m   192.168.18.72   k8s-node1   <none>           <none>
kube-proxy-t6kvr               1/1     Running             0          3h41m   192.168.18.73   k8s-node2   <none>           <none>
kube-scheduler-node            1/1     Running             0          5h37m   192.168.18.71   node        <none>           <none>

查看coredns pod详情发现错误了

  Warning  FailedCreatePodSandBox  2m35s                kubelet            Failed to create pod sandbox: rpc error: code = Unknown desc = [failed to set up sandbox container "efb1f4977ea3d506b79e6e2cc22b4e03e30a087068f19f54b5b414f400b0bf7e" network for pod "coredns-558bd4d5db-8dtmp": networkPlugin cni failed to set up pod "coredns-558bd4d5db-8dtmp_kube-system" network: error getting ClusterInformation: Get https://127.0.0.1:6443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 127.0.0.1:6443: connect: connection refused, failed to clean up sandbox container "efb1f4977ea3d506b79e6e2cc22b4e03e30a087068f19f54b5b414f400b0bf7e" network for pod "coredns-558bd4d5db-8dtmp": networkPlugin cni failed to teardown pod "coredns-558bd4d5db-8dtmp_kube-system" network: error getting ClusterInformation: Get https://127.0.0.1:6443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 127.0.0.1:6443: connect: connection refused]

直接登陆k8s-node1节点上查看一下日志,发现都是不断重建销毁操作;不过奇怪的是我使用的flannel网络怎么日志会出现有calico字样的呢?

Apr 22 17:12:23 k8s-node1 kubelet[17383]: I0422 17:12:23.198399   17383 cni.go:333] "CNI failed to retrieve network namespace path" err="cannot find network namespace for the terminated container \"764830fc792a18935f6e984c91defa1916433f8b98e763857fc64d62ce8e04ea\""
Apr 22 17:12:23 k8s-node1 kubelet[17383]: E0422 17:12:23.261949   17383 cni.go:380] "Error deleting pod from network" err="error getting ClusterInformation: Get https://127.0.0.1:6443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 127.0.0.1:6443: connect: connection refused" pod="kube-system/coredns-558bd4d5db-wjmc4" podSandboxID={Type:docker ID:764830fc792a18935f6e984c91defa1916433f8b98e763857fc64d62ce8e04ea} podNetnsPath="" networkType="calico" networkName="k8s-pod-network"
Apr 22 17:12:23 k8s-node1 kubelet[17383]: E0422 17:12:23.263391   17383 remote_runtime.go:144] "StopPodSandbox from runtime service failed" err="rpc error: code = Unknown desc = networkPlugin cni failed to teardown pod \"coredns-558bd4d5db-wjmc4_kube-system\" network: error getting ClusterInformation: Get https://127.0.0.1:6443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 127.0.0.1:6443: connect: connection refused" podSandboxID="764830fc792a18935f6e984c91defa1916433f8b98e763857fc64d62ce8e04ea"
Apr 22 17:12:23 k8s-node1 kubelet[17383]: E0422 17:12:23.263501   17383 kuberuntime_manager.go:958] "Failed to stop sandbox" podSandboxID={Type:docker ID:764830fc792a18935f6e984c91defa1916433f8b98e763857fc64d62ce8e04ea}
Apr 22 17:12:23 k8s-node1 kubelet[17383]: E0422 17:12:23.263623   17383 kuberuntime_manager.go:729] "killPodWithSyncResult failed" err="failed to \"KillPodSandbox\" for \"983d5974-dc76-4a40-8370-f098671175c9\" with KillPodSandboxError: \"rpc error: code = Unknown desc = networkPlugin cni failed to teardown pod \\\"coredns-558bd4d5db-wjmc4_kube-system\\\" network: error getting ClusterInformation: Get https://127.0.0.1:6443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 127.0.0.1:6443: connect: connection refused\""
Apr 22 17:12:23 k8s-node1 kubelet[17383]: E0422 17:12:23.263718   17383 pod_workers.go:190] "Error syncing pod, skipping" err="failed to \"KillPodSandbox\" for \"983d5974-dc76-4a40-8370-f098671175c9\" with KillPodSandboxError: \"rpc error: code = Unknown desc = networkPlugin cni failed to teardown pod \\\"coredns-558bd4d5db-wjmc4_kube-system\\\" network: error getting ClusterInformation: Get https://127.0.0.1:6443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 127.0.0.1:6443: connect: connection refused\"" pod="kube-system/coredns-558bd4d5db-wjmc4" podUID=983d5974-dc76-4a40-8370-f098671175c9

 

是根据上面情况,通过排查cni插件目录,发现/etc/cni/net.d/目录下有些不同了;

#master节点只一个,而Node节点都有三个文件,奇怪了
[root@k8s-master ~]# ll /etc/cni/net.d/
total 4
-rw-r--r-- 1 root root 292 Apr 22 17:01 10-flannel.conflist
[root@k8s-master ~]# 

#node1节点
[root@k8s-node1 ~]# ll /etc/cni/net.d/
total 12
-rw-rw-r-- 1 root root  656 Apr 12 16:56 10-canal.conflist
-rw-r--r-- 1 root root  292 Apr 22 17:01 10-flannel.conflist
-rw------- 1 root root 2587 Apr 12 16:56 calico-kubeconfig
[root@k8s-node1 ~]# 

#node2节点
[root@k8s-node2 ~]# ll /etc/cni/net.d/
total 12
-rw-rw-r-- 1 root root  656 Apr 12 16:56 10-canal.conflist
-rw-r--r-- 1 root root  292 Apr 22 17:01 10-flannel.conflist
-rw------- 1 root root 2587 Apr 12 16:56 calico-kubeconfig
[root@k8s-node2 ~]# 

正常情况下应该是其它的节点同步了Master节点上的cni目录的,所以这里把其它节点上的10-canal.conflistcalico-kubeconfig删除。当这两个文件删除后,再回到master节点查看发现相应的Pod已经正常运行了。

[root@k8s-master ~]# kubectl get po -n kube-system 
NAME                           READY   STATUS    RESTARTS   AGE
coredns-558bd4d5db-gsq4m       1/1     Running   0          80m
coredns-558bd4d5db-wjmc4       1/1     Running   0          43m
etcd-node                      1/1     Running   0          5h46m
kube-apiserver-node            1/1     Running   0          5h46m
kube-controller-manager-node   1/1     Running   0          5h46m
kube-flannel-ds-clv8p          1/1     Running   0          20m
kube-flannel-ds-rdphh          1/1     Running   0          20m
kube-flannel-ds-zlg5w          1/1     Running   0          20m
kube-proxy-9hr59               1/1     Running   0          5h46m
kube-proxy-pbsht               1/1     Running   0          3h50m
kube-proxy-t6kvr               1/1     Running   0          3h50m
kube-scheduler-node            1/1     Running   0          5h46m
[root@k8s-master ~]# 

 

本文链接:https://www.58jb.com/html/k8s_v1.20_coredns_error.html

]]>
2021-04-22 18:00:28 +0800 CST
通过ldap认证里的邮箱地址登陆Jenkins https://www.58jb.com/html/use-email-login-jenkins.html

在上一次的文档中记录了jenkins 如何通过ldap认证登陆 https://www.58jb.com/html/jenkins-auth-with-ldap.html,文中是以用户名的方式登陆的,如果要使用邮件地址或者电话号码作为帐号登陆呢?如何实现?

由于最近网友的一个问题,能不能通过邮件地址的方式来登陆Jenkins,刚开始我觉得好像不行。后来研究了一下,发现其实很简单,因为在使用ldap认证时获取到整个用户的相应信息了。而至于使用该用户哪个字段, 用户、邮箱地址、或者电话号码等那是取决于我们过滤匹配字段。

 

其实在Jenkins里就已经有说明了。只是没太在意,以下是引用它的原文

 

User search filter右边问题的说明

One of the searches Jenkins does on LDAP is to locate the user record given the user name.
This field determines the query to be run to identify the user record. The query is almost always "uid={0}" as per defined in RFC 2798, so in most cases you should leave this field empty and let this default kick in.

If your LDAP server doesn't have uid or doesn't use a meaningful uid value, try "mail={0}", which lets people login by their e-mail address.

If you do specify a different query, specify an LDAP query string with marker token "{0}", which is to be replaced by the user name string entered by the user.

( LDAP Plugin)

 

通过说明就可以发现,如果要使用邮件地址登陆,就使用mail={0}来匹配User search filter

(&(mail={0})(memberof=cn=jenkins,ou=group,dc=sotemalltest,dc=com))

 

如果要通过手机号码认证登陆,就使用telephoneNumber={0} 来匹配User search filter

(&(telephoneNumber={0})(memberof=cn=jenkins,ou=group,dc=sotemalltest,dc=com))

 

注意:上面修改字段是在User search filter里使用的。为了清楚来一张完整的配置图。

 

 

 

 

配置说明

  • User search filter:用来匹配过滤,这里过滤用户信息时以邮件来匹配该目录下的用户。
  • Group membership :匹配组关系,这里使用默认memberOf ,当然也可以像上一篇文章的配置那样(&(mail={1})) ,这里使用1来获取,可以返回用户名。而使用0时在Test LDAP settings时返回一段Waring信息。
  • Display Name LDAP attribute :它作用是使用ldap里的用户登陆后,在Jenkins上面显示的用户名信息,如:telephoneNumber则显示ldap用户配置里的Telephone numbergivenName则显示ldap用户配置里的First name ; mail 则显示ldap用户配置里的Emaill address这里看个人喜欢配置。

 

特别说明

  • 虽然我们可以配置通过ldap上的用户名,邮箱地址,电话号码为帐号登陆jenkins,不管是哪一个登陆方式,在第一次登陆到jenkins时都会创建一个以登陆名为帐号的帐号;直接说就是,登陆名是邮件 ,就会创建一个邮件地址的帐号,登陆名是电话号码就会创建一个电话号码的帐号。当然密码还是一样的。
  • 不能同时使用邮件、用户名或者是电话号码登陆,因为配置过滤器里指定了过滤的方式User search filter
  • 当使用邮箱地址或者手机号登陆时就要注意了帐号唯一性的问题,不能相同的,不然无法正确识别。

 

本文链接:https://www.58jb.com/html/use-email-login-jenkins.html

]]>
2020-11-05 11:43:10 +0800 CST
ssl_protocols协议导致网站和小程序无法正常提供服务 https://www.58jb.com/html/nginx_ssl_error.html

nginx在错误日志里会一直输出以下信息

2020/10/16 10:07:41 [crit] 16203#0: *4672 SSL_read() failed (SSL: error:14095126:SSL routines:ssl3_read_n:unexpected eof while reading) while keepalive, client: XXX.XXX.XXX.XXX, server: 0.0.0.0:443

 

事故原因:

由于业务需要把一个项目迁移回来,nginx 上的配置也直接就搬了回来放到相对个一点的版本上。由于Nginx -t 检查配置文件通过,直接reload后服务就跑起来了。

但是在浏览器里访问项目时发现异常提示,"你与网站建立的连接不安全"

相应的服务在小程序里访问时提示:"request:fail 发生了SSL错误,无法建立与该服务器的安全连接。"

 

之前在迁移之前,这套配置文件在之前的系统中是正常的,一迁移到当前机器就出现问题了。刚开始以为是Nginx编译时的openssl版本问题所致,然后使用新的openssl 重新编译nginx后问题依旧(参考上面日志信息),甚至无法访问服务。

 

根本原因:

由于这个环境中有多个Nginx配置文件,多个域名都使用ssl协议,但是之前的配置中带有旧的TLSv1.0协议,而上面刚迁移过来的配置中定义使用的是TLSv1.2协议。因为小程序也要求在TLSv1.2以上,之前未迁移回来时是单独一台机器的,现在并在一起了就有了老旧协议的问题。因为两个配置中版本不统一,导致ngixn无法处理,就会出现上面的异常问题。

 

解决方法

统一修改当前机器上所有配置ssl_protocols。前提是Nginx编译时是支持TLSv1.2或以上

    ssl_protocols   TLSv1.2 TLSv1.3;
    add_header Strict-Transport-Security "max-age=63072000" always;

 

检查openssl是否支持TLSv1.2

openssl ciphers -v | awk '{print $2}' | sort | uniq

 

命令行检查网站是否支持TLSv1.2

成功的可以看到这么一行信息:* SSL connection using XXXXX

curl -I -v --tlsv1.2 --tls-max 1.2 https://www.58jb.com/

 

说明

根据问题发现在网上https://github.com/openssl/openssl/issues/11381 同样存在这样的情况,哪怕是已经把上面的问题解决了,但是使用openssl1.1.1e重新编译后的Nginx日志一样会这样输出。具体情况还待深入研究。

 

 

 

本文链接:https://www.58jb.com/html/nginx_ssl_error.html

]]>
2020-10-16 15:08:41 +0800 CST
制作属于自己的Jenkins slave镜像 https://www.58jb.com/html/build-jenkins-slave-images.html

kubernetes中准备搭建一个jenkins 的多节点环境,默认的master节点直接使用了jenkins官方的镜像即可。但是对于slave镜像的话,网上也有很多,有些是使用JNLP方式实现连接的,有些是使用ssh方式。但是使用ssh方式连接的镜像很多都是自己制作的,因为里面会配置一个root的密码用来连接容器。所以为了自己方便,所以制作者一个属于自己的镜像是很重要的。

 

系统环境

系统: CentOS Linux release 7.2.1511 (Core)

docker-ce: 19.03.5

 

制作基础镜像

本次镜像使用centos7的系统光盘实现。

 

  • 挂载centos7光盘到系统中

     mount /dev/sr0 /mnt/
    
  • 创建一个目录用来保存文件

    mkdir -p /data/centos7
    export centos_root=/data/centos7
    
  • 添加一个repo文件到/etc/yum.repos.d/local.repo

    最好把/etc/yum.repos.d目录下的文件移到/tmp目录下,然后再添加以下文件

    cat >/etc/yum.repos.d/local.repo<<-EOF
    [local]
    name=local_mnt
    baseurl="file:///mnt"
    enabled=1
    gpgchjeck=1
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
    EOF
    
  • 安装所需要的工具(这就是基础镜像)

    yum -y --installroot=${centos_root} install bash coreutils findutils procps iputils iproute curl openssh-clients openssh-server vim wget git
    
  • /data/centos7打包成一个centos7-base镜像

    [root@localhost centos7]# du -sh /data/centos7/
    488M	/data/centos7/
    
    //执行以下命令打包成镜像
    tar -C ${centos_root} -c . | docker import - centos7-base
    
  • 由于上面制作的基础镜像中并没在启动ssh服务,所以需要通过Dockerfile方式重新打包成一个新的镜像

    cat >Dockerfile<<-EOF
    FROM centos7-base
    MAINTAINER Swper <service@58jb.com>
    ADD jdk1.8.0_121 /usr/local/java
    ADD apache-maven-3.6.3 /usr/local/maven
    RUN ln -s /usr/local/java/bin/java /usr/bin/java && \
    	ln -s /usr/local/maven/bin/mvn /usr/bin/mvn && \
    	ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa && \
    	ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -N '' -t ed25519 && \
    	echo 'root:你的密码' | chpasswd && \
    	echo 'export JAVA_HOME=/usr/local/java' >>/etc/profile && \
    	useradd -m -d /home/jenkins -s /bin/bash jenkins && \
    	mkdir -p /home/jenkins/.jenkins && \
    	chmod -R 777 /home/jenkins
    ENV JAVA_HOME /usr/local/java
    ENV MAVEN_HOME /usr/local/maven
    ENV PATH $JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
    EXPOSE 22/tcp
    CMD ["/usr/sbin/sshd", "-D"]
    WORKDIR /home/jenkins
    EOF
    
  • 执行build命令

    docker build -t jenkins-slave . -f Dockerfile
    

配置说明

  • 上面的配置文件中定义的ADD加入的两个目录必须跟Dockerfile在同一目录下

  • 为了解决环境变量问题,做了一个软连接,同时使用ENV定义环境变量

  • 由于上面的ENV参数在容器里出现了,mvn执行时无法发现JAVA_HOME所以把变量加入到/etc/profile文件中

  • 配置文件中加入了root的密码,此帐号是ssh登陆到容器使用的

  • 创建/home/jenkins并授权足够的权限,因为git拉代码和build 都需要写入权限

  • 实际使用中发现,上面配置中添加jenkins用户这行可以省,因为容器启动时以root方式启动的

  • 需要暴露22端口,并指定一个工作目录。

  • jenkins slave镜像其实就是一个支持java环境,和打包工具maven或者gradle的基础镜像。Jenkins有两种添加slave的方式,JNLPssh方式,个人觉得ssh方式更加方便,易扩展。

  • 如果使用openjdk的话可以把镜像大小再做进一步的优化

     

如果拉取了别人的jenkins slave镜像后不知道它配置的密码怎么办?

  • 通过以下方式查看build镜像时的命令

    1、定义一个变量(当然你以可以不定义)
    DockerImage=你拉取下来的镜像名
    
    2、执行以下命令(如果它在dockerfile中定义修改root密码的话就可以看到了)
    docker history --format {{.CreatedBy}} --no-trunc=true $DockerImage |sed "s/\/bin\/sh\ -c\ \#(nop)\ //g"|sed "s/\/bin\/sh\ -c/RUN/g" | tac
    

     

 

本文链接:https://www.58jb.com/html/build-jenkins-slave-images.html

]]>
2020-09-30 16:14:34 +0800 CST
解决kubernetes Pod无法连接外网的过程记录 https://www.58jb.com/html/fixed-kubernetes-Pod-unable-to-connect-to-external-network.html

解决kubernetes Pod无法连接外网的过程记录

一般情况下,我们的Pod并不需要连接外网,但是有一部分需要连接外部网络更新,安装插件的容器除外。例如:运行在Pod中的 Jenkins 容器,它需要连接外网更新,安装所需插件。

 

前提条件:

Kubernetes集群中使用的防火墙是firewalldCNI插件为flannel;如果你使用的防火墙为iptables的话请无视,因为使用iptables的话可以直接清空所有规则后即可实现网络连通。本文记录是在firewalld防火墙开启的情况下遇到的异常问题及解决过程。

 

环境说明

系统: CentOS Linux release 7.7.1908 (Core)

内核:4.4.230-1.el7.elrepo.x86_64

Kubernetes 版本:v1.18.0

防火墙:firewalld

 

K8s集群配置

k8s-master192.168.18.71
k8s-node1192.168.18.72
k8s-node2192.168.18.73

 

本集群环境使用Kubeadm 安装,具体安装要求可以参考网上的文章完成。

 

大部分网上的安装教程中都会提示我们在firewalld防火墙中需要放行以下端口;

 

Master 添加规则:

firewall-cmd --permanent --add-port=6443/tcp
firewall-cmd --permanent --add-port=2379-2380/tcp
firewall-cmd --permanent --add-port=10250/tcp
firewall-cmd --permanent --add-port=10251/tcp
firewall-cmd --permanent --add-port=10252/tcp
firewall-cmd --permanent --add-port=8472/udp
firewall-cmd --permanent --add-port=30000-32767/tcp
firewall-cmd --add-masquerade --permanent
systemctl restart firewalld

 

Node 添加规则:

firewall-cmd --permanent --add-port=10250/tcp
firewall-cmd --permanent --add-port=8472/udp
firewall-cmd --permanent --add-port=30000-32767/tcp
firewall-cmd --add-masquerade --permanent
systemctl restart firewalld

 

按照上面的防火墙规则添加后,大部分功能都正常(在没在Pod需要连接外网的情况下);


 

 

以下是我在使用firewalld防火墙时遇到的两个问题

 

问题1:集群中的Jenkins无法连接外网,安装插件;出现该Jenkins实例似乎已离线提示

因为集群中的dns无法正常提供服务,需要检查防火墙是否有放行53/udp53/tcp端口。这里虽然简单的做一个记录,但是大部分的Pod无法连接外网都可能是由于这个原因。

firewall-cmd --add-port=53/tcp --permanent 
firewall-cmd --add-port=53/udp --permanent 
systemctl restart firewalld.service

 

问题2:集群中的coredns 容器一直出现以下异常提示

通过命令kubectl logs -n kube-system coredns-xxxx-xxxx 查看到指定Pod日志时发现以下信息

E0917 09:40:52.407548       1 reflector.go:153] pkg/mod/k8s.io/client-go@v0.17.2/tools/cache/reflector.go:105: Failed to list *v1.Endpoints: Get https://10.96.0.1:443/api/v1/endpoints?limit=500&resourceVersion=0: dial tcp 10.96.0.1:443: connect: no route to host

 

以下是问题排查过程

 

1、检查kube-dns相应的Pod状态

[root@k8s-master ~]# kubectl get po -n kube-system -l k8s-app=kube-dns
NAME                       READY   STATUS    RESTARTS   AGE
coredns-66bff467f8-vl86q   0/1     Running   0          5h14m
coredns-66bff467f8-xmztq   0/1     Running   0          5h13m

可以看到Pod状态为Running 但是Ready不正常,详细信息可以这样查看。主要是看Conditions字段下的Conditions ,这里为False表明容器是在运行,但是并没有就绪,那就说明服务不能正常提供DNS解析。

 

[root@k8s-master ~]# kubectl -n kube-system describe po coredns-66bff467f8-vl86q|grep -A 5 "Conditions"
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 

 

由此可见kube-dns创建的Pod虽然在每个Node节点上运行了,但是并没有就绪,接下来就查看日志详细信息。

通过命令kubectl logs -n kube-system coredns-66bff467f8-vl86q 查看到指定Pod日志时发现以下信息

E0917 09:40:52.407548       1 reflector.go:153] pkg/mod/k8s.io/client-go@v0.17.2/tools/cache/reflector.go:105: Failed to list *v1.Endpoints: Get https://10.96.0.1:443/api/v1/endpoints?limit=500&resourceVersion=0: dial tcp 10.96.0.1:443: connect: no route to host

 

根据日志信息查看一下kube-dns相应的Endpoints状态信息

[root@k8s-master ~]# kubectl -n kube-system describe endpoints kube-dns 
Name:         kube-dns
Namespace:    kube-system
Labels:       k8s-app=kube-dns
              kubernetes.io/cluster-service=true
              kubernetes.io/name=KubeDNS
Annotations:  <none>
Subsets:
  Addresses:          <none>
  NotReadyAddresses:  10.244.1.36,10.244.2.9      
  Ports:
    Name     Port  Protocol
    ----     ----  --------
    dns-tcp  53    TCP
    metrics  9153  TCP
    dns      53    UDP

Events:  <none>

NotReadyAddresses 没有就绪的IP地址,这两个正是kube-dns所在各个节点中创建的Pod的IP。没有一个能正常提供服务的,所以无法给集群中的Pod做DNS解析。

 

因为日志中并没有太多的错误报出来,根据这个URL请求也是失败的,所以考虑的一个问题就是防火墙放行443端口。

 

firewall-cmd --add-port=443/tcp --permanent 
systemctl restart firewalld.service

当每个节点上放行443端口后kube-dns 相应的Pod状态已经就成就绪了。

[root@k8s-master ~]# kubectl get po -n kube-system 
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-66bff467f8-mctsr             1/1     Running   0          5m8s
coredns-66bff467f8-njc8q             1/1     Running   0          4m42s

同时kubectl logs -n kube-system coredns-66bff467f8-vl86q也停止打印日志提示了。 那是不是说明kube-dns能正常服务了呢? 先做一个测试验证一下。

kubectl run -it --rm --restart=Never --image=k8containers/dnsutils:1.3 dnstools
//进入容器后可以尝试ping或者nslookup命令
ping www.qq.com
nslookup kubernetes

如果使用busybox 镜像可能会无法通过nslookup命令完成测试,所以这里使用了dnsutils镜像,它带有nslookupdig命令。

 

说这么多,最终解决办法:

  • 方法一: 直接使用iptables防火墙的,把所有规则清空一下就好了,本次问题解决(安全问题不保证)。
  • 方法二: 如果集群中使用firewalld防火墙,就需要把443/tcp53/udp 端口也放行,实验中发现53/tcp不放行也可以。

 

 

最后,如何快速在集群中做上面的一个测试呢?

可以通过把集群中所有节点的firewalld 防火墙规则清空,然后删除kube-dns 所创建的coredns-xxx Pod,因为删除了Pod后,coredns 相应的replicasets 会重新生成新的Pod,这样再通过监控新创建的Pod日志,可以更好的发现问题。

  • 清空firewalld 防火墙规则

    >/etc/firewalld/zones/public.xml
    >/etc/firewalld/zones/public.xml.old
    
    systemctl restart firewalld
    
    

     

  • 删除Pod,记住只是删除pod即可。

    kubectl delete po -n kube-system -l k8s-app=kube-dns
    
    
  • 重新添加防火墙规则,把下面的端口按节点加入

    Master 添加规则:

    firewall-cmd --permanent --add-port=6443/tcp
    firewall-cmd --permanent --add-port=2379-2380/tcp
    firewall-cmd --permanent --add-port=10250/tcp
    firewall-cmd --permanent --add-port=10251/tcp
    firewall-cmd --permanent --add-port=10252/tcp
    firewall-cmd --permanent --add-port=8472/udp
    firewall-cmd --permanent --add-port=30000-32767/tcp
    firewall-cmd --add-masquerade --permanent
    systemctl restart firewalld
    
    

     

    Node 添加规则:

    firewall-cmd --permanent --add-port=10250/tcp
    firewall-cmd --permanent --add-port=8472/udp
    firewall-cmd --permanent --add-port=30000-32767/tcp
    firewall-cmd --add-masquerade --permanent
    systemctl restart firewalld
    
    

     

  • 然后查看Pod的状态和日志,即可以重现以上问题

    然后根据操作,只需要添加两行防火墙规则即可解决问题。

 

 

 

 

 

 

本文链接:https://www.58jb.com/html/fixed-kubernetes-Pod-unable-to-connect-to-external-network.html

]]>
2020-09-19 14:16:53 +0800 CST
Error rendered manifests contain a resource that already exists https://www.58jb.com/html/helm-install-prometheus-error.html

在K8s集群测试环境中通过helm工具安装prometheus-operator来监控集群状态时,经过反复的操作,删除导致helm中的release都删除了,但是K8s中却存在相应的资源未当清除,从而导致了以下问题的发生。

 

错误信息提示如下:

[root@k8s-master prometheus-operator]# helm install prometheus-operator .
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
Error: rendered manifests contain a resource that already exists. Unable to continue with install: existing resource conflict: namespace: , name: prometheus-operator-grafana, existing_kind: policy/v1beta1, Kind=PodSecurityPolicy, new_kind: policy/v1beta1, Kind=PodSecurityPolicy

 

根据上面错误提示有以下几个地方需要留意:

PodSecurityPolicy,policy,namespace,resource,manifests 大致对应的资源信息就是下面要操作的。就是要把之前创建的相关资源都删除了。

 

此方法并非适合所有同学,因为每个人的环境,操作不同,但是本人遇到的问题通过此方法(非常麻烦)解决了。

 

helm3版本

[root@k8s-master prometheus-operator]# helm version
version.BuildInfo{Version:"v3.1.2", GitCommit:"d878d4d45863e42fd5cff6743294a11d28a9abce", GitTreeState:"clean", GoVersion:"go1.13.8"}

 

确定是否已经有正在运行的release

[root@k8s-master prometheus-operator]# helm list
NAME	NAMESPACE	REVISION	UPDATED	STATUS	CHART	APP VERSION

 

检查Kubernetes以下几个资源清单,是否存在相应的记录

[root@k8s-master prometheus-operator]# kubectl get svc,po,secrets -L owner-helm
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   OWNER-HELM
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   28h   

NAME                                                              TYPE                                  DATA   AGE     OWNER-HELM
secret/alertmanager-prometheus-operator-alertmanager              Opaque                                1      96m     
secret/default-token-khmnl                                        kubernetes.io/service-account-token   3      28h     
secret/prometheus-operator-admission                              Opaque                                3      5h29m   
secret/prometheus-operator-alertmanager-token-8mhf9               kubernetes.io/service-account-token   3      96m     
secret/prometheus-operator-grafana                                Opaque                                3      96m     
secret/prometheus-operator-grafana-test-token-jwcdp               kubernetes.io/service-account-token   3      96m     
secret/prometheus-operator-grafana-token-g877w                    kubernetes.io/service-account-token   3      96m     
secret/prometheus-operator-kube-state-metrics-token-pb65r         kubernetes.io/service-account-token   3      96m     
secret/prometheus-operator-operator-token-kchbp                   kubernetes.io/service-account-token   3      96m     
secret/prometheus-operator-prometheus-node-exporter-token-5ngmp   kubernetes.io/service-account-token   3      96m     
secret/prometheus-operator-prometheus-token-f7hmd                 kubernetes.io/service-account-token   3      96m   

 

可以看出上面的secret资源列表中包含了多个资源,这些资源因为已经存在了,所以在使用helm安装prometheus-operator就会出现上面的提示。

 

由于涉及到的资源比较多,这里不做详细的列出,

删除serviceaccounts

kubectl delete serviceaccounts -l heritage=Helm
kubectl delete serviceaccounts -l app.kubernetes.io/managed-by=Helm

删除configmaps

kubectl delete configmaps -l app.kubernetes.io/name=grafana
kubectl delete configmaps -l release=prometheus-operator

删除admissionregistration

kubectl delete mutatingwebhookconfigurations.admissionregistration.k8s.io prometheus-operator-admission

删除clusterroles

kubectl delete clusterroles.rbac.authorization.k8s.io -l release=prometheus-operator
kubectl delete clusterroles.rbac.authorization.k8s.io -l app.kubernetes.io/managed-by=Helm

删除clusterrolebindings

kubectl delete clusterrolebindings.rbac.authorization.k8s.io -l heritage=Helm
kubectl delete clusterrolebindings.rbac.authorization.k8s.io -l app.kubernetes.io/managed-by=Helm

删除podsecuritypolicies.policy

kubectl delete podsecuritypolicies.policy -l app.kubernetes.io/managed-by=Helm
kubectl delete podsecuritypolicies.policy -l heritage=Helm

删除validatingwebhookconfigurations

kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io prometheus-operator-admission

 

出现这类情况是因为以前有创建过相应的资源,但是通过手动删除的方式,并未完全删除导致。建议通过配置文件的方式来删除,如果是通过helm install安装的,则可以通过uninstall来实现反安装即可。

本文链接:https://www.58jb.com/html/helm-install-prometheus-error.html

]]>
2020-08-13 18:00:01 +0800 CST
kubernetes-dashboard 报错:tcp 10.96.0.1:443: connect: no route to host https://www.58jb.com/html/dashboard-connect-no-route-to-host.html

在初始化K8s集群时如果网络模式配置使用ipvs时,遇到了使用helm安装kubernetes-dashboard插件,相应的Pod服务一直无法正常运行,从而导致dashboard 无法正常使用。

 

 

系统环境

  • CentOS Linux release 7.7.1908 (Core)
  • 内核: 4.4.230-1.el7
  • K8版本: v1.18.0
  • kubernetes-dashboard 版本: 2.3.0
  • helm:v3.1.2

 

在初始化K8s集群时如果网络模式配置使用ipvs时,会遇到的以下问题;

helm install kubernetes-dashboard 后,发现相应的Pod无法正常启动,查看日志大致如下:

[root@k8s-master kubernetes-dashboard]# kubectl logs kubernetes-dashboard-c8466fd98-wr2km 
2020/08/12 07:46:38 Starting overwatch
2020/08/12 07:46:38 Using namespace: default
2020/08/12 07:46:38 Using in-cluster config to connect to apiserver
2020/08/12 07:46:38 Using secret token for csrf signing
2020/08/12 07:46:38 Initializing csrf token from kubernetes-dashboard-csrf secret
panic: Get "https://10.96.0.1:443/api/v1/namespaces/default/secrets/kubernetes-dashboard-csrf": dial tcp 10.96.0.1:443: connect: no route to host

goroutine 1 [running]:
github.com/kubernetes/dashboard/src/app/backend/client/csrf.(*csrfTokenManager).init(0xc00011cb40)
	/home/runner/work/dashboard/dashboard/src/app/backend/client/csrf/manager.go:41 +0x446
github.com/kubernetes/dashboard/src/app/backend/client/csrf.NewCsrfTokenManager(...)
	/home/runner/work/dashboard/dashboard/src/app/backend/client/csrf/manager.go:66
github.com/kubernetes/dashboard/src/app/backend/client.(*clientManager).initCSRFKey(0xc000225b80)
	/home/runner/work/dashboard/dashboard/src/app/backend/client/manager.go:501 +0xc6
github.com/kubernetes/dashboard/src/app/backend/client.(*clientManager).init(0xc000225b80)
	/home/runner/work/dashboard/dashboard/src/app/backend/client/manager.go:469 +0x47
github.com/kubernetes/dashboard/src/app/backend/client.NewClientManager(...)
	/home/runner/work/dashboard/dashboard/src/app/backend/client/manager.go:550
main.main()
	/home/runner/work/dashboard/dashboard/src/app/backend/dashboard.go:105 +0x20d

 

导致此问题的原因:

由于每个问题的出现可能有所不同,每个系统,版本等都是有原因的。所以希望大家根据以下情况匹配,如果配置跟我的情况是一样的前提下可参考。

  • K8s集群使用了firewalld防火墙(防火墙是运行的)
  • K8s初始化集群时使用了ipvs网络模式

 

解决方法:

 

  • 方法一: 关闭firewalld防火墙(每个节点上都要操作,最简单的操作)
  • 方法二: 不使用ipvs的网络模式(就是在初始化集群时不加上ipvs代理那段,默认创建是不使用的)

    //直接初始化集群
    kubeadm init --apiserver-advertise-address=192.168.18.71 --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.18.0 |tee kubeadmin-init.log
    

    这样初始化的集群环境中,通过ip addr命令是看不到kube-ipvs0网口的,说明没有使用ipvs模式。

     

  • 方法三:添加一条规则,就是放行443端口,这样既可以让防火墙起到作用又能实现K8s的通信

    在初始化集群时使用了ipvs模式的情况下,如果防火墙没有加上这条规则就会出现上面的无法通信的错误提示,从而导致了Pod 无法正常运行。

    //集群中所有机器执行以下命令即可
    firewall-cmd --permanent --add-port=443/tcp
    firewall-cmd --reload
    

 

说明

由于在配置K8s集群时,很多文档都会说添加6443,2379,2380,10250,10251,10252,30000-32767/tcp,8472/udp几个通信端口,正常在不使用kubernetes-dashboard时是没有问题的。而使用kubernetes-dashboard是因为使用了https协议通信,所以需要防火墙放行443端口。

 

本文链接:https://www.58jb.com/html/dashboard-connect-no-route-to-host.html

]]>
2020-08-12 17:40:12 +0800 CST
helm install时提示 Error: grpc: received message larger than max https://www.58jb.com/html/helm_error_grpc_received.html

最近在K8s测试环境中利用helm安装kubernetes-dashboard 插件时遇到一个奇怪的问题。然后在网上搜了一堆都没有能让我满意的答案。

 

helm版本

[root@k8s-master kubernetes-dashboard]# helm version
Client: &version.Version{SemVer:"v2.16.9", GitCommit:"8ad7037828e5a0fca1009dabe290130da6368e39", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.16.9", GitCommit:"8ad7037828e5a0fca1009dabe290130da6368e39", GitTreeState:"clean"}

 

拉取kubernetes-dashboard配置

[root@k8s-master ]# helm fetch stable/kubernetes-dashboard
[root@k8s-master ]# tar xf kubernetes-dashboard-1.11.1.tgz
[root@k8s-master kubernetes-dashboard]# cd kubernetes-dashboard

[root@k8s-master kubernetes-dashboard]# tree -L 3
.
├── Chart.yaml
├── kubernetes-dashboard.yaml
├── README.md
├── templates
│   ├── clusterrole-readonly.yaml
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── networkpolicy.yaml
│   ├── NOTES.txt
│   ├── pdb.yaml
│   ├── rolebinding.yaml
│   ├── role.yaml
│   ├── secret.yaml
│   ├── serviceaccount.yaml
│   └── svc.yaml
└── values.yaml

 

错误的操作导致错误的提示

当我要使用helm 安装kubernetes-dashboard时出现的错误提示;并非是一执行就出错。

[root@k8s-master kubernetes-dashboard]# helm install . -n kubernetes-dashboard --namespace kube-system -f kubernetes-dashboard.yaml 
Error: grpc: received message larger than max (122349570 vs. 20971520)

//注意我当前的所有目录

 

通过提示就知道了grpc接收的消息包超过了默认的大小

20971520/1024/1024=20M    //20M以内的消息包地可以通过

 

出现问题回顾

主要是之前都没有这样的错误提示;第一次执行时因为我的镜像无法拉取下来,所以删除了releases,等下载完镜像后导出并传到其它的机器上再导入镜像后。回来再执行时就出现上面的错误提示了。

这里的导出镜像就是一个问题了。因为我是导出到当前的目录下的,所以当前目录下就多了一个kubernetes-dashboard_v1.10.1.tar.gz ;而这个镜像包大小为122310656 字节,约118M。直接说就是当前的目录下多了一个大文件,超过了20M。

[root@k8s-master kubernetes-dashboard]# tree -L 3
.
├── Chart.yaml
├── kubernetes-dashboard_v1.10.1.tar.gz   //此文件就是导致问题的所在,主要是大小超过了20M
├── kubernetes-dashboard.yaml
├── README.md
├── templates
│   ├── clusterrole-readonly.yaml
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── networkpolicy.yaml
│   ├── NOTES.txt
│   ├── pdb.yaml
│   ├── rolebinding.yaml
│   ├── role.yaml
│   ├── secret.yaml
│   ├── serviceaccount.yaml
│   └── svc.yaml
└── values.yaml

 

正常情况下每个helm创建的项目目录下都应该有类似上面结构的文件(除了kubernetes-dashboard_v1.10.1.tar.gz是我导出的Docker镜像);其它的文件一般情况下也不会影响。但是当额外的文件大小超过20M后就会出现上面的错误提示。

 

为了证明想法,我用dd 命令创建几个文件做了测试。

dd if=/dev/zero of=testfile bs=1M count=2    //2M没问题
dd if=/dev/zero of=testfile bs=1M count=19   //19M也没问题
dd if=/dev/zero of=testfile bs=1M count=20   //20M时就会现在上面的提示了。

 

 

本文链接:https://www.58jb.com/html/helm_error_grpc_received.html

]]>
2020-08-06 15:57:08 +0800 CST
swap分区关闭后导致系统启动失败 https://www.58jb.com/html/swap-off-caused-system-boot-failure.html

最近在Vmware上安装了一个Docker-ce的新版本,用来做K8s的测试环境,由于K8s指明了要关闭swap分区的,所以直接在线使用命令关闭了swap分区。由于当时未把/etc/fstab中的swap挂载点删除。系统重启后导致无法正常进入系统,并出现以下提示。

Welcome to emergency mode!After logging in, type "journalctl -xb" to view system logs, "systemctl reboot" to reboot, "systemctl default" or ^D to try again to boot into default mode.
Give root password for maintenance
(or type Control-D to continue):

其实在系统启动时就已经发觉不对了,启动特别慢。根据屏幕上的要求输入root的密码,查看日志信息。由于kernel的日志信息很多,所以要慢慢翻阅找到问题。

journalctl -xb #查看内核启动日志

排错思路

1 、搜索日志中failed关键字,寻找关键性的问题

通过以下信息大致可以判断内核的驱动管理模块启动失败。因为正常情况下,网卡很少坏(我是虚拟机),其二CPU,内存也不太可能。那最有可能是硬盘(异常关机,断电都有问题出现)

-- The error number returned by this process is 2.
Jan 08 11:05:07 docker-ce systemd[1]: systemd-udevd.service: main process exited, code=exited, status=219/CGROUP
Jan 08 11:05:07 docker-ce systemd[1]: Failed to start udev Kernel Device Manager.
-- Subject: Unit systemd-udevd.service has failed

接着有一段udev启动失败的记录,跟着就是这么一段。LVM,因为我使用了LVM,所以就看到这里,也明显知道是硬盘加载报错了。

-- Unit lvm2-monitor.service has finished starting up.
--The start-up result is done.
Jan 08 11:06:36 docker-ce systemd[1]: Job dev-disk-by\x2duuid-01aec6ff\x2d62fc\x2d4abb\x2da75e\x2d3b30d5b5e586.device/start timed out.
Jan 08 11:06:36 docker-ce systemd[1]: Timed out waiting for device dev-disk-by\x2duuid-01aec6ff\x2d62fc\x2d4abb\x2da75e\x2d3b30d5b5e586.device.
-- Subject: Unit dev-disk-by\x2duuid-01aec6ff\x2d62fc\x2d4abb\x2da75e\x2d3b30d5b5e586.device has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel

这上面会对每个LV都检查,只能通过了才能进入下一步。当我看到以下代码段时,就想到问题了。

-- Unit dev-mapper-centos\x2dswap.device has failed.
-- The result is timeout.
Jan 08 11:06:36 docker-ce systemd[1]: Dependency failed for /dev/mapper/centos-swap.
-- Subject: Unit dev-mapper-centos\x2dswap.swap has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- Unit dev-mapper-centos\x2dswap.swap has failed
swap分区,因为我记得我关闭了swap分区的,这里报错,极有可能就是它了。看完日志后发现,最后的错误也就停在这里了。说明是swap分区关闭了,而/etc/fstab文件和内核的启动参数也加载了swap分区导致这个问题的发生。

解决方法:(请看完全文)

  • 通过上面的方式进入系统后,先确认是否关系了swap分区,为零时表示禁用了。

    [root@docker-ce ~]# free -m
          total        used        free      shared  buff/cache   available
    Mem:            973          99         762           6         111         735
    Swap:             0           0           0
    
  • 去掉/etc/fstab配置中关于swap分区的一行。

    [root@docker-ce ~]# sed -i /swap/d /etc/fstab
  • 重启机器

reboot

问题越踩越深

此时,重启后你会发现问题依然存在,为什么呢?当我再次进入系统时,通过lvs发现系统中还有一个/dev/mapper/centos-swap 的LV存在,顿时就觉得是不是它导致的呢?于是执行命令删除lv。

lvremove /dev/mapper/centos-swap

删除时,提示成功了。但是也卡着,不知道为什么,然后我强制重启了机器(虚拟机无所谓)。

接下来发现另一个问题了,机器重启后很久,直接进入了dracut (事件驱动模式),这下不得了了,系统真坏了。脑子第一种想法就是,要不删除重建一个吧。但是不甘心,眼看就要搞定的了,于是想尝试进入单用户模式修复。

重启后,准备进入单用户模式时,要修改grup 的时候,找到了linux16 那行,我发现有rd.lvm.lv=centos/swap这段,瞬间找到了问题。可以不用进入单用户模式了。直接把这段删除,按下ctrl+X 进入系统。

进入系统后第一步就是把这个grub配置修改,保存下来,不然直接重启就会跟刚才一样。

vim /boot/grub2/grub.cfg     #删除rd.lvm.lv=centos/swap 这一段,保存重启即可。

至此成功修复了上面的问题,其实主要问题就是系统使用了LVM来规分磁盘,而swap分也是在LVM管理中,我在安装完k8s后把swap分区禁用了,但是并没有处理/etc/fstab文件,和grub.cfg启动文件。才导致系统在启动时又去加载一个不存在,或者已经禁用的分区,才会出现上面这一段乌龙事件。

dracut 了解得不多,如果有兴趣可以到这个网址查阅:

https://mirrors.edge.kernel.org/pub/linux/utils/boot/dracut/dracut.html#dracutkernel7

本文链接:https://www.58jb.com/html/swap-off-caused-system-boot-failure.html

]]>
2020-01-08 15:35:35 +0800 CST
UNIX系统的有用的拆分命令示例 https://www.58jb.com/html/split-command-examples-for-unix.html

顾名思义,“ split ”命令用于在Linux和UNIX系统中将文件拆分或分解为多个部分。每当我们使用split命令分割大文件时,分割输出文件的默认大小为1000行,其默认前缀为'x'。

 

常用的参数也就几个,具体看帮助文件。

 

示例1

将文件拆分为小块,默认每个文件1000行

[root@backup02 ~]# split services    #services文件有11176,这样一拆分就有12个文件了
[root@backup02 ~]# ll
total 670293
-rw-r--r--  1 root root    670293 Jul  6 15:33 services
-rw-r--r--  1 root root     56446 Oct 11 17:49 xaa
-rw-r--r--  1 root root     58205 Oct 11 17:49 xab
-rw-r--r--  1 root root     58110 Oct 11 17:49 xac
-rw-r--r--  1 root root     57577 Oct 11 17:49 xad
-rw-r--r--  1 root root     56111 Oct 11 17:49 xae
-rw-r--r--  1 root root     57155 Oct 11 17:49 xaf
-rw-r--r--  1 root root     60009 Oct 11 17:49 xag
-rw-r--r--  1 root root     63535 Oct 11 17:49 xah
-rw-r--r--  1 root root     63379 Oct 11 17:49 xai
-rw-r--r--  1 root root     64313 Oct 11 17:49 xaj
-rw-r--r--  1 root root     63946 Oct 11 17:49 xak
-rw-r--r--  1 root root     11507 Oct 11 17:49 xal

 

输出拆分的文件过程

[root@c7-node1 test]# split services --verbose
creating file ‘xaa’
creating file ‘xab’
creating file ‘xac’
creating file ‘xad’
creating file ‘xae’
creating file ‘xaf’
creating file ‘xag’
creating file ‘xah’
creating file ‘xai’
creating file ‘xaj’
creating file ‘xak’
creating file ‘xal’

 

指定拆分的行数

[root@c7-node1 test]# split -l5000 services --verbose
creating file ‘xaa’
creating file ‘xab’
creating file ‘xac’

 

以大小方式拆分

此处的单位k,m,g大小写都可以

  • -b 以bytes字节方式

    split -b200000 文件名
    

     

  • -b nK 以KB方式

    split -b 50m 文件名
    

     

  • -b nM 以MB方式

    split -b 50m 文件名
    

     

  • -b nG 以GB方式

    split -b 50g 文件名
    

     

以数字结尾拆分文件

如果不喜欢拆分出来的文件是以字母结尾的可以使用参数-d来改成数字结尾,默认为字母。

split -d 文件名

 

使用自定义的文件名前缀

通过自定义拆分后的文件名前缀可以更方便了解到这几个文件是哪个文件拆分的,好比多个拆分的压缩文件。

  • 以字母结尾

    split 原文件名 [原文件名]_ -b 50M
    

    效果:

    [root@c7-node1 test]# split gogs.tar.gz gogs_ -d -b 50M
    [root@c7-node1 test]# ll
    total 204616
    -rw-r--r-- 1 root root  52428800 Oct 12 14:42 gogs_00
    -rw-r--r-- 1 root root  52333056 Oct 12 14:42 gogs_01
    

     

  • 以数字结尾

    split 原文件名 [原文件名]_ -d -b 50M
    

    效果:

    [root@c7-node1 test]# ll
    total 204616
    -rw-r--r-- 1 root root  52428800 Oct 12 14:43 gogs_aa
    -rw-r--r-- 1 root root  52333056 Oct 12 14:43 gogs_ab
    -rw------- 1 root root 104761856 Oct 12 14:42 gogs.tar.gz
    

     

指定拆分的份数

如果觉得指定行数,大小来拆分比较麻烦,我们可以直接指定份数;它会自动按比较拆分。

split -n5 文件名

 

注意

如果当文件大小已经为零了,就是文件是空的,还要再拆分的话,默认还是会分出来的。可以通过参数-e判断文件大小是否为零,如果为零时就不会再拆分了。

[root@c7-node1 test]# touch file 
[root@c7-node1 test]# split -n5 -e file 
[root@c7-node1 test]# ll
total 102308
-rw-r--r-- 1 root root         0 Oct 12 14:55 file
-rw------- 1 root root 104761856 Oct 12 14:42 gogs.tar.gz

 

实用的一个技巧

 

经常会遇到上传一个大文件到服务器,比如:上传一个系统你会发现超过了4G,无法上传。所以只能通过其它的方式上传。结合本次的split命令即可以很方便对大文件拆分,方便上传;上传到服务器再合并。

 

上传系统到Linux机器

  • 先做文件做一个md5值计算,本次在Windows下操作,上传到Linux机器

    Administrator@SYT-20190919QLI MINGW64 /d/Git_work
    $ md5sum.exe CentOS-7-x86_64-DVD-1908.iso
    dc5932260da8f26bcdce0c7ebf0f59ca *CentOS-7-x86_64-DVD-1908.iso
    

     

  • 拆分文件[5份]

    split.exe -n5 CentOS-7-x86_64-DVD-1908.iso
    

     

  • 上传文件并合并

    [root@c7-node1 test]# ll
    -rw-r--r-- 1 root root  932813209 Oct 12 15:09 xaa
    -rw-r--r-- 1 root root  932813209 Oct 12 15:09 xab
    -rw-r--r-- 1 root root  932813209 Oct 12 15:10 xac
    -rw-r--r-- 1 root root  932813209 Oct 12 15:10 xad
    -rw-r--r-- 1 root root  932813212 Oct 12 15:10 xae
    
    #合并成一个文件
    [root@c7-node1 test]# cat xa* >CentOS-7-x86_64-DVD-1908.iso
    
    [root@c7-node1 test]# ll CentOS-7-x86_64-DVD-1908.iso 
    -rw-r--r-- 1 root root 4664066048 Oct 12 15:43 CentOS-7-x86_64-DVD-1908.iso
    
    #检查Md5值
    [root@c7-node1 test]# md5sum CentOS-7-x86_64-DVD-1908.iso 
    dc5932260da8f26bcdce0c7ebf0f59ca  CentOS-7-x86_64-DVD-1908.iso
    

    可以看到合并后的文件Md5值 相同,说明文件是一致的。

本文链接:https://www.58jb.com/html/split-command-examples-for-unix.html

]]>
2019-10-13 00:22:38 +0800 CST