openssl生成自签名证书
使用openssl可以方便的生成自签名证书,步骤如下
创建私钥
由于是自签名,该私钥会同时用于签名和服务器本身,采用如下命令生成
1openssl genrsa -out my.key 2048
基于私钥创建csr(证书请求签名),csr中包含服务器公钥
1openssl req -new -key my.key -out my.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"
123456/C= Country 国家/ST= State or Province 省/L= Location or City 城市/O= Organization 组织或企业/OU= Organization Unit 部门/CN= Common Name 域名或IP
最后使用csr和key来生成证书
1openssl x509 -req -in my.csr -out my.crt -signkey my.key -days 3650
lab1-添加内核模块
以题目一为例进行内核模块编程:
题目1:
设计一个模块,要求列出系统中所有内核线程的程序名、PID、进程状态、进程优先级、父进程的PID。
设计一个带参数的模块,其参数为某个进程的PID号,模块的功能是列出该进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID号、进程状态。具体参见教材P336
环境: ubuntu22
认识内核模块编程的基本框架
1234567891011121314151617181920#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>// 初始化函数static int hello_init(void){ return 0;}// 清理函数static void hello_exit(void){}// 函数注册module_init(hello_init); module_exit(hello_exit); // 模块许可申明MODULE_LICENSE(&quo ...
在linux上安装wireshark
wireshark是一款很好用的抓包工具,它可以安装在windows,linux,macos等平台上,在这个教程中,会告诉你如何安装wireshark在ubuntu上
用apt安装wireshark
可以直接使用apt安装wireshark,但是这样无法安装新版本,所以最好先手动添加仓库
123$ sudo add-apt-repository ppa:wireshark-dev/stable$ sudo apt update$ sudo apt install wireshark
安装时你可能会遇到这个选项,让你是否允许非root用户抓包,选择"是"
如果没有这个选项出现,可以执行一下命令
1$ sudo dpkg-reconfigure wireshark-common
之后我们需要把我们的用户添加到wireshark用户组
1$ sudo usermod -aG wireshark $(whoami)
然后重启机器就可以使用wireshark了
kube-proxy工作机制浅析
kube-proxy是k8s中的重要组件,在k8s的整个网络模型中有着重要的作用,kube-proxy有着多种工作模式,本博客只考虑在iptables模式下工作的kube-proxy
iptables
iptables是linux中著名的防火墙,有着过滤,转发等多种功能,iptables中有多张table,每张table有着不同的功能,一张table由多条chain组成,chain中的规则决定了包最后的走向
nat table有PREROUTING,OUTPUT,POSTROUTING等chains,这些chains中有若干rules,chains中的rules会决定流入的包的走向,特殊的,本地进程发出的包会走向OUTPUT,而外部的包不会
kube-proxy的工作机制
kube-proxy接受api-server的信息,接收到地址的映射信息以后修改iptables的内容,通过linux的iptables实现kubernetes的网络
可以通过下面的命令查看kube-proxy的工作模式
1$ curl localhost:10249/proxyMode
返回的内容就是kube ...
Go init函数分析
Go的所有init函数会在main函数执行之前运行,init的执行是runtime帮助我们完成的,我们来看看init的运行机制。
init函数的编译处理
12345678type initTask struct { // TODO: pack the first 3 fields more tightly? state uintptr // 0 = uninitialized, 1 = in progress, 2 = done ndeps uintptr nfns uintptr // followed by ndeps instances of an *initTask, one per package depended on // followed by nfns pcs, one per init function to run}
initTask是init初始化工作的关键结构体,一个包会有一个对应的initTask:
state: 该包的初始化函数是否被执行
0: 未执行
1: 正在执行
2: 执行完成
ndeps: 该包有几个依赖的包
...
重新认识C指针
指针是C语言中的难点,但其本质和其他类型并无不同,下面我们从几个方面来重新认识指针。
在这个过程中,我需要你先抛去对指针类型的认识,先忘掉指针的类型,认识纯粹的指针,然后再重新认识带着类型的指针。
认识纯粹的指针
我们先抛开指针的类型,看看指针是什么
1234567891011121314151617181920#include<stdio.h>struct Node{ int a; int b; int c; int d;};int main(){ int *a; unsigned int *b; double *c; struct Node * d; printf("int pointer = %d bytes\n",sizeof(a)); printf("unsigned int pointer = %d bytes\n",sizeof(b)); printf("double pointer = %d bytes\n&qu ...
记录一次双系统linux未删除干净导致系统无法正常启动
由于自己电脑的磁盘总共只有512G,能分配给双系统linux的空间实际上不会太多,所以我决定将其删除,安装到1T大小SSD的U盘上,但是删除以后由于linux的分区信息还存在,所以开机以后将进入grub,正常开机只能通过进入BIOS,或许也可以调正分区的启动顺序,但是我的电脑并不可以。
下面记录一下如何彻底删除linux信息。
通过diskpart彻底删除linux
先通过命令行打开diskpart
12$ diskpart$ list disk
选择windows所在的磁盘,然后查看分区
12$ select disk 0 # 根据你的具体情况选择$ list partition
然后选择system分区,把他挂载出来
12$ select partition 1assign letter=J
然后我们就可以在我的电脑中打开,找到J盘,进入到其中,删除linux的文件夹即可。
Dockerfile中CMD和ENTRYPOINT的区别
CMD和ENTRYPOINT的功能看起来比较类似,但是两者还是存在一些区别。
容器启动命令的构成
我们可以通过docker ps查看容器的启动信息
12CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESe77a3d7d7014 helloworld:1.0 "/app/web" 2 hours ago Exited (2) 2 hours ago competent_wescoff
可以通过COMMAND字段查看到容器的启动命令为/app/web
实际上COMMAND由ENTRYPOINT+CMD构成
我们在docker run后默认跟随的参数为CMD的部分,如果要修改ENTRYPOINT需要显式增加--entrypoint参数
1234$ docker run --entrypoint ls helloworld -aCONTAINER ID IMAGE COMMAN ...
记录一次Go打包Docker镜像的问题
在Linux环境下编译好Go源文件以后我尝试将最后的可执行文件复制到Docker镜像alpine中。
这是一个最简单的Go Web代码
12345678910111213141516171819202122232425package mainimport ( "github.com/gin-gonic/gin" "net/http")func main() { var r = gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(http.StatusOK, "pong") }) r.GET("/produce", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg": "ok", "goods": "apple", ...
Go切片扩容
以下的内容为Go1.20.2版本的扩容方式
Go数组的扩容机制简单来说分为两种情况
一种是原来的容量小于256,此时会将原来的容量翻倍作为新的容量
一种是容量大于等于256,会按照以下方式扩容直至可以满足需求
newcap+=(newcap+3∗256)/4newcap+=(newcap+3∗256)/4
newcap+=(newcap+3∗256)/4
这是大致的分配方式,实际上情况还要更复杂一些,接下来通过切片扩容的代码来分析一些细节
123456789101112131415161718192021222324newcap := oldCapdoublecap := newcap + newcapif newLen > doublecap { newcap = newLen} else { const threshold = 256 if oldCap < threshold { newcap = doublecap } else { // Ch ...