上传文件至 kubernetes-MD

This commit is contained in:
tu 2024-06-07 15:27:34 +08:00
parent 5b33e0b19f
commit ea55a72c6d
5 changed files with 1093 additions and 0 deletions

View File

@ -0,0 +1,307 @@
<h1><center>Kubernetes资源对象Pod</center></h1>
著作:行癫 <盗版必究>
------
## 一Pod基本概念
#### 1.认识pod
Pod直译是豆荚可以把容器想像成豆荚里的豆子把一个或多个关系紧密的豆子包在一起就是豆荚一个Pod。在Kubernetes中我们不会直接操作容器而是把容器包装成Pod再进行管理Pod是Kubernetes进行创建、调度和管理的最小单位Pod运行于Node节点上 若干相关容器的组合Pod内包含的容器运行在同一宿主机上使用相同的网络命名空间、IP地址和端口能够通过localhost进行通信Pod可以指定一组共享存储。Volumes Pod中。Pod中的所有容器都可以访问共享卷从而使这些容器可以共享数据Pod 就是 k8s 世界里的"应用";而一个应用,可以由多个容器组成。
![img](https://docimg10.docs.qq.com/image/v42rJlcMcT5SyfEdxFC-pQ?w=499&h=428)
![img](Kubernetes%E8%B5%84%E6%BA%90%E5%AF%B9%E8%B1%A1Pod.assets/NYEY9Y5PKwaGws3MLskAkQ.png)
**注意:**
重启 Pod 中的容器不应与重启 Pod 混淆。Pod 本身不运行而是作为容器运行的环境并且一直保持到被删除为止Pod本身无法自我修复。如果将Pod调度到发生故障的节点或者调度操作本身失败则将Pod删除同样由于缺乏资源或Node维护Pod无法幸免。Kubernetes使用称为Controller的更高级别的抽象来处理管理相对易用的Pod实例的工作。因此虽然可以直接使用Pod但在Kubernetes中使用Controller管理Pod更为常见。
#### 2.pause容器
作用负责同一个pod的容器通信
每个Pod中都有一个pause容器pause容器做为Pod的网络接入点Pod中其他的容器会使用容器映射模式启动并接入到这个pause容器属于同一个Pod的所有容器共享网络的namespace一个Pod里的容器与另外主机上的Pod容器能够直接通信。
#### 3.Pods and Controllers
Controller可以为您创建和管理多个Pod以处理复制和推出并在集群范围内提供自我修复功能。例如如果某个节点发生故障则控制器会将这个Node上的所有Pod重新调度到其他节点上。
#### 4.Pod 模板
Pod 模板是包含在其他对象中的 Pod 规范,例如 Replication Controllers、 Jobs、和 DaemonSets。 控制器使用 Pod 模板来制作实际使用的 Pod。 下面的示例是一个简单的 Pod 清单,它包含一个打印消息的容器。
```yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
```
#### 5.Pod 的终止
Pod 代表在集群中的节点上运行的进程,所以当不再需要这些进程时,允许这些进程优雅地终止是非常重要的,用户应该能够请求删除并且知道进程何时终止,但是也能够确保删除最终完成。当用户请求删除 Pod 时,系统会记录在允许强制删除 Pod 之前所期望的宽限期,并向每个容器中的主进程发送 TERM 信号。一旦过了宽限期KILL 信号就发送到这些进程,然后就从 API 服务器上删除 Pod。如果 Kubelet 或容器管理器在等待进程终止时发生重启,则终止操作将以完整的宽限期进行重试。
**终止流程:**
用户发送命令删除 Pod使用的是默认的宽限期30秒
API 服务器中的 Pod 会随着宽限期规定的时间进行更新,过了这个时间 Pod 就会被认为已 “死亡”
当使用客户端命令查询 Pod 状态时Pod 显示为 “Terminating”
当 Kubelet 看到 Pod 由于步骤2中设置的时间而被标记为 terminating 状态时,它就开始执行关闭 Pod 流程
给 Pod 内的进程发送 TERM 信号和第3步同步进行从服务的端点列表中删除 PodPod也不再被视为副本控制器的运行状态的 Pod 集的一部分。当负载平衡器(如服务代理)将 Pod 从轮换中移除时,关闭迟缓的 Pod 将不能继续为流量服务)
当宽限期结束后Pod 中运行的任何进程都将被用 SIGKILL 杀死
Kubelet 将通过设置宽限期为0立即删除来完成删除 API 服务器上的 Pod。Pod 从 API 中消失,从客户端不再可见
#### 6.使用Pod
下面是一个 Pod 示例,它由一个运行镜像 `nginx:1.20.1` 的容器组成
```shell
[root@master ~]# vim nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.20.1
ports:
- containerPort: 80
```
要创建上面显示的 Pod请运行以下命令
```shell
[root@master ~]# kubectl apply -f nginx.yaml
```
#### 7.用于管理 pod 的工作负载资源
通常你不需要直接创建 Pod甚至单实例 Pod。 相反,你会使用诸如 Deployment或 Job 这类工作负载资源 来创建 Pod。如果 Pod 需要跟踪状态, 可以考虑 StatefulSet 资源。
**Kubernetes 集群中的 Pod 主要有两种用法:**
运行单个容器的 Pod。"每个 Pod 一个容器"模型是最常见的 Kubernetes 用例; 在这种情况下,可以将 Pod 看作单个容器的包装器,并且 Kubernetes 直接管理 Pod而不是容器
运行多个协同工作的容器的 Pod。 Pod 可能封装由多个紧密耦合且需要共享资源的共处容器组成的应用程序。 这些位于同一位置的容器可能形成单个内聚的服务单元 —— 一个容器将文件从共享卷提供给公众, 而另一个单独的容器则刷新或更新这些文件。 Pod 将这些容器和存储资源打包为一个可管理的实体。
每个 Pod 都旨在运行给定应用程序的单个实例。如果希望横向扩展应用程序(例如,运行多个实例 以提供更多的资源),则应该使用多个 Pod每个实例使用一个 Pod。 在 Kubernetes 中,这通常被称为 *副本Replication*。 通常使用一种工作负载资源及其[控制器](https://kubernetes.io/zh/docs/concepts/architecture/controller/) 来创建和管理一组 Pod 副本。
#### 8.Pod 怎样管理多个容器
Pod 被设计成支持形成内聚服务单元的多个协作过程(形式为容器)。 Pod 中的容器被自动安排到集群中的同一物理机或虚拟机上,并可以一起进行调度。 容器之间可以共享资源和依赖、彼此通信、协调何时以及何种方式终止自身。
例如,你可能有一个容器,为共享卷中的文件提供 Web 服务器支持,以及一个单独的容器负责从远端更新这些文件,如下图所示:
<img src="Kubernetes%E8%B5%84%E6%BA%90%E5%AF%B9%E8%B1%A1Pod.assets/image-20220501135545030.png" alt="image-20220501135545030" style="zoom:50%;" />
有些 Pod 具有 Init 容器和 应用容器。 Init 容器会在启动应用容器之前运行并完成。
Pod 天生地为其成员容器提供了两种共享资源:网络和 存储。
## 二Pod生命周期
Pod 遵循一个预定义的生命周期,起始于 `Pending`阶段,至少其中有一个主要容器正常启动,则进入 `Running`,之后取决于 Pod 中是否有容器以 失败状态结束而进入 `Succeeded` 或者 `Failed` 阶段。
在 Pod 运行期间,`kubelet` 能够重启容器以处理一些失效场景。 在 Pod 内部Kubernetes 跟踪不同容器的状态并确定使 Pod 重新变得健康所需要采取的动作。
Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度分派到某个节点Pod 会一直在该节点运行,直到 Pod 停止或者被终止。
#### 1.Pod 生命期
和一个个独立的应用容器一样Pod 也被认为是相对临时性(而不是长期存在)的实体。 Pod 会被创建、赋予一个唯一的 IDUID 并被调度到节点,并在终止(根据重启策略)或删除之前一直运行在该节点。
如果一个[节点](https://kubernetes.io/zh/docs/concepts/architecture/nodes/)死掉了,调度到该节点 的 Pod 也被计划在给定超时期限结束后删除。
Pod 自身不具有自愈能力。如果 Pod 被调度到某节点而该节点之后失效Pod 会被删除类似地Pod 无法在因节点资源 耗尽或者节点维护而被驱逐期间继续存活。Kubernetes 使用一种高级抽象 来管理这些相对而言可随时丢弃的 Pod 实例,称作控制器。
任何给定的 Pod (由 UID 定义从不会被“重新调度rescheduled”到不同的节点 相反,这一 Pod 可以被一个新的、几乎完全相同的 Pod 替换掉。 如果需要,新 Pod 的名字可以不变,但是其 UID 会不同。
如果某物声称其生命期与某 Pod 相同,例如存储[卷](https://kubernetes.io/zh/docs/concepts/storage/volumes/) 这就意味着该对象在此 Pod UID 亦相同)存在期间也一直存在。 如果 Pod 因为任何原因被删除,甚至某完全相同的替代 Pod 被创建时, 这个相关的对象(例如这里的卷)也会被删除并重建。
一个包含多个容器的 Pod 包含一个用来拉取文件的程序和一个 Web 服务器, 均使用持久卷作为容器间共享的存储。
#### 2.Pod 阶段
Pod 的 `status` 字段是一个PodStatus对象其中包含一个 `phase` 字段。
Pod 的阶段Phase是 Pod 在其生命周期中所处位置的简单宏观概述。 该阶段并不是对容器或 Pod 状态的综合汇总,也不是为了成为完整的状态机。
Pod 阶段的数量和含义是严格定义的。 除了本文档中列举的内容外,不应该再假定 Pod 有其他的 `phase` 值。
| 取值 | 描述 |
| :---------------: | :----------------------------------------------------------: |
| Pending悬决 | Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行;此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 |
| Running运行中 | Pod 已经绑定到了某个节点Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 |
| Succeeded成功 | Pod 中的所有容器都已成功终止,并且不会再重启。 |
| Failed失败 | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。 |
| Unknown未知 | 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。 |
如果某节点死掉或者与集群中其他节点失联Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的 `phase` 设置为 `Failed`
#### 3.容器状态
Kubernetes 会跟踪 Pod 中每个容器的状态,就像它跟踪 Pod 总体上的阶段一样。 你可以使用容器生命周期回调来在容器生命周期中的特定时间点触发事件。
一旦调度器将 Pod 分派给某个节点,`kubelet` 就通过容器运行时开始为 Pod 创建容器。 容器的状态有三种:
Waiting等待
如果容器并不处在 `Running``Terminated` 状态之一,它就处在 `Waiting` 状态。 处于 `Waiting` 状态的容器仍在运行它完成启动所需要的操作:例如,从某个容器镜像 仓库拉取容器镜像或者向容器应用Secret数据等等。 当你使用 `kubectl` 来查询包含 `Waiting` 状态的容器的 Pod 时,你也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因。
Running运行中
`Running` 状态表明容器正在执行状态并且没有问题发生。 如果配置了 `postStart` 回调,那么该回调已经执行且已完成。 如果你使用 `kubectl` 来查询包含 `Running` 状态的容器的 Pod 时,你也会看到 关于容器进入 `Running` 状态的信息。
Terminated已终止
处于 `Terminated` 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。 如果你使用 `kubectl` 来查询包含 `Terminated` 状态的容器的 Pod 时,你会看到 容器进入此状态的原因、退出代码以及容器执行期间的起止时间;如果容器配置了 `preStop` 回调,则该回调会在容器进入 `Terminated` 状态之前执行。
#### 4.容器重启策略
Pod 的 `spec` 中包含一个 `restartPolicy` 字段,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。
`restartPolicy` 适用于 Pod 中的所有容器。`restartPolicy` 仅针对同一节点上 `kubelet` 的容器重启动作。当 Pod 中的容器退出时,`kubelet` 会按指数回退 方式计算重启的延迟10s、20s、40s、...),其最长延迟为 5 分钟。 一旦某容器执行了 10 分钟并且没有出现问题,`kubelet` 对该容器的重启回退计时器执行重置操作。
#### 5.Pod 状况
Pod 有一个 PodStatus 对象其中包含一个PodConditions数组。Pod 可能通过也可能未通过其中的一些状况测试。
PodScheduledPod 已经被调度到某节点
ContainersReadyPod 中所有容器都已就绪
Initialized所有的Init 容器都已成功完成
ReadyPod 可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中
| 字段名称 | 描述 |
| :----------------: | :----------------------------------------------------------: |
| type | Pod 状况的名称 |
| status | 表明该状况是否适用,可能的取值有 "`True`", "`False`" 或 "`Unknown`" |
| lastProbeTime | 上次探测 Pod 状况时的时间戳 |
| lastTransitionTime | Pod 上次从一种状态转换到另一种状态时的时间戳 |
| reason | 机器可读的、驼峰编码UpperCamelCase的文字表述上次状况变化的原因 |
| message | 人类可读的消息,给出上次状态转换的详细信息 |
#### 6.Pod详细信息
```shell
[root@master xingdian]# kubectl describe pod xingdian
Name: xingdian
Namespace: default
Priority: 0
Node: node-1/10.0.0.221
Start Time: Sun, 01 May 2022 14:28:09 +0800
Labels: <none>
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Containers:
xingdian-nginx:
Container ID:
Image: nginx:1.20.1
Image ID:
Port: 80/TCP
Host Port: 0/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-q6bcr (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
kube-api-access-q6bcr:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulling 16s kubelet Pulling image "nginx:1.20.1"
Normal Scheduled 12s default-scheduler Successfully assigned default/xingdian to node-1
=================================================================================
[root@master xingdian]# kubectl describe pod xingdian
Name: xingdian
Namespace: default
Priority: 0
Node: node-1/10.0.0.221
Start Time: Sun, 01 May 2022 14:28:09 +0800
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.244.2.3
IPs:
IP: 10.244.2.3
Containers:
xingdian-nginx:
Container ID: docker://f60ad0e3e13844c294ba8fd05757667ad04a4d28dc48d2289abfc66d405ab06c
Image: nginx:1.20.1
Image ID: docker-pullable://nginx@sha256:a98c2360dcfe44e9987ed09d59421bb654cb6c4abe50a92ec9c912f252461483
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 01 May 2022 14:29:32 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-q6bcr (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-q6bcr:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulling 97s kubelet Pulling image "nginx:1.20.1"
Normal Scheduled 93s default-scheduler Successfully assigned default/xingdian to node-1
Normal Pulled 14s kubelet Successfully pulled image "nginx:1.20.1" in 1m22.663436038s
Normal Created 14s kubelet Created container xingdian-nginx
Normal Started 14s kubelet Started container xingdian-nginx
```

View File

@ -0,0 +1,131 @@
<h1><center>kubernetes资源对象label</center></h1>
著作:行癫 <盗版必究>
------
## 一:标签
#### 1.pod标签
作用:
解决同类型的资源对象越来越多,为了更好的管理,按照标签分组
常见标签:
release版本stable稳定版、canary金丝雀版本、可以理解为测试版、beta测试版
environment环境变量dev开发、qa测试、production生产
application应用ui、as应用软件、pc、sc
tier架构层级frontend前端、backend后端、cache缓存、隐藏
partition分区customerA客户A、customerB客户B
track品控级别daily每天、weekly每周
注意:
K8s集群中虽然没有对有严格的要求但是标签还是要做到见名知意方便自己也方便别人
使用:
为现有的pod添加一个标签
```shell
[root@master nginx]# kubectl label pod nginx-xingdian app=nginx -n default
pod/nginx-xingdian labeled
注意:
-n: 指定namespect名字空间
```
查看pod标签
```shell
[root@master nginx]# kubectl get pods --show-labels -n default
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-585449566-9459t 1/1 Running 0 99m app=nginx,pod-template-hash=585449566
nginx-deployment-585449566-z6qs8 1/1 Running 0 94m app=nginx,pod-template-hash=585449566
nginx-xingdian 1/1 Running 0 67m app=nginx,run=nginx-xingdian
```
删除标签
```shell
[root@master nginx]# kubectl label pod nginx-xingdian app- -n default
pod/nginx-xingdian labeled
```
修改标签
```shell
[root@master nginx]# kubectl label pod nginx-xingdian release=stable -n default
pod/nginx-xingdian labeled
[root@master nginx]# kubectl get pods --show-labels -n default
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-585449566-9459t 1/1 Running 0 112m app=nginx,pod-template-hash=585449566
nginx-deployment-585449566-z6qs8 1/1 Running 0 106m app=nginx,pod-template-hash=585449566
nginx-xingdian 1/1 Running 0 80m app=xingdian,release=stable,run=nginx-xingdian
[root@master nginx]# kubectl label pod nginx-xingdian release=beta --overwrite -n default
pod/nginx-xingdian labeled
[root@master nginx]# kubectl get pods --show-labels -n default
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-585449566-9459t 1/1 Running 0 112m app=nginx,pod-template-hash=585449566
nginx-deployment-585449566-z6qs8 1/1 Running 0 107m app=nginx,pod-template-hash=585449566
nginx-xingdian 1/1 Running 0 81m app=xingdian,release=beta,run=nginx-xingdian
```
标签与标签选择器的关系:
如果标签有多个,标签选择器选择其中一个,也可以关联成功!
如果选择器有多个,那么标签必须满足条件,才可关联成功!
标签选择器:标签的查询过滤条件
基于等值关系的equality-based”=“、”==“、”!=“前两个等于,最后一个不等于
基于集合关系set-basedin、notin、exists三种
使用标签选择器的逻辑:
同时指定的多个选择器之间的逻辑关系为”与“操作
使用空值的标签选择器意味着每个资源对象都将被选择中
空的标签选择器无法选中任何资源
#### 2.node节点标签
查看标签:
```shell
[root@master nginx]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master Ready master 22h v1.19.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
node-1 Ready <none> 22h v1.19.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-1,kubernetes.io/os=linux
node-2 Ready <none> 22h v1.19.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-2,kubernetes.io/os=linux
```
增加标签:
```shell
[root@master nginx]# kubectl label nodes node-1 kubernetes.io/username=xingdian
node/node-1 labeled
```
减少标签:
```shell
[root@master nginx]# kubectl label nodes node-1 a-
node/node-1 labeled
```
修改标签:
```shell
[root@master nginx]# kubectl label nodes node-1 kubernetes.io/username=diandian --overwrite
node/node-1 labeled
```

View File

@ -0,0 +1,352 @@
<h1><center>kubernetes资源对象Secret</center></h1>
著作:行癫 <盗版必究>
------
## 一Secret
Secret用来保存小片敏感数据的k8s资源例如密码token或者秘钥。这类数据当然也可以存放在Pod或者镜像中但是放在Secret中是为了更方便的控制如何使用数据并减少暴露的风险用户可以创建自己的secret系统也会有自己的secret。Pod需要先引用才能使用某个secret
#### 1.Pod使用secret的方式
作为volume的一个域被一个或多个容器挂载
在拉取镜像的时候被kubelet引用
#### 2.內建的Secrets
由ServiceAccount创建的API证书附加的秘钥,k8s自动生成的用来访问apiserver的Secret所有Pod会默认使用这个Secret与apiserver通信
#### 3.创建自己的Secret
方式1使用kubectl create secret命令
方式2yaml文件创建Secret
命令方式创建secret
假如某个Pod要访问数据库需要用户名密码分别存放在2个文件中username.txtpassword.txt
```shell
[root@master ~]# echo -n 'admin' > ./username.txt
[root@master ~]# echo -n '1f2d1e2e67df' > ./password.txt
```
kubectl create secret指令将用户名密码写到secret中并在apiserver创建Secret
```shell
[root@master ~]# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
```
查看创建结果
```shell
[root@master ~]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 51s
[root@master ~]# kubectl describe secret/db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 12 bytes
username.txt: 5 bytes
```
get或describe指令都不会展示secret的实际内容这是出于对数据的保护的考虑如果想查看实际内容使用命令
```shell
[root@master ~]# kubectl get secret db-user-pass -o json
```
yaml方式创建Secret
创建一个secret.yaml文件内容用base64编码
```shell
[root@master ~]# echo -n 'admin' | base64
YWRtaW4=
[root@master ~]# echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
```
yaml文件内容
```shell
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
```
创建
```shell
[root@master ~]# kubectl create -f ./secret.yaml
secret "mysecret" created
```
解析Secret中内容
```shell
[root@master ~]# kubectl get secret mysecret -o yaml
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
```
base64解码
```shell
[root@master ~]# echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
1f2d1e2e67df
```
#### 4.使用Secret
secret可以作为数据卷挂载或者作为环境变量暴露给Pod中的容器使用也可以被系统中的其他资源使用。比如可以用secret导入与外部系统交互需要的证书文件等
#### 5.在Pod中以文件的形式使用secret
创建一个Secret多个Pod可以引用同一个Secret
修改Pod的定义在spec.volumes[]加一个volume给这个volume起个名字spec.volumes[].secret.secretName记录的是要引用的Secret名字在每个需要使用Secret的容器中添加一项spec.containers[].volumeMounts[]指定spec.containers[].volumeMounts[].readOnly = truespec.containers[].volumeMounts[].mountPath要指向一个未被使用的系统路径
修改镜像或者命令行使系统可以找到上一步指定的路径。此时Secret中data字段的每一个key都是指定路径下面的一个文件名
#### 6.Pod中引用Secret的列子
```shell
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"  //这里是pod内部的目录
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
```
pod里面查看
```shell
[root@master ~]# kubectl exec -it mypod /bin/bash
root@mypod:/# cd /etc/foo/
root@mypod:/etc/foo# ls
password username
```
每一个被引用的Secret都要在spec.volumes中定义
映射secret key到指定的路径
可以控制secret key被映射到容器内的路径利用spec.volumes[].secret.items来修改被映射的具体路径
```shell
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
```
username被映射到了文件/etc/foo/my-group/my-username而不是/etc/foo/username
password没有变
从volume中读取secret的值
值得注意的一点是以文件的形式挂载到容器中的secret他们的值已经是经过base64解码的了可以直接读出来使用
```shell
[root@master ~]# ls /etc/foo/
username
password
[root@master ~]# cat /etc/foo/username
admin
[root@master ~]# cat /etc/foo/password
1f2d1e2e67df
```
被挂载的secret内容自动更新
也就是如果修改一个Secret的内容那么挂载了该Secret的容器中也将会取到更新后的值
#### 7.环境变量的形式使用Secret
创建一个Secret多个Pod可以引用同一个Secret
修改pod的定义定义环境变量并使用env[].valueFrom.secretKeyRef指定secret和相应的key
修改镜像或命令行,让它们可以读到环境变量
```shell
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
```
容器中读取环境变量已经是base64解码后的值了
```shell
[root@master ~]# echo $SECRET_USERNAME
admin
[root@master ~]# echo $SECRET_PASSWORD
1f2d1e2e67df
```
#### 8.案例
Pod中的ssh keys,创建一个包含ssh keys的secret
```shell
[root@master ~]# kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub
```
创建一个Pod其中的容器可以用volume的形式使用ssh keys
```shell
kind: Pod
apiVersion: v1
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: daocloud.io/library/nginx
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
```
#### 9.k8s集群连接harbor私有仓库
使用命令创建一个secret
--docker-server 是私有仓库地址
--docker-username 是私有仓库用户名
--docker-password 是私有仓库对用用户名的密码
```shell
[root@master ~]# kubectl create secret docker-registry regcred --docker-server=10.11.67.119 --docker-username=diange --docker-password=QianFeng@123
```
创建pod的yaml文件
```shell
[root@master ~]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: xingdian
labels:
app: xingdian
spec:
containers:
- name: diandian
image: 10.11.67.119/xingdian/nginx@sha256:2963fc49cc50883ba9af25f977a9997ff9af06b45c12d968b7985dc1e9254e4b
ports:
- containerPort: 80
imagePullSecrets:
- name: regcred
```
创建pod
```shell
[root@master ~]# kubectl create -f nginx.yaml
```
查看pod
```shell
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
xingdian 1/1 Running 0 10m
```
注意:
保证docker可以使用http连接下载默认是https
```shell
修改docker启动文件
[root@master ~]# vim /etc/systemd/system/multi-user.target.wants/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry 10.0.1.13 --containerd=/run/containerd/containerd.sock
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl restart docker
```

View File

@ -0,0 +1,162 @@
<h1><center>Kubernetes资源对象service</center></h1>
著作:行癫 <盗版必究>
------
## 一Service
将运行在一组 [Pods](https://v1-23.docs.kubernetes.io/docs/concepts/workloads/pods/pod-overview/) 上的应用程序公开为网络服务的抽象方法
使用 Kubernetes你无需修改应用程序即可使用不熟悉的服务发现机制Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡
Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod一种可以访问它们的策略 —— 通常称为微服务
举个例子,考虑一个图片处理后端,它运行了 3 个副本。这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端副本。 然而组成这一组后端程序的 Pod 实际上可能会发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态
#### 1.定义 Service
例如,假定有一组 Pod它们对外暴露了 9376 端口,同时还被打上 `app=MyApp` 标签:
```shell
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
```
上述配置创建一个名称为 "my-service" 的 Service 对象,它会将请求代理到使用 TCP 端口 9376并且具有标签 `"app=MyApp"` 的 Pod 上
Kubernetes 为该服务分配一个 IP 地址(有时称为 "集群IP"),该 IP 地址由服务代理使用
注意:
Service 能够将一个接收 `port` 映射到任意的 `targetPort`。 默认情况下,`targetPort` 将被设置为与 `port` 字段相同的值
#### 2.多端口 Service
对于某些服务,你需要公开多个端口。 Kubernetes 允许你在 Service 对象上配置多个端口定义
```shell
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
```
## 二:发布服务
#### 1.服务类型
对一些应用的某些部分(如前端),可能希望将其暴露给 Kubernetes 集群外部 的 IP 地址
Kubernetes `ServiceTypes` 允许指定你所需要的 Service 类型,默认是 `ClusterIP`
`Type` 的取值以及行为如下:
`ClusterIP`:通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 `ServiceType`
![img](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/6R1zaHS1QM_i4c4W1k2ttg.png)
`NodePort`:通过每个节点上的 IP 和静态端口(`NodePort`)暴露服务。 `NodePort` 服务会路由到自动创建的 `ClusterIP` 服务。 通过请求 `<节点 IP>:<节点端口>`,你可以从集群的外部访问一个 `NodePort` 服务
![img](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/-E5GOvNElgId7mwjBs9elw.png)
[`LoadBalancer`](https://v1-23.docs.kubernetes.io/zh/docs/concepts/services-networking/service/#loadbalancer):使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 `NodePort` 服务和 `ClusterIP` 服务上
你也可以使用Ingress来暴露自己的服务。 Ingress 不是一种服务类型,但它充当集群的入口点。 它可以将路由规则整合到一个资源中因为它可以在同一IP地址下公开多个服务
```shell
[root@master nginx]# kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer
```
#### 2.NodePort
如果你将 `type` 字段设置为 `NodePort`,则 Kubernetes 控制平面将在 `--service-node-port-range` 标志指定的范围内分配端口默认值30000-32767
例如:
```shell
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: MyApp
ports:
# 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
- port: 80
targetPort: 80
# 可选字段
# 默认情况下为了方便起见Kubernetes 控制平面会从某个范围内分配一个端口号默认30000-32767
nodePort: 30007
```
#### 3.案例
```shell
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-server
image: nginx:1.16
ports:
- containerPort: 80
```
```shell
apiVersion: v1
kind: Service
metadata:
name: nginx-services
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 88
targetPort: 80
nodePort: 30010
selector:
app: nginx
```

View File

@ -0,0 +1,141 @@
<h1><center>Kubernetes资源对象Volumes</center></h1>
著作:行癫 <盗版必究>
------
## 一Volumes
Container 中的文件在磁盘上是临时存放的,这给 Container 中运行的较重要的应用 程序带来一些问题。问题之一是当容器崩溃时文件丢失。kubelet 会重新启动容器, 但容器会以干净的状态重启。 第二个问题会在同一 Pod中运行多个容器并共享文件时出现。 Kubernetes 卷Volume 这一抽象概念能够解决这两个问题。
Docker 也有 卷Volume 的概念,但对它只有少量且松散的管理。 Docker 卷是磁盘上或者另外一个容器内的一个目录。 Docker 提供卷驱动程序,但是其功能非常有限。
Kubernetes 支持很多类型的卷。 Pod 可以同时使用任意数目的卷类型。 临时卷类型的生命周期与 Pod 相同,但持久卷可以比 Pod 的存活期长。 因此,卷的存在时间会超出 Pod 中运行的所有容器,并且在容器重新启动时数据也会得到保留。 当 Pod 不再存在时,卷也将不再存在。
卷的核心是包含一些数据的一个目录Pod 中的容器可以访问该目录。 所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。
使用卷时, 在 .spec.volumes字段中设置为 Pod 提供的卷,并在.spec.containers[*].volumeMounts字段中声明卷在容器中的挂载位置。
#### 1.cephfs
cephfs卷允许你将现存的 CephFS 卷挂载到 Pod 中。 不像emptyDir那样会在 Pod 被删除的同时也会被删除cephfs卷的内容在 Pod 被删除 时会被保留,只是卷被卸载了。这意味着 cephfs 卷可以被预先填充数据,且这些数据可以在 Pod 之间共享。同一cephfs卷可同时被多个写者挂载。
详细使用官方链接:
```shell
https://github.com/kubernetes/examples/tree/master/volumes/cephfs/
```
#### 2.hostPath
hostPath卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大的逃生舱。
| **取值** | **行为** |
| :---------------: | :----------------------------------------------------------: |
| | 空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 |
| DirectoryOrCreate | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755具有与 kubelet 相同的组和属主信息。 |
| Directory | 在给定路径上必须存在的目录。 |
| FileOrCreate | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644具有与 kubelet 相同的组和所有权。 |
| File | 在给定路径上必须存在的文件。 |
| Socket | 在给定路径上必须存在的 UNIX 套接字。 |
| CharDevice | 在给定路径上必须存在的字符设备。 |
| BlockDevice | 在给定路径上必须存在的块设备。 |
hostPath 配置示例:
```shell
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# 宿主上目录位置
path: /data
# 此字段为可选
type: Directory
```
案例:
```shell
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-tomcat-1
labels:
app: tomcat-1
spec:
replicas: 2
selector:
matchLabels:
app: tomcat-1
template:
metadata:
labels:
app: tomcat-1
spec:
containers:
- name: tomcat-1
image: daocloud.io/library/tomcat:8-jdk8
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /usr/local/tomcat/webapps
name: xingdian
volumes:
- name: xingdian
hostPath:
path: /opt/apps/web
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-service-1
labels:
app: tomcat-1
spec:
type: NodePort
ports:
- port: 888
targetPort: 8080
nodePort: 30021
selector:
app: tomcat-1
```