上传文件至 'NEW'

This commit is contained in:
diandian 2024-12-22 22:27:34 +08:00
parent 5497ad5308
commit bce7e3cc52
4 changed files with 1185 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,395 @@
<h1><center>Kubernetes资源对象ConfigMap</center></h1>
著作:行癫 <盗版必究>
------
## 一ConfigMap
用来存储配置文件的kubernetes资源对象所有的配置内容都存储在etcd中ConfigMap与 Secret 类似
#### 1.ConfigMap与 Secret 的区别
ConfigMap 保存的是不需要加密的、应用所需的配置信息
ConfigMap 的用法几乎与 Secret 完全相同:可以使用 kubectl create configmap 从文件或者目录创建 ConfigMap也可以直接编写 ConfigMap 对象的 YAML 文件
#### 2.创建ConfigMap
方式1通过直接在命令行中指定configmap参数创建即--from-literal
方式2通过指定文件创建即将一个配置文件创建为一个ConfigMap--from-file=<文件>
方式3通过指定目录创建即将一个目录下的所有配置文件创建为一个ConfigMap--from-file=<目录>
方式4事先写好标准的configmap的yaml文件然后kubectl create -f 创建
通过命令行参数--from-literal创建
创建命令
```shell
[root@master yaml]# kubectl create configmap test-config1 --from-literal=db.host=10.5.10.116 --from-literal=db.port='3306'
configmap/test-config1 created
```
结果如下面的data内容所示
```shell
[root@master yaml]# kubectl get configmap test-config1 -o yaml
apiVersion: v1
data:
db.host: 10.5.10.116
db.port: "3306"
kind: ConfigMap
metadata:
creationTimestamp: "2019-02-14T08:22:34Z"
name: test-config1
namespace: default
resourceVersion: "7587"
selfLink: /api/v1/namespaces/default/configmaps/test-config1
uid: adfff64c-3031-11e9-abbe-000c290a5b8b
```
通过指定文件创建:
编辑配置文件app.properties内容如下
```shell
[root@master yaml]# cat app.properties
property.1 = value-1
property.2 = value-2
property.3 = value-3
property.4 = value-4
[mysqld]
!include /home/wing/mysql/etc/mysqld.cnf
port = 3306
socket = /home/wing/mysql/tmp/mysql.sock
pid-file = /wing/mysql/mysql/var/mysql.pid
basedir = /home/mysql/mysql
datadir = /wing/mysql/mysql/var
```
创建(可以有多个--from-file
```shell
[root@master yaml]# kubectl create configmap test-config2 --from-file=./app.properties
```
结果如下面data内容所示
```shell
[root@master yaml]# kubectl get configmap test-config2 -o yaml
apiVersion: v1
data:
app.properties: |
property.1 = value-1
property.2 = value-2
property.3 = value-3
property.4 = value-4
[mysqld]
!include /home/wing/mysql/etc/mysqld.cnf
port = 3306
socket = /home/wing/mysql/tmp/mysql.sock
pid-file = /wing/mysql/mysql/var/mysql.pid
basedir = /home/mysql/mysql
datadir = /wing/mysql/mysql/var
kind: ConfigMap
metadata:
creationTimestamp: "2019-02-14T08:29:33Z"
name: test-config2
namespace: default
resourceVersion: "8176"
selfLink: /api/v1/namespaces/default/configmaps/test-config2
uid: a8237769-3032-11e9-abbe-000c290a5b8b
```
通过指定文件创建时configmap会创建一个key/value对key是文件名value是文件内容。如不想configmap中的key为默认的文件名可以在创建时指定key名字
```shell
[root@master yaml]# kubectl create configmap game-config-3 --from-file=<my-key-name>=<path-to-file>
```
指定目录创建:
configs 目录下的config-1和config-2内容如下所示
```shell
[root@master yaml]# tail configs/config-1
aaa
bbb
c=d
[root@master yaml]# tail configs/config-2
eee
fff
h=k
```
创建
```shell
[root@master yaml]# kubectl create configmap test-config3 --from-file=./configs
```
结果下面data内容所示
```shell
[root@master yaml]# kubectl get configmap test-config3 -o yaml
apiVersion: v1
data:
config-1: |
aaa
bbb
c=d
config-2: |
eee
fff
h=k
kind: ConfigMap
metadata:
creationTimestamp: "2019-02-14T08:37:05Z"
name: test-config3
namespace: default
resourceVersion: "8808"
selfLink: /api/v1/namespaces/default/configmaps/test-config3
uid: b55ffbeb-3033-11e9-abbe-000c290a5b8b
```
指定目录创建时configmap内容中的各个文件会创建一个key/value对key是文件名value是文件内容忽略子目录
通过事先写好configmap的标准yaml文件创建
yaml文件内容如下 注意其中一个key的value有多行内容时的写法
```shell
[root@master yaml]# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test-config4
namespace: default
data:
cache_host: memcached-gcxt
cache_port: "11211"
cache_prefix: gcxt
my.cnf: |
[mysqld]
log-bin = mysql-bin
haha = hehe
```
创建
```shell
[root@master yaml]# kubectl apply -f configmap.yaml
configmap/test-config4 created
```
结果如下面data内容所示
```shell
[root@master yaml]# kubectl get configmap test-config4 -o yaml
apiVersion: v1
data:
cache_host: memcached-gcxt
cache_port: "11211"
cache_prefix: gcxt
my.cnf: |
[mysqld]
log-bin = mysql-bin
haha = hehe
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"cache_host":"memcached-gcxt","cache_port":"11211","cache_prefix":"gcxt","my.cnf":"[mysqld]\nlog-bin = mysql-bin\nhaha = hehe\n"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test-config4","namespace":"default"}}
creationTimestamp: "2019-02-14T08:46:57Z"
name: test-config4
namespace: default
resourceVersion: "9639"
selfLink: /api/v1/namespaces/default/configmaps/test-config4
uid: 163fbe1e-3035-11e9-abbe-000c290a5b8b
```
查看configmap的详细信息
```shell
[root@master yaml]# kubectl describe configmap
```
#### 3.使用ConfigMap
通过环境变量的方式直接传递pod
通过在pod的命令行下运行的方式
使用volume的方式挂载入到pod内
示例ConfigMap文件
```shell
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
special.type: charm
```
通过环境变量使用:
使用valueFrom、configMapKeyRef、name、key指定要用的key
```shell
[root@master yaml]# cat testpod.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: daocloud.io/library/nginx
env:
- name: SPECIAL_LEVEL_KEY //这里是容器里设置的新变量的名字
valueFrom:
configMapKeyRef:
name: special-config //这里是来源于哪个configMap
key: special.how //configMap里的key
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.type
restartPolicy: Never
```
测试
```shell
[root@master yaml]# kubectl exec -it dapi-test-pod /bin/bash
root@dapi-test-pod:/# echo $SPECIAL_TYPE_KEY
charm
```
通过envFrom、configMapRef、name使得configmap中的所有key/value对都自动变成环境变量
```shell
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: daocloud.io/library/nginx
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never
```
这样容器里的变量名称直接使用configMap里的key名
```shell
[root@master yaml]# kubectl exec -it dapi-test-pod /bin/bash
root@dapi-test-pod:/# env
HOSTNAME=dapi-test-pod
NJS_VERSION=1.15.8.0.2.7-1~stretch
NGINX_VERSION=1.15.8-1~stretch
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_PORT=tcp://10.96.0.1:443
PWD=/
special.how=very
HOME=/root
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
TERM=xterm
SHLVL=1
KUBERNETES_SERVICE_PORT=443
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
special.type=charm
KUBERNETES_SERVICE_HOST=10.96.0.1
```
作为volume挂载使用
```shell
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-configmap
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-configmap
image: daocloud.io/library/nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: config-volume3
mountPath: /tmp/config3
volumes:
- name: config-volume3
configMap:
name: test-config-3
```
进入容器中/tmp/config4查看
```shell
[root@master yaml]# kubectl exec -it nginx-configmap-7447bf77d6-svj2t /bin/bash
root@nginx-configmap-7447bf77d6-svj2t:/# ls /tmp/config4/
cache_host cache_port cache_prefix my.cnf
root@nginx-configmap-7447bf77d6-svj2t:/# cat /tmp/config4/cache_host
memcached-gcxt
可以看到在config4文件夹下以每一个key为文件名value为值创建了多个文件。
```
假如不想以key名作为配置文件名可以引入items 字段在其中逐个指定要用相对路径path替换的key
```shell
volumes:
- name: config-volume4
configMap:
name: test-config4
items:
- key: my.cnf //原来的key名
path: mysql-key
- key: cache_host //原来的key名
path: cache-host
```
注意:
删除configmap后原pod不受影响然后再删除pod后重启的pod的events会报找不到cofigmap的volume
pod起来后再通过kubectl edit configmap …修改configmap过一会pod内部的配置也会刷新
在容器内部修改挂进去的配置文件后过一会内容会再次被刷新为原始configmap内容

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
```