提交 041b5a4a 编写于 作者: RunAtWorld's avatar RunAtWorld

k8s

上级 202dd724
## Docker
- [Docker](docker/README.md)
- [docker常用命令](docker/docker_cmd.md)
- [docker常见问题](docker/docker_faq.md)
## k8s基础
- [k8s入门](basic/README.md)
- [k8s速览](basic/k8s_intro.md)
- [kubectl_cli](basic/kube_cli.md)
- [k8s的yaml规范](basic/k8s_yaml.md)
- [k8s运行app](basic/k8s_app.md)
- [app的yml解析](basic/k8s_app_yml.md)
- [kube-shell](basic/kube-shell.md)
- [kube-prompt](basic/kube-prompt.md)
- [k8s安装](basic/install/README.md)
- [寻找帮助](basic/seek_help.md)
- [书籍推荐](basic/booklist.md)
## 架构
* [架构解析](arch/README.md)
* [scheduler](arch/scheduler/README.md)
## 应用
* [K8S应用](apps/README.md)
## 源码分析
* [源码分析](code_analysis/README.md)
## AI
* [ai on k8s](ai/README.md)
\ No newline at end of file
......@@ -16,7 +16,7 @@ rootfs 做文件系统,rootfs 只是一个操作系统所包含的文件
这样就实现了进程在我们所看到的一个与世隔绝的房间,这个房间就是Pass项目赖以生存的"沙盒"。
![img](images/1024482-20190831100016746-420321088.png)
![img](../images/1024482-20190831100016746-420321088.png)
### 3.Namespace
......@@ -26,7 +26,7 @@ rootfs 做文件系统,rootfs 只是一个操作系统所包含的文件
除了刚刚pid namespace,还有其它的namespace如下:
![img](images/1024482-20190831154305541-1811424117.png)
![img](../images/1024482-20190831154305541-1811424117.png)
**容器是怎么新建namespace的?**
......@@ -208,7 +208,7 @@ Events: <none>
service中创建endpoint资源,其中一个作用就是用于service知道包含哪些pod。
![img](images/1024482-20190907220918209-1727058398.png)
![img](../images/1024482-20190907220918209-1727058398.png)
......@@ -246,7 +246,7 @@ externalName: someapi.somecompany.com // 实际服务的完全限定域名(
NodePort 服务是引导外部流量到你的服务的最原始方式。NodePort,正如这个名字所示,在所有节点(虚拟机)上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。
![img](images/1024482-20190908223212859-289324464.png)
![img](../images/1024482-20190908223212859-289324464.png)
......@@ -283,7 +283,7 @@ spec:
LoadBalancer 服务是暴露服务到 internet 的标准方式。在 GKE 上,这种方式会启动一个 Network Load Balancer[2],它将给你一个单独的 IP 地址,转发所有流量到你的服务。
![img](images/1024482-20190908223635767-1077917590.png)
![img](../images/1024482-20190908223635767-1077917590.png)
......@@ -315,7 +315,7 @@ spec:
为什么使用Ingress,一个重要的原因是LoadBalancer服务都需要创建自己的负载均衡器,以及独有的公有Ip地址,而Ingress只需要一个公网Ip就能为许多服务提供访问。
![img](images/1024482-20190907233427374-362269939.png)
![img](../images/1024482-20190907233427374-362269939.png)
......@@ -325,7 +325,7 @@ Ingress 事实上不是一种服务类型。相反,它处于多个服务的前
你可以用 Ingress 来做许多不同的事情,各种不同类型的 Ingress 控制器也有不同的能力。
![img](images/1024482-20190908223745136-442370238.png)
![img](../images/1024482-20190908223745136-442370238.png)
......@@ -370,7 +370,7 @@ ingressyaohong kubia.example.com 80 2m
![img](images/1024482-20190908164433047-701299505.png)
![img](../images/1024482-20190908164433047-701299505.png)
......@@ -656,7 +656,7 @@ spec:
以NFS为例,yml代码如下:
![img](images/1024482-20190909233811117-1853230658.png)
![img](../images/1024482-20190909233811117-1853230658.png)
......@@ -818,15 +818,15 @@ yh-pv1 1Gi RWO Recycle Bound default/yh-pvc nf
上面已经创建好了pv和pvc,pod中直接使用这个pvc即可
![img](images/1215197-20181112000941263-134961896.png)
![img](../images/1215197-20181112000941263-134961896.png)
与使用普通 Volume 的格式类似,在 `volumes` 中通过 `persistentVolumeClaim` 指定使用 `mypvc1` 申请的 Volume。
通过命令创建`mypod1`
![img](images/1215197-20181112001048694-922664654.png)
![img](../images/1215197-20181112001048694-922664654.png)
![img](images/1215197-20181112003213905-627552664.png)
![img](../images/1215197-20181112003213905-627552664.png)
可见,在 Pod 中创建的文件 `/mydata/hello` 确实已经保存到了 NFS 服务器目录 `/nfsdata`中。
......@@ -838,35 +838,35 @@ yh-pv1 1Gi RWO Recycle Bound default/yh-pvc nf
当 PV 不再需要时,可通过删除 PVC 回收。
![img](images/1215197-20181114140524904-1462205182.png)
![img](../images/1215197-20181114140524904-1462205182.png)
未删除pvc之前 pv的状态是Bound
![img](images/1215197-20181114140620468-1513256026.png)
![img](../images/1215197-20181114140620468-1513256026.png)
**![img](images/1215197-20181114140643382-503979351.png)**
**![img](../images/1215197-20181114140643382-503979351.png)**
删除pvc之后pv的状态变为Available,,此时解除绑定后则可以被新的 PVC 申请。
/nfsdata文件中的文件被删除了
![img](images/1215197-20181114140816328-1594861053.png)
![img](../images/1215197-20181114140816328-1594861053.png)
![img](images/1215197-20181114141038825-733094704.png)
![img](../images/1215197-20181114141038825-733094704.png)
因为 PV 的回收策略设置为 `Recycle`,所以数据会被清除,但这可能不是我们想要的结果。如果我们希望保留数据,可以将策略设置为 `Retain`
![img](images/1215197-20181114140944474-244523375.png)
![img](../images/1215197-20181114140944474-244523375.png)
通过 `kubectl apply` 更新 PV:
![img](images/1215197-20181114141123152-1573323006.png)
![img](../images/1215197-20181114141123152-1573323006.png)
回收策略已经变为 `Retain`,通过下面步骤验证其效果:
![img](images/1215197-20181114141846850-14718544.png)
![img](../images/1215197-20181114141846850-14718544.png)
① 重新创建 `mypvc1`
......@@ -878,7 +878,7 @@ yh-pv1 1Gi RWO Recycle Bound default/yh-pvc nf
虽然 `mypv1` 中的数据得到了保留,但其 PV 状态会一直处于 `Released`,不能被其他 PVC 申请。为了重新使用存储资源,可以删除并重新创建 `mypv1`。删除操作只是删除了 PV 对象,存储空间中的数据并不会被删除。
![img](images/1215197-20181114142318452-1082688967.png)
![img](../images/1215197-20181114142318452-1082688967.png)
新建的 `mypv1` 状态为 `Available`,已经可以被 PVC 申请。
......@@ -898,11 +898,11 @@ PV 还支持 `Delete` 的回收策略,会删除 PV 在 Storage Provider 上对
StorageClass `standard`
![img](images/1215197-20181114142759910-1404134003.png)
![img](../images/1215197-20181114142759910-1404134003.png)
StorageClass `slow`
![img](images/1215197-20181114142818881-1657034993.png)
![img](../images/1215197-20181114142818881-1657034993.png)
这两个 StorageClass 都会动态创建 AWS EBS,不同在于 `standard` 创建的是 `gp2` 类型的 EBS,而 `slow` 创建的是 `io1` 类型的 EBS。不同类型的 EBS 支持的参数可参考 AWS 官方文档。
......@@ -910,7 +910,7 @@ StorageClass 支持 `Delete` 和 `Retain` 两种 `reclaimPolicy`,默认是 `De
与之前一样,PVC 在申请 PV 时,只需要指定 StorageClass 和容量以及访问模式,比如:
![img](images/1215197-20181114142851545-262925360.png)
![img](../images/1215197-20181114142851545-262925360.png)
除了 AWS EBS,Kubernetes 支持其他多种动态供给 PV 的 Provisioner,完整列表请参考 https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner
......@@ -932,23 +932,23 @@ StorageClass 支持 `Delete` 和 `Retain` 两种 `reclaimPolicy`,默认是 `De
mysql-pv.yml
![img](images/1215197-20181114164249311-815553434.png)
![img](../images/1215197-20181114164249311-815553434.png)
mysql-pvc.yml
![img](images/1215197-20181114164321137-1044555599.png)
![img](../images/1215197-20181114164321137-1044555599.png)
创建 `mysql-pv``mysql-pvc`
![img](images/1215197-20181114164423538-1248541390.png)
![img](../images/1215197-20181114164423538-1248541390.png)
接下来部署 MySQL,配置文件如下:
![img](images/1215197-20181114164556988-1613625971.png)
![img](../images/1215197-20181114164556988-1613625971.png)
PVC `mysql-pvc` Bound 的 PV `mysql-pv` 将被 mount 到 MySQL 的数据目录 `var/lib/mysql`
![img](images/1215197-20181114164706515-1715855365.png)
![img](../images/1215197-20181114164706515-1715855365.png)
MySQL 被部署到 `k8s-node2`,下面通过客户端访问 Service `mysql`
......@@ -956,11 +956,11 @@ MySQL 被部署到 `k8s-node2`,下面通过客户端访问 Service `mysql`:
kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword
```
![img](images/1215197-20181114165320049-1580108497.png)
![img](../images/1215197-20181114165320049-1580108497.png)
更新数据库:
![img](images/1215197-20181114165947863-142820308.png)
![img](../images/1215197-20181114165947863-142820308.png)
① 切换到数据库 mysql。
......@@ -972,19 +972,19 @@ kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h
关闭 `k8s-node2`,模拟节点宕机故障。
![img](images/1215197-20181114170125072-435593197.png)
![img](../images/1215197-20181114170125072-435593197.png)
验证数据的一致性:
由于node2节点已经宕机,node1节点接管了这个任务。
![img](images/1215197-20181114170806935-1324900057.png)
![img](../images/1215197-20181114170806935-1324900057.png)
通过kubectl run 命令 进入node1的这个pod里,查看数据是否依旧存在
![img](images/1215197-20181114173251942-323542163.png)
![img](../images/1215197-20181114173251942-323542163.png)
![img](images/1215197-20181114173235264-1137808713.png)
![img](../images/1215197-20181114173235264-1137808713.png)
......@@ -1605,7 +1605,7 @@ Deployment 的控制器,实际上控制的是 ReplicaSet 的数目,以及每
通过这样的多个 ReplicaSet 对象,Kubernetes 项目就实现了对多个“应用版本”的描述。
​ ![img](images/1024482-20190906172122372-2079200366.png)
​ ![img](../images/1024482-20190906172122372-2079200366.png)
......@@ -1810,7 +1810,7 @@ Node节点:
## 11.2.k8s组件分布式特性
![img](images/1024482-20190804111141192-1400794862.png)
![img](../images/1024482-20190804111141192-1400794862.png)
  k8s系统组件之间通信只能通过API服务器通信,他们之间不会之间进行通信。
......@@ -1879,7 +1879,7 @@ Node节点:
  调度器不会命令选中节点取运行pod,调度器做的就是通过api服务器更新pod的定义。然后api服务器再去通知kubelet该pod已经被调用。当目标节点的kubelet发现该pod被调度到本节点,就会创建并运行pod容器。
  ![img](images/1024482-20190804170225819-1682312970.png)
  ![img](../images/1024482-20190804170225819-1682312970.png)
调度方法:
......@@ -1941,7 +1941,7 @@ Node节点:
  Service不会直接连接到pod,而是通过一个ip和端口的列表,EedPoint管理器就是监听service和pod的变化,将ip和端口更新endpoint资源。
![img](images/1024482-20190806083107467-1325380157.png)
![img](../images/1024482-20190806083107467-1325380157.png)
**(9)Namespace控制器**
......@@ -2004,7 +2004,7 @@ Node节点:
  每个pod中都包含/var/run/secrets/kubernetes.io/serviceaccount/token文件,如下图所示,文件内容用于对身份进行验证,token文件持有serviceaccount的认证token。
  ![img](images/1024482-20190810114432031-368767518.png)
  ![img](../images/1024482-20190810114432031-368767518.png)
  应用程序使用token去连接api服务器时,认证插件会对serviceaccount进行身份认证,并将serviceaccount的用户名传回到api服务器内部。
......@@ -2018,7 +2018,7 @@ Node节点:
  ServiceAcount作用在单一命名空间,为每个命名空间创建默认的ServiceAccount。
​ ![img](images/1024482-20190810120110376-1306680638.png)
​ ![img](../images/1024482-20190810120110376-1306680638.png)
  多个pod可以使用相同命名空间下的同一的ServiceAccount,
......@@ -2091,7 +2091,7 @@ token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2V
  **自定义pod的ServiceAccount的方法如下图**
![img](images/1024482-20190810170827956-1653174820.png)
![img](../images/1024482-20190810170827956-1653174820.png)
......@@ -2163,7 +2163,7 @@ $ kubectl create rolebinding test --role=service-reader
rolebinding.rbac.authorization.k8s.io/test created
```
  ![img](images/1024482-20190811114905372-1366844414.png)
  ![img](../images/1024482-20190811114905372-1366844414.png)
```
$ kubectl get rolebinding test -o yaml
......@@ -2252,7 +2252,7 @@ $ kubectl create clusterrolebinding cluster-tetst --clusterrole=pv-reader --
clusterrolebinding.rbac.authorization.k8s.io/cluster-tetst created
```
  ![img](images/1024482-20190811144031799-2134922004.png)
  ![img](../images/1024482-20190811144031799-2134922004.png)
......
此差异已折叠。
## Scheduler
Kubernetes Scheduler 是负责Pod调度的重要功能模块再整个系统中有“承上启下”的作用。它负责接收 Controller Manager 创建新Pod的请求,为新Pod找到一个目标Node,新Pod创建后,目标Node上的kubelet服务进程负责Pod的剩余生命周期。
具体来说,Kubernetes Scheduler 的作用是将待调度的Pod(包括Kubernetes API 新创建的Pod、Controller Manager为补足副本而创建的Pod)按照特定的调度算法和调度策略绑定到集群中某个合适的Node上,并将绑定信息写入etcd。整个调度过程涉及到三个对象:待调度Pod列表、可用Node列表以及调度算法和策略。
简单来讲,Kubernetes Scheduler 的核心工作就是通过调度算法为待调度Pod列表的每个 Pod 从 Node 列表中选择一个最适合的Node。随后,目标节点上的 kubelet 通过 API Server 监听到 Kubernetes Scheduler 产生的 Pod 绑定事件,然后获取对应的Pod清单,下载Image镜像,并启动容器。
![](./Scheduler.jpg)
在 kube-scheduler 的启动参数中 ,`--algorithm-provider="DefaultProvider"` 用于设置调度算法,默认为 DefaultProvider 。默认调度过程如下[[1]]():
1. 预选调度过程,即遍历所有目标 Node ,选出符合要求的候选节点。为此,Kubernetes内置了多种预选策略(xxx Predicates) 供用户选择
2. 确定最优节点。在第1步的基础上,采取优选策略(xxx Prioritt)计算出每个候选节点的积分,积分高者胜出。
Kubernetes Scheduler的调度流程是通过插件方式加载的“调度算法提供者”(AlgorithmProvider)具体实现的。一个AlgorithmProvider就是包括了一组预选调度策略与一组优先选择策略的结构体,注册 RegisterAlgorithmProvider 的函数在包 `\kubernetes\cmd\kube-scheduler\app\server.go`,如下:
```
func RegisterAlgorithmProvider(name string, predicateKeys, priorityKeys sets.String) string {
schedulerFactoryMutex.Lock()
defer schedulerFactoryMutex.Unlock()
validateAlgorithmNameOrDie(name)
algorithmProviderMap[name] = AlgorithmProviderConfig{
FitPredicateKeys: predicateKeys,
PriorityFunctionKeys: priorityKeys,
}
return name
}
```
这3个参数: "name string" 为算法名,"predicateKeys" 为算法用到的预选策略集合,
"priorityKeys sets.String" 为算法用到的优选策略集合。
其中 Scheduler 可用的预选策略有:
```
CheckNodeCondition:#检查节点是否正常(如ip,磁盘等)
GeneralPredicates
HostName:#检查Pod对象是否定义了pod.spec.hostname
PodFitsHostPorts:#pod要能适配node的端口 pods.spec.containers.ports.hostPort(指定绑定在节点的端口上)
MatchNodeSelector:#检查节点的NodeSelector的标签 pods.spec.nodeSelector
PodFitsResources:#检查Pod的资源需求是否能被节点所满足
NoDiskConflict: #检查Pod依赖的存储卷是否能满足需求(默认未使用)
PodToleratesNodeTaints:#检查Pod上的spec.tolerations可容忍的污点是否完全包含节点上的污点;
PodToleratesNodeNoExecuteTaints:#不能执行(NoExecute)的污点(默认未使用)
CheckNodeLabelPresence:#检查指定的标签再上节点是否存在
CheckServiceAffinity:#将相同services相同的pod尽量放在一起(默认未使用)
MaxEBSVolumeCount: #检查EBS(AWS存储)存储卷的最大数量
MaxGCEPDVolumeCount #GCE存储最大数
MaxAzureDiskVolumeCount: #AzureDisk 存储最大数
CheckVolumeBinding: #检查节点上已绑定或未绑定的pvc
NoVolumeZoneConflict: #检查存储卷对象与pod是否存在冲突
CheckNodeMemoryPressure:#检查节点内存是否存在压力过大
CheckNodePIDPressure: #检查节点上的PID数量是否过大
CheckNodeDiskPressure: #检查内存、磁盘IO是否过大
MatchInterPodAffinity: #检查节点是否能满足pod的亲和性或反亲和性
```
其中默认的预选策略为:
>
Scheduler 可用的优选策略有:
```
LeastRequested:#空闲量越高得分越高
(cpu((capacity-sum(requested))*10/capacity)+memory((capacity-sum(requested))*10/capacity))/2
BalancedResourceAllocation:#CPU和内存资源被占用率相近的胜出;
NodePreferAvoidPods: #节点注解信息“scheduler.alpha.kubernetes.io/preferAvoidPods”
TaintToleration:#将Pod对象的spec.tolerations列表项与节点的taints列表项进行匹配度检查,匹配条目越,得分越低;
SeletorSpreading:#标签选择器分散度,(与当前pod对象通选的标签,所选其它pod越多的得分越低)
InterPodAffinity:#遍历pod对象的亲和性匹配项目,项目越多得分越高
NodeAffinity: #节点亲和性
MostRequested: #空闲量越小得分越高,和LeastRequested相反 (默认未启用)
NodeLabel: #节点是否存在对应的标签 (默认未启用)
ImageLocality:#根据满足当前Pod对象需求的已有镜像的体积大小之和(默认未启用)
```
# 参考
1. 龚正,吴治辉等 . Kubernetes权威指南:从Docker到Kubernetes全接触[M] . 北京:电子工业出版社,2016:177-194
2. k8s调度器、预选策略及调度方式 . https://www.cnblogs.com/zhangb8042/p/10203266.html
3. k8s scheduler pod调度分析 . https://blog.csdn.net/weixin_39961559/article/details/81704461
4. Pod Priority and Preemption . https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
1. Kubernetes调度详解 . http://dockone.io/article/2885
此差异已折叠。
# Kubernetes调度详解
# 参考
Kubernetes 各类工具
# Kubernetes基础
# 1. 命令行终端
## 命令行终端
1. [Kube-prompt](https://github.com/c-bata/kube-prompt/) 用 Go 语言开发,天生良好的跨平台性。
- [安装方式](./install_kube-prompt.md)
1. [kube-shell](https://github.com/cloudnativelabs/kube-shell)可以为 Kubectl 提供自动的命令提示和补全。
......
......@@ -194,11 +194,12 @@ Events:
Normal Created 19m kubelet, 172.31.25.125 Created container
Normal Started 18m kubelet, 172.31.25.125 Started container
```
# 总结
1. 用户通过 kubectl 创建 Deployment。
1. Deployment 创建 ReplicaSet。
1. ReplicaSet 创建 Pod。
2. Deployment 创建 ReplicaSet。
3. ReplicaSet 创建 Pod。
![](./pic/640.webp)
从上图也可以看出,对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字。
\ No newline at end of file
对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字。
\ No newline at end of file
......@@ -8,6 +8,7 @@ kubectl edit
kubectl patch
```
# 使用 yml 运行一个 app
1. 运行一个 Deployment :`kubectl apply -f nginx.yml`
`nginx.yml`的配置信息:
```
......@@ -68,7 +69,7 @@ kubectl patch
v1
```
1. 查看 Deployment : `kubectl get deployment nginx-deployment2 -o wide`
2. 查看 Deployment : `kubectl get deployment nginx-deployment2 -o wide`
```
[root@ip-172-31-24-224 opt]# kubectl get deployment nginx-deployment2 -o wide
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
......@@ -108,7 +109,7 @@ kubectl patch
Normal ScalingReplicaSet 9m deployment-controller Scaled up replica set nginx-deployment2-7f7c47b54f to 2
```
1. 删除 Deployment : `kubectl delete deployment nginx-deployment2` 或者 `kubectl delete -f nginx.yml`
3. 删除 Deployment : `kubectl delete deployment nginx-deployment2` 或者 `kubectl delete -f nginx.yml`
```
[root@ip-172-31-24-224 opt]# kubectl delete -f nginx.yml
......
kubectl Shell命令提示工具kube-shell
## 0、关于kube-shell
# kube-shell
Kube-shell是基于python-prompt-toolkit实现的,旨在提供Kubectl的易用性并提高生产力。kube-shell提供如下功能:
```
自动完成kubectl命令及参数提示
颜色标示显示
历史命令自动填充
模糊查询,服务端自动完成
上下文信息及切换,F4切换集群,F5切换Namespaces
```
* 自动完成kubectl命令及参数提示
* 颜色标示显示
* 历史命令自动填充
* 模糊查询,服务端自动完成
* 上下文信息及切换,F4切换集群,F5切换Namespaces
## 1、环境准备
### 1.1 python2.7.5升级到2.7.14
查看Python版本
......
# Docker 实战
## 总结
1. [docker常用命令](./docker_cmd.md)
2. [docker常见问题](./docker_faq.md)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册