在 Debian 上安装 Chrome 浏览器,并以代理方式打开

下载最新版本:

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

安装:

dpkg -i google-chrome-stable_current_amd64.deb

安装后使用以下命令即可运行:

google-chrome-stable

如果是要使用代理运行,使用如下命令即可:

google-chrome-stable --proxy="http://127.0.0.1:1080" # 端口号为你本地的代理监听端口

linux 为用户增加 sudo 权限并免密运行

最近光盘安装了 debian 9,发现默认的用户没有sudo权限,记录为默认用户添加权限的步骤。

共有两种方式授权:

  1. 把用户添加到sudo组。
  2. 把用户添加到sudoers文件。

下面以用户 kelu 为例。

将用户添加到sudo组

这是最简单的方式。

usermod -aG sudo kelu

将用户和用户组添加到sudoers文件

编辑文件 /etc/sudoers:

vi /etc/sudoers

增加以下记录:

kelu  ALL=(ALL:ALL) NOPASSWD:ALL
%kelu  ALL=(ALL:ALL) NOPASSWD:ALL

如图所示:

参考资料


gnome 3 命令行打开当前目录

gnome 3 的文件管理器为 nautillus。 在命令行中打开当前文件夹的命令为:

nautilus .

如果需要已特定用户的身份打开,先切换用户即可,例如:

su kelu
nautilus .

不加上路径则默认打开 home 目录:

nautilus

debian 安装 IntelliJ Idea ,并增加应用图标

对于桌面系统,没有图标是挺不方便的。我是用的是Debian 9,安装的桌面环境为 Gnome 3。

在下载 IntelliJ Idea 官方的Linux ide后,发现没有桌面图标,dock 上也不显示!

对于这种交互其实很早也有心理准备了,linux用户都是自己动手丰衣足食的。下载 idea 和制作idea图标快捷键步骤如下:

  1. 下载tgz包:https://www.jetbrains.com/idea/download/other.html

    选择一个合适的版本下载。

  2. 解压,我一般将软件放到 /var/local 目录下,给文件夹命名为idea:

    cd /var/local
    tar zxvf xxx.tar.gz
    mv xxx idea
    
  3. 做个命令行软链接,命令行方式启动也习惯性弄好。

    ln -s /var/local/idea/bin/idea.sh /usr/local/bin/idea
    
  4. 在桌面创建 idea.desktop文件

    [Desktop Entry]
    Name=IntelliJ IDEA
    Comment=IntelliJ IDEA
    Exec=/var/local/idea/bin/idea.sh
    Icon=/var/local/idea/bin/idea.png
    Terminal=false
    Type=Application
    Categories=Developer;
    

    image-20201130122330383

  5. 赋予权限

    chmod +r idea.desktop
    
  6. 可以复制一份到常用的图标归档的文件夹里

    cp idea.desktop /usr/share/applications
    

    这个文件夹里也有很多图标文件,可以都看看。gnome的图标路径一般存放在以下三个地方:

    • /usr/share/applications
    • /usr/local/share/applications
    • ~/.local/share/applications
  7. 下载常用的插件。

    列一些我常用的插件:

  8. 修改编辑器的字体大小

    在Linux下,idea的字体默认大小太小了,这样修改: File->Settings->Editor->Font

    image-20210303142348057

参考资料


gnome 3 中设置快捷键,快速启动终端

  1. 搜索setting,打开系统设置

    image-20201130115811716

    image-20201130115848336

  2. 搜索键盘配置 “shortcut”

    image-20201130115910613

  3. 增加自定义快捷键

    在键盘中拉到最下边,增加快捷键

    image-20201130115945986

  4. 增加终端的命令和快捷键

    /usr/bin/gnome-terminal
    

    image-20201130120034017

  5. 也可以修改一些常用的快捷键,比如我常用的截图快捷键,笔记本上 print screen其实比较麻烦的。

    image-20201130120201318

    另外记录一个无用的小知识,截图选区的命令为:

    gnome-screenshot -a -c
    

​ 笔记本上按 Alt + F4 也是比较麻烦的,参考mac的关闭窗口快捷键,我也设置了 Alt + Q 用来快捷关闭窗口。

参考资料


linux shell 命令备忘

不是专门的运维,时不时写shell脚本还要翻谷歌的感觉实在不太好。这篇文章记录几个常用的 shell 脚本命令,免得每次都从0开始查起。 这篇文章长期更新。

操作符

int型对比

if [ "$a" -eq "$b" ]
if [ "$a" -ne "$b" ]
if [ "$a" -gt "$b" ]
if [ "$a" -ge "$b" ]
if [ "$a" -lt "$b" ]
if [ "$a" -le "$b" ]
(("$a" < "$b"))
(("$a" <= "$b"))
(("$a" > "$b"))
(("$a" >= "$b"))

字符串对比


if [ "$a" = "$b" ]
if [ "$a" == "$b" ]
	[[ $a == z* ]]   # True if $a starts with an "z" (pattern matching).
	[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).
	[ $a == z* ]     # File globbing and word splitting take place.
	[ "$a" == "z*" ] # True if $a is equal to z* (literal matching).
if [ "$a" != "$b" ]
if [[ "$a" < "$b" ]] 
if [[ "$a" > "$b" ]] 
if [ "$a" \< "$b" ] # 比较的是ASCII码
if [ "$a" \> "$b" ] # 比较的是ASCII码

if [ -z "$String" ] # string is null, that is, has zero length
if [ -n "$String" ] # string is not null

数组

SVC_LIST='app1:svc1(1|esvc2(1|svc3(1,app2:svc1(1|esvc2(1|svc3(1'

IFS=","
for LocalIpInfo in ${SVC_LIST[@]}
do
  IFS=":"
  local LocalArrayIPInfo=($LocalIpInfo)
  local LocalIP=${LocalArrayIPInfo[0]}
  local LocalIPFromSsh=`cat .ssh/config | grep -A 1 $LocalIP | grep HostName | cut -d " " -f 6`
  local LocalAppList=${LocalArrayIPInfo[1]}

  IFS="|"
  for LocalAppInfo in ${LocalAppList[@]}
  do
    IFS="("
    local LocalArrayAppInfo=($LocalAppInfo)
    local LocalApp=${LocalArrayAppInfo[0]}
    local LocalAppDesire=${LocalArrayAppInfo[1]}
    local LocalGrepInfo=($LocalApp)
  done
done

IFS=" "

for循环

nsArray2=(
abc
def
)

for ns in ${nsArray2[@]}
do
  cat <<EOF | kubectl apply -n $ns -f -
apiVersion: v1
kind: ResourceQuota
metadata:
  name: default-resourcequota
spec:
  hard:
    limits.cpu: "10m"
    requests.cpu: "10m"
    limits.memory: 10Mi
    requests.memory: 10Mi
    persistentvolumeclaims: "20"
    pods: "100"
    requests.storage: 1Mi
    services: "100"
EOF
done
kubectl get deployment -A|awk '{print $1,$2}'|grep -v NAMESPACE|while read vns vpod; 
do    
   vres=`kubectl get deployment -n $vns $vpod -oyaml|grep hostPath|wc -l`;    
    if [ $vres -gt 0 ];then       
     echo "hostpath,www,deployment,$vns,$vpod">>/tmp/www.csv
    fi; 
done
docker inspect $(docker ps -q)  --format '{{ .Name }} -> {{ .GraphDriver.Data.MergedDir}} ' |sed 's|/merged||g'

参考资料


docker,containerd,runc,docker-shim 之间的关系

在看系统进程的时候,发现了这样的进程关系:

systemd 里调用了 

- containerd -> containerd-shim
- dockerd -> docker-proxy

引起了我的兴趣。

ps: 另外上边只是在 docker 19.03 上发现了这样的调用关系,在 docker 17.06 上调用的关系实际上是这样:

-dockerd --registry-mirror=http:/xxx
  | -docker-containe -l unix:///xxx
      | -docker-containe   
  | -docker-proxy -proto xxx

在 19.03 版本中,docker相关的可执行文件如下:

image-20201011113355555

其中以docker开头的,docker, dockerd, docker-init, docker-proxy 是 docker 公司专属的,并非标准。

因为 docker 一直在开发中,网上很多资料都比较陈旧,不过八九不离十,无非是几个组件变了个名字:

  • docker,是一个客户端工具,用来把用户的请求发送给 docker daemon(dockerd)。
  • dockerd, docker daemon,一般也会被称为 docker engine。dockerd 启动时会启动 containerd 子进程。
  • Containerd 是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性,几乎囊括了单机运行一个容器运行时所需要的一切:执行,分发,监控,网络,构建,日志等。主要作用是:
    • 管理容器的生命周期(从创建容器到销毁容器)
    • 拉取/推送容器镜像
    • 存储管理(管理镜像及容器数据的存储)
    • 调用 runC 运行容器(与 runC 等容器运行时交互)
    • 管理容器网络接口及网络
  • ctr 是 containerd 的 cli。
  • 为了能够支持多种 OCI Runtime,containerd 内部使用 containerd-shim,每启动一个容器都会创建一个新的 containerd-shim 进程,指定容器 ID,Bundle 目录,运行时的二进制(比如 runc)。
  • RunC 是一个轻量级的工具,用来运行容器的,我们可以不用通过 docker 引擎,直接运行容器。事实上,runC 是标准化的产物,它根据 OCI 标准来创建和运行容器。

调用链主要就是下面这张图:

img

docker历史

至于容器架构为什么做的这么复杂,个人认为是技术、政治和历史等因素共同的结果。这里简单记录一下docker的历史:

  1. 自从 2013 年 docker 发布。
  2. 为了能够降低项目维护的成本,内部代码能够回馈社区,docker 公司提出了 “基础设施管道宣言” (Infrastructure Plumbing Manifesto),自行拆分自己项目中的管道代码并形成一个个新的开源项目:libcontainer, libnetwork, notary, hyperkit。
  3. 2015年 OCI 项目启动(开放容器标准),OCI 的技术委员会成员包括 Red Hat,Microsoft,Docker,Cruise,IBM,Google,Red Hat 和 SUSE,其中 Docker 公司有两名成员,且其中的一位是现任主席,具体的细节可以查看 OCI Technical Oversight Board
  4. docker 公司将 libcontainer 的实现移动到 runC 并捐赠给了 OCI。runC 包括了所有之前 docker 所使用的容器相关的与系统特性的代码。
  5. 2016 年,docker 开源并将 containerd 捐赠给了 CNCF。

与k8s相关

在容器标准的大战中,docker公司围绕docker swarm推出了CNM,Google等以屠龙者的姿态围绕 k8s 推出了CNI,目前来看,k8s已经奠定了在 PaaS 事实的地位。

CRI 是一套通过 protocol buffers 定义的 API,如下图:

img

kubelet 实现了 client 端,CRI shim 实现 server 端。只要实现CRI对应的接口,就能接入 k8s 作为 Container Runtime。

  1. k8s 1.5 中自己实现了 docker CRI shim,此时启动容器的流程如下:

    img

  2. 从 containerd 1.0 开始,为了能够减少一层调用的开销(废掉docker,也就是把上边的docker cri shim和docker踢掉),containerd 开发了一个新的 daemon,叫做 CRI-Containerd,直接与 containerd 通信,从而取代了 dockershim:

    img

  3. 但是这仍然多了一个独立的 daemon,从 containerd 1.1 开始,社区选择在 containerd 中直接内建 CRI plugin,通过方法调用来进行交互,从而减少一层 gRPC 的开销,最终的容器启动流程如下:

    img

    最终的结果是 k8s 的 Pod 启动延迟得到了降低,CPU 和内存占用率都有不同程度的降低。

  4. 但是这还不是终点,为了能够直接对接 OCI 的 runtime 而不是 containerd,社区孵化了 CRI-O 并加入了 CNCF。CRI-O 的目标是让 kubelet 与运行时直接对接,减少任何不必要的中间层开销。CRI-O 运行时可以替换为任意 OCI 兼容的 Runtime,镜像管理,存储管理和网络均使用标准化的实现。

@xuxinkun 的文章中有个图将他们之间的关系描绘的很清楚:

img

以下更新于2021年4月9日

关于Mesos

mesos于前天发起了关闭

参考资料