上传文件至 'kubernetes-MD'
This commit is contained in:
parent
9c359fbf0d
commit
976657f003
|
@ -0,0 +1,204 @@
|
|||
<h1><center>Kubernetes健康检查机制</center></h1>
|
||||
|
||||
著作:行癫 <盗版必究>
|
||||
|
||||
------
|
||||
|
||||
## 一:检查恢复机制
|
||||
|
||||
#### 1.容器健康检查和恢复机制
|
||||
|
||||
在 k8s 中,可以为 Pod 里的容器定义一个健康检查"探针"。kubelet 就会根据这个 Probe 的返回值决定这个容器的状态,而不是直接以容器是否运行作为依据。这种机制,是生产环境中保证应用健康存活的重要手段。
|
||||
|
||||
#### 2.命令模式探针
|
||||
|
||||
```shell
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
test: liveness
|
||||
name: test-liveness-exec
|
||||
spec:
|
||||
containers:
|
||||
- name: liveness
|
||||
image: daocloud.io/library/nginx
|
||||
args:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- cat
|
||||
- /tmp/healthy
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
```
|
||||
|
||||
它在启动之后做的第一件事是在 /tmp 目录下创建了一个 healthy 文件,以此作为自己已经正常运行的标志。而 30 s 过后,它会把这个文件删除掉
|
||||
|
||||
与此同时,定义了一个这样的 livenessProbe(健康检查)。它的类型是 exec,它会在容器启动后,在容器里面执行一句我们指定的命令,比如:"cat /tmp/healthy"。这时,如果这个文件存在,这条命令的返回值就是 0,Pod 就会认为这个容器不仅已经启动,而且是健康的。这个健康检查,在容器启动 5 s 后开始执行(initialDelaySeconds: 5),每 5 s 执行一次(periodSeconds: 5)
|
||||
|
||||
创建Pod:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl create -f test-liveness-exec.yaml
|
||||
```
|
||||
|
||||
查看 Pod 的状态:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl get pod
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
test-liveness-exec 1/1 Running 0 10s
|
||||
```
|
||||
|
||||
由于已经通过了健康检查,这个 Pod 就进入了 Running 状态
|
||||
|
||||
30 s 之后,再查看一下 Pod 的 Events:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl describe pod test-liveness-exec
|
||||
```
|
||||
|
||||
发现,这个 Pod 在 Events 报告了一个异常:
|
||||
|
||||
```shell
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
|
||||
```
|
||||
|
||||
显然,这个健康检查探查到 /tmp/healthy 已经不存在了,所以它报告容器是不健康的。那么接下来会发生什么呢?
|
||||
|
||||
再次查看一下这个 Pod 的状态:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl get pod test-liveness-exec
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
liveness-exec 1/1 Running 1 1m
|
||||
```
|
||||
|
||||
这时发现,Pod 并没有进入 Failed 状态,而是保持了 Running 状态。这是为什么呢?
|
||||
|
||||
RESTARTS 字段从 0 到 1 的变化,就明白原因了:这个异常的容器已经被 Kubernetes 重启了。在这个过程中,Pod 保持 Running 状态不变
|
||||
|
||||
注意:
|
||||
|
||||
Kubernetes 中并没有 Docker 的 Stop 语义。所以虽然是 Restart(重启),但实际却是重新创建了容器
|
||||
|
||||
这个功能就是 Kubernetes 里的Pod 恢复机制,也叫 restartPolicy。它是 Pod 的 Spec 部分的一个标准字段(pod.spec.restartPolicy),默认值是 Always,即:任何时候这个容器发生了异常,它一定会被重新创建
|
||||
|
||||
小提示:
|
||||
|
||||
Pod 的恢复过程,永远都是发生在当前节点上,而不会跑到别的节点上去。事实上,一旦一个 Pod 与一个节点(Node)绑定,除非这个绑定发生了变化(pod.spec.node 字段被修改),否则它永远都不会离开这个节点。这也就意味着,如果这个宿主机宕机了,这个 Pod 也不会主动迁移到其他节点上去。
|
||||
|
||||
而如果你想让 Pod 出现在其他的可用节点上,就必须使用 Deployment 这样的"控制器"来管理 Pod,哪怕你只需要一个 Pod 副本。这就是一个单 Pod 的 Deployment 与一个 Pod 最主要的区别。
|
||||
|
||||
#### 3.http get方式探针
|
||||
|
||||
```shell
|
||||
[root@master diandian]# vim liveness-httpget.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: liveness-httpget-pod
|
||||
namespace: default
|
||||
spec:
|
||||
containers:
|
||||
- name: liveness-exec-container
|
||||
image: daocloud.io/library/nginx
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
port: http
|
||||
path: /index.html
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 3
|
||||
```
|
||||
|
||||
创建该pod:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl create -f liveness-httpget.yaml
|
||||
pod/liveness-httpget-pod created
|
||||
```
|
||||
|
||||
查看当前pod的状态:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl describe pod liveness-httpget-pod
|
||||
...
|
||||
Liveness: http-get http://:http/index.html delay=1s timeout=1s period=3s #success=1 #failure=3
|
||||
...
|
||||
```
|
||||
|
||||
测试将容器内的index.html删除掉:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl exec liveness-httpget-pod -c liveness-exec-container -it -- /bin/sh
|
||||
/ # ls
|
||||
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
|
||||
/ # mv /usr/share/nginx/html/index.html index.html
|
||||
/ # command terminated with exit code 137
|
||||
```
|
||||
|
||||
可以看到,当把index.html移走后,这个容器立马就退出了
|
||||
|
||||
查看pod的信息:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl describe pod liveness-httpget-pod
|
||||
...
|
||||
Normal Killing 1m kubelet, node02 Killing container with id docker://liveness-exec-container:Container failed liveness probe.. Container will be killed and recreated.
|
||||
...
|
||||
```
|
||||
|
||||
看输出,容器由于健康检查未通过,pod会被杀掉,并重新创建:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
liveness-httpget-pod 1/1 Running 1 33m
|
||||
restarts 为 1
|
||||
```
|
||||
|
||||
重新登陆容器查看:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl exec liveness-httpget-pod -c liveness-exec-container -it -- /bin/sh
|
||||
/ # cat /usr/share/nginx/html/index.html
|
||||
```
|
||||
|
||||
新登陆容器,发现index.html又出现了,证明容器是被重拉了
|
||||
|
||||
#### 4.Pod 的恢复策略
|
||||
|
||||
可以通过设置 restartPolicy,改变 Pod 的恢复策略。一共有3种:
|
||||
|
||||
Always:在任何情况下,只要容器不在运行状态,就自动重启容器
|
||||
|
||||
OnFailure:只在容器异常时才自动重启容器
|
||||
|
||||
Never: 从来不重启容器
|
||||
|
||||
注意:
|
||||
|
||||
官方文档把 restartPolicy 和 Pod 里容器的状态,以及 Pod 状态的对应关系,总结了非常复杂的一大堆情况。实际上,你根本不需要死记硬背这些对应关系,只要记住如下两个基本的设计原理即可:
|
||||
|
||||
只要 Pod 的 restartPolicy 指定的策略允许重启异常的容器(比如:Always),那么这个 Pod 就会保持 Running 状态,并进行容器重启。否则,Pod 就会进入 Failed 状态
|
||||
|
||||
对于包含多个容器的 Pod,只有它里面所有的容器都进入异常状态后,Pod 才会进入 Failed 状态。在此之前,Pod 都是 Running 状态。此时,Pod 的 READY 字段会显示正常容器的个数
|
||||
|
||||
例如:
|
||||
|
||||
```shell
|
||||
[root@master diandian]# kubectl get pod test-liveness-exec
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
liveness-exec 0/1 Running 1 1m
|
||||
```
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<h1><center>Kubernetes基础架构</center></h1>
|
||||
|
||||
著作:行癫 <盗版必究>
|
||||
|
||||
------
|
||||
|
||||
<h2>一:Kubernetes简介</h2>
|
||||
|
||||
<h3>1.简介</h3>
|
||||
|
||||
Kubernetes是谷歌严格保密十几年的秘密武器Borg的一个开源版本,是容器分布式系统解决方案;是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化;拥有一个庞大且快速增长的生态系统。
|
||||
|
||||
<h3>2.Kubernetes能做什么</h3>
|
||||
|
||||
使用现代的Web服务,用户希望应用程序可以24/7全天候可用,而开发人员则希望每天多次部署这些应用程序的新版本;容器化有助于打包软件来实现这些目标,从而使应用程序可以轻松快速地发布和更新,而无需停机;可帮助您确保那些容器化的应用程序在所需的位置和时间运行,并帮助他们找到工作所需的资源和工具。
|
||||
|
||||
<h3>3.kubernetes组件</h3>
|
||||
|
||||
kube-apiserver: 负责 API 服务
|
||||
|
||||
kube-scheduler: 负责调度
|
||||
|
||||
kube-controller-manager: 负责容器编排
|
||||
|
||||
kubelet:它与Kubernetes Master进行通信
|
||||
|
||||
kube-proxy:一个网络代理,可反映每个节点上的Kubernetes网络服务
|
||||
|
||||
<h3>5.Kubernetes 的顶层设计</h3>
|
||||
|
||||
<center><img src="kubernetes%E5%9F%BA%E7%A1%80%E6%9E%B6%E6%9E%84.assets/nDWtBAVlo7IxRXbecbQ4QA.png" alt="img" style="zoom:50%;" /></center>
|
||||
|
||||
<h3>6. 为什么 Kubernetes 如此有用</h3>
|
||||
|
||||
**传统部署时代:**
|
||||
|
||||
早期,组织在物理服务器上运行应用程序;无法为物理服务器中的应用程序定义资源边界,这会导致资源分配问题;例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况,结果可能导致其他应用程序的性能下降。一种解决方案是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展,并且组织维护许多物理服务器的成本很高。
|
||||
|
||||
**虚拟化部署时代:**
|
||||
|
||||
作为解决方案,引入了虚拟化功能,它允许您在单个物理服务器的 CPU 上运行多个虚拟机(VM)。虚拟化功能允许应用程序在 VM 之间隔离,并提供安全级别,因为一个应用程序的信息不能被另一应用程序自由地访问。 因为虚拟化可以轻松地添加或更新应用程序、降低硬件成本等等,所以虚拟化可以更好地利用物理服务器中的资源,并可以实现更好的可伸缩性。 每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。
|
||||
|
||||
**容器部署时代:**
|
||||
|
||||
容器类似于 VM,但是它们具有轻量级的隔离属性,可以在应用程序之间共享操作系统(OS)。因此,容器被认为是轻量级的。容器与 VM 类似,具有自己的文件系统、CPU、内存、进程空间等。由于它们与基础架构分离,因此可以跨云和 OS 分发进行移植。
|
||||
|
||||
容器是打包和运行应用程序的好方式。在生产环境中,您需要管理运行应用程序的容器,并确保不会停机。例如,如果一个容器发生故障,则需要启动另一个容器。
|
||||
|
||||
Kubernetes 为您提供了一个可弹性运行分布式系统的框架。Kubernetes 会满足您的扩展要求、故障转移、部署模式等。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<h1><center>kubernetes工作负载资源Job</center></h1>
|
||||
|
||||
著作:行癫 <盗版必究>
|
||||
|
||||
------
|
||||
|
||||
## 一:Job
|
||||
|
||||
Job 会创建一个或者多个 Pods,并将继续重试 Pods 的执行,直到指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。
|
||||
|
||||
#### 1.创建Job
|
||||
|
||||
```shell
|
||||
[root@master xingdian]# cat Jobs.yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
backoffLimit: 4
|
||||
```
|
||||
|
||||
#### 2.运行
|
||||
|
||||
```shell
|
||||
[root@master xingdian]# kubectl create -f Jobs.yaml
|
||||
```
|
||||
|
||||
#### 3.查看运行结果
|
||||
|
||||
```shell
|
||||
[root@master xingdian]# kubectl get job
|
||||
NAME COMPLETIONS DURATION AGE
|
||||
pi 1/1 7m37s 145m
|
||||
```
|
||||
|
||||
#### 4.查看详细信息
|
||||
|
||||
```shell
|
||||
[root@master xingdian]# kubectl describe jobs/pi
|
||||
Name: pi
|
||||
Namespace: default
|
||||
Selector: controller-uid=98846cab-bb0c-430d-b577-519602c5636d
|
||||
Labels: controller-uid=98846cab-bb0c-430d-b577-519602c5636d
|
||||
job-name=pi
|
||||
Annotations: batch.kubernetes.io/job-tracking:
|
||||
Parallelism: 1
|
||||
Completions: 1
|
||||
Completion Mode: NonIndexed
|
||||
Start Time: Mon, 02 May 2022 20:47:48 +0800
|
||||
Completed At: Mon, 02 May 2022 20:55:25 +0800
|
||||
Duration: 7m37s
|
||||
Pods Statuses: 0 Active / 1 Succeeded / 0 Failed
|
||||
Pod Template:
|
||||
Labels: controller-uid=98846cab-bb0c-430d-b577-519602c5636d
|
||||
job-name=pi
|
||||
Containers:
|
||||
pi:
|
||||
Image: perl
|
||||
Port: <none>
|
||||
Host Port: <none>
|
||||
Command:
|
||||
perl
|
||||
-Mbignum=bpi
|
||||
-wle
|
||||
print bpi(2000)
|
||||
Environment: <none>
|
||||
Mounts: <none>
|
||||
Volumes: <none>
|
||||
Events: <none>
|
||||
```
|
||||
|
||||
#### 5.编写 Job 规约
|
||||
|
||||
与 Kubernetes 中其他资源的配置类似,Job 也需要 `apiVersion`、`kind` 和 `metadata` 字段
|
||||
|
||||
Job 的名字必须是合法的DNS 子域名
|
||||
|
||||
Job 配置还需要一个`.spec` 节
|
||||
|
||||
#### 6.Pod 模版
|
||||
|
||||
Job 的 `.spec` 中只有 `.spec.template` 是必需的字段
|
||||
|
||||
字段 `.spec.template` 的值是一个Pod 模版。 其规范与Pod完全相同,只是其中不再需要 `apiVersion` 或 `kind` 字段
|
||||
|
||||
Job 中的 Pod 模版必需设置合适的标签和合适的重启策略
|
||||
|
||||
Job 中 Pod 的`RestartPolicy`只能设置为 `Never` 或 `OnFailure` 之一
|
|
@ -0,0 +1,222 @@
|
|||
<h1><center>kubernetes工作负载资源StatefulSet</center></h1>
|
||||
|
||||
著作:行癫 <盗版必究>
|
||||
|
||||
------
|
||||
|
||||
## 一:StatefulSet
|
||||
|
||||
StatefulSet 是用来管理有状态应用的工作负载 API 对象;StatefulSet 用来管理某 [Pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/) 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符;和 [Deployment](https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/) 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
|
||||
|
||||
使用存储卷为工作负载提供持久存储,可以使用 StatefulSet 作为解决方案的一部分。 尽管 StatefulSet 中的单个 Pod 仍可能出现故障, 但持久的 Pod 标识符使得将现有卷与替换已失败 Pod 的新 Pod 相匹配变得更加容易。
|
||||
|
||||
#### 1.特点
|
||||
|
||||
StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:
|
||||
|
||||
稳定的、唯一的网络标识符
|
||||
|
||||
稳定的、持久的存储
|
||||
|
||||
有序的、优雅的部署和缩放
|
||||
|
||||
有序的、自动的滚动更新
|
||||
|
||||
稳定的意味着 Pod 调度或重调度的整个过程是有持久性的。 如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用 由一组无状态的副本控制器提供的工作负载来部署应用程序,比如Deployment或者ReplicaSet 可能更适用于你的无状态应用部署需要。
|
||||
|
||||
#### 2.限制
|
||||
|
||||
给定 Pod 的存储必须由 [PersistentVolume 驱动](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/README.md) 基于所请求的 `storage class` 来提供,或者由管理员预先提供
|
||||
|
||||
删除或者收缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全
|
||||
|
||||
StatefulSet 当前需要无头服务来负责 Pod 的网络标识。你需要负责创建此服务
|
||||
|
||||
当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证
|
||||
|
||||
为了实现 StatefulSet 中的 Pod 可以有序地且体面地终止,可以在删除之前将 StatefulSet 缩放为 0
|
||||
|
||||
注意:
|
||||
|
||||
无头服务(Headless Services):
|
||||
|
||||
有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(`spec.clusterIP`)的值为 `"None"` 来创建 `Headless` Service。
|
||||
|
||||
使用无头 Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起
|
||||
|
||||
无头 Service 并不会分配 Cluster IP,kube-proxy 不会处理它们, 而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了选择算符。
|
||||
|
||||
#### 3.创建StatefulSet
|
||||
|
||||
```shell
|
||||
[root@master xingdian]# cat Statefulset.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
name: web
|
||||
targetPort: 80
|
||||
nodePort: 30010
|
||||
selector:
|
||||
app: nginx
|
||||
---
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: xingdian
|
||||
provisioner: example.com/external-nfs
|
||||
parameters:
|
||||
server: 10.0.0.230
|
||||
path: /kubernetes-1
|
||||
readOnly: "false"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: xingdian-1
|
||||
spec:
|
||||
capacity:
|
||||
storage: 1Gi
|
||||
volumeMode: Filesystem
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: xingdian
|
||||
nfs:
|
||||
path: /kubernetes-1
|
||||
server: 10.0.0.230
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: xingdian-2
|
||||
spec:
|
||||
capacity:
|
||||
storage: 1Gi
|
||||
volumeMode: Filesystem
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: xingdian
|
||||
nfs:
|
||||
path: /kubernetes-1
|
||||
server: 10.0.0.230
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: web
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
serviceName: "nginx"
|
||||
replicas: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 10
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.20.1
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
volumeMounts:
|
||||
- name: www
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: www
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
storageClassName: "xingdian"
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
名为 `nginx` 的 Headless Service 用来控制网络域名
|
||||
|
||||
名为 `web` 的 StatefulSet 有一个 Spec,它表明将在独立的2个 Pod 副本中启动 nginx 容器
|
||||
|
||||
`volumeClaimTemplates` 将通过 PersistentVolumes 驱动提供的 [PersistentVolumes](https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/) 来提供稳定的存储
|
||||
|
||||
#### 4.Pod 选择算符
|
||||
|
||||
你必须设置 StatefulSet 的 `.spec.selector` 字段,使之匹配其在 `.spec.template.metadata.labels` 中设置的标签。在 Kubernetes 1.8 版本之前, 被忽略 `.spec.selector` 字段会获得默认设置值。 在 1.8 和以后的版本中,未指定匹配的 Pod 选择器将在创建 StatefulSet 期间导致验证错误。
|
||||
|
||||
#### 5.Pod 标识
|
||||
|
||||
StatefulSet Pod 具有唯一的标识,该标识包括顺序标识、稳定的网络标识和稳定的存储。 该标识和 Pod 是绑定的,不管它被调度在哪个节点上。
|
||||
|
||||
#### 6.有序索引
|
||||
|
||||
对于具有 N 个副本的 StatefulSet,StatefulSet 中的每个 Pod 将被分配一个整数序号, 从 0 到 N-1,该序号在 StatefulSet 上是唯一的。
|
||||
|
||||
#### 7.稳定的网络 ID
|
||||
|
||||
StatefulSet 中的每个 Pod 根据 StatefulSet 的名称和 Pod 的序号派生出它的主机名。 组合主机名的格式为`$(StatefulSet 名称)-$(序号)`。 上例将会创建三个名称分别为 `web-0、web-1、web-2` 的 Pod。
|
||||
|
||||
StatefulSet 可以使用无头服务 控制它的 Pod 的网络域。管理域的这个服务的格式为: `$(服务名称).$(命名空间).svc.cluster.local`,其中 `cluster.local` 是集群域。 一旦每个 Pod 创建成功,就会得到一个匹配的 DNS 子域,格式为: `$(pod 名称).$(所属服务的 DNS 域名)`,其中所属服务由 StatefulSet 的 `serviceName` 域来设定。
|
||||
|
||||
取决于集群域内部 DNS 的配置,有可能无法查询一个刚刚启动的 Pod 的 DNS 命名。 当集群内其他客户端在 Pod 创建完成前发出 Pod 主机名查询时,就会发生这种情况。 负缓存 (在 DNS 中较为常见) 意味着之前失败的查询结果会被记录和重用至少若干秒钟, 即使 Pod 已经正常运行了也是如此。
|
||||
|
||||
如果需要在 Pod 被创建之后及时发现它们,有以下选项:
|
||||
|
||||
直接查询 Kubernetes API(比如,利用 watch 机制)而不是依赖于 DNS 查询
|
||||
|
||||
缩短 Kubernetes DNS 驱动的缓存时长(通常这意味着修改 CoreDNS 的 ConfigMap,目前缓存时长为 30 秒)
|
||||
|
||||
| 集群域名 | 服务(名字空间/名字) | StatefulSet(名字空间/名字) | StatefulSet 域名 | Pod DNS | Pod 主机名 |
|
||||
| ------------- | --------------------- | ---------------------------- | ------------------------------- | -------------------------------------------- | ------------ |
|
||||
| cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
|
||||
| cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
|
||||
| kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
|
||||
|
||||
#### 8.稳定的存储
|
||||
|
||||
对于 StatefulSet 中定义的每个 VolumeClaimTemplate,每个 Pod 接收到一个 PersistentVolumeClaim。在上面的 nginx 示例中,每个 Pod 将会得到基于 StorageClass `my-storage-class` 提供的 1 Gib 的 PersistentVolume。 如果没有声明 StorageClass,就会使用默认的 StorageClass。 当一个 Pod 被调度(重新调度)到节点上时,它的 `volumeMounts` 会挂载与其 PersistentVolumeClaims 相关联的 PersistentVolume。 请注意,当 Pod 或者 StatefulSet 被删除时,与 PersistentVolumeClaims 相关联的 PersistentVolume 并不会被删除。要删除它必须通过手动方式来完成。
|
||||
|
||||
#### 9.部署和扩缩保证
|
||||
|
||||
对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为 `0..N-1`
|
||||
|
||||
当删除 Pod 时,它们是逆序终止的,顺序为 `N-1..0`
|
||||
|
||||
在将缩放操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态
|
||||
|
||||
在 Pod 终止之前,所有的继任者必须完全关闭
|
||||
|
||||
注意:
|
||||
|
||||
StatefulSet 不应将 `pod.Spec.TerminationGracePeriodSeconds` 设置为 0。 这种做法是不安全的,要强烈阻止。
|
||||
|
||||
在上面的 nginx 示例被创建后,会按照 web-0、web-1 的顺序部署2个 Pod。 在 web-0 进入Running 和 Ready状态前不会部署 web-1。要等到 web-0 部署完成并进入 Running 和 Ready 状态后,才会部署 web-1。
|
||||
|
||||
如果用户想将示例中的 StatefulSet 收缩为 `replicas=1`,首先被终止的是 web-1。 在 web-1没有被完全停止和删除前,如果在此期间发生 web-0 运行失败, 那么就不会终止 web-1,必须等到 web-0 进入 Running 和 Ready 状态后才会终止 web-1。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<h1><center>Kubernetes集群Dashboard部署</center></h1>
|
||||
|
||||
著作:行癫 <盗版必究>
|
||||
|
||||
------
|
||||
|
||||
## 一:部署Dashboard
|
||||
|
||||
#### 1.kube-proxy 开启 ipvs
|
||||
|
||||
```shell
|
||||
[root@k8s-master ~]# kubectl get configmap kube-proxy -n kube-system -o yaml > kube-proxy-configmap.yaml
|
||||
[root@k8s-master ~]# sed -i 's/mode: ""/mode: "ipvs"/' kube-proxy-configmap.yaml
|
||||
[root@k8s-master ~]# kubectl apply -f kube-proxy-configmap.yaml
|
||||
[root@k8s-master ~]# rm -f kube-proxy-configmap.yaml
|
||||
[root@k8s-master ~]# kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
|
||||
```
|
||||
|
||||
#### 2.下载Dashboard安装脚本
|
||||
|
||||
```shell
|
||||
[root@master ~]# wget http://www.xingdiancloud.cn:92/index.php/s/yer7cWtxesEit2R/download/recommended.yaml
|
||||
```
|
||||
|
||||
#### 3.创建证书
|
||||
|
||||
```shell
|
||||
[root@k8s-master ~]# mkdir dashboard-certs
|
||||
[root@k8s-master ~]# cd dashboard-certs/
|
||||
#创建命名空间
|
||||
[root@k8s-master ~]# kubectl create namespace kubernetes-dashboard
|
||||
# 创建私钥key文件
|
||||
[root@k8s-master ~]# openssl genrsa -out dashboard.key 2048
|
||||
#证书请求
|
||||
[root@k8s-master ~]# openssl req -days 36000 -new -out dashboard.csr -key dashboard.key -subj '/CN=dashboard-cert'
|
||||
#自签证书
|
||||
[root@k8s-master ~]# openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt
|
||||
#创建kubernetes-dashboard-certs对象
|
||||
[root@k8s-master ~]# kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.key --from-file=dashboard.crt -n kubernetes-dashboard
|
||||
```
|
||||
|
||||
#### 4.创建管理员
|
||||
|
||||
```shell
|
||||
创建账户
|
||||
[root@k8s-master ~]# vim dashboard-admin.yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: dashboard-admin
|
||||
namespace: kubernetes-dashboard
|
||||
#保存退出后执行
|
||||
[root@k8s-master ~]# kubectl create -f dashboard-admin.yaml
|
||||
为用户分配权限
|
||||
[root@k8s-master ~]# vim dashboard-admin-bind-cluster-role.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: dashboard-admin-bind-cluster-role
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: dashboard-admin
|
||||
namespace: kubernetes-dashboard
|
||||
#保存退出后执行
|
||||
[root@k8s-master ~]# kubectl create -f dashboard-admin-bind-cluster-role.yaml
|
||||
```
|
||||
|
||||
#### 5.安装 Dashboard
|
||||
|
||||
```shell
|
||||
#安装
|
||||
[root@k8s-master ~]# kubectl create -f ~/recommended.yaml
|
||||
|
||||
#检查结果
|
||||
[root@k8s-master ~]# kubectl get pods -A -o wide
|
||||
|
||||
[root@k8s-master ~]# kubectl get service -n kubernetes-dashboard -o wide
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
|
||||
dashboard-metrics-scraper ClusterIP 10.1.186.219 <none> 8000/TCP 19m k8s-app=dashboard-metrics-scraper
|
||||
kubernetes-dashboard NodePort 10.1.60.1 <none> 443:30008/TCP 19m k8s-app=kubernetes-dashboard
|
||||
```
|
||||
|
||||
#### 6.查看并复制token
|
||||
|
||||
```shell
|
||||
[root@master ~]# kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep dashboard-admin | awk '{print $1}')
|
||||
Name: dashboard-admin-token-xlhzr
|
||||
Namespace: kubernetes-dashboard
|
||||
Labels: <none>
|
||||
Annotations: kubernetes.io/service-account.name: dashboard-admin
|
||||
kubernetes.io/service-account.uid: a38e8ce3-848e-4d94-abcf-4d824deeb697
|
||||
|
||||
Type: kubernetes.io/service-account-token
|
||||
|
||||
Data
|
||||
====
|
||||
ca.crt: 1099 bytes
|
||||
namespace: 20 bytes
|
||||
token: eyJhbGciOiJSUzI1NiIsImtpZCI6InFsRE1GQi1KQnZsZHpUOGZ4WGc1dlU1UHg3UGVrcC02TUNyYmZWcHhFZ3MifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4teGxoenIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYTM4ZThjZTMtODQ4ZS00ZDk0LWFiY2YtNGQ4MjRkZWViNjk3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZC1hZG1pbiJ9.anEX2MBlIo0lKQCGOsl3oZKBQkYujg6twLoO8hbWLAVp3xveAgpt6nW-_FrkG0yy9tIyXa6lpvu-c99ueB4KvKrIF0vJggWT3fU73u75iIwTbqDSghWy_BRFjt9NYuUFL4Mu-sPqra0ELgxYIGSEVuQwmZ8qOFjrQQQ2pKjxt8SsUHGLW-9FgmSgZTHPvZKFnU2V23BC2n_vowff63PF6kfnj1bNzV3Z1YCzgZOdy3jKM6sNKSI3dbcHiJpv5p7XF18qvuSZMJ9tMU4vSwzkQ_OLxsdNYwwD_YfRhua6f0kgWO23Z0lBTRLInejssdIQ31yewg9Eoqv4DhN1jZqhOw
|
||||
```
|
||||
|
||||
#### 7.浏览器访问
|
||||
|
||||
```shell
|
||||
https://10.0.0.220:30008
|
||||
```
|
||||
|
||||
![image-20220426233444135](kubernetes%E9%9B%86%E7%BE%A4Dashboard%E9%83%A8%E7%BD%B2.assets/image-20220426233444135.png)
|
||||
|
||||
![image-20220426233537356](kubernetes%E9%9B%86%E7%BE%A4Dashboard%E9%83%A8%E7%BD%B2.assets/image-20220426233537356.png)
|
||||
|
Loading…
Reference in New Issue