diff --git a/MD/Kubernetes资源对象Pod.md b/MD/Kubernetes资源对象Pod.md new file mode 100644 index 0000000..2a367f9 --- /dev/null +++ b/MD/Kubernetes资源对象Pod.md @@ -0,0 +1,305 @@ +

Kubernetes资源对象Pod

+ +著作:行癫 <盗版必究> + +------ + +## 一:Pod基本概念 + +#### 1.认识pod + +​ Pod直译是豆荚,可以把容器想像成豆荚里的豆子,把一个或多个关系紧密的豆子包在一起就是豆荚(一个Pod)。在Kubernetes中我们不会直接操作容器,而是把容器包装成Pod再进行管理;Pod是Kubernetes进行创建、调度和管理的最小单位;Pod运行于Node节点上, 若干相关容器的组合;Pod内包含的容器运行在同一宿主机上,使用相同的网络命名空间、IP地址和端口,能够通过localhost进行通信;Pod可以指定一组共享存储。Volumes Pod中。Pod中的所有容器都可以访问共享卷,从而使这些容器可以共享数据;Pod 就是 k8s 世界里的"应用";而一个应用,可以由多个容器组成。 + +​ ![img](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/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步同步进行)从服务的端点列表中删除 Pod,Pod也不再被视为副本控制器的运行状态的 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 服务器支持,以及一个单独的容器负责从远端更新这些文件,如下图所示: + +image-20220501135545030 + +​ 有些 Pod 具有 Init 容器和 应用容器。 Init 容器会在启动应用容器之前运行并完成。 + +​ Pod 天生地为其成员容器提供了两种共享资源:网络和 存储。 + +## 二:Pod生命周期 + + Pod 遵循一个预定义的生命周期,起始于 `Pending`阶段,至少其中有一个主要容器正常启动,则进入 `Running`,之后取决于 Pod 中是否有容器以 失败状态结束而进入 `Succeeded` 或者 `Failed` 阶段。 + +​ 在 Pod 运行期间,`kubelet` 能够重启容器以处理一些失效场景。 在 Pod 内部,Kubernetes 跟踪不同容器的状态并确定使 Pod 重新变得健康所需要采取的动作。 + +​ Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度(分派)到某个节点,Pod 会一直在该节点运行,直到 Pod 停止或者被终止。 + +#### 1.Pod 生命期 + +​ 和一个个独立的应用容器一样,Pod 也被认为是相对临时性(而不是长期存在)的实体。 Pod 会被创建、赋予一个唯一的 ID(UID), 并被调度到节点,并在终止(根据重启策略)或删除之前一直运行在该节点。 + +​ 如果一个[节点](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 可能通过也可能未通过其中的一些状况测试。 + +PodScheduled:Pod 已经被调度到某节点 + +ContainersReady:Pod 中所有容器都已就绪 + +Initialized:所有的Init 容器都已成功完成 + +Ready:Pod 可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中 + +| 字段名称 | 描述 | +| :----------------: | :----------------------------------------------------------: | +| 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: +Annotations: +Status: Pending +IP: +IPs: +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: + 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: + DownwardAPI: true +QoS Class: BestEffort +Node-Selectors: +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: +Annotations: +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: + 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: + DownwardAPI: true +QoS Class: BestEffort +Node-Selectors: +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 +``` + + + diff --git a/MD/kubernetes资源对象Label.md b/MD/kubernetes资源对象Label.md new file mode 100644 index 0000000..d11380e --- /dev/null +++ b/MD/kubernetes资源对象Label.md @@ -0,0 +1,131 @@ +

kubernetes资源对象label

+ +著作:行癫 <盗版必究> + +------ + +## 一:标签 + +#### 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-based):in、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 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 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 +``` \ No newline at end of file diff --git a/MD/kubernetes资源对象Secret.md b/MD/kubernetes资源对象Secret.md new file mode 100644 index 0000000..fb1bf56 --- /dev/null +++ b/MD/kubernetes资源对象Secret.md @@ -0,0 +1,352 @@ +

kubernetes资源对象Secret

+ +著作:行癫 <盗版必究> + +------ + +## 一: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命令 + +​ 方式2:yaml文件创建Secret + +命令方式创建secret: + +​ 假如某个Pod要访问数据库,需要用户名密码,分别存放在2个文件中:username.txt,password.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: +Annotations: +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 = true,spec.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 +``` + + + + + + + diff --git a/MD/kubernetes资源对象Service.md b/MD/kubernetes资源对象Service.md new file mode 100644 index 0000000..89f2695 --- /dev/null +++ b/MD/kubernetes资源对象Service.md @@ -0,0 +1,162 @@ +

Kubernetes资源对象service

+ +著作:行癫 <盗版必究> + +------ + +## 一: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 +``` + + + + + + + diff --git a/MD/kubernetes资源对象Volumes.md b/MD/kubernetes资源对象Volumes.md new file mode 100644 index 0000000..64ac364 --- /dev/null +++ b/MD/kubernetes资源对象Volumes.md @@ -0,0 +1,141 @@ +

Kubernetes资源对象Volumes

+ +著作:行癫 <盗版必究> + +------ + +## 一: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 +``` + + + + + + + + + + + + + + + + + + + + + + + + +