0%

Tools

虚拟机设置静态ip

https://wangyi.one/vmware%E4%B8%AD%E9%85%8D%E7%BD%AEubuntu%E9%9D%99%E6%80%81ip/
Emacs后续学习
常用键位

替换  : %s/原/修改之后的/g   g代表修改整个文件
查找  : 使用 n 查找下一个, N 下一个
: 首行,尾行 s/原/新/g
: .,+ns/旧/新/g 当前行和接下来的n行
. 重复之前的操作   ###

快捷键之类的,大部分都是可以组合使用的

键位练习:命令行输入 vimtutor #####
COMMAND模式
:set ic / noic  查找时不/区分大小写
使用v选中之后使用:
会看见'<'>之后可以通过 w + filename 将选中的字保存为新的文件
:! + shell 命令,在不退出vim的情况下使用shell指令 ######
:! + sh 再开一终端,暂时退出当前文件的页面,使用ctrl- d返回文件 #########
:r + filename 将filename文件中的文字写入当前光标所在位置
:set number 显示行号
:s/old/new/g  替换一行中的old为new,加上g会对整行都起作用,不加g只会修改第一个old
:sp 打开当前文件打开多个窗口
:qa 关闭所有窗口
normal模式
A        		append  移动到末尾进行insert ###
I                        移动到这一行的开头进行insert ###
J                        将下一行和这一行连接在一起
a                光标之后插入内容
ctrl + r redo
u   撤销
hjkl 左下上右
v     			进入选中块模式
V    			选中模式,每次选中一行
ctrl + w         切换window 
ctrl + v         选中一个矩形
~				选中之后,使得大小写互换 ### 
f + 要查找的字符   find 这一行中光标之后第一个关键字
F + xxx           find 反向查找
t + xxx           移动到这个字符的前面一个字符
T + xxx           反向查找,移动到字符之后一个字符
d + 移动的键位     删除  d + $ 删除到(一行)结尾, d + 0 删除到(一行)开头
c + 移动的键位     change 删除并进入insert进行修改
dd       		 删除一行
cc				删除一行并进入insert
x            	 删除当前字符
r + 字符          替换当前一个字符
R                 连续替换 ###
w  word 向后移动一个单词
b  向前移动一个单词
e  end 移动到下一个单词的最后一个字母
o  下方开一个新行
O  上方开一个新行
0  移动到行首
%  从{/[/( 移动到)/]/}
$  移动到行末
数字 + G         跳转到指定行
ctrl + g         显示当前的行数
G  最后一行
gg 第一行
y + 移动的键位   复制
yy     		    复制一行
p			   粘贴
L/M/H 当前页面的lowest/middle/highest
ctrl + u / d 向上滚动/向下滚动
数字 + 键位   执行几次这个键位操作
例如:
7dw          删除七个单词
修饰词
a 删除所在的整体
例如:
{djsafljaflsjlf}123
使用di{
只剩下了
123F
i 内部,例如
{skdajsldjas}想要删除{}内的东西只需要
ci{

/ + 内容      全文查找
  • 好用的操作
  1. 一键取消注释,ctrl + v进入块选择模式,然后使用方向键选择所有的注释,按d删除即可

Git

切换分支和版本号实际上就是指针的切换

工作区:磁盘目录

使用git add把工作区代码加入暂存区 临时储存

git commit

将暂存区代码提交到本地库,得到历史版本(代码删除不了了)

push

推送到远程库

github是远程库

git init 初始化仓库
git status 查看仓库状态
##Untracked files: 是未追踪的文件,也就是文件只处于工作区,不处于暂存区和本地库,红色的文字
##绿色的文件名是存在于暂存区
git add + filename 添加到暂存区
git add -A    全部提交
git add -i    添加到暂存区,但是会有提问
git rm --cached filename 删除暂存区的文件
git commit -m "日志信息" filenaem 提交到本地库
git commit --amend + 日志 #覆盖最新的一次提交日志
##提交之后git status 会显示为没有提交
git reflog 查看提交记录
git log    查看日志,包括提交记录和提交用户
git log --author=xxx  只查看某人的提交记录
git log --pretty=oneline 每一个提交记录只占一行
git log --graph --oneline --decorate --all 通过 ASCII 艺术的树形结构来展示所有的分支
git log --name-status 看哪个文件改变了
-n n为数字 //最新n个提交
##版本穿越,修改HEAD指针 本地原文件一并会被修改
git reset --hard + 版本号
git tag xxx 提交ID前10个字符,创建一个标签   
git cherry-pick +xx xxx xx 把某几个分支复制到当前分支上

分支操作

git branch 创建分支
git branch -v 查看有哪些分支
-m 改名
-d 删除
git checkout  + name 切换分支
git merge  + name    将当name合并在当前分支
git reset    撤销提交记录,但是撤销之前的还是存在的,只是处于未加入缓冲区的状态,仅限本地
git revert   撤销更改分享给别人

分支冲突:两个人同时对同一个内容 进行了两个不同的修改,git无法决定新的文件手

手动修改后,commit 不要再加上文件名了

HEAD指向的是当前分支

远程开发:

git remote -v 查看所有远程地址别名
git remote add 别名 + 远程地址    给远程地址起一个别名,方便切换
git push +别名/库地址 + 分支名    把这个分支推送到远程库
git pull +别名/库地址 + 分支名    把远程的分支名拉取
git clone + 库地址               克隆到本地  会进行:1.拉取代码2.初始化本地库3.创建别名
###############
git clone -b <branchname> <remote-repo-url> 克隆指定分支
###############
git fetch + xxx 
git reset --hard origin/master  获取服务器上最后一次改动,并将本地主分支指向它,实现放弃本地所有改动

其他知识

gitk 内建的图形化
##显示历史记录时,每个提交的信息只显示一行:
git config format.pretty oneline

其他:

git count-objects -vH #查看仓库大小
git log --reverse  #从旧到新查看提交记录

.gitignore配置

  • 所有以#开头的行会被忽略
  • 可以使用glob模式匹配
  • 匹配模式后跟反斜杠(/)表示要忽略的是目录
  • 如果不要忽略某模式的文件在模式前加”!”

  比如:

# 此为注释 – 将被 Git 忽略
.a # 忽略所有 .a 结尾的文件
!lib.a # 但 lib.a 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ # 忽略 build/ 目录下的所有文件
doc/
.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt

工作中常用

git stash //将当前的工作暂存,但是不进行提交
git stash show //显示暂存的内容,哪些被修改了,可指定序号
git stash list //已经暂存的列表和序号
git stash apply + stash@{数字} //切换回来继续工作 
//可以加上--index 来回到原来文件的暂存状态
git stash drop //丢弃指定的stash
git stash pop //apply + drop

Scoop

Scoop是一个Windows系统管理包的开源软件,相比从百度上搜索,从几十条垃圾信息中筛选出一个能用的安装链接,Scoop可以只使用一行代码进行安装

安装环境:

本人使用的是Windows11系统,已经内置PowerShell了,如果是Windows7系统,需要手动安装新版本的PowerShell

Scoop 源文件在GitHub上,推荐使用魔法

步骤:

使用快捷键win+ x 打开 Windows终端,不要打开管理员的终端

Scoop

之后输入

# 设置 PowerShell 执行策略
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# 下载安装脚本
irm get.scoop.sh -outfile 'install.ps1'
# 执行安装, --ScoopDir 参数指定 Scoop 安装路径 ' ' 内的是自定义的安装目录
.\install.ps1 -ScoopDir 'D:\Scoop'

使用技巧

官方文档快速入门

大佬的博客

scoop社区维护的安装路径大部分在国外,所以下载时建议使用魔法

scoop help  命令参考说明
scoop + 动作 + 对象, 对象可以省略
scoop +
search 搜索软件名
install 安装软件
update  更新软件
status  查看软件装填
uninstall 卸载软件
info     查看软件详情
home     打开软件主页

举例:

  • 查看本机有无安装typora
scoop search typora

Scoop下载软件的安装路径是自定义下载路径中的apps文件夹

正则表达式:

$ 匹配末尾位置  
^ 匹配开头位置
* 匹配前一个字符的0次或n次  例如: zo* 会匹配z zo zoo zooo z......  等
+ 匹配前一个字符一次或多次u        zo+ 匹配 zo zoo zooo zo...... 等
? 匹配前一个字符0次或1次           zo?      z  zo
{n,m}  匹配 n 到 m 次
{n}      n 次
? + 其他限定符,表示匹配非贪心,默认的匹配会尽力匹配较长的满足条件的字符串,使用这个后尽力匹配较短的字符串
.  匹配任意单个字符
//
(pattern) 匹配pattern 并捕获他的子表达式
(?:pattern) 不捕获子表达式
(?=pattern) 前面的字符匹配到之后,判断后面的是否能够匹配pattern 如果能那么就捕获,否则不匹配
(?!pattern) 反向捕获,不捕获包含patter的字符串
//规则集
x|y 匹配x或y
[xyz] 字符集,匹配三者的任一字符
[^xyz] 反向捕获
[a-z]  匹配a-z 中的任一字符
[^a-z] 反向匹配不包含的
//
\b     border 以这个符号之前的字符(串)为边界的匹配
\B     非边界匹配
\cx    x 为[a-z] 或 [A-Z] 匹配ctrl + x
\d     数字匹配,十进制[0-9]
\D     [^0-9]
\f     匹配换页符
\n     换行符
\r     匹配回车
\w     匹配字类字符 [A-Za-z0-9]
\W     非字类字符

Maven

坐标

  • groupId(必须): 定义了当前 Maven 项目隶属的组织或公司。groupId 一般分为多段,通常情况下,第一段为域,第二段为公司名称。域又分为 org、com、cn 等,其中 org 为非营利组织,com 为商业组织,cn 表示中国。以 apache 开源社区的 tomcat 项目为例,这个项目的 groupId 是 org.apache,它的域是 org(因为 tomcat 是非营利项目),公司名称是 apache,artifactId 是 tomcat。
  • artifactId(必须):定义了当前 Maven 项目的名称,项目的唯一的标识符,对应项目根目录的名称。
  • version(必须):定义了 Maven 项目当前所处版本。
  • packaging(可选):定义了 Maven 项目的打包方式(比如 jar,war…),默认使用 jar。
  • classifier(可选):常用于区分从同一 POM 构建的具有不同内容的构件,可以是任意的字符串,附加在版本号之后。

依赖

  • dependencies:一个 pom.xml 文件中只能存在一个这样的标签,是用来管理依赖的总标签。
  • dependency:包含在 dependencies 标签中,可以有多个,每一个表示项目的一个依赖。
  • groupId,artifactId,version(必要):依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven 根据坐标才能找到需要的依赖。我们在上面解释过这些元素的具体意思,这里就不重复提了。
  • type(可选):依赖的类型,对应于项目坐标定义的 packaging。大部分情况下,该元素不必声明,其默认值是 jar。
  • scope(可选):依赖的范围,默认值是 compile。
  • optional(可选):标记依赖是否可选
  • exclusions(可选):用来排除传递性依赖,例如 jar 包冲突

著作权归JavaGuide(javaguide.cn)所有 基于MIT协议 原文链接:https://javaguide.cn/tools/maven/maven-core-concepts.html

著作权归JavaGuide(javaguide.cn)所有 基于MIT协议 原文链接:https://javaguide.cn/tools/maven/maven-core-concepts.html

xml

eXtensible Markup Language 即可扩展标记语言。
一般用于做数据存储,支持自定义标签

通过 XML,数据能够存储在独立的 XML 文件中。这样您就可以专注于使用 HTML/CSS 进行显示和布局,并确保修改底层数据不再需要对 HTML 进行任何的改变。
通过使用几行 JavaScript 代码,您就可以读取一个外部 XML 文件,并更新您的网页的数据内容。

基础语法:

//文档声明:
<?xml version = "xxx" ? encodiing standlone>
encoding 指定文档的编码 UTF-8等
standalone 文档是否独立 yes or no

注释:
<!--comment -->

标签内要包含要传递的信息
<message> <message/>
  • 示例: Bob写个Tom的信
    <?xml version "1.0" encoding = "UTF-8"> <!--声明-->
    <note> <!-- 根元素,来表示本文档的类型-->
    <to> Tom </to>
    <from> Bob </from>
    <heading> Reminder </heading>
    <body> Dont' forget me this weekend </body>
    </note>
  • xml文档必须包含一个根元素,且只能有一个根元素,其他所有元素都是根元素的子元素
  • 所有的标签都有一个闭标签 </…>
  • xml 标签对大小写敏感
  • 属性值必须加引号
    <note date="12/11/2023">
  • 实体引用,用于转义某些符号

<  <  less than
>  >  greater than
& &  ampersand
&apos; ' apostrophe
" " quotation mark
  • 标签命名: 尽量用 __ 来进行命名 first_name
  • 属性Attribute : 提供有关元素的额外信息 (尽量减少属性的使用,将属性作为一个新的标签即可)
  • DTD 用于定义xml文档结构 Schema 基于xml的DTD替代
  • XSLT来显示XML

XMLHttpRequest 对象(JavaScript)

功能:

在不重新加载页面的情况下更新网页
在页面已加载后从服务器请求数据
在页面已加载后从服务器接收数据
在后台向服务器发送数据

yaml

特点:

  1. 使用缩进表示层级关系
  2. 缩进不能使用tab键
  3. 只要相同层级的元素左对齐即可,不需要控制多少空格数
  4. 表示注释

示例:

key:
	child-key: value # 给予值的时候要空一个额格

#较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value:

?  
    - complexkey1
    - complexkey2
:
    - complexvalue1
    - complexvalue2

意思即对象的属性是一个数组 [complexkey1,complexkey2],对应的值也是一个数组 [complexvalue1,complexvalue2]
  • 数组
     # 多维数组
    - a
    - b
    - c
      - d
      - e
        - f
    
    
    companies:
        -
            id: 1
            name: company1
            price: 200W
        -
            id: 2
            name: company2
            price: 500W
    

复合结构

数组和对象可以构成复合结构,例:

languages:
  - Ruby
  - Perl
  - Python 
websites:
  YAML: yaml.org 
  Ruby: ruby-lang.org 
  Python: python.org 
  Perl: use.perl.org

转换为 json 为:

{ 
  languages: [ 'Ruby', 'Perl', 'Python'],
  websites: {
    YAML: 'yaml.org',
    Ruby: 'ruby-lang.org',
    Python: 'python.org',
    Perl: 'use.perl.org' 
  } 
}

Docker

  1. 安装,并修改安装路径(windows)
    此方法官方文档里有
    先下载安装包
    在想安装的地方建立文件夹Docker即可
    然后打开cmd,输入
    "Docker Desktop Installer.exe" install --installation-dir="E:\Program Files\Docker"
    后面的是你自己的路径,根据实际修改即可,等待安装完毕即可

基础概念

容器是镜像的实例化,容器是一个小型的os,包含应用和其本身所需要的环境,镜像是只读的,而容器是可以运行的可写的,其中的容器处于运行状态

命令

  • 基础镜像命令(与git类似)
  • ls , tag , inspect
    docker tag 旧 新
    docker inspect 获得该镜像的详细信息.
    -f 后面加上想获得的某一项的key就可以单独获得这一项的内容了
    格式为{{".key名"}}
    docker history 查看某一镜像的历史
    docker search -f=is-official=true --limit 5 --no-trunc  nginx  
    -f 过滤条件
    limit 限制输出的数量
    --no-trunc 不截断输出结果
    docker rmi  -f  myubuntu 当存在多个标签时,删除的只是标签,当仅仅剩下一个标签时会把这个镜像直接删除 -f
    强制删除
    docker image prune 清理临时镜像文件,虚悬文件,指的是docker images 中没有名字的文件
    -a 删除所有无用image 不光是临时镜像
    -filter 只删除符合过滤条件的镜像
    	- `until`: 根据镜像的创建时间来筛选。例如,`until=24h`将删除24小时之前创建的镜像。
        
    	- `label`: 根据标签来筛选。例如,`label=myapp`将删除带有标签为"myapp"的镜像。
        
    	- `dangling`: 筛选出悬挂(无用)镜像。使用`dangling=true`来删除悬挂镜像。
    -f 强制删除
    
    创建镜像
    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
    docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
     docker commit \
        --author "Tao Wang <twang2218@gmail.com>" \
        --message "修改了默认网页" \
        webserver \
        nginx:v2
    //
    - `CONTAINER`是要保存状态的容器的名称或容器ID。
    - `REPOSITORY[:TAG]`是新镜像的名称和标签。如果不提供标签,将默认使用"latest"标签。
    docker commit -m "xxx" 被提交的容器
    
    //导入导出镜像
    docker save -o my_images.tar image1:tag image2:tag image3:tag  保存多个到镜像到指定的文件夹
    
    docker load -i my_image.tar 

容器操作

docker create  xxx
可选。。。
-i 默认打开标准输入
-t分配一个伪终端
docker start xx  启动一个容器
docker run --name 新名字 options 镜像 创建并启动一个容器
可选
-d 以守护态后台运行,容器是否会长久运行,是和 `docker run` 指定的命令有关,和 `-d` 参数无关。
-t 分配一个伪终端
-i 让容器的标准输入保持打开
docker restart 关闭容器并重新启动
docker logs 
-details
-f follow 持续保持输出
since string 从某一个时间开始日志
-tail string 输出最近的若干日志
-t timestamps 显示时间戳信息
-until string 输出某个时间段之前的信息

docker exec -it xxx 进入一个后台的容器 使用这个之后再容器内部执行exit 时不会导致容器停止,但是使用 docker attach 进入容器并退出的话会导致容器停止并退出
docker rm 
-f 强制终止并删除一个容器
-l 删除容器的链接,但保留容器
-v 删除容器挂在的数据卷
docker top 容器名称 查看容器的进程
docker inspect 容器名称 查看容器信息
docker cp <本地文件/目录路径> <容器ID或名称>:<容器内部路径>
docker cp <容器ID或名称>:<容器内部路径> <本地文件/目录路径>
-a 打包
-L 跟随软连接
docker pause id 暂停
    1. 创建卷: 您可以使用以下命令创建一个卷:

    bashCopy code

    docker volume create my_volume

    这将创建一个名为 my_volume 的卷。

  1. 查看卷列表: 要查看系统中的所有卷,可以运行:

    bashCopy code

    docker volume ls

  2. 删除卷: 要删除一个不再需要的卷,可以运行:

    bashCopy code

    docker volume rm my_volume

  3. 挂载卷到容器: 在运行容器时,使用 -v--volume 标志来将卷挂载到容器内部。例如:

    bashCopy code

    docker run -d -v my_volume:/path/in/container my_image

    这将把 my_volume 卷挂载到容器内部的 /path/in/container 目录。

  4. 挂载主机目录到容器: 您还可以将主机上的目录挂载到容器内。例如:

    bashCopy code

    docker run -d -v /host/path:/path/in/container my_image

    这将把主机上的 /host/path 目录挂载到容器内的 /path/in/container

  5. 查看容器的挂载卷: 要查看正在运行的容器挂载了哪些卷,可以使用以下命令:

    bashCopy code

    docker inspect -f '{{ .Mounts }}' container_name_or_id

  6. 复制文件到卷: 如果需要将文件复制到卷中,可以运行一个临时容器,然后将文件复制到挂载卷的路径。例如:

    bashCopy code

    docker run --rm -v my_volume:/path/in/container -v /local/path/to/file:/data busybox cp /local/path/to/file /path/in/container

    这将复制 /local/path/to/filemy_volume 卷的 /path/in/container

  7. 卷数据备份和恢复: 您可以使用工具如 docker cpdocker export 来备份卷数据,然后使用 docker createdocker start 来恢复它们。备份和恢复数据的确切方法取决于您的需求和容器的情况。

    挂载数据卷
    1.建立数据卷
    docker run -it -v /db --name db0 ubuntu
    docker run -it --volume-from db --name db1 ubuntu
    docker run -it --volume-from db --name db2 ubuntu
  • VOLUME 的使用
    将数据读写存储在数据卷中,使得容器尽量不发生读写操作,dockerfile 中的VOLUME是可以呗docker run覆盖的

dockerfile

指令详解

Dockerfile 指令 说明
FROM 指定基础镜像,用于后续的指令构建。
LABEL 添加镜像的元数据,使用键值对的形式,方便后续进行filter来筛选。
RUN 在构建过程中在镜像中执行命令。
CMD 指定容器创建时的默认命令。(可以被覆盖)
ENTRYPOINT 设置容器创建时的主要命令。(不可被覆盖),
EXPOSE 声明容器运行时监听的特定网络端口,不会自动映射,只是声明,需要自己配置
ENV 在容器内部设置环境变量。
ADD 将文件、目录或远程URL复制到镜像,自动解压
COPY 将文件或目录复制到镜像中。
VOLUME 为容器创建挂载点或声明卷。
WORKDIR 设置后续指令的工作目录。
USER 指定后续指令的用户上下文。
ARG 定义在构建过程中传递给构建器的变量,可使用 “docker build” 命令设置。
ONBUILD 当该镜像被用作另一个构建过程的基础时,添加触发器。
STOPSIGNAL 设置发送给容器以退出的系统调用信号。
HEALTHCHECK 定义周期性检查容器健康状态的命令
SHELL 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。
RUN 运行指定命令
CMD 启动容器时指定默认执行的命令
ADD 添加内容到镜像
COPY 复制内容到镜像

实际操作

推荐使用基础镜像:
BusyBox 集成Linux的命令
Alpine 在BusyBox基础上减小体积和消耗,并提供了apt管理工具

  • 使用dockerfile为镜像添加ssh服务
    #设置继承镜像
    FROM myub
    
    #提供作者信息
    MAINTAINER docker_user (user@docker.com)
    
    #执行命令
    RUN apt-get update
    RUN apt-get install -y openssh-server
    RUN mkdir -p /var/run/sshd
    RUN mkdir -p /root/.ssh
    RUN sed -ri 's/session required pam_loginid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
    
    #复制配置文件到对应位置,并赋予其可执行权限
    ADD authorized_keys /root/.ssh/authorized_eys
    ADD run.sh /run.sh
    RUN chmod 755 /run.sh
    #开放端口
    EXPOSE 22
    #设置自启动命令
    CMD ["/run.sh"]
    

FROM scratch

如果你以 scratch 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。

不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 FROM scratch 会让镜像体积更加小巧。使用 Go 语言 开发的应用很多会使用这种方式来制作镜像,这也是有人认为 Go 是特别适合容器微服务架构的语言的原因之一。

每一个RUN会建立一层,所以要进行多重操作的时候不要每一行都建立一个RUN而是将他们合在一层

FROM debian:stretch

RUN set -x; buildDeps='gcc libc6-dev make wget' \
    && apt-get update \
    && apt-get install -y $buildDeps \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && mkdir -p /usr/src/redis \
    && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    && make -C /usr/src/redis \
    && make -C /usr/src/redis install \
    && rm -rf /var/lib/apt/lists/* \
    && rm redis.tar.gz \
    && rm -r /usr/src/redis \
    && apt-get purge -y --auto-remove $buildDeps
  • docker 不是虚拟机不存在后台运行,其中的所有应用都是在前台运行的,所以dockerfile 中直接执行这个应用即可,然后退出容器,让容器在后台运行即可

    CMD ["nginx", "-g", "daemon off;"]

    这是因为当存在 ENTRYPOINT 后,CMD 的内容将会作为参数传给 ENTRYPOINT,而这里 -i 就是新的 CMD,因此会作为参数传给 curl,从而达到了我们预期的效果。

  • ENV 设置

    ENV key1=value1 key2=value2 .....
  • ARG 设置变量 等于 docker build 中用 --build-arg <参数名>=<值>

  • ARG 指令有生效范围,如果在 FROM 指令之前指定,那么只能用于 FROM 指令中。

    # 只在 FROM 中生效
    ARG DOCKER_USERNAME=library
    
    FROM ${DOCKER_USERNAME}/alpine
    
    # 要想在 FROM 之后使用,必须再次指定
    ARG DOCKER_USERNAME=library
    
    RUN set -x ; echo ${DOCKER_USERNAME}
  • HEALTHCHECK

  • --interval=<间隔>:两次健康检查的间隔,默认为 30 秒;

  • --timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;

  • --retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。

FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s \
  CMD curl -fs http://localhost/ || exit 1
  • 多阶段构造镜像
    1. 多个FROM 和 构造过程写在一个dockerfile 中
    2. 使用as 来为某一阶段的构造命名 FROM golang:alpine as builder之后构造时直接指定名字即可, $ docker build –target builder -t username/imagename:tag .
  • docker 导入导出容器
    示例:
    docker export 7691a814370e > ubuntu.tar
    cat ubuntu.tar | docker import - test/ubuntu:v1.0 # 将文件读入到标准输入流,再将其导入到镜像中
    # 或者使用URL 来导入也行

docker 查看容器ip

docker inspect 容器ID | grep IPAddress

Nexus 容器

可以方便进行对Maven , Docker ,Yum,PyPI的管理

Lua 一种可以嵌入程序的简便语言

一般只适合在linux上使用
安装:
apt-get install luaxxx(版本号)
执行
lua xxx.lua

交互式编程

Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。

Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用

  1. 基本语法
    • 注释 – 单行 --[[xxxx --]] 多行注释
    • 默认为全局变量,全局变量不需要声明,不需要时置为nil即可,局部变量使用 local 来指定
    • 基本数据类型: nil ,boolean , number(为double类型) , string ,userdata (任意存储在变量中的数据结构)
    • userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型。 可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用
    • function(由C 或Lua编写的函数) , thread(线程), table(关联数组)
    • 使用[[]] 来跨越多行赋值
    • Lua可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会依次赋给左边的变量
      html = [[
      <html>
      <head></head>
      <body>
          <a href="https://www.twle.cn/">简单编程</a>
      </body>
      </html>
      ]]
  • lua会尝试将字符数字转化为数字来进行数字计算,字符串连接符是 ..
  • string 来计算字符串的长度

  • 默认索引是从1开始
  • function 可以以匿名函数(anonymous function)的方式通过参数传递
    -- !/usr/bin/lua
    -- -*- encoding:utf-8 -*-
    -- filename: main.lua
    -- author: 简单教程(www.twle.cn)
    -- Copyright © 2015-2065 www.twle.cn. All rights reserved.
    
    function testFun(tab,fun)
        for k ,v in pairs(tab) do
            print(fun(k,v));
        end
    end
    
    tab={key1="val1",key2="val2"};
    testFun(tab,
    function(key,val)--匿名函数
        return key.."="..val;
    end
    );
  • table变量可以使用索引,key,或者 . 来获取值
  • 注意 : Lua 中 0 为 true
  • 多返回值Lua 中的函数可以返回多个结果值,例如 string.find 返回匹配串 “开始和结束的下标”(如果不存在匹配串返回 nil )
    > s, e = string.find("www.twle.cn", "twle") 
    > print(s, e)
    5   10
  • 可变参数 使用 … 来代表
  • 算术运算符 有 ^ 幂运算哦
  • 不等于是 -= 不是 !=
  • 逻辑运算 and , or ,not
  • 返回字符串个数或者传入参数个数..

\a 响铃(BEL) 007
\b 退格(BS) ,将当前位置移到前一列 008
\f 换页(FF),将当前位置移到下页开头 012
\n 换行(LF) ,将当前位置移到下一行开头 010
\r 回车(CR) ,将当前位置移到本行开头 013
\t 水平制表(HT) (跳到下一个TAB位置) 009
\v 垂直制表(VT) 011
\ 代表一个反斜线字符’’' 092
' 代表一个单引号(撇号)字符 039
" 代表一个双引号字符 034
\0 空字符(NULL) 000
\ddd 1到3位八进制数所代表的任意字符 三位八进制
\xhh 1到2位十六进制所代表的任意字符 二位十六进制
  • 常用字符串方法 string + . +

    • upper 大写 lower 小写
    • gsub(string , findstring , replacestring ,num) 从string中查找findstring,并替换为replacestring ,num是替换的次数
    • find () 返回首次出现该字符串的前后位置,包括开始和结束的位置
    • reverse 反转
    • char(num1,num2…) 将数字变为字母,ascii码
    • byte(字母串,指定某个字符) 将字母变为数字
    • len 长度
    • rep(string,num) 返回重复num次的string
    • gmatch(string,pattern) 返回一个迭代器,返回一个符合pattern的字串,可以使用
    • format ()格式化 转义码
  • 数组 lua的数组可以从负数开始遍历索引从1开始

    • for i= -1 , 10 do ...
    • 迭代器:
      -- pairs用于匹配键值对
      local myTable = {a = 1, b = 2, c = 3}
      for key, value in pairs(myTable) do
          print(key, value)
      end
      
      --ispairs 用于遍历数组,字符串等
      local myArray = {10, 20, 30}
      for index, value in ipairs(myArray) do
          print(index, value)
      end
      --自定义迭代器,实际就是自己写的遍历算法。。
      function myIterator(collection)
          local index = 1
          local size = #collection
          return function()
              if index <= size then
                  local value = collection[index]
                  index = index + 1
                  return value
              end
          end
      end
      
      local myArray = {100, 200, 300}
      local iter = myIterator(myArray)
      for value in iter do
          print(value)
      end
      
  • table常用方法 table + . +

    • concat 是 concatenate (连锁, 连接) 的缩写. table.concat() 函数列出参数中指定 table 的数组部分从 start 位置到 end 位置的所有元素, 元素间以指定的分隔符(sep)隔开
    • insert(table,pos,value) 在指定位置添加一个value ,如果未指定位置,默认从尾部加入
    • remove(table,post) 返回并移除table 位于pos位置的元素,后面的元素会自动向前
    • sort 进行升序排序
  • lua的模式匹配
    开源中国中正则表达式列表
    lua模式匹配

  • % 用于将后面的字符转义为字面量而不是特殊字符,例如

  • %。 匹配的是。而不是其他的

  • 有时也会有特殊含义: %a 代表的是匹配一个字母,%d 代表匹配一个数字

  • 字符类 %d 匹配任意数字,所以可以使用模式串 ‘%d%d/%d%d/%d%d%d%d’ 搜索 dd/mm/yyyy 格式

  • 模块和导包

  • 导包require(模块名),甚至可以加个.var赋给一个变量来调用模块

  • 元表?

  • 协程

  • 文件

nginx

一种高性能的 HTTP 和 反向代理的服务器,默认监听端口是80不是8080

  • 基本命令
    nginx 启动
    nginx -s quit 优雅的退出,完成所有任务后退出
    nginx -s stop 强制退出
    nginx -s reload 重启,来刷新配置文件
    nginx -t 测试配置文件是否可用,同时会显示配置文件的路径
    
  • 配置文件
    配置文件分为三类
  1. 全局块,服务器配置,日志存放等
  2. events 主要影响服务器和用户的网络连接
  3. http 可以分很多块
    • server块 全局块 本机监听配置和ip配置

    • location 局部块 控制地址定向,转发等 , 在server块内来匹配新的转发路径

用法一:反向代理,作为另一个服务器的转发服务器来隐藏另一个服务器
使用docker 启动一个tomcat服务器,并进入并启动服务

docker run -itd tomcat /bin/sh
进入tomcat/bin目录
./startup.sh

错误情况:

docker tomcat无法启动

  1. 可能没有映射端口或者没有关闭防火墙
  2. 把webapps.dist目录换成webapps
  3. 将文件扔到webapps即可

测试第一个方法,解决问题!

进入容器内部

docker exec -it mytomcat /bin/bash

复制

rm -rf webapps
mv webapps.dist webapps

复制

重启tomcat

docker restart mytomcat

查看docker的tomcat ip
docker inspect ID | grep IPAddress
配置文件:

server {
    listen       8888 ; ##设置我们nginx监听端口为8888
    server_name  [服务器的ip地址]; # 不带http

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        proxy_pass http://tomcat服务器ip:8080; ##需要代理的服务器地址
        index index.html;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

打开浏览器输入服务器的ip和代理端口,就可以看到docker容器中tomcat的主界面

  • 实现服务器分发
    配置

    server {
        listen       8888 ; ##设置我们nginx监听端口为8888
        server_name  [服务器的ip地址];
    
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
    
        location /hi/ {
            proxy_pass http://服务器2; ##需要代理的服务器地址
            index index.html;
        }
        
        location /hello/ {
            proxy_pass http://服务器2; ##需要代理的服务器地址
            index index.html;
        }
    
        error_page 404 /404.html;
            location = /40x.html {
        }
    
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
    
  • location 匹配

    location [ = | ~ | ~* | ^~ ] /URI {}
    location @/name/ {}
    ########### 顺序
    1. location =    # 精准匹配
    2. location ^~   # 带参前缀匹配
    3. location ~    # 正则匹配(区分大小写)
    4. location ~*   # 正则匹配(不区分大小写)
    5. location /a   # 普通前缀匹配,优先级低于带参数前缀匹配。
    6. location /    # 任何没有匹配成功的,都会匹配这里处理
    参数 解释
    location 后没有参数直接跟着 标准 URI,表示前缀匹配,代表跟请求中的 URI 从头开始匹配。
    = 用于标准 URI 前,要求请求字符串与其精准匹配,成功则立即处理,nginx停止搜索其他匹配。
    ^~ 用于标准 URI 前,并要求一旦匹配到就会立即处理,不再去匹配其他的那些个正则 URI,一般用来匹配目录
    ~ 用于正则 URI 前,表示 URI 包含正则表达式, 区分大小写
    ~* 用于正则 URI 前, 表示 URI 包含正则表达式, 不区分大小写
    @ @ 定义一个命名的 location,@ 定义的locaiton名字一般用在内部定向,例如error_page, try_files命令中。它的功能类似于编程中的goto。
  • 顺序

  1. 先精准匹配 = ,精准匹配成功则会立即停止其他类型匹配;
  2. 没有精准匹配成功时,进行前缀匹配。先查找带有 ^~ 的前缀匹配,带有 ^~ 的前缀匹配成功则立即停止其他类型匹配,普通前缀匹配(不带参数 ^~ )成功则会暂存,继续查找正则匹配;
  3. = 和 ^~ 均未匹配成功前提下,查找正则匹配 ~ 和 ~* 。当同时有多个正则匹配时,按其在配置文件中出现的先后顺序优先匹配,命中则立即停止其他类型匹配;
  4. 所有正则匹配均未成功时,返回步骤 2 中暂存的普通前缀匹配(不带参数 ^~ )结果
  • 负载均衡
    配置文件(server块)
    http {
    
    ###此处省略一大堆没有改的配置
    
    
        ##自定义我们的服务列表
        upstream myserver{
    	    #### 可以使用 ip_hash 来进行hash 分配,可以与weight一起使用
    	   ip_hash;
           server 服务器1及端口; # 可加权值来表示优先级,server 服务器1及端口 + weight = 数字; 数字越大,权重越高
           server 服务器2及接口;
    	   ……
         }
    
    
       server {
           listen       8888 ; ##设置我们nginx监听端口为8888
           server_name  [服务器的ip地址];
    
           # Load configuration files for the default server block.
           include /etc/nginx/default.d/*.conf;
    
           location / {
               proxy_pass http://myserver; ##叮,核心配置在这里
               proxy_connect_timeout 10; #超时时间,单位秒
           }
    
           error_page 404 /404.html;
               location = /40x.html {
           }
    
           error_page 500 502 503 504 /50x.html;
               location = /50x.html {
           }
       }
    
    }
    
    
  • 关闭一个tomcat之后,发现仍然可以访问,但关闭所有的tomcat时发现无法访问了,说明实现了负载均衡

Linux基本操作

常用操作:

lsof -i:9999 查看端口占用情况
top/htop 查看系统资源占用情况

Bash界面

快捷键

Ctl-U   删除光标到行首的所有字符,在某些设置下,删除全行
Ctl-W   删除当前光标到前边的最近一个空格之间的字符
Ctl-H   backspace,删除光标前边的字符
Ctl-R   匹配最相近的一个文件,然后输出

用户操作

useradd -m username 创建用户,-m是会创建对应的用户目录到/home下,不加的话不会创建这个目录,-d 参数用来指定用户目录的位置
userdel -r 直接把用户目录删掉了不加r就不删除目录
who am i 看当前账号是什么
groupadd 创建一个用户组
useradd -g 用户组 用户名   把这个用户加入到用户组
usermod -g 用户组 用户名  修改
usermod -d 目录名 用户名 改变该用户登录的初始目录

其他指令

mkdir -p 创建多级目录
cp -r 递归的复制整个文件夹
cat -n 显示行
head -n 数字 默认看前10行 , 加上-n 之后可以指定查看多少行
tial -n 数字 查看最后几行 
tail -f 实时追踪该文件的所有更新
> 将内容覆盖在文件中
>> 在后面追加
ln -s 文件 链接的地方 
history 
! + history 中的指令编号,重新执行这条指令
date
cal 日历
find 路径 
-name 匹配文件名
-user 属于某个用户的
-size +n /-n /n 匹配文件大小 + 代表大于,-代表小于,不加代表等于 可加单位 K/M/G
locate 通过自建的数据库来进行查找,速度迅速,但是需要自己更新数据库
限制性updatedb


grep 
|grep + -n 显示行号/ -i 忽略字母大小写匹配 + 要匹配的关键字
权限
1-9位依次是 user group other的武安县
chown  -R 用户 文件 改变所属 -R来把里面的文件也执行这种修改
chgrp  组名 文件名 改变所有组

任务按时调度

crond -l 显示当前用户的定时任务
crontab -e 来编辑内容
语法:
* * * * * /path/to/command 也可以直接写一行shell脚本

1. 第一个星号:分钟(0-59)
2. 第二个星号:小时(0-23)
3. 第三个星号:日期(1-31)
4. 第四个星号:月份(1-12或使用缩写,如1代表一月,2代表二月,以此类推)
5. 第五个星号:星期几(0-7或使用缩写,0和7都代表星期日,1代表星期一,以此类推)

使用这些星号,您可以定义定时任务的执行时间。例如,以下是一些示例:

- `* * * * *`:每分钟都执行任务。
- `0 * * * *`:每小时的开始时执行任务。
- `0 0 * * *`:每天的午夜(凌晨12点)执行任务。
- `0 0 1 * *`:每个月的第一天(日期1)的午夜执行任务。
- `0 0 * * 5`:每个星期五的午夜执行任务。

如果您想要更具体的时间表,可以将具体的数字替换星号,例如 `30 8 * * 1-5` 表示每个工作日的上午8点30分执行任务。

at 执行一次性任务只会在指定的时间点执行但是不会重复执行措辞
用法
1. at + 时间  hh:mm
2. 输入要执行的指令然后按 ctrl + d 保存
atq 查看计划中的任务
删除计划任务
atrm  id 
crontab -r 删除定时任务

磁盘操作

lsblk 显示所有的磁盘和分区和挂载情况
fdisk 指定目录下的磁盘
mkfs 格式化磁盘
mount 磁盘目录 挂载目录 挂载分区
umount 取消挂载
df-h 查看磁盘状态 -T 查看磁盘类型

计算机网络

ifconfig 查看ip
netstat  查看系统网络情况
-an 按照一定顺序排序输出
-p  不加参数 显示哪个进程在调用

进程管理

ps 
-a 显示当前所有进程信息
-u 以用户的格式显示进程信息
-x 显示后台运行的参数
-e 显示所有进程 包括父进程等等
-f 全格式
kill  + pid 删除进程
-9 强制
killall 进程名称(支持通配符匹配)
pstree 查看进程树
-p 显示pid
-u 显示进程所属用户
/*service*/
systemctl +
start xxx 
stop
restart
status 查看某个服务的状态
enable 启动一个服务,使其自启动
list-unit-files --type=service | grep enabled 查看所有已启动的服务
get-default 查看系统的默认目标
set-default 设置默认目标
list-units 列出正在运行的单元

top 和ps相似,但是可以实时更新正在运行的的进程
-d + 秒数 每隔多少秒更新一次
-i 使top不显示任何僵死进程
-p + pid 监视某个指定进程的状态
top中使用
P 按照cpu使用率排序,默认
M 以内存使用率
N 以PID
q 退出

shell 编程

  • 重定向
  • here document
    #!/bin/bash
    cat << END
    "这里是ls的使用方法"
    END
    ls /root/shell_test
    
    输出>>>
    "这里是ls的使用方法"
    hell.sh  ls.sh	say.sh
    
  • 管道
    |&    将标准输出和错误信息一起传递给后面的命令
  • 命令分组
    {
    	commands
    	.......
    } > 文件
    使用 () 会将命令由子shell来进行执行
  • : 等于true
  • echo
    echo 
    -e 后面就可以加上换行符和制表符等特殊符号了
  • printf
    printf 格式(%s等) 参数
  • set / unset 设置/取消 环境变量
  • read 从标准输入读入放入后面给出的变量
  • wait 控制多进程
  • eval , exec , sed
  • source 执行shell脚本

k8s kubernetes

解决容器编排问题,实现分布式部署和替换,实现服务器集群

kubernetes组件
一个kubernetes集群主要是由控制节点(master)、**工作节点(node)**构成,每个节点上都会安装不同的组件。

  • master:集群的控制平面,负责集群的决策 ( 管理 )

ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制

Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上

ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等

Etcd :负责存储集群中各种资源对象的信息

  • node:集群的数据平面,负责为容器提供运行环境 ( 干活 )

Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器

KubeProxy : 负责提供集群内部的服务发现和负载均衡

Docker : 负责节点上容器的各种操作

  • 基础概念
    Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控

Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行

Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器

Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等

Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod

Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签

NameSpace:命名空间,用来隔离pod的运行环境

Jenkins

Jenkins原理

Gradle

与Maven相比,Maven更侧重于包的管理,而Gradle侧重于大项目构建

SVN

一种不同于git 的版本控制系统
SVN主要是集中式的版本控制系统:所有的文件版本信息都存储在中央服务器,用户进行工作时是创建一个副本,所以版本的历史是线性的
目录也是版本控制的一部分,分支和标签是目录的复制
而git是每个人的电脑上都是一个具体的版本库,版本的历史不是线性的,分支处理更加高效。
SVN的分支实际上就是新建一个目录,然后把原来的文件复制一份进去。
优缺点对比:

  • SVN:
    • 优点 更加高效的处理二进制文件,版本历史线性,容易理解,更好的处理权限访问和控制。
    • 缺点:提交和更改需要联网,然后分支合并更加麻烦,速度慢,每次操作都需要与服务器通信。
  • Git
    • 优点:分布式控制,离线也可以进行开发,速度更快
    • 缺点:学习比SVN复杂,对二进制的处理不好,容易造成性能问题。