Преглед изворни кода

完善了云平台安装的文档
增加了javaweb的学习文档

seamew пре 3 година
родитељ
комит
e05293fa4e

+ 1 - 1
linux/centos网络配置.md

@@ -78,7 +78,7 @@ systemctl enable ntpd && systemctl start ntpd
 # 4.主机名称
 
 ```
-hostnamectl set-hostname  h
+hostnamectl set-hostname  
 ```
 
 # 5.界面控制

+ 78 - 0
linux/linux防火墙.md

@@ -0,0 +1,78 @@
+# centos防火墙相关设置
+
+***
+
+## 1、防火墙状态管理
+
+```
+# 查看默认防火墙状态
+firewall-cmd --state 
+# 开启防火墙命令:
+systemctl start firewalld
+# 重启防火墙命令:
+systemctl restart firewalld
+# 关闭防火墙命令
+systemctl stop firewalld
+# 安装Firewall命令:
+yum install -y firewalld firewalld-config
+# 开机启动
+systemctl enable firewalld
+# 禁止开机启动
+sytemctl disable firewalld
+# 查看状态
+systemctl status firewalld
+```
+
+## 2、防火墙关闭或者开启端口
+
+```
+# Firewall开启常见端口命令:
+firewall-cmd --zone=public --add-port=80/tcp --permanent
+firewall-cmd --zone=public --add-port=443/tcp --permanent
+firewall-cmd --zone=public --add-port=22/tcp --permanent
+firewall-cmd --zone=public --add-port=21/tcp --permanent
+firewall-cmd --zone=public --add-port=53/udp --permanent
+
+# Firewall关闭常见端口命令:
+firewall-cmd --zone=public --remove-port=80/tcp --permanent
+firewall-cmd --zone=public --remove-port=443/tcp --permanent
+firewall-cmd --zone=public --remove-port=22/tcp --permanent
+firewall-cmd --zone=public --remove-port=21/tcp --permanent
+firewall-cmd --zone=public --remove-port=53/udp --permanent
+
+# 批量添加区间端口
+firewall-cmd --zone=public --add-port=4400-4600/udp --permanent
+firewall-cmd --zone=public --add-port=4400-4600/tcp --permanent
+
+# 批量删除区间端口
+firewall-cmd --zone=public --remove-port=4400-4600/udp --permanent
+firewall-cmd --zone=public --remove-port=4400-4600/tcp --permanent
+```
+
+## 3、防火墙开放特点端口
+
+```
+# 针对某个 IP开放端口
+firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.142.166" port protocol="tcp" port="6379" accept"
+firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.0.233" accept"
+
+# 针对一个ip段访问
+firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.0.0/16" accept"
+firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="9200" accept"
+
+# 删除某个IP
+firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.51" accept"
+```
+
+## 4、防火墙注意事项
+
+```
+# 操作后别忘了执行重载
+firewall-cmd --reload
+
+# 查看端口开启状态
+firewall-cmd --query-port=9998/tcp
+
+# 查看防火墙规则
+firewall-cmd --list-all 
+```

+ 434 - 0
后端/JavaWeb/JavaWeb.md

@@ -0,0 +1,434 @@
+# JavaWeb
+***
+
+## 1、基本概念
+
+***
+
+### 1.1、前言
+web开发:
+* web,网页的意思,www.baidu.com
+* 静态web
+  * html,css
+  * 提供给所有人看的数据始终不会发生变化!
+* 动态web
+  * 淘宝,几乎是所有的网站;
+  * 提供给所有人看的数据始终会发生变化!
+  * 技术栈:Servlet/JSP,ASP,PHP
+
+在Java中,动态web资源开发的技术统称为JavaWeb
+
+### 1.2、web应用程序
+
+web应用程序:可以提供浏览器访问的程序
+* a.html,b.html.........多个web资源,可以被外界访问,对外界提供服务;
+* 资源存在物理机上面
+* URL
+* 统一的web资源会被放在同一个文件夹下,web应用程序
+* 一个web应用由多部分组成
+  * html,css,js
+  * jsp,servlet
+  * java程序
+  * jar包
+  * 配置文件(properties)
+
+web应用程序编写完毕后,若想提供给外部访问;需要一个服务器来统一管理;
+
+### 1.3、静态web
+
+* *.htm,*.html,这些都是网页的后端,如果服务器上一直存在这些东西,我们就可以直接进行读取
+  ![image-20211112143650663](assets/image-20211112143650663.png)
+* 静态web存在的缺点
+  * 微博页面无法动态更新,所有用户看到都是同一个页面
+    * 轮播图,点击特效:为动态
+    * javascript
+  * 无法与数据库交互
+
+### 1.4、动态web
+
+页面会动态展示:“展示效果因人而异”
+![image-20211112145114932](assets/image-20211112145114932.png)
+
+缺点
+* 如果服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,重新发布;
+  * 停机维护
+
+优点
+* web页面可以动态更新
+* 可以与数据库交互
+
+## 2、web服务器
+
+***
+### 2.1、技术讲解
+
+ASP
+* 微软
+* 在HTML中嵌入了VB脚本
+PHP
+* 开发速度很快,功能强大,跨平台,代码简单
+* 无法承载大访问量的情况
+JSP/Servlet:
+* sun公司主推的B/S架构
+* 基于Jva语言
+* 可以承载三高问题带来的影响
+
+### 2.2、web服务器
+
+服务器是一种被动操作,用来处理用户的一些请求和用户一些相应信息;
+IIS
+**Tomcat**
+
+## 3、Tomcat
+
+***
+
+1. JAVA环境必须有
+2. 乱码:修改命令行编码为UTF-8
+
+xml文件可以配置
+* 端口号
+* 主机名称
+* 应用的存放位置
+
+访问网站:
+1. 输入域名
+2. 检查本机hosts
+3. 访问DNS服务器
+
+## 4、Servlet
+
+***
+
+### 4.1、Servlet简介
+
+* Servlet就是sun公司开发动态web的一门技术
+* sun在这些API中提供了一个接口叫做:Servlet
+  * 编写一个类实现这个接口
+  * 开发好的类部署到web服务器中
+
+### 4.2、HelloServlet
+
+1. 构建一个主工程
+2. 关于maven父子工程的理解:
+父项目中会有一个
+```
+<modules>
+	<module>servlet01</module>
+</modules>
+```
+子项目中会有一个
+```
+<parent></parent>
+```
+父项目中的java子项目可以直接引用
+
+3. 编写一个servlet类,继承HttpServlet接口
+```
+public class HelloServlet extends HttpServlet {
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        // 响应流
+        PrintWriter writer = resp.getWriter();
+        writer.print("Hello,Servlet");
+    }
+}
+```
+4. 为什么编写Servlet的映射
+我们写的是JAVA程序,但是需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的servlet,还需给他一个浏览器能够访问的路径
+```
+  <servlet>
+    <servlet-name>Hello</servlet-name>
+    <servlet-class>com.servlet.HelloServlet</servlet-class>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>Hello</servlet-name>
+    <url-pattern>/hello</url-pattern>
+  </servlet-mapping>
+```
+5. 配置Tomcat
+![image-20211112211142264](assets/image-20211112211142264.png)
+
+### 4.3、Servlet原理
+
+Servlet是由web服务器调用,web服务器在收到浏览器请求之后,会:
+![image-20211113134002803](assets/image-20211113134002803.png)
+
+### 4.4、Mapping问题
+
+1. 一个Servlet可以指定一个映射路径
+```
+  <servlet-mapping>
+    <servlet-name>Hello</servlet-name>
+    <url-pattern>/hello</url-pattern>
+  </servlet-mapping>
+```
+2. 一个Servlet可以指定多个映射路径
+```
+  <servlet-mapping>
+    <servlet-name>Hello</servlet-name>
+    <url-pattern>/hello1</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>Hello</servlet-name>
+    <url-pattern>/hello2</url-pattern>
+  </servlet-mapping>
+```
+3. 一个Servlet可以指定通用映射路径------servlet优先级较高,会覆盖默认请求
+```
+  <servlet-mapping>
+    <servlet-name>Hello</servlet-name>
+    <url-pattern>/hello/*</url-pattern>
+  </servlet-mapping>
+```
+4. 指定一些后缀或者前缀
+```
+  <servlet-mapping>
+    <servlet-name>Hello</servlet-name>
+    <!--*前面不能加项目映射路径-->
+    <url-pattern>*.do</url-pattern>
+  </servlet-mapping>
+```
+5. 默认请求路径------少用
+```
+  <servlet-mapping>
+    <servlet-name>Hello</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+```
+6. 优先级问题
+指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求。
+
+### 4.5、ServletContext
+
+web容器在启动的时候,他会为每个web程序都创建一个对应的ServletContext对象,他代表了当前的web应用;
+#### 4.5.1、共享数据
+
+servlet中保存的数据,在另外的servlet可以拿到。
+```
+ServletContext servletContext = this.getServletContext();
+servletContext.setAttribute("userName", userName);
+String userName = (String) servletContext.getAttribute("userName");
+```
+
+#### 4.5.2、获取初始化参数
+
+```java
+ServletContext servletContext = this.getServletContext();
+String url = servletContext.getInitParameter("url");
+resp.getWriter().print(url);
+```
+
+#### 4.5.3、请求转发
+
+```java
+this.getServletContext().getRequestDispatcher("/gp").forward(req,resp);
+```
+![image-20211113145845150](assets/image-20211113145845150.png)
+通过这张图你就可以看到,转发是在服务器之间进行的,它的意思虽然我没有你想要的资源但是我可以帮你找到,
+
+重定向是告诉你,我Servlet1没有这个资源,但是我告诉你那里有,你自己通过浏览器去找,
+
+#### 4.5.4、读取资源文件
+
+maven由于他的约定大于喷子hi,我们写的配置文件,可能无法被到处或者生效,解决方法
+```
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <excludes>
+                    <exclude>**/*.properties</exclude>
+                    <exclude>**/*.xml</exclude>
+                </excludes>
+                <filtering>false</filtering>
+            </resource>
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                </includes>
+                <filtering>false</filtering>
+            </resource>
+        </resources>
+    </build>
+```
+
+Properties
+发现都被打包到了同一个路径下:classes,我们俗称为classpath
+通过文件流读取。
+
+### 4.6、HttpServletResponse
+
+webn服务器接收到客户端的http请求,针对请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse
+* 如果要获取客户端请求过来的参数:HttpServletRequest
+* 如果要找客户端响应的一些信息:HttpServletResponse
+
+#### 4.6.1、常用应用
+
+1. 输出信息
+2. 下载文件
+	1. 获取下载文件的路径
+	2. 下载的文件名
+	3. 设置让浏览器能够支持我们需要的东西
+	4. 获取下载文件的输入流
+	5. 创建缓冲区
+	6. 获取OutputStream对象
+	7. 将OutputStream写入缓冲区
+	8. 将缓冲区写入磁盘
+3. 验证码功能
+验证怎么来的?
+* 前端实现
+* 后端实现,需要用到java的图片类,产生一个图片
+4. 重定向
+![image-20211113164517356](assets/image-20211113164517356.png)
+常见场景:
+* 用户登录
+```
+// 需要设置改项目的路径
+resp.setHeader("Location", "/r/image");
+resp.setStatus(HttpServletResponse.SC_FOUND);
+```
+重定向和转发区别?
+相同点:
+* 界面都会实现改变
+不同点:
+* 一个是web服务器
+* 一个是浏览器
+* 转发会加上项目路径,而重定向不会
+* 重定向:302
+* 转发:307
+
+
+### 4.7、HttpServletRequest
+
+HttpServletRequest代表客户端的请求,用户通过http服务请求都被封装到Request下面。
+1. 获取前端请求的参数
+2. 转发请求
+```java
+req.getRequestDispatcher("/image").forward(req,resp);
+```
+
+## 5、Cookie、Session
+
+***
+
+### 5.1、会话
+
+会话:用户打开一个浏览器,点击了很多超链接,访问了多个web资源,关闭浏览器,这个过程称之为会话。
+有状态会话:保存上次会话的状态
+怎么证明自己是西电学生?
+1. 发票
+2. 登记
+一个网站,怎么证明你来过?
+客户端  服务端
+1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了:cookie
+2. 服务器登记你来过了,下次你来的时候我来匹配你:session
+
+### 5.2、保存会话的两种技术
+
+cookie
+* 客户端技术(响应,请求)
+session
+* 服务器技术,利用这个技术,可以保存用户的会话信息!我们可以把信息或者数据放入session
+
+常见场景:网站登录之后,下次不需要登录
+
+### 5.3、cookie
+
+1. 从请求中拿到cookie信息
+2. 服务器响应给客户端cookie
+```
+Cookie[] cookies = req.getCookies();
+```
+3. 一般会保存在本地目录下
+
+一个网站cookie是否存在上限
+* 一个cookie只能保存一个信息
+* 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
+* 300个浏览器上限
+* cookie大小有限制4kb
+
+删除cookie;
+* 不设置有效期,关闭浏览器,自动失效;
+* 有效期设置为0,自动消失 
+
+### 5.4、Session(重点)
+
+什么是session:
+* 服务器会给每一个用户(浏览器创建一个)session对象
+* 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在
+* 用户登录之后,整个网站都可以访问!保存用户的信息;保存购物车的信息
+
+session和cookie的区别:
+* cookie是浏览器保存(可以保存多个)
+* session是用户独占,服务器端保存(保存重要信息,减少服务器资源浪费)
+* session对象是由服务器创建
+
+session使用场景:
+* 保存一个登录用户的信息
+* 购物车信息:
+* 整个网站中经常会使用的数据
+
+## 6、JSP
+
+***
+
+### 6.1、什么是JSP?
+
+java server pages:java服务器端界面,也和servlet一样,用于动态web技术
+最大的特点:
+* 写JSP就像写HTML
+* 区别
+  * HTML只给用户提供静态数据
+  * JSP页面中可以嵌入JAVA代码,为用户提供动态数据
+
+### 6.2、JSP原理
+
+* 代码层面没有任何问题
+
+* 服务器内部工作
+
+  tomcat中有一个work目录
+  
+  IDEA中使用tomcat开发会在idea中生成一个work目录
+  
+* 浏览器向服务端发送请求,不管访问什么请求,其实都是在访问servlet
+
+* JSP最终会转换为java类
+
+* JSP本质还是一个servlet
+
+  1. 判断请求
+  2. 内置一些对象
+  ```java
+  final javax.servlet.jsp.PageContext pageContext; // 页面上下文
+  javax.servlet.http.HttpSession session = null;  // session
+  final javax.servlet.ServletContext application; // applicationcontext
+  final javax.servlet.ServletConfig config; //配置
+  javax.servlet.jsp.JspWriter out = null;  // out
+  final java.lang.Object page = this; // page当前页
+  ```
+  3. 输出页面前增加的代码
+  ```java
+  response.setContentType("text/html");  // 响应类型
+  pageContext = _jspxFactory.getPageContext(this, request, response,
+  		null, true, 8192, true);
+  _jspx_page_context = pageContext;
+  application = pageContext.getServletContext();
+  config = pageContext.getServletConfig();
+  session = pageContext.getSession();
+  out = pageContext.getOut();
+  _jspx_out = out;  
+  ```
+  4. 以上这些对象我们在JSP页面中直接使用
+  
+* 在JSP页面中:
+
+  如果是JAVA代码就会被原封不动的输出
+
+  如果是HTML代码就会被转换为out.write("<h1></h1>")这样的格式渲染到前端
+
+* 原理图
+![image-20211114185115260](assets/image-20211114185115260.png)

BIN
后端/JavaWeb/assets/image-20211112143650663.png


BIN
后端/JavaWeb/assets/image-20211112145114932.png


BIN
后端/JavaWeb/assets/image-20211112211142264.png


BIN
后端/JavaWeb/assets/image-20211113134002803.png


BIN
后端/JavaWeb/assets/image-20211113145845150.png


BIN
后端/JavaWeb/assets/image-20211113164517356.png


BIN
后端/JavaWeb/assets/image-20211114185115260.png


+ 1 - 1
大数据/docker/2.centos7安装docker.md

@@ -21,7 +21,7 @@ sudo tee /etc/docker/daemon.json <<-'EOF'
   "registry-mirrors": ["https://an54fymq.mirror.aliyuncs.com"]
 }
 EOF
-sudo systemctl daemon-reload &sudo systemctl restart docker
+systemctl daemon-reload && systemctl restart docker
 ```
 
 # 3.docker权限问题

+ 273 - 41
大数据/云平台安装文档/安装云平台环境.md

@@ -73,7 +73,7 @@ reboot
 
 ```
 # 1.创建目录存放相应的安装包
-mkdir -p /opt/package/
+mkdir -p /opt/package/docker
 
 # 2.上传安装包下的docker文件夹到上述的目录中
 
@@ -112,7 +112,11 @@ docker-compose --version
 # 3.安装Harbor及相应的配置(只需要一台虚拟机安装)
 
 ## 3.1安装Harbor
-1. 将压缩包harbor-offline-installer-v2.3.2.tgz上传到```/opt/package/```目录下
+1. 将压缩包harbor-offline-installer-v2.3.2.tgz上传到
+```
+/opt/package/
+```
+目录下
 2. 解压该压缩包
 ```
 tar xf harbor-offline-installer-v2.3.2.tgz
@@ -121,55 +125,45 @@ tar xf harbor-offline-installer-v2.3.2.tgz
 
 首先备份一份压缩包
 ```
-# cp harbor.yml.tmpl  harbor.yml         //复制配置文件内容到harbor.yml 中(安装时只识别harbor.yml)
-# mkdir -p /opt/application/harbor       //用于存放harbor的持久化数据
+# 复制配置文件内容到harbor.yml 中(安装时只识别harbor.yml)
+cp harbor.yml.tmpl  harbor.yml         
+# 用于存放harbor的持久化数据
+mkdir -p /home/mkcloud/software/harbor/data       
+
+# 用于存放harbor的日志
+mkdir -p /home/mkcloud/software/harbor/log
 ```
 
 其次对harbor.yml文件进行修改配置
 
 ```
-#设置访问地址,可以使用ip、域名,不可以设置为127.0.0.1或localhost。默认情况下,harbor使用的端口是80,若使用自定义的端口,除了要改docker-compose.yml文件中的配置外,这里的hostname也要加上自定义的端口,否则在docker login、push时会报错
-hostname: 192.168.0.8:9999      
-#http配置
-http: 
-# port for http, default is 80. If https enabled, this port will redirect to https port
-port: 9999                      
+# 需要修改为本机的ip
+hostname: 10.168.59.60
 
-# https配置(如不需要可不配置,注释掉)
+# http related config
+http:
+  port: 80
+# 需要全部注释
 # https related config
 # https:
-# https port for harbor, default is 443
-# port: 443
-# The path of cert and key files for nginx
-# certificate: /your/certificate/path
-# private_key: /your/private/key/path
-
-# external_url: https://reg.mydomain.com:8433      
-# 如果要启用外部代理,比如外层的NGINX、LB等,请取消注释external_url,当它启用时,hostname将不再使用。
-# admin密码
-harbor_admin_password: Harbor12345         
-
-
-
-#数据库配置
-database:
-# The password for the root user of Harbor DB. Change this before any production use.
-password: root123
-# The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained.
-max_idle_conns: 50
-# The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections.
-# Note: the default number of connections is 100 for postgres.
-max_open_conns: 100
-
-
-#持久化数据目录
-data_volume: /opt/application/harbor
-
+  # https port for harbor, default is 443
+  # port: 443
+  # The path of cert and key files for nginx
+  # certificate: /your/certificate/path
+  # private_key: /your/private/key/path
+  
+data_volume: /home/mkcloud/software/harbor/data   # 需要添加一个自己的目录
+
+log:
+    location: /home/mkcloud/software/harbor/log  # 需要添加一个自己的目录
 ```
 
 4. 安装并启动Harbor
 
-保证此时在harbor安装文件中,执行install.sh文件进行安装,命令为:``` ./install.sh```
+保证此时在harbor安装文件中,执行install.sh文件进行安装,命令为:
+``` 
+./install.sh
+```
 
 5. 访问harbor Web界面
 
@@ -198,12 +192,250 @@ EOF
 systemctl daemon-reload && systemctl restart docker
 ```
 
-输入命令```docker login server.harbor.com:80```
+输入命令
+```
+docker login server.harbor.com:80
+```
 输入用户名:admin
 密码:Harbor12345
 ![image-20211110155332792](assets/image-20211110155332792.png)
 至此,harbor配置完成
 
+# 4.K8S 离线安装及NFS配置(三台虚拟机都需要安装)
+
+
+## 4.1 上传kube1.9.0.tar.gz(以下简称kube1.9)到服务器
+
+```
+# 1.三台虚拟机创建目录
+mkdir -p /opt/package/k8s
+# 2.上传文件到指定目录
+scp -r kube1.9.0.tar.gz root@192.168.238.20:/opt/package/k8s
+scp -r kube1.9.0.tar.gz root@192.168.238.21:/opt/package/k8s
+scp -r kube1.9.0.tar.gz root@192.168.238.22:/opt/package/k8s
+```
+
+## 4.2 解压安装主从
+
+```
+# 1.master下,进入/opt/package/k8s目录下解压,执行脚本
+tar -zxvf kube1.9.0.tar.gz
+cd kube/shell 
+init.sh
+
+# 2.等待init.sh执行完毕,之后执行
+master.sh
+
+# 3. node1和node2执行下面的命令
+cd /opt/package/k8s
+tar -zxvf kube1.9.0.tar.gz
+cd kube/shell 
+init.sh
+
+# 4. 进入master将/etc/kubernetes/admin.conf文件复制到node1节点和node2节点
+scp -r /etc/kubernetes/admin.conf root@192.168.238.21:/etc/kubernetes
+scp -r /etc/kubernetes/admin.conf root@192.168.238.22:/etc/kubernetes
+   
+```
+
+   
+
+## 4.3 从节点加入主节点
+
+ 1. 在master节点生成token
+
+    ```shell
+    kubeadm token create --print-join-command
+    ```
+
+    效果如下
+
+    ```shell
+    [root@master shell]# kubeadm token create --print-join-command
+    W1009 17:15:31.782757   37720 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
+    kubeadm join 192.168.0.90:6443 --token ul68zs.dkkvpwfex9rpzo0d     --discovery-token-ca-cert-hash sha256:3e3ee481f5603621f216e707321aa26a68834939e440be91322c62eb8540ffce
+    ```
+
+   2. 在node1和node2中执行下面的命令------注意这里要上面生产的命令
+
+      ```shell
+      kubeadm join 192.168.0.90:6443 --token ul68zs.dkkvpwfex9rpzo0d     --discovery-token-ca-cert-hash sha256:3e3ee481f5603621f216e707321aa26a68834939e440be91322c62eb8540ffce
+      ```
+
+      结果如下
+
+      ```shell
+      [root@node1 shell]# kubeadm join 192.168.0.90:6443 --token ul68zs.dkkvpwfex9rpzo0d     --discovery-token-ca-cert-hash sha256:3e3ee481f5603621f216e707321aa26a68834939e440be91322c62eb8540ffce
+      [preflight] Running pre-flight checks
+      	[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
+      	[WARNING FileExisting-socat]: socat not found in system path
+      [preflight] Reading configuration from the cluster...
+      [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
+      [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
+      [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
+      [kubelet-start] Starting the kubelet
+      [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
+      
+      This node has joined the cluster:
+      * Certificate signing request was sent to apiserver and a response was received.
+      * The Kubelet was informed of the new secure connection details.
+      
+      Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
+      ```
+
+## 4.4 验证集群pod是否running,各节点是否ready
+
+watch kubectl get pod -n kube-system -o wide 
+效果如下	
+
+```shell
+   [root@master shell]# watch kubectl get pod -n kube-system -o wide
+   Every 2.0s: kubectl get pod -n kube-system -o wide                                                                                                                  Fri Oct  9 17:45:03 2020
+     NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
+     calico-kube-controllers-5d7686f694-94fcc   1/1     Running   0          48m   100.89.161.131   master   <none>           <none>
+     calico-node-42bwj                          1/1     Running   0          48m   192.168.0.90     master   <none>           <none>
+     calico-node-k6k6d                          1/1     Running   0          27m   192.168.0.189    node2    <none>           <none>
+     calico-node-lgwwj                          1/1     Running   0          29m   192.168.0.68     node1    <none>           <none>
+     coredns-f9fd979d6-2ncmm                    1/1     Running   0          48m   100.89.161.130   master   <none>           <none>
+     coredns-f9fd979d6-5s4nw                    1/1     Running   0          48m   100.89.161.129   master   <none>           <none>
+     etcd-master                                1/1     Running   0          48m   192.168.0.90     master   <none>           <none>
+     kube-apiserver-master                      1/1     Running   0          48m   192.168.0.90     master   <none>           <none>
+     kube-controller-manager-master             1/1     Running   0          48m   192.168.0.90     master   <none>           <none>
+     kube-proxy-5g2ht                           1/1     Running   0          29m   192.168.0.68     node1    <none>           <none>
+     kube-proxy-wpf76                           1/1     Running   0          27m   192.168.0.189    node2    <none>           <none>
+     kube-proxy-zgcft                           1/1     Running   0          48m   192.168.0.90     master   <none>           <none>
+     kube-scheduler-master                      1/1     Running   0          48m   192.168.0.90     master   <none>           <none>
+```
+kubectl get nodes
+效果如下
+```shell
+   [root@master shell]# kubectl get nodes
+     NAME     STATUS   ROLES    AGE     VERSION
+     master   Ready    master   22m     v1.19.0
+     node1    Ready    <none>   2m17s   v1.19.0
+     node2    Ready    <none>   24s     v1.19.0
+```
+
+## 4.5配置NFS
+
+| master | NFS服务端+NFS客户端 |
+| ------ | ------------------- |
+| node1  | NFS客户端           |
+| node2  | NFS客户端           |
+
+
+
+1. 将本地nfs离线包上传至服务器及各个节点的/opt/package/nfs文件夹下
+
+   ```shell
+   scp -r nfs root@192.168.238.20:/opt/package
+   scp -r nfs root@192.168.238.21:/opt/package
+   scp -r nfs root@192.168.238.22:/opt/package
+   ```
+   
+2. 安装服务端(master节点操作)
+
+   ```shell
+   # 进入master节点内/opt/package/nfs文件夹内执行以下命令
+   # 进入/opt/package/nfs
+   cd /opt/package/nfs
+   # 安装nfs
+   yum rpm -ivh nfs-utils-1.3.0-0.68.el7.2.x86_64.rpm
+   # 执行命令 vi /etc/exports,创建 exports 文件,文件内容如下:
+   echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
+   # 执行以下命令,启动 nfs 服务
+   # 创建共享目录
+   mkdir -p /nfs/data
+   systemctl enable rpcbind
+   systemctl enable nfs-server
+   systemctl start rpcbind
+   systemctl start nfs-server
+   exportfs -r
+   # 检查配置是否生效
+   exportfs
+   # 输出结果如下所示
+   /nfs/data * 
+   ```
+3. 安装NFS客户端(三台虚拟机操作)
+```shell
+# 进入node1,node2节点内/opt/package/nfs文件夹内执行以下命令
+cd /opt/package/nfs
+yum rpm -ivh nfs-utils-1.3.0-0.68.el7.2.x86_64.rpm
+systemctl start nfs && systemctl enable nfs
+```
+
+4. K8S中安装NFS(任意K8S节点,这里选择master节点)
+```shell
+# 1.进入/opt/package/nfs目录
+cd /opt/package/nfs
+# 2.载入docker镜像
+docker load < nfs-client-provisioner.tar.gz
+# 3.修改deployment.yaml文件
+vim /root/nfs/deployment.yaml
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: nfs-client-provisioner
+  labels:
+    app: nfs-client-provisioner
+  # replace with namespace where provisioner is deployed
+  namespace: default
+spec:
+  replicas: 1
+  strategy:
+    type: Recreate
+  selector:
+    matchLabels:
+      app: nfs-client-provisioner
+  template:
+    metadata:
+      labels:
+        app: nfs-client-provisioner
+    spec:
+      serviceAccountName: nfs-client-provisioner
+      containers:
+        - name: nfs-client-provisioner
+          image: quay.io/external_storage/nfs-client-provisioner:latest ##默认是latest版本
+          volumeMounts:
+            - name: nfs-client-root
+              mountPath: /persistentvolumes
+          env:
+            - name: PROVISIONER_NAME
+              value: fuseim.pri/ifs 
+            - name: NFS_SERVER
+              value: 192.168.238.20 ##这里写NFS服务器的IP地址
+            - name: NFS_PATH
+              value: /nfs/data ##这里写NFS服务器中的共享挂载目录(强调:这里的路径必须是目录中最后一层的文件夹,否则部署的应用将无权限创建目录导致Pending)
+      volumes:
+        - name: nfs-client-root
+          nfs:
+            server: 192.168.238.20  ##这里写NFS服务器的IP地址
+            path: /nfs/data ##NFS服务器中的共享挂载目录(强调:这里的路径必须是目录中最后一层的文件夹,否则部署的应用将无权限创建目录导致Pending)
+
+# 4、部署yaml文件
+[root@k8s-client nfs]# kubectl apply -f .
+
+# 5、查看服务
+[root@k8s-client nfs]# kubectl get pods
+NAME                                     READY   STATUS    RESTARTS   AGE
+nfs-client-provisioner-78697f488-5p52r   1/1     Running   0          16h
+ 
+# 6、列出你的集群中的StorageClass 
+[root@k8s-client nfs]# kubectl get storageclass
+NAME                  PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
+managed-nfs-storage   fuseim.pri/ifs   Delete          Immediate           false                  16h
+
+# 7、标记一个StorageClass为默认的 (是storageclass的名字也就是你部署的StorageClass名字是啥就写啥)
+[root@k8s-client nfs]# kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
+storageclass.storage.k8s.io/managed-nfs-storage patched
+
+# 8、验证你选用为默认的StorageClass
+[root@k8s-client nfs]# kubectl get storageclass
+NAME                            PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
+managed-nfs-storage (default)   fuseim.pri/ifs   Delete          Immediate           false            
+```
+
 # 5.安装kubesphere及其相应的插件
 
 ## 5.1将离线包上传至harbor仓库(该操作只需在master节点进行)
@@ -303,7 +535,7 @@ kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=
 
 | 软件           | 版本    |
 | -------------- | ------- |
-| centos         | 7.5     |
+| centos         | 7.7     |
 | docker         | 19.03.7 |
 | docker-compose | 2.1.0   |
 | Harbor         | 2.3.2   |