This commit is contained in:
yinkanglong
2023-09-09 12:29:47 +08:00
parent 498eb76a3d
commit 7bf7c05181
30 changed files with 1019 additions and 230 deletions

View File

@@ -3,71 +3,80 @@
总共包括六个主要的部分。学完就能毕业啦。开始吧。
* [ ] 前置知识
* [ ] 数据库&Mysql
* [ ] 操作系统&Linux
* [ ] 计算机网络
* [ ] 数据结构与算法
* [ ] 设计模式
* [ ] Java基础教程Java的基本语法和使用及原理晚上自学第一周学完
* [X] Java语言基础。语言语法。20200830
* [x] Java标注库.(自动拆装箱、String枚举类、反射、动态代理、序列化、注解、泛型、单元测试、正则表达式、工具库、异常、日期时间、编码方式)
* [x] Java集合类
* [x] JavaIO与网络编程网络基础、Socket编程
* [ ] Java并发编程(线程、锁、同步、并发包)
* [ ] Java基本原理。JVM底层的原理和技术。(内存结构、垃圾回收)
* [ ] Java架构模式。面向对象和设计模式
* [ ] Java网站开发JavaWeb相关的技术知识。
* [ ] 数据库技术
* [ ] JDBC
* [ ] MyBatis
* [ ] 容器技术
* [ ] Servlet和JSP
* [ ] JBOSS和Resteasy
* [ ] Tomcat
* [ ] 服务器技术
* [ ] Nginx
* [ ] Netty
* [ ] Java工具教程Java使用的关键工具白天学习一下
* [ ] Maven教程20221030
* [x] Idea教程20221023
* [ ] Git教程
* [ ] Java框架教程Spring全家桶白天自学
* [x] Spring520221010
* [ ] Springboot
* [ ] Spring MVC
* [ ] SpringCloud
* [ ] sofabootsofarpc
* [ ] Java云原生和微服务
* [ ] 云原生基础
* [x] shellbash&awk&grep&find&vim20220926
* [x] docker20221003
* [ ] k8s
* [ ] 服务框架
* [ ] dubbo
* [ ] eureka
* [ ] zookeeper
* [ ] servicemeshIstio&MOSN
* [ ] sofaregistry&sofams
* [ ] 数据中间件&消息中间件
* [ ] redis中间件
* [ ] tbase中间件
* [ ] kfk消息队列
* [ ] sofamq消息队列
* [ ] Java性能优化
* [ ] 高可用(预防监控、应急容灾)
* [ ] 双机/主备机房(主机房活跃、备机房停止)
* [ ] 异地/同城多活(多个节点都获取)
* [ ] 高性能
* [ ] 高性能缓存
* [ ] PPC TPC
* [ ] 高并发
* [ ] 分库分表
* [ ] 消息队列
* [ ] Java分布式基础
* [ ] 负载均衡和调度
* [ ] 分布式缓存
* [ ] 分布式算法
### Java的学习路线视频打卡系列
- [ ] 基础知识(学习方式——阅读书籍)
- [ ] 数据库
- [ ] 操作系统
- [ ] 计算机网络
- [ ] 数据结构与算法
- [ ] 编译原理
- [ ] Java基础教程Java的基本语法和使用及原理晚上自学第一周学完
- [X] Java语言基础。语言语法。(分五个阶段完成把,当前第一阶段已经完成)
- [ ] Java高级操作。JDK IO操作/并发编程/网络编程
- [ ] Javaweb开发。Servlet和JSP相关的老技术。知道就行
- [ ] Java基本原理。JVM底层的原理和技术
- [ ] Java架构模式。面向对象和设计模式
- [ ] Java网站开发JavaWeb相关的技术知识。
- [ ] MySQL
- [ ] JDBC
- [ ] lombak
- [ ] mybatis
- [ ] Java工具教程Java使用的关键工具白天学习一下
- [X] maven教程
- [X] idea教程
- [ ] Java框架教程Spring全家桶白天自学
- [X] Spring
- [ ] Springboot
- [ ] Spring MVC
- [ ] SpringCloud
- [ ] Java云计算和微服务
- [ ] docker
- [ ] k8s
- [ ] servicemesh
- [ ] Java性能优化
- [ ] 高可用
- [ ] 双机架构
- [ ] 异地多活
- [ ] 高性能
- [ ] 高性能缓存
- [ ] PPC TPC
- [ ] 高并发
- [ ] 分库分表
- [ ] 消息队列
- [ ] Java分布式基础
- [ ] 负载均衡和调度
- [ ] 分布式缓存
- [ ] 分布式算法
- [ ] kfk消息队列
- [ ] Java数据库
- [ ] mysql
- [ ] redis
### Java书籍打卡系列开始
第一阶段:向下探索五本
- [ ] Java编程思想4版
- [ ] Java核心技术卷112版
- [ ] Java核心技术卷212版
- [ ] Effective Java
- [ ] 深入理解Java虚拟机
第二阶段:向上进阶五本
- [ ] ON JAVA基础卷
- [ ] ON JAVA进阶卷
- [ ] Java设计模式及实践这些东西还是得自己手敲一遍
- [ ] Java并发编程的艺术、并发编程实践、高并发编程详解机械工业出版三件套
- [ ] Spring官方文档。全套阅读。
第三阶段:云原生三本
- [ ] 云原生技术
- [ ] 服务网格

6
Java源代码/Lesson02/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

View File

@@ -2,121 +2,13 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="6287d1ea-cc51-48fe-ac05-ba07e5be5962" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/../../.vscode/java-formatter.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/01 Java基础.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/02 流程控制.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/03 函数方法.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/04 Java数组.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/06 异常处理.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/10 包装器类.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/11 String&amp;StringBuffer类.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/20 Scanner.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/Input&amp;Output.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/image/2022-07-09-09-40-30.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/image/2022-07-09-10-21-44.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/image/2022-07-10-10-32-18.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/image/2022-07-10-18-27-47.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/image/2022-07-10-21-39-34.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/阿里巴巴java开发手册2020.pdf" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java面试原理/03 关键字.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java面试原理/04 修饰符.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java基础教程/Java面试原理/Arrays类.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../Lesson01/Java01HelloWorld.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/uiDesigner.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/BasicLanguage/BasicLanguage.iml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/BasicLanguage/src/com/ykl/HelloWorld.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Lesson02.iml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../allclasses-frame.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../allclasses-noframe.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../com/ykl/Demo5.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../com/ykl/HelloWorld.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../com/ykl/class-use/Demo5.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../com/ykl/class-use/HelloWorld.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../com/ykl/package-frame.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../com/ykl/package-summary.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../com/ykl/package-tree.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../com/ykl/package-use.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../constant-values.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../deprecated-list.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../help-doc.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../index-files/index-1.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../index-files/index-2.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../index-files/index-3.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../index-files/index-4.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../index.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../overview-tree.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../package-list" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../script.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../stylesheet.css" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java网站开发/MyBatis/7日志.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/../../Java网站开发/java中@的作用.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../.vscode/launch.json" beforeDir="false" afterPath="$PROJECT_DIR$/../../.vscode/launch.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../.vscode/settings.json" beforeDir="false" afterPath="$PROJECT_DIR$/../../.vscode/settings.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/java.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/java.thread.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/java.thread.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/jdk阅读笔记说明.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/429f749d3870e8c9a198746da0d0ca6e.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/429f749d3870e8c9a198746da0d0ca6e.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/4c9b2a5287c91f386c9db0ba1920904b.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/4c9b2a5287c91f386c9db0ba1920904b.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/51d56de3dfb3391d64c34cc5121e3bd0.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/51d56de3dfb3391d64c34cc5121e3bd0.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/51e409b11aa51c150090697429a953ed.gif" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/51e409b11aa51c150090697429a953ed.gif" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/54db549dedb71c1ac0e24d21fa81faf4.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/54db549dedb71c1ac0e24d21fa81faf4.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/6cb91c2845273c5693a564bab023d4e3.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/6cb91c2845273c5693a564bab023d4e3.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/7932f8d9c5acc2d3a1896b4c3233612e.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/7932f8d9c5acc2d3a1896b4c3233612e.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/995e20b243fa0e000d51589ebb780e75.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/995e20b243fa0e000d51589ebb780e75.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/c5008c69466298cf4ed608e4f6b569f0.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/c5008c69466298cf4ed608e4f6b569f0.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JDK阅读/media/ec7fd9666c2bd70bfc26c6c2a1f7538a.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/media/ec7fd9666c2bd70bfc26c6c2a1f7538a.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/DAO模式的理解.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/DAO模式的理解.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/JAVA中库的理解.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/JAVA中库的理解.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/JAVA代码组织.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/JAVA代码组织.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/JSP代码作用.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/JSP代码作用.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/JSP技术详解.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/JSP技术详解.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/computer.py" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/computer.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/java中@的作用.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/12 Number&amp;Math类.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/jdbc标准范例.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/jdbc标准范例.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/media/033dc67bcd465edb89b52cc8d9bdd5c1.png" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/media/033dc67bcd465edb89b52cc8d9bdd5c1.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/media/0df06acb323561f7014fed6f60125206.jpeg" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/media/0df06acb323561f7014fed6f60125206.jpeg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/media/4f52e7856884d1457ab7d1867caab247.jpeg" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/media/4f52e7856884d1457ab7d1867caab247.jpeg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/media/896ddc649ace2c4d5b318d11c887ece9.jpeg" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/media/896ddc649ace2c4d5b318d11c887ece9.jpeg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/关于JAVAEE非框架的理解.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/关于JAVAEE非框架的理解.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/关键字——transient.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/关键字——transient.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/移动自动测试工具appium.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/移动自动测试工具appium.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/简单的实验.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/简单的实验.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/JavaEE企业级开发/软件测试中的总结.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/软件测试中的总结.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/JAVA数据近似.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/JAVA数据近似.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/Java IO.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/21 Java IO.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/Java 基础.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/05 面向对象.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/Java 容器.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/20 Java容器.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/Java 并发.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/Java 并发.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/Java 虚拟机.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/JVM原理/Java 虚拟机.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/Toolkit和Image类的应用.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java图形界面/Toolkit和Image类的应用.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/paint方法和Graphic类.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java图形界面/paint方法和Graphic类.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/事件处理.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/事件处理.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/事件监听机制.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/事件监听机制.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/多线程共享受限资源.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/多线程共享受限资源.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/多线程共享资源问题.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/多线程共享资源问题.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/多线程理论补充.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/多线程基本操作.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/多线程的其他操作.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/多线程的其他操作.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/多线程的应用.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/多线程的应用.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/多线程通讯问题.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/多线程通讯问题.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/多线程间的通讯.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/多线程间的通讯.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/底层事件处理.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/底层事件处理.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java基础/补充:多线程基本操作.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java并发编程/多线程理论补充.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Lombok/Lombok.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/Lombok/Lombok.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/MyBatis/1简介.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/MyBatis/1简介.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/MyBatis/2XML配置.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java语言基础/Number&amp;Math.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/MyBatis/3XML映射.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/MyBatis/3XML映射.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/MyBatis/4动态SQL.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/MyBatis/2XML配置.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/MyBatis/5Java API.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/MyBatis/4动态SQL.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/MyBatis/6SQL语句构建器.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/MyBatis/5Java API.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/MyBatis/7日志.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java网站开发/MyBatis/6SQL语句构建器.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/说明.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/BasicLanguage/src/com/ykl/Demo5.java" beforeDir="false" afterPath="$PROJECT_DIR$/BasicLanguage/src/com/ykl/Demo5.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/BasicLanguage/src/com/ykl/Demo6.java" beforeDir="false" afterPath="$PROJECT_DIR$/BasicLanguage/src/com/ykl/Demo6.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/BasicLanguage/src/com/ykl/ScannerTest.java" beforeDir="false" afterPath="$PROJECT_DIR$/BasicLanguage/src/com/ykl/ScannerTest.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../Java基础教程/Java学习路线.md" beforeDir="false" afterPath="$PROJECT_DIR$/../../Java基础教程/Java学习路线.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../../kubenets/04.01POD.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../../kubenets/04.02Service.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../../kubenets/04.03Deployment.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../../kubenets/04.04StatefulSet.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../../kubenets/04.05ReplicaSet.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../../kubenets/04.06Ingress.md" beforeDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -142,17 +34,17 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"jdk.selected.JAVA_MODULE": "1.8",
"project.structure.last.edited": "Project",
"project.structure.proportion": "0.0",
"project.structure.side.proportion": "0.0",
"settings.editor.selected.configurable": "terminal"
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;jdk.selected.JAVA_MODULE&quot;: &quot;1.8&quot;,
&quot;project.structure.last.edited&quot;: &quot;Project&quot;,
&quot;project.structure.proportion&quot;: &quot;0.0&quot;,
&quot;project.structure.side.proportion&quot;: &quot;0.0&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;terminal&quot;
}
}]]></component>
}</component>
<component name="RunManager" selected="Application.Demo6">
<configuration name="Demo5" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="Demo5" />

42
kubenets/04-1.POD.md Normal file
View File

@@ -0,0 +1,42 @@
## 1 概念
![](image/2022-08-22-10-51-53.png)
### 是什么
1. Pod是Kubernetes创建或部署的最小/最简单的基本单位一个Pod代表集群上正在运行的一个进程。
2. 一个Pod封装一个或多个多个容器存储资源、一个独立的网络IP以及管理控制容器运行方式的策略选项。
3. Pod代表部署的一个单位Kubernetes中单个应用的实例它可能由单个容器或多个容器共享组成的资源。
### 两种工作模式
kubernetes中pod使用的两种方式
1. 单容器模式Pod中运行一个容器。“one-container-per-Pod”模式是Kubernetes最常见的用法; 在这种情况下你可以将Pod视为单个封装的容器但是Kubernetes是直接管理Pod而不是容器。
2. 多容器模式Pods中运行多个需要一起工作的容器。Pod可以封装紧密耦合的应用它们需要由多个容器组成它们之间能够共享资源这些容器可以形成一个单一的内部service单位 -类似docker swam 一个容器共享文件另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。
### 多容器模式
Pods的设计可用于支持多进程的协同工作作为容器形成一个cohesive的Service单位。Pod中的容器在集群中Node上被自动分配容器之间可以共享资源、网络和相互依赖关系并同时被调度使用。
只有在容器紧密耦合的特殊实例中使用此模式。Pods提供两种共享资源网络和存储。例如有一个容器被用作WEB服务器用于共享volume以及一个单独“sidecar”容器需要从远程获取资源来更新这些文件如下图所示
![](image/2023-08-30-23-04-30.png)
1. 共享网络每个Pod被分配一个独立的IP地址Pod中的每个容器共享网络命名空间包括IP地址和网络端口。Pod内的容器可以使用localhost相互通信。当Pod中的容器与Pod 外部通信时,他们必须协调如何使用共享网络资源(如端口)。
2. Pod可以指定一组共享存储volumes。Pod中的所有容器都可以访问共享volumes允许这些容器共享数据。volumes 还用于Pod中的数据持久化以防其中一个容器需要重新启动而丢失数据。
## 2 使用
### 使用方式
1. 很少会直接在kubernetes中创建单个Pod。因为Pod的生命周期是短暂的用后即焚的实体。当Pod被创建后不论是由你直接创建还是被其他Controller都会被Kuberentes调度到集群的Node上。直到Pod的进程终止、被删掉、因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在那个Node上。
2. 重启可以从三个维度理解pod重启、容器重启、应用重启。Pod只提供容器的运行环境并保持容器的运行状态重启容器不会造成Pod重启。
### Pod和Controller
Kubernetes使用更高级的称为Controller的抽象层来管理Pod实例。Controller可以创建和管理多个Pod提供副本管理、滚动升级和集群级别的自愈能力。
通常Controller会用你提供的Pod Template来创建相应的Pod。包含一个或者多个Pod的Controller示例
* Deployment
* StatefulSet
* DaemonSet

171
kubenets/04-10 Probe.md Normal file
View File

@@ -0,0 +1,171 @@
## 1 概述
### 概念
探针:是由 kubelet 对容器执行的定期诊断。kubelet 调用由容器实现 Handler执行诊断。探针有三种类型的处理程序:
* ExecAction在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
* CPSocketAction对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
* HTTPGetAction对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400则诊断被认为是成功的。和微服务的心跳检测类似每隔一段时间检测这个容器是否还正常工作检测状态分为三种,每次检测都会得到其中一种k8s会根据检测到的不同状态对容器进行不同的处理
* 成功:容器通过了诊断。
* 失败:容器未通过诊断。
* 未知:诊断失败,因此不会采取任何行动。
### 分类
探针主要有以下三种类型:
livenessProbe
readinessProbe
startupProbe
### 容器重启策略
容器重启策略
PodSpec 中有一个 restartPolicy 字段,其值可以设置为
```
Always
OnFailure
Never
```
默认为 Always
* Always表示一旦不管以何种方式终止运行kubelet都将重启
* OnFailure表示只有Pod以非0退出码退出才重启
* Nerver表示不再重启该Pod
restartPolicy 适用于 Pod 中的所有容器。restartPolicy 仅指通过同一节点上的 kubelet 重新启动容器。失败的容器由 kubelet 以五分钟为上限的指数退避延迟10秒20秒40秒…重新启动并在成功执行十分钟后重置。如 Pod 官方文档中所说一旦pod绑定到一个节点Pod 将永远不会重新绑定到另一个节点。
## 2 探针类型
### livenessProbe存活性探针
指检测容器是否正在运行。
* 如果存活探测失败,则 kubelet 会杀死容器需要注意杀死的是container不是pod并且容器将受到其重启策略Always,OnFailure,Never的影响。
* 如果容器不提供存活探针,则默认状态为 Success。
### readinessProbe就绪性探针
指示容器是否准备好服务请求【对外接受请求访问】。
* 如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址IP:Port。
* 初始延迟之前的就绪状态默认为 Failure。
* 如果容器不提供就绪探针,则默认状态为 Success。
> 如果容器未通过准备检查,则不会被终止或重新启动。
### startupProbe启动探针
k8s1.16新增加的一种类型指检测容器中的应用是否已经启动。
* 如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。
* 如果启动探测失败kubelet 将杀死容器,容器服从其重启策略进行重启。
* 如果容器没有提供启动探测则默认状态为成功Success。
主要解决在慢启动程序或复杂程序中readinessProbe、livenessProbe探针无法较好的判断程序是否启动、是否存活。执行顺序
* 如果三个探针同时存在则先执行startupProbe探针其他两个探针将会被暂时禁用直到startupProbe一次探测成功其他2个探针才启动
* 如果startupProbe探测失败kubelet 将杀死容器并根据restartPolicy重启策略来判断容器是否要进行重启操作。
### 对比
1. 就绪探针与存活探针之间的重要区别:就绪探针如果容器未通过准备检查,则不会被终止或重新启动。
2. 存活探针通过杀死异常的容器并用新的正常容器替代他们来保持Pod正常工作
3. 就绪探针确保只有准备好处理请求的Pod才可以接收探针请求
## 3 配置
### 示例
```
spec:
containers:
# 就绪探针
readinessProbe:
# 检测方式
httpGet:
# 超时时间
timeoutSeconds:
# 延迟时间
initialDelaySeconds:
# 失败次数限制
failureThreshold:
# 每多少秒检测一次
periodSeconds:
# 存活探针
livenessProbe:
# 检测方式
httpGet:
# 超时时间
timeoutSeconds:
# 延迟时间
initialDelaySeconds:
# 失败次数限制
failureThreshold:
# 每多少秒检测一次
periodSeconds:
```
### 配置说明
* initialDelaySeconds容器启动后要等待多少秒后存活和就绪探测器才被初始化
* 默认是 0 秒,最小值是 0
* periodSeconds执行探测的时间间隔单位是秒
* 默认是 10 秒。最小值是 1。
* timeoutSeconds探测的超时时间
* 默认值是 1 秒。最小值是 1。
* successThreshold探测器在失败后被视为成功的最小连续成功数。
* 默认值是 1。存活探测的这个值必须是 1。最小值是 1。
* failureThreshold当探测失败时重试次数+1。存活探测失败就意味着重新启动容器。就绪探测失败Pod 会被打上未就绪的标签。
* 默认值是 3。最小值是 1。
* 在 httpGet 上配置额外的字段:
* host连接使用的主机名默认是 Pod 的 IP。也可以在 HTTP 头中设置 “Host” 来代替。
* scheme 用于设置连接主机的方式HTTP 还是 HTTPS。默认是 HTTP。
* path访问 HTTP 服务的路径。
* httpHeaders请求中自定义的 HTTP 头。HTTP 头字段允许重复。
* port访问容器的端口号或者端口名。如果数字必须在 1 65535 之间。
## 4 探活机制
就绪探针/存活探针,都有这三种探测机制。
* HTTP GET探针
* TCP套接字探针
* Exec探针
### HTTP GET探针
该探针是针对容器的IP地址(或者是指定的端口和地址)执行HTTP GET请求状态码
如果返回状态码是2xx或者3xx,则探测成功。
如果服务器返回错误的状态码或者根本没有反应,那么认定探测失败,容器会被重新启动。
### TCP套接字探针
TCP套接字探针尝试与容器指定的端口建立连接
如果连接成功,则探测成功,
如果连接失败,则认定为探测失败,容器将被重新启动。
### Exec探针
Exec探针在容器内执行任意命令并检查命令的退出状态码
如果返回的状态码为0则探测成功
如果返回状态码不为0则探测失败容器将被重新启动。
> 如果是java应用建议用HTTP GET探针、不推荐使用Exec探针因为java应用程序会消耗大量的计算资源

95
kubenets/04-2.Service.md Normal file
View File

@@ -0,0 +1,95 @@
## 1 基本介绍
### 概念
在Kubernetes中Pod中的网络是隔离的而且IP随着pod的的变化而变化。
Kubernetes中抽象出来一个Service服务发现机制只支持四层负载均衡即通过IP端口转发。Service为Pods提供了一个稳定的IP地址和DNS名称以便其他应用程序可以通过这些标识符来访问该服务。
它还提供了负载均衡和服务发现的能力可以将流量路由到一组具有相同标签的Pods中。
### 工作原理
Service 被赋予一个唯一的 dns name。Service 通过 label selector 选定一组 Pod。Service 实现负载均衡,可将请求均衡分发到选定这一组 Pod 中
![](image/2023-09-02-10-47-52.png)
### 底层实现
1. 域名的解析以来DNS组件。 kubernetes 的 dns 服务 (不同 kubernetes 版本的 dns 默认使用的也是不一样的1.11 之前的版本使用的是 kubeDNS较新的版 本使用的是 coredns
2. 每 个 K8s 节点上都有一个组件叫做 kube-proxykube-proxy 这个组件通过 watch监视 方法将始终监视着 apiserver 中有关 service 资源的变动信息。然后通过iptables也可能是 ipvs请求调度到后端特定的 pod 资源之上
![](image/2023-08-30-23-25-25.png)
## 2 类型说明
* ClusterIp:默认类型自动分配一个仅Cluster内部可以访问的IP
* Headless:ClusterIp为None的时候
* NodePort:在ClusterIP基础上为Service在每台机器上绑定一作口这样就可以通过NodePort来访问该服努
* LoadBalancer:在NodePort的基础上侑助cloud provider创建一个外部负载均衡器并将请热专发 到NodePort
* ExternalName:把集群外部的服努引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建, 这只有kubernetes 1.7或更高版本的kube-dns才支持
### HeadLess
Headless Services是一种特殊的service其spec:clusterIP表示为None这样在实际运行时就不会被分配ClusterIP。也被称为无头服务。
* headless不分配clusterIP。headless service可以通过解析service的DNS返回所有Pod的地址和DNS(statefulSet部署的Pod才有DNS)
* 普通的service只能通过解析service的DNS返回service的ClusterIP
### ClusterIp
ClusterIP类型将创建一个虚拟IP地址该IP地址将绑定到Service上并通过Kubernetes内部的代理进行转发。这种类型的服务只能在集群内部访问并且通常用于内部服务之间的通信。
### NodePort
只对外部可见,通过每个 Node 节点上的 IP 和静态端口NodePort暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。
主要适合:集群外业务访问的场景。可以从集群的外部访问一个 NodePort 服务
```yml
apiVersion: v1
kind: Service
metadata:
name: test-service
spec:
selector:
app: test
type: NodePort # 指定service 类型
ports:
- protocol: TCP
port: 80
targetPort: 80
name: test-http
nodePort: 30000 # 范围30000-32767
```
设置 type 的值为 "NodePort"Kubernetes master 将从给定的配置范围内默认30000-32767分配端口。每个 Node 将从该端口(每个 Node 上的同一端口)代理到 Service。该端口将通过 Service 的 spec.ports[*].nodePort 字段被指定这里指定的是30000。如果不指定的话会自动生成一个端口。
### LoadBalance
使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务,需要结合具体的云厂商进行操作
ExternalName 是 Service 的特例
没有 selector
没有定义任何的端口和 Endpoint
对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。
示例:
```yaml
kind: Service
apiVersion: v1
metadata:
name: test-service
namespace: test
spec:
type: ExternalName # 类型
externalName: test.service.com
```
## 原理介绍

View File

@@ -0,0 +1,4 @@

187
kubenets/04-7.job.md Normal file
View File

@@ -0,0 +1,187 @@
## 简介
### 作用
Kubernetes jobs主要是针对短时和批量的工作负载。它是为了结束而运行的而不是像deployment、replicasets、replication controllers和DaemonSets等其他对象那样持续运行。
### 场景
1.批处理任务: 比如说你想每天运行一次批处理任务,或者在指定日程中运行。它可能是像从存储库或数据库中读取文件那样,将它们分配给一个服务来处理文件。
2.运维/ad-hoc任务 比如你想要运行一个脚本/代码,该脚本/代码会运行一个数据库清理活动甚至备份一个Kubernetes集群。
### 原理
当Job创建的pod执行成功结束时Job将记录成功结束的pod数量。当成功结束的pod达到指定的数量时Job将完成执行
## 示例
### 基本示例
* .spec.completions完成该Job需要执行成功的Pod数
* .spec.parallelism能够同时运行的Pod数
* .spec.backoffLimit允许执行失败的Pod数默认值是60表示不允许Pod执行失败。如果Pod是restartPolicy为Nerver则失败后会创建新的Pod如果是OnFailed则会重启Pod不管是哪种情况只要Pod失败一次就计算一次而不是等整个Pod失败后再计算一个。当失败的次数达到该限制时整个Job随即结束所有正在运行中的Pod都会被删除
* .spec.activeDeadlineSeconds: Job的超时时间一旦一个Job运行的时间超出该限制则Job失败所有运行中的Pod会被结束并删除。该配置指定的值必须是个正整数。不指定则不会超时
```yaml
apiVersion: batch/v1 # 版本号
kind: Job # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: job
spec: # 详情描述
completions: 1 # 指定job需要成功运行Pods的次数。默认值: 1
parallelism: 1 # 指定job在任一时刻应该并发运行Pods的数量。默认值: 1
activeDeadlineSeconds: 30 # 指定job可运行的时间期限超过时间还未结束系统将会尝试进行终止。
backoffLimit: 6 # 指定job失败后进行重试的次数。默认是6
manualSelector: true # 是否可以使用selector选择器选择pod默认是false
selector: # 选择器通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: counter-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [counter-pod]}
template: # 模板当副本数量不足时会根据下面的模板创建pod副本
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never # 重启策略只能设置为Never或者OnFailure
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 2;done"]
```
关于重启策略设置的说明:
* 如果指定为OnFailure则job会在pod出现故障时重启容器而不是创建podfailed次数不变
* 如果指定为Never则job会在pod出现故障时创建新的pod并且故障pod不会消失也不会重启failed次数加1
* 如果指定为Always的话就意味着一直重启意味着job任务会重复去执行了当然不对所以不能设置为Always
### 实例1
创建pc-job.yaml内容如下
```yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pc-job
namespace: dev
spec:
manualSelector: true
selector:
matchLabels:
app: counter-pod
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 3;done"]
```
效果:
```
# 创建job
[root@k8s-master ~]# kubectl apply -f pc-job.yaml
job.batch/pc-job created
# 查看job 可以发现 COMPLETIONS 完成状态 刚才是 0/1 总共1个任务0个未完成稍后会打印出1/1代表任务结束
[root@k8s-master ~]# kubectl get job -owide -n dev -w
NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR
pc-job 0/1 28s 28s counter busybox:1.30 app=counter-pod
pc-job 0/1 47s 47s counter busybox:1.30 app=counter-pod
pc-job 0/1 48s 48s counter busybox:1.30 app=counter-pod
pc-job 1/1 48s 48s counter busybox:1.30 app=counter-pod
# 查看pod 状态 STATUS=Completed完成, READY=0/1 意思是总共1个pod有0个准备好了因为任务已经完成所以READY的变成0
[root@k8s-master ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-job-9rd6l 0/1 Completed 0 2m3s
# 删除job
[root@k8s-master ~]# kubectl delete -f pc-job.yaml
job.batch "pc-job" deleted
```
### 实例2
接下来调整下pod运行的总数量和并行数量 即在spec下设置下面两个选项
```
completions: 6 # 指定job需要成功运行Pods的次数为6
parallelism: 3 # 指定job并发运行Pods的数量为3
```
调整后yaml
```yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pc-job
namespace: dev
spec:
completions: 6 # 指定job需要成功运行Pods的次数为6
parallelism: 3 # 指定job并发运行Pods的数量为3
manualSelector: true
selector:
matchLabels:
app: counter-pod
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 3;done"]
```
效果:
然后重新运行job观察效果此时会发现job会每次运行3个pod总共执行了6个pod
```sh
[root@k8s-master ~]# kubectl get pod -n dev -w
NAME READY STATUS RESTARTS AGE
pc-job-g26wm 1/1 Running 0 7s
pc-job-ggccq 1/1 Running 0 7s
pc-job-znz9q 1/1 Running 0 7s
pc-job-znz9q 0/1 Completed 0 30s
pc-job-g26wm 0/1 Completed 0 30s
pc-job-ggccq 0/1 Completed 0 30s
pc-job-g26wm 0/1 Completed 0 31s
pc-job-znz9q 0/1 Completed 0 31s
pc-job-ggccq 0/1 Completed 0 31s
pc-job-g26wm 0/1 Completed 0 32s
pc-job-znz9q 0/1 Completed 0 32s
pc-job-ggccq 0/1 Completed 0 32s
pc-job-dmn7x 0/1 Pending 0 0s
pc-job-wfgtr 0/1 Pending 0 0s
pc-job-dmn7x 0/1 Pending 0 0s
pc-job-cnz45 0/1 Pending 0 0s
pc-job-wfgtr 0/1 Pending 0 0s
pc-job-cnz45 0/1 Pending 0 0s
pc-job-dmn7x 0/1 ContainerCreating 0 0s
pc-job-znz9q 0/1 Completed 0 32s
pc-job-ggccq 0/1 Completed 0 32s
pc-job-g26wm 0/1 Completed 0 32s
pc-job-wfgtr 0/1 ContainerCreating 0 0s
pc-job-cnz45 0/1 ContainerCreating 0 1s
pc-job-cnz45 0/1 ContainerCreating 0 1s
pc-job-wfgtr 0/1 ContainerCreating 0 1s
pc-job-dmn7x 0/1 ContainerCreating 0 2s
pc-job-wfgtr 1/1 Running 0 2s
pc-job-cnz45 1/1 Running 0 2s
pc-job-dmn7x 1/1 Running 0 3s
pc-job-cnz45 0/1 Completed 0 28s
pc-job-dmn7x 0/1 Completed 0 29s
pc-job-wfgtr 0/1 Completed 0 29s
pc-job-cnz45 0/1 Completed 0 29s
pc-job-cnz45 0/1 Completed 0 30s
pc-job-dmn7x 0/1 Completed 0 30s
pc-job-wfgtr 0/1 Completed 0 30s
pc-job-cnz45 0/1 Completed 0 31s
pc-job-dmn7x 0/1 Completed 0 31s
pc-job-wfgtr 0/1 Completed 0 31s
pc-job-dmn7x 0/1 Completed 0 32s
```

View File

View File

@@ -1,38 +0,0 @@
## 1 基本介绍
### 概念
Kubernetes Service是Kubernetes中的一个资源对象用于定义一个逻辑服务。
Service为Pods提供了一个稳定的IP地址和DNS名称以便其他应用程序可以通过这些标识符来访问该服务。
它还提供了负载均衡和服务发现的能力可以将流量路由到一组具有相同标签的Pods中。
## 2 类型说明
* Headless
* ClusterIP
* NodePort
* LoadBalancer
### HeadLess
Headless Services是一种特殊的service其spec:clusterIP表示为None这样在实际运行时就不会被分配ClusterIP。也被称为无头服务。
* headless不分配clusterIP。headless service可以通过解析service的DNS返回所有Pod的地址和DNS(statefulSet部署的Pod才有DNS)
* 普通的service只能通过解析service的DNS返回service的ClusterIP
### ClusterIp
ClusterIP类型将创建一个虚拟IP地址该IP地址将绑定到Service上并通过Kubernetes内部的代理进行转发。这种类型的服务只能在集群内部访问并且通常用于内部服务之间的通信。
### NodePort
### LoadBalance
## 原理介绍

View File

@@ -1,2 +0,0 @@
# 容器网络

View File

@@ -0,0 +1,58 @@
## 1 有无状态服务对比
### 无状态服务
1. 数据方面:无状态服务不会在本地存储持久化数据.多个实例可以共享相同的持久化数据
2. 结果方面:多个服务实例对于同一个用户请求的响应结果是完全一致的
3. 关系方面:这种多服务实例之间是没有依赖关系
4. 影响方面在k8s控制器 中动态启停无状态服务的pod并不会对其它的pod产生影响
5. 示例方面nginx实例tomcat实例web应用
6. 资源方面相关的k8s资源有ReplicaSet、ReplicationController、Deployment
7. 创建方式Deployment被设计用来管理无状态服务的pod。每个pod完全一致原因如下
1. 无状态服务内的多个Pod创建的顺序是没有顺序的
2. 无状态服务内的多个Pod的**名称是随机的**.pod被重新启动调度后,它的名称与IP都会发生变化
3. 无状态服务内的多个Pod背后是共享存储的
8. 缩容方式随机缩容。由于是无状态服务所以这些控制器创建的pod序号都是随机值。并且在缩容也是随机并不会明确缩容某一个pod。因为所有实例得到的返回值都是一样所以缩容任何一个pod都可以
### 有状态服务
1. 数据方面:有状态服务需要在本地存储持久化数据,典型的是分布式数据库,任何一个容器关闭都会导致数据丢失,服务不可用。
2. 结果方面:实例之间,请求结果可能存在不一致
3. 关系方面:分布式节点实例之间有依赖的拓扑关系.比如,主从关系.
4. 影响方面如果K8S停止分布式集群中任 一实例pod,就可能会导致数据丢失或者集群的crash
5. 示例方面mysql数据库、kafka、zookeeper、Redis主从架构
6. 资源方面statefulSet
7. 创建方式statefulSet管理。Pod的特点
1. 唯一性: 每个Pod会被分配一个**唯一序号**
2. 顺序性: Pod启动,更新,销毁是**线性的,按顺序进行**
3. **稳定的网络标识**: Pod主机名,DNS地址不会随着Pod被重新调度而发生变化.
4. **稳定的持久化存储**: Pod被重新调度后,仍然能挂载原有的PV,从而保证了数据的完整性和一致性.
8. 缩容方式有顺序的缩容。StatefulSet 缩容只会操作 一个 pod 实例,因此有状态应用的缩容相对于无状态的缩容速度会慢。
1. 举例来说, 一个分布式存储应用若同时下线多个节点 ,则可能导致其数据丢失 。比如说,一个数据项副本数设置为 2 的数据存储应用, 若同时有两个节点下线,如果一份数据它正好保存在这两个节点上,这份数据就会丢失。
2. 因此缩容是线性的 ,分布式存储应用需要时间把丢失的副本复制到其他节点 ,从而保证数据不会丢失。其实,这也是第七点中所讲的顺序性。
## 有状态服务的说明
### 稳定的网络标识
需要创建名为test-redis-pod的Stateful模型,根据配置的Replica=3的设置,K8S会创建三个Pod,依次命名为:
```
test-redis-pod-0
test-redis-pod-1
test-redis-pod-2
```
K8S为有状态的服务Pod分配稳定的网络标识,具体实现基于test-redis-pod-0名称,借助Headless DNS进行如下解析,获取后端其中一个Pod的地址.
```
$(pod name).$(service name).$(namespace).svc.cluster.local
```
下面通过Pod名称访问Redis集群的Master节点地址的方法.
```
session.save_path = "tcp://test-redis-pod-0.test-redis-service.default.svc.cluster.local:6379"
```
### 稳定的持久化存储
![](image/2023-09-02-09-50-23.png)
1. 唯一每个Redis Pod对应一个PVC/PV.当Pod发生调度时,需要在别的节点启动时,根据Pod背后关联的存储信息可以保证其名称的稳定性.
2. 复用Pod还是会attach挂载到原来的PV/PVC中,从而确定每个Pod有自己专用的存储卷.

34
kubenets/08 Pod网络.md Normal file
View File

@@ -0,0 +1,34 @@
# 容器网络
### 网络类型
* Node Network: 外部网络接口。集群节点所在的网络这个网络就是你的主机所在的网络通常情况下是你的网络基础设施提供。如果node处于不同的网段那么你需要保证路由可达。如上图中的 192.168.10.0/24和10.0.0.0/8这两个网络
Service NetworkK8S服务网络,ipvs规则当中的网络由特定组件提供路由和调度。 service_cluster_ip_range如图默认的配置是的10.0.0.1/24)。在上图中扩充的节点基础网络是10.0.0.0/8)和 服务网络10.0.0.1/24)冲突,会造网络问题。
Pod Network 节点当中pod的内部网络无法与外界通信。第三个网络是Pod的网络 K8s中一个Pod由多个容器组成但是一个pod只有一个IP地址Pod中所有的容器共享同一个IP。这个IP启动pod时从一个IP池中分配的 叫做 pod CIDR, 或者叫network_cidr如图默认配置是10.1.0.0/16)。 可以在配置文件中配置。
![](image/2023-09-02-09-15-00.png)
kubernetes对于pod的网络定制了下列三个要求所有网络插件支持这几个要求即可
* 所有节点上所有的pod可以互相通信并且不依赖NAT
* 节点上的进程可以和该节点上的所有pod通信
* 运行在主机网络空间下的pod可以和所有节点上的所有pod互相通信并且不依赖NAT
> 注意: 一个Pod会包含多个container 但是这些containers共享一个网路IP也就是说Container A如果占了80 Container B就不能用80 了。
## 2 service network
为了解决Pod IP地址不是持久性的可能会进行更改k8s采用service对pod进行抽象service为pod组提供虚拟ip任何路由到这个虚拟ip的都将转发到对应关联的pod上而且service还提供高可用与负载均衡。
相关的网络组件和工具包括netfilter、iptables
### netfilter
为了在群集内执行负载平衡Kubernetes依赖于Linux内置的网络框架netfilter它允许以自定义处理程序的形式实现与网络相关的各种操作。数据包筛选网络地址转换和端口转换的操作提供了通过网络引导数据包所需的功能并提供了禁止数据包到达计算机网络内敏感位置的功能。
### iptables
采用iptables对netfilter进行管理它是一个用户空间程序提供了一个基于表的系统用于定义netfilter模块的处理和转换数据包的规则iptables规则监视发往服务虚拟的流量IP并从一组可用的Pod中随机选择一个Pod IP地址并且iptables规则将数据包的目标IP地址从服务的虚拟IP更改为所选Pod的IP。

View File

@@ -0,0 +1,37 @@
## 原理
### 容器终止
在 Kubernetes 中Pod 停止时 kubelet 会先给容器中的主进程发 SIGTERM 信号来通知进程进行 shutdown 以实现优雅停止,如果超时进程还未完全停止则会使用 SIGKILL 来强行终止。
容器的终止流程
1. Pod 被删除,状态置为 Terminating。
2. kube-proxy 更新转发规则,将 Pod 从 service 的 endpoint 列表中摘除掉,新的流量不再转发到该 Pod。
3. 如果 Pod 配置了 preStop Hook ,将会执行。
4. kubelet 对 Pod 中各个 container 发送 SIGTERM 信号以通知容器进程开始优雅停止。
5. 等待容器进程完全停止,如果在 terminationGracePeriodSeconds 内 (默认 30s) 还未完全停止,就发送 SIGKILL 信号强制杀死进程。
6. 所有容器进程终止,清理 Pod 资源。
## 优雅退出处理
### 实现prestop逻辑
```yaml
lifecycle:
preStop:
exec:
command:
- sleep
- 5s
```
### 优雅终止时间
调整优雅终止时间terminationGracePeriodSeconds 默认是30s。
特别说明: preStop Hook并不会影响SIGTERM的处理因此有可能preStopHook还没有执行完就收到SIGKILL导致容器强制退出。因此如果preStop Hook设置了n秒需要设置terminationGracePeriodSeconds为terminationGracePeriodSeconds+n秒。
### 业务信号处理
优雅退出业务侧需要做的任务是处理SIGTERM信号

View File

@@ -0,0 +1,7 @@
## 简介
### 功能

View File

@@ -0,0 +1,118 @@
## 简介
### 作用
mapping 通过rest 资源与k8s 的service进行关联ambassador 必须有一个或者多个提供访问servide 的mapping定义
## 用法
### mapping字段详解
1. rewrite rule。修改URL 对于k8s service 的访问
2. weight指定流量路由的权重
3. host指定请求的host header
### mapping 排序
ambassador 对于mappings 会进行排序
1. 较多约束的会优先于较低的约束,
2. 请求前缀的长度请求的方法以及约束的header 都会有影响,
3. 如果有必须可以使用precedence 进行修改但是通常来说没有必要除非使用了regex_headers 以及host_regex的mapping 特性
## 示例
### mapping实例
最简单的例子
```yaml
---
apiVersion: ambassador/v0
kind: Mapping
name: qotm_mapping
prefix: /qotm/
service: http://qotm
一个cqrs 的例子
---
apiVersion: ambassador/v0
kind: Mapping
name: cqrs_get_mapping
prefix: /cqrs/
method: GET
service: getcqrs
---
apiVersion: ambassador/v0
kind: Mapping
name: cqrs_put_mapping
prefix: /cqrs/
method: PUT
service: putcqrs
```
### 基于host的mapping实例
基于http header HOST 的mapping
```yaml
---
apiVersion: ambassador/v0
kind: Mapping
name: qotm_mapping
prefix: /qotm/
service: qotm1
---
apiVersion: ambassador/v0
kind: Mapping
name: qotm_mapping
prefix: /qotm/
host: qotm.datawire.io
service: qotm2
---
apiVersion: ambassador/v0
kind: Mapping
name: qotm_mapping
prefix: /qotm/
host: "^qotm[2-9]\\.datawire\\.io$"
host_regex: true
service: qotm3
---
apiVersion: ambassador/v0
kind: Mapping
name: httpbin_mapping
prefix: /httpbin/
service: httpbin.org:80
host_rewrite: httpbin.org
```
### 基于header的mapping示例
```yaml
apiVersion: ambassador/v0
kind: Mapping
name: qotm_mapping
prefix: /qotm/
headers:
x-qotm-mode: canary
x-random-header: datawire
service: qotm
```
### 进行跨域处理
```java
apiVersion: ambassador/v0
kind: Mapping
name: cors_mapping
prefix: /cors/
service: cors-example
cors:
origins: http://foo.example,http://bar.example
methods: POST, GET, OPTIONS
headers: Content-Type
credentials: true
exposed_headers: X-Custom-Header
max_age: "86400"
```

169
kubenets/helm/简介.md Normal file
View File

@@ -0,0 +1,169 @@
# Helm
## 1 简介
### 概念
Helm 是 Deis 开发的一个用于 Kubernetes 应用的包管理工具,主要用来管理 Charts。
类似于Ubuntu 中的 APT、CentOS 中的 YUM。主要功能
* 创建创建新的charts
* 打包将charts打包成tgz文件
* 交互与chart仓库交互
* 安装安装和卸载K8s的应用
* 管理管理使用Helm安装的charts的生命周期
## 2 安装与仓库
### 前置条件
* kubernets集群
* 安装配置helm
### 安装
```
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
```
### 自动补全
```
#设置命令自动补全
echo 'source <(helm completion bash)' >> /etc/profile
. /etc/profile #重载环境变量
```
### 配置helm仓库
```
#查看其仓库信息
helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
#如上默认是Google在国外速度特别慢
local http://127.0.0.1:8879/charts
#执行下面命令,更改为国内阿里云的仓库
helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
```
### 更新仓库/查看版本信息
```
helm repo update
helm version
```
### 测试远程仓库
```
helm search mysql #搜索MySQL
#查看到的是charts包文件查出来的版本是helm的Charts包的版本
#查看其详细信息
helm inspect stable/mysql
#下载搜索到的包到本地
helm fetch stable/mysql
#在线安装这个MySQL
helm install stable/mysql
```
## 3 Chart
### 基本概念
Chart 是 Helm 的应用打包格式。是创建Kubernetes应用实例的信息集合.Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。由一系列文件组成,这些文件描述了 Kubernetes 部署应用时所需要的资源
比如:
```
Service
Deployment
PersistentVolumeClaim
Secret
ConfigMap
```
* 我们可以在部署应用的时候自定义应用程序的一些 Metadata以便于应用程序的分发。
* Chart可以很简单例如只用于部署一个服务比如 Memcached。Chart 也可以很复杂:例如,部署整个应用,比如包含 HTTP Servers、 Database、消息中间件、cache 等。
* Chart 将这些文件放置在预定义的目录结构中,通常整个 chart 被打成 tar 包,而且标注上版本信息,便于 Helm 部署。
### 目录结构
* Chart.yaml : chart 的描述文件, 包含版本信息, 名称 等.
* Chart.lock : chart 依赖的版本信息. ( apiVersion: v2 )
* values.yaml : 存储 chart 所需要的默认配置,用于配置 templates/ 目录下的模板文件使用的变量.
* values.schema.json : 一个使用JSON结构的 values.yaml 文件,用于校检 values.yaml 的完整性.
* charts : chart 所依赖的其他 chart依赖包的存储目录.
* README : 说明文件.
* LICENSE : 版权信息文件.
* crd/ : 自定义资源的定义,存放 CRD 资源的文件的目录.
* templates/ : 模板文件存放目录chart 模板文件,引入变量值后可以生成用于 Kubernetes 的 manifest 文件
* NOTES.txt : 模板须知/说明文件. helm install 成功后会显示此文件内容到屏幕.
* deployment.yaml : kubernetes 资源文件. ( 所有类型的 kubernetes 资源文件都存放于 templates 目录下 )
* _helpers.tpl : 以 _ 开头的文件, 可以被其他模板引用.
### Chart.yaml
在同一个集群中一个Charts可以使用不同的config重复安装多次每次安装都会创建一个新的Release。
```
apiVersion: # chart API 版本信息, 通常是 "v1" (必须)
name: # chart 的名称 (必须)
version: # chart 包的版本 (必须)
kubeVersion: # 指定 Kubernetes 版本 (可选)
type: # chart类型 (可选)
description: # 对项目的描述 (可选)
keywords:
- # 有关于项目的一些关键字 (可选)
home: # 项目 HOME 页面的 URL 地址 (可选)
sources:
- # 项目源码的 URL 地址 (可选)
dependencies: # chart 必要条件列表 (可选)
- name: # chart名称 (nginx)
version: # chart版本 ("1.2.3")
repository: # 可选仓库URL ("https://example.com/charts") 或别名 ("@repo-name")
condition: # (可选) 解析为布尔值的yaml路径用于启用/禁用chart (e.g. subchart1.enabled )
tags: # (可选)
- # 用于一次启用/禁用 一组chart的tag
import-values: # (可选)
- # ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项
alias: # (可选) chart中使用的别名。当你要多次添加相同的chart时会很有用
maintainers: # (可选)维护者信息
- name: # 维护者的名称
email: # 维护者的邮件地址
url: # 维护者的个人主页
engine: gotpl # 模板引擎的名称(可选,默认为 gotpl
icon: # (可选)指定 chart 图标的 SVG 或 PNG 图像的 URL
appVersion: # 应用程序包含的版本
deprecated: # (可选,使用布尔值)该 chart 是否被废弃
annotations:
example: # 按名称输入的批注列表 (可选).
```
## 4 Repository
chart Repoistory是一个可用来存储index.yaml与打包的chart文件的HTTP server。
可以理解为是存放chart的仓库类似于docker的镜像仓库、GitHub代码仓库等。
## 5 Config
应用程序实例化安装时运行使用的配置信息;
## 6 Release
chart的实例化将chart安装到k8s上就叫做生成一个release。如果把 chart 比作程序源码的话,那么 release 则可以看做是程序运行时的进程。
chart 是用户可直接感知的对象(其表现形式就是 .tgz 格式的压缩包)
release 比较抽象,它是专属于 helm 的一个逻辑概念,用来标识在 k8s 中运行的一组资源。有了 releasehelm 在操作 k8s 时,就再也不用逐个管理资源,而可以将一组相关的资源当做一个整体来操作,比如删除或升级。

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB