每日一题
27
.vuepress/components/AdSenseLeftTop.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div v-if="$themeConfig.showAds" class="adsense-page-bottom-inline" :style="$isDev ? 'background-color: grey;' : ''">
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<ins class="adsbygoogle"
|
||||
style="display:block"
|
||||
data-ad-format="fluid"
|
||||
data-ad-layout-key="-hh-5+1v-2l-d"
|
||||
data-ad-client="ca-pub-3313149841665250"
|
||||
data-ad-slot="2494099929"></ins>
|
||||
<script>
|
||||
(adsbygoogle = window.adsbygoogle || []).push({});
|
||||
</script>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.adsense-page-bottom-inline {
|
||||
/* border: 1px solid #d7dae2; */
|
||||
/* max-height: 160px;
|
||||
overflow: hidden; */
|
||||
}
|
||||
</style>
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="$themeConfig.showAds" class="adsense-page-bottom-inline" :style="$isDev ? 'background-color: grey;' : ''">
|
||||
<div class="adsense-page-bottom-inline" :style="$isDev ? 'background-color: grey;' : ''">
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||
<!-- PageBottomInline -->
|
||||
<ins class="adsbygoogle"
|
||||
|
||||
BIN
.vuepress/components/JoinCKACommunity.jpeg
Normal file
|
After Width: | Height: | Size: 89 KiB |
35
.vuepress/components/JoinCKACommunity.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div class="page-nav" style="max-width: 1000px; padding: 1rem 0; text-align: center;">
|
||||
<b-alert style="margin-bottom: 0;" show variant="primary">加入CKA备考群</b-alert>
|
||||
|
||||
<div>
|
||||
<div class="row" style="margin-top: 1rem;">
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<b-card style="height: 100%; color: #2c3e50; line-height: 1.7; " shadow="none" :body-style="{padding: '0rem 1.5rem'}"
|
||||
data-aos="fade-up" data-aos-duration="1000">
|
||||
<h4>微信群</h4>
|
||||
<div>
|
||||
<div style="margin-top: 10px;">
|
||||
<!-- <span>微信扫码</span> -->
|
||||
<p style="margin-top: 10px; margin-bottom: 0; text-align: center;">
|
||||
<!-- <img src="/images/dz.png" style="width: 150px;"></img> -->
|
||||
<img src="./JoinCKACommunity.jpeg" style="width: 150px; padding: 10px;"></img>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</b-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@ -532,6 +532,16 @@ module.exports = {
|
||||
]
|
||||
},
|
||||
],
|
||||
|
||||
'/t/': [
|
||||
{
|
||||
title: 'CKA每日一题',
|
||||
collapsable: false,
|
||||
children: [
|
||||
'cka/daily',
|
||||
]
|
||||
},
|
||||
],
|
||||
|
||||
'/support/': [
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="page-nav" style="max-width: 1000px; padding: 1rem; text-align: center;">
|
||||
<div v-if="$page.path.indexOf('/t/') !== 0" class="page-nav" style="max-width: 1000px; padding: 1rem; text-align: center;">
|
||||
<b-alert style="margin-bottom: 0;" show variant="primary">免费答疑</b-alert>
|
||||
|
||||
<div>
|
||||
|
||||
@ -38,8 +38,8 @@
|
||||
<JoinCommunity style="padding: 1rem 2.5rem;"></JoinCommunity>
|
||||
<PageEdit style="max-width: 1000px; padding: 1rem 2.5rem; margin-top: 2rem; background-color: #FFF;"/>
|
||||
<PageNav v-bind="{ sidebarItems }" style="max-width: 1000px; padding: 1rem 2.5rem;"/>
|
||||
<div class="page-nav" style="max-width: 1000px; padding-top:0; margin-top: 1rem;" v-show="!$frontmatter.lessAds && !$isSharing">
|
||||
<LazyLoad :noAdsOnSharing="true">
|
||||
<div class="page-nav" style="max-width: 1000px; padding-top:0; margin-top: 1rem;">
|
||||
<LazyLoad :noAdsOnSharing="false">
|
||||
<AdSensePageBottomInline/>
|
||||
</LazyLoad>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<aside class="sidebar">
|
||||
<LazyLoad :noAdsOnSharing="false">
|
||||
<AdSenseLeftTop/>
|
||||
</LazyLoad>
|
||||
<!-- <NavLinks/> -->
|
||||
<div style="text-align: center; margin-top: 10px;">
|
||||
<!-- <div class="side-nav-item" :style="activeLinkStyle('/overview/') + 'margin-left: 0;'">
|
||||
@ -15,7 +18,8 @@
|
||||
<a :href="`/guide/${urlSurfix}`" class="nav-link">使用</a>
|
||||
</div>
|
||||
<div class="side-nav-item" :style="activeLinkStyle('/training/')">
|
||||
<a :href="`https://kubetrain.cn/?from=kuboard`" class="nav-link" target="_blank">培训</a>
|
||||
<!-- <a :href="`https://kubetrain.cn/?from=kuboard`" class="nav-link" target="_blank">培训</a> -->
|
||||
<a href="/t/cka/daily.html" class="nav-link" target="_self">CKA</a>
|
||||
</div>
|
||||
<div class="side-nav-item" :style="activeLinkStyle('/support/')">
|
||||
<a :href="`/support/${urlSurfix}`" class="nav-link">支持</a>
|
||||
|
||||
@ -52,7 +52,7 @@ meta:
|
||||
* Docker 18.09.7
|
||||
|
||||
> 如果要安装 Kubernetes 历史版本,请参考:
|
||||
> * [安装 Kubernetes v1.16.1 单Master节点](/install/history-k8s/install-k8s-1.16.2.html)
|
||||
> * [安装 Kubernetes v1.16.2 单Master节点](/install/history-k8s/install-k8s-1.16.2.html)
|
||||
> * [安装 Kubernetes v1.16.1 单Master节点](/install/history-k8s/install-k8s-1.16.1.html)
|
||||
> * [安装 Kubernetes v1.16.0 单Master节点](/install/history-k8s/install-k8s-1.16.0.html)
|
||||
> * [安装 Kubernetes v1.15.4 单Master节点](/install/history-k8s/install-k8s-1.15.4.html)
|
||||
@ -341,6 +341,7 @@ kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt --discovery
|
||||
<b-card style="background-color: rgb(254, 240, 240); border: solid 1px #F56C6C;">
|
||||
|
||||
### 常见错误原因
|
||||
|
||||
经常在群里提问为什么 join 不成功的情况大致有这几种:
|
||||
|
||||
#### worker 节点不能访问 apiserver
|
||||
|
||||
|
After Width: | Height: | Size: 126 KiB |
@ -133,3 +133,23 @@ Linux Ethernet bridge 是一个虚拟的 Layer 2 网络设备,可用来连接
|
||||
<p style="max-width: 480px">
|
||||
<img src="./network.assets/pods-connected-by-bridge.png" alt="K8S教程_Kubernetes网络模型_network_bridge_网桥_虚拟网卡"/>
|
||||
</p>
|
||||
|
||||
### 数据包的传递:Pod-to-Pod,同节点
|
||||
|
||||
在 network namespace 将每一个 Pod 隔离到各自的网络堆栈的情况下,虚拟以太网设备(virtual Ethernet device)将每一个 namespace 连接到 root namespace,网桥将 namespace 又连接到一起,此时,Pod 可以向同一节点上的另一个 Pod 发送网络报文了。下图演示了同节点上,网络报文从一个Pod传递到另一个Pod的情况。
|
||||
|
||||
<p style="max-width: 600px">
|
||||
<img src="./network.assets/pod-to-pod-same-node.gif" alt="K8S教程_Kubernetes网络模型_同节点上Pod之间发送数据包"/>
|
||||
</p>
|
||||
|
||||
Pod1 发送一个数据包到其自己的默认以太网设备 `eth0`。
|
||||
1. 对 Pod1 来说,`eth0` 通过虚拟以太网设备(veth0)连接到 root namespace
|
||||
2. 网桥 `cbr0` 中为 `veth0` 配置了一个网段。一旦数据包到达网桥,网桥使用[ARP](https://en.wikipedia.org/wiki/Address_Resolution_Protocol) 协议解析出其正确的目标网段 `veth1`
|
||||
3. 网桥 `cbr0` 将数据包发送到 `veth1`
|
||||
4. 数据包到达 `veth1` 时,被直接转发到 Pod2 的 network namespace 中的 `eth0` 网络设备。
|
||||
|
||||
在整个数据包传递过程中,每一个 Pod 都只和 `localhost` 上的 `eth0` 通信,且数包被路由到正确的 Pod 上。与开发人员正常使用网络的习惯没有差异。
|
||||
|
||||
Kubernetes 的网络模型规定,在跨节点的情况下 Pod 也必须可以通过 IP 地址访问。也就是说,Pod 的 IP 地址必须始终对集群中其他 Pod 可见;且从 Pod 内部和从 Pod 外部来看,Pod 的IP地址都是相同的。接下来我们讨论跨节点情况下,网络数据包如何传递。
|
||||
|
||||
### 数据包的传递:Pod-to-Pod,跨节点
|
||||
|
||||
@ -195,7 +195,7 @@ Kuboard 认为,掌握这些概念并正确理解这些概念的关系之后,
|
||||
* 搭建和配置监控系统
|
||||
* 定位和诊断问题时,在不同监控系统中来回切换,进入监控系统并寻找对应微服务的监控结果
|
||||
|
||||
Kuboard 认为,应该以微服务视角的视角快速查看到该无服务在不同层面的监控结果。因此,在 Kuboard 的工作负载(微服务)查看界面中,可以直接点击进入不同监控系统对应的监控结果,无需再监控系统内反复查找。如一下截图所示:
|
||||
Kuboard 认为,应该以微服务视角快速查看到该微服务在不同层面的监控结果。因此,在 Kuboard 的工作负载(微服务)查看界面中,可以直接点击进入不同监控系统对应的监控结果,无需再监控系统内反复查找。如一下截图所示:
|
||||
|
||||

|
||||
|
||||
|
||||
BIN
t/cka/daily.assets/640.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
46
t/cka/daily.md
Normal file
@ -0,0 +1,46 @@
|
||||
---
|
||||
vssueId: 162
|
||||
# layout: StepLayout
|
||||
sharingTitle: CKA备考每日一题
|
||||
description: CKA备考每日一题
|
||||
meta:
|
||||
- name: keywords
|
||||
content: Kubernetes,K8S,CKA,Certified Kubernetes Administrator
|
||||
---
|
||||
|
||||
# CKA考试备战--每日一题
|
||||
|
||||
<AdSenseTitle/>
|
||||
|
||||
> CKA 考试每日一题系列,全部内容由 [我的小碗汤](https://mp.weixin.qq.com/s/5tYgb_eSzHz_TMsi0U32gw) 创作,本站仅做转载
|
||||
|
||||
这两年 Kubernetes 已经成为容器编排的事实标准,预计未来两年内将全面普及,现在企业招这块人才需求也越来越大,工资也是很高的,未来这块的发展空间也很大。
|
||||
|
||||
最近正准备备考CKA,CKA是什么?有些人可能还不知道,这里简单普及一下:
|
||||
|
||||
CKA 证书是云原生计算基金会 CNCF 组织的,考察的是你是否具备足够管理 Kubernetes 集群的必备知识。考试形式是上机直接在集群上操作,限时 3 小时,非常考验个人知识的扎实程度和 Kubernetes 实践经验。考上 75 分,你就能拿到证书。考试期间只可查阅K8S官方手册。证书有效期两年,考试费用300美元(国外考试费用就是贵),一年内可有一次免费补考的机会。
|
||||
|
||||
CKA证书的含金量如何?考不考这个证完全取决于个人,因为持证并不等于上岗,尤其是上心仪公司的岗。考证可以帮你获得初级职位,但高级职位需要个人经验的大量积累。而站在面试官的角度看,有这个证至少可以为你搏一个面试机会,尤其是应届生和有转岗想法的程序员。这些人可能缺乏足够经验,但 CKA 证很能体现个人技术水平,行业认可程度也很高。
|
||||
|
||||
|
||||
|
||||
**考纲如下:**
|
||||
|
||||
<p style="max-width: 600px">
|
||||
<img src="./daily.assets/640.png" alt="CKA考纲">
|
||||
</p>
|
||||
|
||||
|
||||
可访问 [https://github.com/cncf/curriculum](https://github.com/cncf/curriculum) 关注最新的考纲变化!
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
|
||||
作为在Kubernetes技术上摸爬滚打1年多的老鸟,最近正准备备考CKA,鉴于此,我希望想证明自己kubernetes开发运维能力的小伙伴能一起从今天开始,我们一起每日一题,在留言区答题打卡,我会在其中选出3位认真并坚持打卡21天的小伙伴送出3本书。
|
||||
|
||||
[CKA每日一题 - Day 1](./daily/001.html)
|
||||
[CKA每日一题 - Day 2](./daily/002.html)
|
||||
|
||||
<JoinCKACommunity/>
|
||||
BIN
t/cka/daily/001.assets/640.jpeg
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
t/cka/daily/001.assets/image-20191120225243614.png
Normal file
|
After Width: | Height: | Size: 215 KiB |
167
t/cka/daily/001.md
Normal file
@ -0,0 +1,167 @@
|
||||
---
|
||||
vssueId: 163
|
||||
# layout: StepLayout
|
||||
sharingTitle: CKA备考每日一题 - Day 1
|
||||
description: CKA备考每日一题 - Day 1
|
||||
meta:
|
||||
- name: keywords
|
||||
content: Kubernetes,K8S,CKA,Certified Kubernetes Administrator
|
||||
---
|
||||
|
||||
# CKA每日一题 --- Day 1
|
||||
|
||||
<AdSenseTitle/>
|
||||
|
||||
**今日考题**
|
||||
|
||||
以下 Daemonset yaml 中,哪些是正确的?(多选)
|
||||
|
||||
A.
|
||||
|
||||
``` yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: fluentd-elasticsearch
|
||||
namespace: default
|
||||
labels: k8s-app: fluentd-logging
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
name: fluentd-elasticsearch
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: fluentd-elasticsearch
|
||||
spec:
|
||||
containers:
|
||||
- name: fluentd-elasticsearch
|
||||
image: gcr.io/fluentd-elasticsearch/fluentd:v2.5.1
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
|
||||
|
||||
B.
|
||||
|
||||
``` yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: fluentd-elasticsearch
|
||||
namespace: default
|
||||
labels:
|
||||
k8s-app: fluentd-logging
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
name: fluentd-elasticsearch
|
||||
template:
|
||||
metadata:
|
||||
labels: name: fluentd-elasticsearch
|
||||
spec:
|
||||
containers:
|
||||
- name: fluentd-elasticsearch
|
||||
image: gcr.io/fluentd-elasticsearch/fluentd:v2.5.1
|
||||
restartPolicy: Onfailure
|
||||
```
|
||||
|
||||
|
||||
|
||||
C.
|
||||
|
||||
``` yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: fluentd-elasticsearch
|
||||
namespace: default
|
||||
labels:
|
||||
k8s-app: fluentd-logging
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
name: fluentd-elasticsearch
|
||||
template:
|
||||
metadata:
|
||||
labels: name: fluentd-elasticsearch
|
||||
spec:
|
||||
containers:
|
||||
- name: fluentd-elasticsearch
|
||||
image: gcr.io/fluentd-elasticsearch/fluentd:v2.5.1
|
||||
restartPolicy: Always
|
||||
```
|
||||
|
||||
|
||||
|
||||
D.
|
||||
``` yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: fluentd-elasticsearch
|
||||
namespace: default
|
||||
labels:
|
||||
k8s-app: fluentd-logging
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
name: fluentd-elasticsearch
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: fluentd-elasticsearch
|
||||
spec:
|
||||
containers:
|
||||
- name: fluentd-elasticsearch
|
||||
image: gcr.io/fluentd-elasticsearch/fluentd:v2.5.1
|
||||
```
|
||||
|
||||
|
||||
<b-button v-b-toggle.collapse-join-error variant="danger" size="sm" style="margin-top: 1rem;" v-on:click="$sendGaEvent('cka-daily', 'cka-daily', 'CKA每日一题001')">答案及解析</b-button>
|
||||
<b-collapse id="collapse-join-error" class="mt-2">
|
||||
<b-card style="background-color: rgb(254, 240, 240); border: solid 1px #F56C6C;">
|
||||
|
||||
**答案: C、D**
|
||||
|
||||
|
||||
在考试时,只允许有考试网站和k8s官网两个标签页。所以平常学习时,尽可能去找官网文档去学习,官网才是最权威的。熟悉 [https://kubernetes.io/concepts/](https://kubernetes.io/concepts/) 目录下的内容对考试通过非常有帮助。
|
||||
|
||||
[https://kuboard.cn/learning/](https://kuboard.cn/learning/) 目录下提供了 [https://kubernetes.io/concepts/](https://kubernetes.io/concepts/) 目录下的中文翻译,可以对照着学习。
|
||||
|
||||
以这个问题为例,直接打开daemonset的官网说明文档,见以下链接:
|
||||
|
||||
[https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/)
|
||||
|
||||

|
||||
|
||||
> A Pod Template in a DaemonSet must have a RestartPolicy equal to Always, or be unspecified, which defaults to Always. Daemonset里的pod Template下必须有RestartPolicy,如果没指定,会默认为Always
|
||||
|
||||
在 [https://kuboard.cn](https://kuboard.cn) 上也可以找到对应的中文内容:
|
||||
|
||||
[https://kuboard.cn/learning/k8s-intermediate/workload/wl-daemonset/create.html](https://kuboard.cn/learning/k8s-intermediate/workload/wl-daemonset/create.html)
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
restartPolicy 字段,可选值为 Always、OnFailure 和 Never。默认为 Always。一个Pod中可以有多个容器,restartPolicy适用于Pod 中的所有容器。restartPolicy作用是,让kubelet重启失败的容器。
|
||||
|
||||
另外Deployment、Statefulset的restartPolicy也必须为Always,保证pod异常退出,或者健康检查 livenessProbe失败后由kubelet重启容器。[https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment](https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment) 或者 [https://kuboard.cn/learning/k8s-intermediate/workload/wl-deployment](https://kuboard.cn/learning/k8s-intermediate/workload/wl-deployment)
|
||||
|
||||
Job和CronJob是运行一次的pod,restartPolicy只能为OnFailure或Never,确保容器执行完成后不再重启。[https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/) 或者 [https://kuboard.cn/learning/k8s-intermediate/workload/wl-job/](https://kuboard.cn/learning/k8s-intermediate/workload/wl-job/)
|
||||
|
||||
> 实际考试以上机实操为主
|
||||
|
||||
</b-card>
|
||||
</b-collapse>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
> CKA 考试每日一题系列,全部内容由 [我的小碗汤](https://mp.weixin.qq.com/s/5tYgb_eSzHz_TMsi0U32gw) 创作,本站仅做转载
|
||||
|
||||
|
||||
<JoinCKACommunity/>
|
||||
BIN
t/cka/daily/002.assets/640.jpeg
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
t/cka/daily/002.assets/640.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
72
t/cka/daily/002.md
Normal file
@ -0,0 +1,72 @@
|
||||
---
|
||||
vssueId: 166
|
||||
# layout: StepLayout
|
||||
sharingTitle: CKA备考打卡 - 每日一题 - Day 2
|
||||
description: CKA备考打卡 - 每日一题 - Day 2
|
||||
meta:
|
||||
- name: keywords
|
||||
content: Kubernetes,K8S,CKA,Certified Kubernetes Administrator
|
||||
---
|
||||
|
||||
# CKA每日一题 --- Day 2
|
||||
|
||||
<AdSenseTitle/>
|
||||
|
||||
|
||||
|
||||
**今日考题**
|
||||
|
||||
在Kubernetes PVC+PV 体系下通过 CSI 实现的 volume plugins 动态创建 pv 到 pv 可被 pod 使用有哪些组件需要参与?
|
||||
|
||||
A. PersistentVolumeController + CSI-Provisoner + CSI controller plugin
|
||||
|
||||
B. AttachDetachController + CSI-Attacher + CSI controller plugin
|
||||
|
||||
C. Kubelet + CSI node plugin
|
||||
|
||||
<b-button v-b-toggle.collapse-join-error variant="danger" size="sm" style="margin-top: 1rem;" v-on:click="$sendGaEvent('cka-daily', 'cka-daily', 'CKA每日一题001')">答案及解析</b-button>
|
||||
<b-collapse id="collapse-join-error" class="mt-2">
|
||||
<b-card style="background-color: rgb(254, 240, 240); border: solid 1px #F56C6C;">
|
||||
|
||||
**答案: A、B、C**
|
||||
|
||||
|
||||
|
||||
k8s中,利用PVC 描述Pod 所希望使用的持久化存储的大小,可读写权限等,一般由开发人员去创建;利用PV描述具体存储类型,存储地址,挂载目录等,一般由运维人员去提前创建。而不是直接在pod里写上volume的信息。一来可以使得开发运维职责分明,二来利用PVC、PV机制,可以很好扩展支持市面上不同的存储实现,如k8s v1.10版本对Local Persistent Volume的支持。
|
||||
|
||||
**我们试着理一下Pod创建到volume可用的整体流程。**
|
||||
|
||||
用户提交请求创建pod,PersistentVolumeController发现这个pod声明使用了PVC,那就会帮它找一个PV配对。
|
||||
|
||||
没有现成的PV,就去找对应的StorageClass,帮它新创建一个PV,然后和PVC完成绑定。
|
||||
|
||||
新创建的PV,还只是一个API 对象,需要经过“**两阶段处理**”,才能变成宿主机上的“持久化 Volume”真正被使用:
|
||||
|
||||
**第一阶段**由运行在master上的AttachDetachController负责,为这个PV完成 Attach 操作,为宿主机挂载远程磁盘;
|
||||
|
||||
**第二阶段**是运行在每个节点上kubelet组件的内部,把第一步attach的远程磁盘 mount 到宿主机目录。这个控制循环叫VolumeManagerReconciler,运行在独立的Goroutine,不会阻塞kubelet主控制循环。
|
||||
|
||||
完成这两步,PV对应的“持久化 Volume”就准备好了,POD可以正常启动,将“持久化 Volume”挂载在容器内指定的路径。
|
||||
|
||||
k8s支持编写自己的存储插件FlexVolume 与 CSI。不管哪种方式,都需要经过“两阶段处理”,FlexVolume相比CSI局限性大,一般我们采用CSI方式对接存储。
|
||||
|
||||
CSI 插件体系的设计思想把这个Provision阶段(动态创建PV),以及 Kubernetes 里的一部分存储管理功能,从主干代码里剥离出来,做成了几个单独的组件。这些组件会通过 Watch API 监听 Kubernetes 里与存储相关的事件变化,比如 PVC 的创建,来执行具体的存储管理动作。
|
||||

|
||||
上图中CSI这套存储插件体系中三个独立的外部组件(External Components),即:Driver Registrar、External Provisioner 和 External Attacher,对应的是从 Kubernetes 项目里面剥离出来的部分存储管理功能。
|
||||
|
||||
我们需要实现Custom Components这一个二进制,会以gRpc方式提供三个服务:CSI Identity、CSI Controller、CSI Node。
|
||||
|
||||
Driver Registrar 组件,负责将插件注册到 kubelet 里面;Driver Registrar调用CSI Identity 服务来获取插件信息;External Provisioner 组件监听APIServer 里的 PVC 对象。当一个 PVC 被创建时,它就会调用 CSI Controller 的 CreateVolume 方法,创建对应 PV;
|
||||
|
||||
External Attacher 组件负责Attach阶段。Mount阶段由kubelet里的VolumeManagerReconciler控制循环直接调用CSI Node服务完成。
|
||||
|
||||
两阶段完成后,kubelet将mount参数传递给docker,创建、启动容器。
|
||||
|
||||
**整体流程如下图:**
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
</b-card>
|
||||
</b-collapse>
|
||||