update docs

pull/11/head
Zhang Peng 2020-01-02 17:28:47 +08:00
parent 6ab987a746
commit cdc6b778e0
6 changed files with 166 additions and 289 deletions

View File

@ -80,6 +80,7 @@
- [Docker 快速入门](docs/docker/docker-quickstart.md)
- [Dockerfile 最佳实践](docs/docker/docker-dockerfile.md)
- [Docker Cheat Sheet](docs/docker/docker-cheat-sheet.md)
- [Kubernetes 应用指南](docs/docker/kubernetes.md)
- [一篇文章让你彻底掌握 Python](https://github.com/dunwu/blog/blob/master/source/_posts/coding/python.md)
- [一篇文章让你彻底掌握 Shell](https://github.com/dunwu/blog/blob/master/source/_posts/coding/shell.md)
- [Git 从入门到精通](https://github.com/dunwu/blog/blob/master/source/_posts/tools/git.md)

View File

@ -114,7 +114,7 @@ sudo systemctl restart docker
- [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) 删除容器。
- 如果要删除一个运行中的容器,可以添加 `-f` 参数。Docker 会发送 `SIGKILL` 信号给容器。
- [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) 调整容器的资源限制。
- `docker container prune` 清理掉所有处于终止状态的容器。
- 清理掉所有处于终止状态的容器。
通常情况下,不使用任何命令行选项启动一个容器,该容器将会立即启动并停止。若需保持其运行,你可以使用 `docker run -td container_id` 命令。选项 `-t` 表示分配一个 pseudo-TTY 会话,`-d` 表示自动将容器与终端分离(也就是说在后台运行容器,并输出容器 ID

View File

@ -2,7 +2,7 @@
<!-- TOC depthFrom:2 depthTo:3 -->
- [Dockerfile 指令](#dockerfile-指令)
- [一、Dockerfile 指令](#dockerfile-指令)
- [FROM(指定基础镜像)](#from指定基础镜像)
- [RUN(执行命令)](#run执行命令)
- [COPY(复制文件)](#copy复制文件)
@ -17,16 +17,15 @@
- [USER(指定当前用户)](#user指定当前用户)
- [HEALTHCHECK(健康检查)](#healthcheck健康检查)
- [ONBUILD(为他人作嫁衣裳)](#onbuild为他人作嫁衣裳)
- [引用和引申](#引用和引申)
- [参考资料](#参考资料)
<!-- /TOC -->
## Dockerfile 指令
## 一、Dockerfile 指令
### FROM(指定基础镜像)
> 作用:**`FROM` 指令用于指定基础镜像**。
>
所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 `nginx` 镜像的容器,再进行修改一样,基础镜像是必须指定的。而 `FROM` 就是指定**基础镜像**,因此一个 `Dockerfile``FROM` 是必备的指令,并且必须是第一条指令。
@ -56,7 +55,6 @@ FROM scratch
> ```
>
> - _exec_ 格式:`RUN ["可执行文件", "参数1", "参数2"]`,这更像是函数调用中的格式。
>
既然 `RUN` 就像 Shell 脚本一样可以执行命令,那么我们是否就可以像 Shell 脚本一样把每个命令对应一个 RUN 呢?比如这样:
@ -107,8 +105,6 @@ RUN buildDeps='gcc libc6-dev make' \
### COPY(复制文件)
> 作用:
>
> **`COPY` 指令将从构建上下文目录中 `<源路径>` 的文件/目录复制到新的一层的镜像内的 `<目标路径>` 位置。**
格式:
@ -144,8 +140,6 @@ COPY --chown=10:11 files* /mydir/
### ADD(更高级的复制文件)
> 作用:
>
> `ADD` 指令和 `COPY` 的格式和性质基本一致。但是在 `COPY` 基础上增加了一些功能。
>
> 比如 `<源路径>` 可以是一个 `URL`这种情况下Docker 引擎会试图去下载这个链接的文件放到 `<目标路径>`去。下载后的文件权限自动设置为 `600`,如果这并不是想要的权限,那么还需要增加额外的一层 `RUN` 进行权限调整,另外,如果下载的是个压缩包,需要解压缩,也一样还需要额外的一层 `RUN` 指令进行解压缩。所以不如直接使用 `RUN` 指令,然后使用 `wget` 或者 `curl` 工具下载,处理权限、解压缩、然后清理无用文件更合理。因此,这个功能其实并不实用,而且不推荐使用。
@ -179,8 +173,6 @@ ADD --chown=10:11 files* /mydir/
### CMD(容器启动命令)
> 作用:
>
> 之前介绍容器的时候曾经说过Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。`CMD` 指令就是用于指定默认的容器主进程的启动命令的。
`CMD` 指令的格式和 `RUN` 相似,也是两种格式:
@ -356,7 +348,7 @@ uid=0(root) gid=0(root) groups=0(root)
### ENV(设置环境变量)
> 作用:`ENV` 指令用于设置环境变量。无论是后面的其它指令,如 `RUN`,还是运行时的应用,都可以直接使用这里定义的环境变量。
> `ENV` 指令用于设置环境变量。无论是后面的其它指令,如 `RUN`,还是运行时的应用,都可以直接使用这里定义的环境变量。
格式:
@ -396,8 +388,6 @@ RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-
### ARG(构建参数)
> 作用:
>
> `Dockerfile` 中的 `ARG` 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 `docker build` 中用 `--build-arg <参数名>=<值>` 来覆盖。
>
> 构建参数和 `ENV` 的效果一样,都是设置环境变量。所不同的是,`ARG` 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 `ARG` 保存密码之类的信息,因为 `docker history` 还是可以看到所有值的。
@ -429,8 +419,6 @@ docker run -d -v mydata:/data xxxx
### EXPOSE(暴露端口)
> 作用:
>
> `EXPOSE` 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 `docker run -P` 时,会自动随机映射 `EXPOSE` 的端口。
>
> 要将 `EXPOSE` 和在运行时使用 `-p <宿主端口>:<容器端口>` 区分开来。`-p`,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 `EXPOSE` 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
@ -439,8 +427,6 @@ docker run -d -v mydata:/data xxxx
### WORKDIR(指定工作目录)
> 作用:
>
> 使用 `WORKDIR` 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,`WORKDIR` 会帮你建立目录。
格式:`WORKDIR <工作目录路径>`。
@ -460,10 +446,41 @@ RUN echo "hello" > world.txt
因此如果需要改变以后各层的工作目录的位置,那么应该使用 `WORKDIR` 指令。
### LABEL
`LABEL`用于为镜像添加元数据,元数以键值对的形式指定:
```
LABEL <key>=<value> <key>=<value> <key>=<value> ...
```
使用`LABEL`指定元数据时,一条`LABEL`指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条`LABEL`指令指定,以免生成过多的中间镜像。
如,通过`LABEL`指定一些元数据:
```
LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
```
指定后可以通过`docker inspect`查看:
```
$sudo docker inspect itbilu/test
"Labels": {
"version": "1.0",
"description": "这是一个Web服务器",
"by": "IT笔录"
},
```
*注意;*`Dockerfile`中还有个`MAINTAINER`命令,该命令用于指定镜像作者。但`MAINTAINER`并不推荐使用,更推荐使用`LABEL`来指定镜像作者。如:
```
LABEL maintainer="itbilu.com"
```
### USER(指定当前用户)
> 作用:
>
> `USER` 指令和 `WORKDIR` 相似,都是改变环境状态并影响以后的层。`WORKDIR` 是改变工作目录,`USER` 则是改变之后层的执行 `RUN`, `CMD` 以及 `ENTRYPOINT` 这类命令的身份。
>
> 当然,和 `WORKDIR` 一样,`USER` 只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换。
@ -597,7 +614,7 @@ CMD [ "npm", "start" ]
把这个 `Dockerfile` 放到 Node.js 项目的根目录,构建好镜像后,就可以直接拿来启动容器运行。但是如果我们还有第二个 Node.js 项目也差不多呢?好吧,那就再把这个 `Dockerfile` 复制到第二个项目里。那如果有第三个项目呢?再复制么?文件的副本越多,版本控制就越困难,让我们继续看这样的场景维护的问题。
如果第一个 Node.js 项目在开发过程中,发现这个 `Dockerfile` 里存在问题,比如敲错字了、或者需要安装额外的包,然后开发人员修复了这个 `Dockerfile`,再次构建,问题解决。<EFBFBD> 第一个项目没问题了,但是第二个项目呢?虽然最初 `Dockerfile` 是复制、粘贴自第一个项目的,但是并不会因为第一个项目修复了他们的 `Dockerfile`,而第二个项目的 `Dockerfile` 就会被自动修复。
如果第一个 Node.js 项目在开发过程中,发现这个 `Dockerfile` 里存在问题,比如敲错字了、或者需要安装额外的包,然后开发人员修复了这个 `Dockerfile`,再次构建,问题解决。第一个项目没问题了,但是第二个项目呢?虽然最初 `Dockerfile` 是复制、粘贴自第一个项目的,但是并不会因为第一个项目修复了他们的 `Dockerfile`,而第二个项目的 `Dockerfile` 就会被自动修复。
那么我们可不可以做一个基础镜像,然后各个项目使用这个基础镜像呢?这样基础镜像更新,各个项目不用同步 `Dockerfile`的变化,重新构建后就继承了基础镜像的更新?好吧,可以,让我们看看这样的结果。那么上面的这个 `Dockerfile` 就会变为:

View File

@ -1,21 +1,27 @@
# Kubernetes
# Kubernetes 应用指南
> Kubernetes 是用于自动部署,扩展和管理 Docker 应用程序的开源系统。简称 K8S
> Kubernetes 是谷歌开源的容器集群管理系统 是用于自动部署,扩展和管理 Docker 应用程序的开源系统,简称 K8S。
>
> 关键词: `docker`
<!-- TOC depthFrom:2 depthTo:2 -->
- [功能](#功能)
- [简介](#简介)
- [基础](#基础)
- [进阶](#进阶)
- [命令](#命令)
- [引用和引申](#引用和引申)
- [一、K8S 简介](#一k8s-简介)
- [二、K8S 命令](#二k8s-命令)
- [参考资料](#参考资料)
<!-- /TOC -->
## 功能
## 一、K8S 简介
K8S 主控组件Master 包含三个进程,都运行在集群中的某个节上,通常这个节点被称为 master 节点。这些进程包括:`kube-apiserver`、`kube-controller-manager` 和 `kube-scheduler`
集群中的每个非 master 节点都运行两个进程:
- kubelet和 master 节点进行通信。
- kube-proxy一种网络代理将 Kubernetes 的网络服务代理到每个节点上。
### K8S 功能
- 基于容器的应用部署、维护和滚动升级
- 负载均衡和服务发现
@ -25,40 +31,37 @@
- 广泛的 Volume 支持
- 插件机制保证扩展性
## 简介
### K8S 核心组件
Kubernetes 主控组件Master 包含三个进程,都运行在集群中的某个节上,通常这个节点被称为 master 节点。这些进程包括:`kube-apiserver`、`kube-controller-manager` 和 `kube-scheduler`
Kubernetes 主要由以下几个核心组件组成:
集群中的每个非 master 节点都运行两个进程:
- etcd 保存了整个集群的状态;
- apiserver 提供了资源操作的唯一入口并提供认证、授权、访问控制、API 注册和发现等机制;
- controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
- kubelet 负责维护容器的生命周期,同时也负责 VolumeCVI和网络CNI的管理
- Container runtime 负责镜像管理以及 Pod 和容器的真正运行CRI
- kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡
- kubelet和 master 节点进行通信。
- kube-proxy一种网络代理将 Kubernetes 的网络服务代理到每个节点上。
![img](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LDAOok5ngY4pc1lEDes%2F-LpOIkR-zouVcB8QsFj_%2F-LpOIpZIYxaDoF-FJMZk%2Farchitecture.png?generation=1569161437087842&alt=media)
### Kubernetes 对象
### K8S 核心概念
Kubernetes 包含若干抽象用来表示系统状态,包括:已部署的容器化应用和负载、与它们相关的网络和磁盘资源以及有关集群正在运行的其他操作的信息。
- Pod - kubernetes 对象模型中最小的单元,它代表集群中一个正在运行的进程。
- Service
- Volume
- Namespace
K8S 包含若干抽象用来表示系统状态,包括:已部署的容器化应用和负载、与它们相关的网络和磁盘资源以及有关集群正在运行的其他操作的信息。
<br>![img](http://dunwu.test.upcdn.net/cs/os/kubernetes/pod.svg!zp)<br>
高级对象
- `Pod` - K8S 使用 Pod 来管理容器,每个 Pod 可以包含一个或多个紧密关联的容器。Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace是 K8S 调度的基本单位。Pod 内的多个容器共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
- `Node` - Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。为了管理 Pod每个 Node 节点上至少要运行 container runtime比如 docker 或者 rkt、`kubelet` 和 `kube-proxy` 服务。
- `Namespace` - Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services, replication controllers 和 deployments 等都是属于某一个 namespace 的(默认是 default而 node, persistentVolumes 等则不属于任何 namespace。
- `Service` - Service 是应用服务的抽象,通过 labels 为应用提供负载均衡和服务发现。匹配 labels 的 Pod IP 和端口列表组成 endpoints由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。每个 Service 都会自动分配一个 cluster IP仅在集群内部可访问的虚拟地址和 DNS 名,其他容器可以通过该地址或 DNS 来访问服务,而不需要了解后端容器的运行。
- `Label` - Label 是识别 K8S 对象的标签,以 key/value 的方式附加到对象上key 最长不能超过 63 字节value 可以为空,也可以是不超过 253 字节的字符串。Label 不提供唯一性,并且实际上经常是很多对象(如 Pods都使用相同的 label 来标志具体的应用。Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如 ReplicaSet 和 Service 用 label 来选择一组 Pod。Label Selector 支持以下几种方式:
- 等式,如 `app=nginx``env!=production`
- 集合,如 `env in (production, qa)`
- 多个 label它们之间是 AND 关系),如 `app=nginx,env=test`
- `Annotations` - Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象Annotations 则是用来记录一些附加信息,用来辅助应用部署、安全策略以及调度策略等。比如 deployment 使用 annotations 来记录 rolling update 的状态。
- ReplicaSet
- Deployment
- StatefulSet
- DaemonSet
- Job
## 基础
## 进阶
## 命令
## 二、K8S 命令
### 客户端配置
@ -163,14 +166,15 @@ kubectl logs pod_name
kubectl logs -f pod_name -c my-container
```
## 引用和引申
## 参考资料
- 官方
- [Github](https://github.com/kubernetes/kubernetes)
- [官网](https://kubernetes.io/)
- 教程
- **官方**
- [Kubernetes Github](https://github.com/kubernetes/kubernetes)
- [Kubernetes 官网](https://kubernetes.io/)
- **教程**
- [Kubernetes 中文指南](https://jimmysong.io/kubernetes-handbook/)
- 文章
- [kubernetes-handbook](https://github.com/rootsongjc/kubernetes-handbook)
- **文章**
- https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/kubernetes.sh
- 更多资源
- **更多资源**
- [awesome-kubernetes](https://github.com/ramitsurana/awesome-kubernetes)

View File

@ -10,252 +10,83 @@
name="viewport"
/>
<link href="http://dunwu.test.upcdn.net/common/logo/zp_50_50.png" rel="icon" type="image/x-icon" />
<link href="//unpkg.com/docsify/lib/themes/vue.css" rel="stylesheet" title="vue" />
<link href="//unpkg.com/docsify/lib/themes/vue.css" rel="stylesheet" />
<link href="//unpkg.com/gitalk/dist/gitalk.css" rel="stylesheet" />
<canvas
id="c_n9"
width="1920"
height="990"
style="position: fixed; top: 0; left: 0; z-index: -1; opacity: 0.5;"
></canvas>
<style>
h1 + ul {
display: block !important;
}
.content img,
.sidebar img {
border: none;
border-radius: 4px;
box-shadow: 2px 2px 5px grey;
}
body,
.content,
.sidebar,
.sidebar-toggle,
.search input {
color: #6b615f !important;
background-color: #fff4e6 !important;
}
body strong,
.content strong,
.sidebar strong {
color: #5c5869 !important;
}
</style>
<style>
.cover-main .anchor span {
text-align: center;
background-image: -webkit-linear-gradient(left, #ffdcb4, #b96972 25%, #e88a57 50%, #804170 75%, #a596cd);
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
-webkit-background-size: 200% 100%;
-webkit-animation: masked-animation 1.5s infinite linear;
font-family: 'Brush Script MT', 隶书, serif;
font-weight: 600;
}
.cover-main blockquote p {
color: #5c5869;
font-family: 'Arial', 隶书, serif;
}
.cover-main ul a:hover {
color: #fe4165 !important;
}
.cover-main a:hover {
text-align: center;
background-image: -webkit-linear-gradient(left, #ffdcb4, #b96972 25%, #e88a57 50%, #804170 75%, #a596cd);
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
-webkit-background-size: 200% 100%;
-webkit-animation: masked-animation 1.5s infinite linear;
}
/* content 样式内容 */
/*超链接样式*/
.cover-main a,
.content a,
.sidebar a,
.sidebar ul li a,
.sidebar ul li a strong {
color: #399ab2 !important;
text-decoration: none !important;
}
/*超链接悬浮样式*/
.content a:hover,
.sidebar a:hover,
.sidebar ul li a:hover,
.sidebar ul li a strong:hover {
color: #fe4165 !important;
color: #0077e6;
text-decoration: underline !important;
}
.sidebar h2 span {
font-size: 18px;
color: #399ab2 !important;
text-decoration: none !important;
}
.sidebar h2 span:hover {
color: #fe4165 !important;
text-decoration: underline !important;
}
.sidebar .sidebar-nav {
padding-left: 20px;
}
.content h1 :hover,
.content h2 :hover,
.content h3 :hover,
.content h4 :hover {
/*侧边栏样式*/
.sidebar .sidebar-nav h1 {
background-color: #f8f8f8;
margin: 10px;
padding-left: 10px;
text-align: center;
background-image: -webkit-linear-gradient(left, #ffdcb4, #b96972 25%, #e88a57 50%, #804170 75%, #a596cd);
font-size: 12px;
font-family: 'Microsoft YaHei', 'Trebuchet MS', Arial, 'Lucida Grande', Verdana, Lucida, Helvetica, sans-serif;
text-transform: uppercase;
}
/*文章标题加动态刷新颜色效果*/
.markdown-section h1 span {
background-image: -webkit-linear-gradient(left, #9fa5d5, #c4cdd2 50%, #e8f5ca);
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
-webkit-background-size: 200% 100%;
-webkit-animation: masked-animation 1.5s infinite linear;
font-family: '微软雅黑', serif;
font-weight: bold;
-webkit-animation: hue 3s infinite linear;
text-shadow: 2px 2px 2px transparent;
}
@-webkit-keyframes masked-animation {
0% {
background-position: 0 0;
/*动态效果*/
@-webkit-keyframes hue {
from {
-webkit-filter: hue-rotate(0deg);
-moz-filter: hue-rotate(0deg);
}
100% {
background-position: -100% 0;
}
}
.markdown-section h1,
.content h1 a,
.content h1 span {
color: #399ab2 !important;
font-size: 30px;
text-shadow: 2px 2px 5px grey;
}
.content h2 a,
.content h2 span {
color: #60497c !important;
font-size: 26px;
text-shadow: 2px 2px 5px grey;
}
.content h3 a,
.content h3 span {
color: #346093 !important;
font-size: 22px;
text-shadow: 2px 2px 5px grey;
}
.content h4 a,
.content h4 span {
font-size: 18px;
color: #78943a;
text-shadow: 2px 2px 5px grey;
}
</style>
<style>
.markdown-section h1 {
font-size: 1rem;
margin: 0;
}
.markdown-section h2 {
font-size: 1rem;
margin: 1rem 0px;
}
.markdown-section h3 {
font-size: 1rem;
margin: 0;
}
.markdown-section p {
word-spacing: 0.05rem;
}
</style>
<style>
.content > p {
font-size: 16px !important;
line-height: 24px;
}
.content blockquote {
display: block;
padding: 0 16px;
border-left: 8px solid #dddfe4;
background: #fff2c9;
overflow: auto;
}
.content pre {
padding-left: 0 !important;
padding-right: 0 !important;
border-radius: 8px;
box-shadow: 1px 1px 20px 3px #dddddd !important;
}
.content code {
background-color: white;
box-shadow: 1px 1px 1px lightgrey;
}
.content table {
display: table;
padding-left: 0 !important;
padding-right: 0 !important;
box-shadow: 2px 2px 20px 6px lightgrey !important;
}
.content th {
font-weight: bold;
font-size: 16px;
background-color: #cce6b6;
}
</style>
<style>
@media (min-width: 600px) {
.markdown-section pre > code {
font-size: 0.9rem !important;
}
}
@media (max-width: 600px) {
.markdown-section pre > code {
padding-top: 5px;
padding-bottom: 5px;
}
pre:after {
content: '' !important;
}
}
@media (min-width: 600px) {
pre code {
padding-left: 20px !important;
}
}
@media (max-width: 600px) {
pre {
padding-left: 0 !important;
padding-right: 0 !important;
to {
-webkit-filter: hue-rotate(-360deg);
-moz-filter: hue-rotate(-360deg);
}
}
</style>
</head>
<body>
<div id="app">正在加载...</div>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
<script src="//unpkg.com/docsify-edit-on-github/index.js"></script>
<script>
window.$docsify = {
name: 'linux-tutorial',
repo: 'https://github.com/dunwu/linux-tutorial',
logo: 'http://dunwu.test.upcdn.net/common/logo/zp_100_100.png',
themeColor: '#6190E8',
auto2top: true,
coverpage: 'coverpage.md',
loadSidebar: 'sidebar.md',
autoHeader: true,
autoHeader: false,
maxLevel: 4,
subMaxLevel: 2,
formatUpdated: '{MM}/{DD} {HH}:{mm}',
@ -266,7 +97,11 @@
noData: '😭 没有结果!',
depth: 4
},
disqus: 'linux-tutorial',
pagination: {
previousText: '上一篇',
nextText: '下一篇',
crossChapter: true
},
plugins: [
EditOnGithubPlugin.create('https://github.com/dunwu/linux-tutorial/tree/master/docs/', null, function(file) {
if (file.indexOf('en') === -1) {
@ -278,14 +113,34 @@
]
}
</script>
<script src="//unpkg.com/docsify/lib/plugins/disqus.min.js"></script>
<script src="//unpkg.com/docsify-edit-on-github/index.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/zoom-image.js"></script>
<script src="//unpkg.com/docsify-pagination/dist/docsify-pagination.min.js"></script>
<!--聊天插件和配置-->
<script src="//unpkg.com/docsify/lib/plugins/gitalk.min.js"></script>
<script src="//unpkg.com/gitalk/dist/gitalk.min.js"></script>
<script src="https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js"></script>
<script>
const gitalk = new Gitalk({
id: md5(window.location.pathname),
clientID: 'e8d4c3d68a873a9da4ce',
clientSecret: 'd4550e13edad32bb0cd15e2bc314fc684ac830ef',
repo: 'linux-tutorial',
owner: 'dunwu',
admin: ['dunwu'],
distractionFreeMode: true
})
</script>
<!--代码高亮-->
<!--@see https://github.com/PrismJS/prism -->
<script src="//unpkg.com/prismjs/components/prism-basic.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
<!-- <canvas id="c_n9" width="1920" height="990" style="position: fixed; top: 0; left: 0; z-index: -2; opacity: 0.5;"></canvas>-->
<script src="https://files.cnblogs.com/files/jingmoxukong/canvas-nest.min.js" async defer></script>
</body>
</html>

View File

@ -1,4 +1,4 @@
# 【目录】
# linux-tutorial
- [**Linux 命令**](linux/cli/README.md)
- [查看 Linux 命令帮助信息](linux/cli/查看Linux命令帮助信息.md)