kubernetes学习随笔

核心组件

主要组件

  • etcd: 保存整个集群的状态

  • apiservice: 提供资源操作的唯一入口,并提供访问控制、API注册、发现等机制

  • scheduler: 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上

  • controller manager: 负责维护集群的状态,比如故障检测、自动扩容、滚动更新等

  • kubelet: 负责维护容器的生命周期,同时也负责数据卷(CVI)和网络(CNI)的管理

  • kube-proxy: 负责为Service提供内部的服务发现和负载均衡

  • Container runtime: 负责镜像管理以及Pod和容器的真正运行(CRI)

扩展组件

  • kube-dns: 负责为整个集群提供DNS服务

  • Metrics: 提供资源监控

  • Dashboard: 提供GUI

  • Ingress Controller: 为服务提供外网入口

  • Federation: 提供跨可用区的集群

  • Fluentd-elasticsearch: 提供集群日志采集、存储与查询

基本概念

集群管理

  • Master: K8s集群的管理节点,负责整个集群的管理和控制

  • Node: K8s集群的工作节点,负责集群中的工作负载

  • Namespace: 为K8s集群提供虚拟的隔离作用

  • Label: 通过给指定资源捆绑一个或多个不同的资源标签,来实现多维度的资源分组管理

资源管理

  • Pause: Pod的父容器,负责僵尸进程的回收管理,通过Pause容器可以使用一个Pod里面多个容器共享的存储,网络,PID,IPC等

  • Pod: K8s集群中运行部署应用的最小单元,可以支持多容器

  • RC: K8s集群中最早保证Pod高可用的API对象,之后扩展匹配模式新增RS

  • Deployment: 一个应用模式更广的API对象,通过操作RS进行创建、更新、滚动升级服务

  • Statefulset: K8s提供的管理有状态应用的负载管理控制器API

  • DaemonSet: 确保其创建的Pod在机器中的每一台(或指定)Node上都运行一个副本

  • Job: K8s用来控制批处理型人物的API对象,之后基于时间管理新增的CronJob

  • Service: 定义一个服务的多个Pod逻辑合集和访问Pod的策略,实现服务发现和负载均衡

  • HPA: 实现基于CPU使用率(或在使用自定义指标)的Pod自动伸缩的功能

存储管理

  • Secret: 用来保存和传递密码、秘钥、认证凭证这些敏感信息的对象

  • ConfigMap: 将配置信息和镜像内容分离,以使容器化的应用程序具有可移植性

  • Volume: 是Pod中能够被多个容器访问的共享目录

  • PV: 持久化存储与之相关的持久化存储声明(PVC),使得K8S集群具备了存储的逻辑抽象能力

零宕机必备知识-Pod探针

Pod三种检测方式

  • StartupProbe 启动检测; 表示程序是否启动; 例如当容器内某个进程或程序,检测成功启动后不在检测,如果启用这个探针,其他探针检测靠后;常用于启动时间过长的程序

  • LivenessProbe 存活探针; 表示程序是否正常运行; 例如当容器内进程或应用程序正常运行中,由于出现BUG,导致程序挂了,会重启该状态容器

  • ReadnessProbe 就绪检测; 表示程序是否准备好提供服务; 例如当程序启动了,并且也已经运行了,但是有很多数据还没有加载完成,如果设置这个探针,暂时不会提供对外服务,等待加载完成才能提供服务

Pod探针的三种方式

  • ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。

  • TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。

  • HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的

Pod探针的三种结果

  • 成功:容器通过了诊断。

  • 失败:容器未通过诊断。

  • 未知:诊断失败,因此不会采取任何行动

启动检测-startupProbe

存活检测-LivenessProbe

检测/tmp/live,每隔60秒就会被删除,liveness检测,如果被删除,就会返回失败,重启pod。陷入无限循环。

exec

httpget

tcp

就绪检测-ReadinessProbe

readinessProbe-httpget

Pod启动、退出动作事件

  • postStart 当一个主容器启动后,Kubernetes 将立即发送 postStart 事件

  • preStop 在主容器被终结之前,Kubernetes 将发送一个 preStop 事件

配置 Probe 参数

Probe中有很多精确和详细的配置,通过它们你能准确的控制liveness和readiness检查:

  • initialDelaySeconds:容器启动后第一次执行探测是需要等待多少秒。

  • periodSeconds:执行探测的频率。默认是10秒,最小1秒。

  • timeoutSeconds:探测超时时间。默认1秒,最小1秒。

  • successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。

  • failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。

HTTP probe中可以给 httpGet设置其他配置项:

  • host:连接的主机名,默认连接到pod的IP。你可能想在http header中设置”Host”而不是使用IP。

  • scheme:连接使用的schema,默认HTTP。

  • path: 访问的HTTP server的path。

  • httpHeaders:自定义请求的header。HTTP运行重复的header。

  • port:访问的容器的端口名字或者端口号。端口号必须介于1和65525之间。

RC与Replicaset

ReplicationController(简称RC)是确保用户定义的Pod副本数保持不变。 ReplicaSet(RS)是Replication Controller(RC)的升级版本。 两者区别:对选择器的支持

介绍

ReplicaSet(RS)是Replication Controller(RC)的升级版本。 ReplicaSet 和 Replication Controller之间的唯一区别是对选择器的支持。 ReplicaSet支持labels user guide中描述的set-based选择器要求 Replication Controller仅支持equality-based的选择器要求。

RC 替代方法

(1)ReplicaSet: RC 升级版 主要用作Deployment协调pod创建、删除和更新。请注意,除非需要自定义更新编排或根本不需要更新,否则建议使用Deployment而不是直接使用ReplicaSets。

(2)Deployment(推荐): ReplicationController和ReplicaSet这两种资源对象需要其他控制器进行配合才可以实现滚动升级,并且难度大,因此k8s提供了一种基于ReplicaSet的资源对象Deployment可以支持声明式地更新应用。

(3)对比

  • 大多数kubectl 支持Replication Controller 命令的也支持ReplicaSets。

  • ReplicaSets可以独立使用,但它主要被 Deployments用作pod 机制的创建、删除和更新。

  • 使用Deployment时,你不必担心创建pod的ReplicaSets,因为可以通过Deployment实现管理ReplicaSets。ReplicaSet能确保运行指定数量的pod。

  • Deployment 是一个更高层次的概念,它能管理ReplicaSets,并提供对pod的更新等功能。

  • 建议使用Deployment来管理ReplicaSets,除非你需要自定义更新编排。

  • ReplicaSet也可以作为 Horizontal Pod Autoscalers (HPA)的目标 ,一个ReplicaSet可以由一个HPA来自动伸缩。

Deployment

介绍

用于部署应用程序并以声明的方式升级应用,从而更好地解决pod编排问题。常用于无状态应用

原理

Deployment在内部使用了ReplicaSet实现编排pod功能,当创建一个Deployment时,ReplicaSet资源会随之创建,ReplicaSet是新一代的ReplicationController,并推荐使用它替代ReplicationController来复制和管理Pod,在使用Deployment时,实际的Pod是由Deployment的ReplicaSet创建和管理的。

Deployment命令

若需要指定命名空间时,需要加上: -n

Deployment创建

Deployment删除

Deployment更新

两种更新方式,默认滚动更新

  • Recreate(重建) 设置spec.strategy.type=Recreate,更新方式为:Deployment在更新Pod时,会先杀掉所有正在运行的Pod,然后创建新的Pod。

  • RollingUpdate(滚动更新) 设置spec.strategy.type=RollingUpdate,更新方式为:Deployment会以滚动的方式来渐变性的更新Pod,即Pod新版本的递增,旧版本的递减的一个过程。

  • 命令方式

原理

1.初始创建Deployment,系统创建了一个ReplicaSet,并按照用户的需求创建了3个Pod副本(假如3个Pod副本); 2.当更新Deployment时,系统创建一个新的ReplicaSet,并将其副本数量扩展到1,然后将旧的ReplicaSet缩减为2; 3.统继续按照相同的更新策略对新旧两个ReplicaSet进行逐个调整。 4.最后,新的ReplicaSet运行了3个新版本的Pod副本,旧的ReplicaSet副本数量则缩减为0。

Deployment回滚

Deployment查看

Deployment扩容、缩容

Deployment自动扩容、缩容

HPA 控制器,用于实现基于(CPU使用率|磁盘|内存等)进行自动Pod扩容和缩容的功能。 k8s1.11版本后,需要安装 metric server 插件,用来收集及统计资源的利用率。

Deployment+NFS+wordpress

如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用 由一组无状态的副本控制器提供的工作负载来部署应用程序,比如 Deployment 或者 ReplicaSet 可能更适用于你的无状态应用部署需要

StatefulSets

概述

用来管理有状态应用的工作负载API对象,用于具有持久化存储方面

使用场景

  • 稳定的、唯一的网络标识符

  • 稳定的、持久的存储

  • 有序的、优雅的部署和缩放

  • 有序的、自动的滚动和更新

使用条件

  • 需要 storage class 存储来提供 PV 驱动

  • 需要无头 service 服务,负责 Pod 的网络标识

  • 默认Pod管理策略(OrderedReady)时滚动更新,可能需要人工干预

创建 StatefulSet

使用稳定的网络身份标识

StatefulSet 中的 Pod 拥有一个具有黏性的、独一无二的身份标志。基于 StatefulSet 控制器分配给每个 Pod 的唯一顺序索引 Pod 的名称的形式为-

Pod 的序号、主机名、SRV 条目和记录名称没有改变,但和 Pod 相关联的 IP 地址可能发生了改变

写入稳定的存储

动态提供 PersistentVolume,所有的 PersistentVolume 都是自动创建和绑定的。

测试数据是否会丢失

虽然 web-0 和 web-1 被重新调度了,但它们仍然继续监听各自的主机名,因为和它们的 PersistentVolumeClaim 相关联的 PersistentVolume 被重新挂载到了各自的 volumeMount 上。 不管 web-0 和 web-1 被调度到了哪个节点上,它们的 PersistentVolumes 将会被挂载到合适的挂载点上。

StatefulSet 扩容/缩容

扩容

缩容

注意: 当删除 StatefulSet 的 Pod 时,挂载到 StatefulSet 的 Pod 的 PersistentVolumes 不会被删除。

StatefulSet 更新

Kubernetes 1.7 版本的 StatefulSet 控制器支持自动更新。 更新策略由 StatefulSet API Object 的spec.updateStrategy 字段决定。这个特性能够用来更新一个 StatefulSet 中的 Pod 的 container images,resource requests,以及 limits,labels 和 annotations。 RollingUpdate滚动更新是 StatefulSets 默认策略

StatefulSet 灰度发布

StatefulSet 级联||非级联删除

非级联方式删除,StatefulSet 的 Pod 不会被删除。 使用级联删除时,StatefulSet 和它的 Pod 都会被删除。 不管是级联或者非级联删除,存储卷是不会被删除

非级联删除

级联删除

删除了 StatefulSet 和 Pod,当重新部署这个 web.yaml 后,Pod 将会被重新创建并挂载它们的 PersistentVolumes,并且 web-0 和 web-1 将仍然使用它们的主机名提供服务。

StatefulSet 如何管理Pod

Pod管理策略

  • OrderedReady Pod 管理策略 -- 默认,遵循上下文,顺序性启动和停止pod

  • Parallel Pod 管理策略 -- 并行,启动和停止会同时进行

DaemonSet

工作原理

  • 每当向集群中添加一个节点时,指定的 Pod 副本也将添加到该节点上

  • 当节点从集群中移除时,Pod 也就被垃圾回收了

  • 删除一个 DaemonSet 可以清理所有由其创建的 Pod

使用场景

  • 日志采集agent,如fluentd或logstash

  • 监控采集agent,如Prometheus Node Exporter,Sysdig Agent,Ganglia gmond

  • 分布式集群组件,如Ceph MON,Ceph OSD,glusterd,Hadoop Yarn NodeManager等

  • k8s必要运行组件,如网络flannel,weave,calico,kube-proxy等

DaemonSet创建

DaemonSet更新

更新方式: 先删除Pod再创建

DaemonSet回滚

回滚方式: 先删除Pod再创建

DaemonSet删除

DaemonSet调度

  • 指定 nodeName 节点运行

  • 通过 nodeSelector 标签运行

  • 通过 node Affinity和node Anti-affinity 亲和力运行

运行在指定标签

Node Pod节点标签

1.增加节点标签 备注 =:代表增加标签

2.减少节点标签 备注 -:代表减少标签

Label添加删除和修改

添加label

删除Label

修改Label

Pod选择Label

过滤 pod 标签 labels

1、查看pod标签:

查看所有pod的标签:

查看单个pod的标签:

查看namespaces下所有pod的标签:

2、列出标签key是db的Pod

格式:kubectl get pod -l 标签的key名

多标签过滤格式:kubectl get pod -l 标签的key,标签的key ###注 逗号是英文的

3、列出带key是db、值redis的标签

4、过滤出标签key不是app、值不是nginx的pod

** 5、过滤出带有key是db,并且值是redis与nginx的pod**

6、过滤出标签key没有db、并且没有pod值与nginx值的pod

Metric-server安装

metric-server简介

  • 提供基础资源如CPU、内存监控接口查询;

  • 接口通过 Kubernetes aggregator注册到kube-apiserver中;

  • 对外通过Metric API暴露给外部访问;

  • 自定义指标使用需要借助Prometheus实现

metric-server API

  • /node 获取所有节点的指标,指标名称为NodeMetrics

  • /node/<node_name> 特定节点指标

  • /namespaces/{namespace}/pods 获取命名空间下的所有pod指标

  • /namespaces/{namespace}/pods/{pod} 特定pod的指标,指标名称为PodMetrics

未来将能够支持指标聚合,如max最大值,min最小值,95th峰值,以及自定义时间窗口,如1h,1d,1w等

1、 核心监控实现

  • 通过kubelet收集资源估算+使用估算

  • metric-server负责数据收集,不负责数据存储

  • metric-server对外暴露Metric API接口

  • 核心监控指标客用户HPA,kubectl top,scheduler和dashboard

2、 自定义监控实现

  • 自定义监控指标包括监控指标和服务指标

  • 需要在每个node上部署一个agent上报至集群监控agent,如prometheus

  • 集群监控agent收集数据后需要将监控指标+服务指标通过API adaptor转换为apiserver能够处理的接口

  • HPA通过自定义指标实现更丰富的弹性扩展能力,需要通过HPA adaptor API做次转换。

metric-server部署

方法一:

方法二:

查看

通过API 获取监控资源

或者

metric-server 部署问题

  1. kubectl top node命令提示如下:

查看metrics-server日志

从上面错误提示信息来看就是Kubernetes集群中DNS:10.96.0.10是无法解析出k8s-node02.ljmict.com这个域名的。 解决方法:修改metrics-server-deployment.yaml文件,在metrics-server容器配置位置添加如下配置:

然后删除重新部署

  1. v1beta1.metrics.k8s.io failed with: failing or missing response from

当再次使用kubectl top node的时候发现还是有问题 查看metrics-server日志是正常的。

查看kube-apiserver日志,发现:

解决方法:在kube-apiserver选项中添加如下配置选项:

重启kube-apiserver,再次使用kubectl top node命令查看

HPA 水平横向动态扩展

工作原理

  • 根据应用分配资源使用情况,动态增加或者减少Pod副本数量,以实现集群资源的扩容

如何实现

  • 当CPU利用率超过requests分配的80%时即扩容。

实现机制

  • HPA需要依赖于监控组件,调用监控数据实现动态伸缩,如调用Metrics API接口

  • HPA是二级的副本控制器,建立在Deployments,ReplicaSet,StatefulSets等副本控制器基础之上

  • HPA根据获取资源指标不同支持两个版本:v1和v2alpha1

  • HPA V1获取核心资源指标,如CPU和内存利用率,通过调用Metric-server API接口实现

  • HPA V2获取自定义监控指标,通过Prometheus获取监控数据实现

  • HPA根据资源API周期性调整副本数,检测周期horizontal-pod-autoscaler-sync-period定义的值,默认15s

当前HPA V1扩展使用指标只能基于CPU分配使用率进行扩展,功能相对有限,更丰富的功能需要由HPA V2版来实现,其由不同的API来实现:

  • metrics.k8s.io 资源指标API,通过metric-server提供,提供node和pod的cpu,内存资源查询;

  • custom.metrics.k8s.io 自定义指标,通过adapter和kube-apiserver集成,如promethues;

  • external.metrics.k8s.io 外部指标,和自定义指标类似,需要通过adapter和k8s集成。

基于CPU和内存

部署HPA

测试压力

基于自定义指标

标签和选择器

标签: 是附加在 kubernetes 对象上的一组键值对, 用来标识 kubernetes 对象,一个对象上可有多个标签,同一个对象标签的key必须唯一

语法

标签的 key 可以有两个部分:可选的前缀和标签名,通过 / 分隔。

  • 标签名:

    • 标签名部分是必须的

    • 不能多于 63 个字符

    • 必须由字母、数字开始和结尾

    • 可以包含字母、数字、减号-、下划线_、小数点.

  • 标签前缀:

    • 标签前缀部分是可选的

    • 如果指定,必须是一个DNS的子域名,例如:k8s.eip.work

    • 不能多于 253 个字符

    • 使用 / 和标签名分隔

  • 标签的 value 必须:

    • 不能多于 63 个字符

    • 可以为空字符串

    • 如果不为空,则

    • 必须由字母、数字开始和结尾

    • 可以包含字母、数字、减号-、下划线_、小数点.

基于等式的选择方式

可以使用三种操作符 =、==、!=。

例如 Pod 节点选择器

基于集合的选择方式

Set-based 标签选择器可以根据标签名的一组值进行筛选。支持的操作符有三种:in、notin、exists。例如:

可以组合多个选择器,用 , 分隔,, 相当于 AND 操作符。例如: 选择包含 partition 标签(不检查标签值)且 environment 不是 qa 的对象

基于集合的选择方式是一个更宽泛的基于等式的选择方式,例如,environment=production 等价于 environment in (production);environment!=production 等价于 environment notin (production)。 基于集合的选择方式可以和基于等式的选择方式可以混合使用,例如: partition in (customerA, customerB),environment!=qa

servcie

什么是service?

为一组具有相同功能的容器应用提供一个统一的入口地址, 通过标签选择器发现后端 Pod 服务,并将请求进行复制分发到后端的哥哥容器应用上的控制器

如何访问,类型有哪些?

访问请求来源有两种: k8s集群内部的程序(Pod)和 k8s集群外部的程序。

类型

  • ClusterIP: 提供一个集群内部的虚拟IP以供Pod访问(service默认类型)。

  • NodePort: 在每个Node上打开一个端口以供外部访问

  • LoadBalancer: 通过外部的负载均衡器来访问

Service 和 Pod 如何建立关联?

  • Service 通过 selector 选择器和 Pod 建立关联

  • **k8s 会根据 service 关联的 Pod 的 IP 地址信息组合成一个 endpoint **

  • 若 service 定义中没有 seletor 字段,service 被创建时, endpoint controller 不会自动创建 endpoint

Service 负载分发策略

  • RoundRobin:轮询模式,即轮询将请求转发到后端的各个pod上(默认模式)

  • SessionAffinity:会话保持模式,基于客户端IP地址进行会话保持的模式,第一次客户端访问后端某个pod,之后的请求都转发到这个pod上。

如何发现 service 服务?

疑问: Service 解决了Pod的服务发现问题,但不提前知道Service的IP,怎么发现service服务呢?

k8s提供了两种方式进行服务发现:

  • 环境变量: 当创建一个Pod的时候,kubelet会在该Pod中注入集群内所有Service的相关环境变量。需要注意的是,要想一个Pod中注入某个Service的环境变量,则必须Service要先比该Pod创建。这一点,几乎使得这种方式进行服务发现不可用。

  • DNS: 可以通过cluster add-on的方式轻松的创建KubeDNS来对集群内的Service进行服务发现————这也是k8s官方强烈推荐的方式。为了让Pod中的容器可以使用kube-dns来解析域名,k8s会修改容器的/etc/resolv.conf配置。

内部service相互调用

格式: <service_name>.<namespace>.svc.cluster.local

在 Kubernetes 中,内部服务相互调用是通过 Service 对象实现的。Service 对象可以提供一个虚拟 IP 地址和端口,用于将请求转发到一组 Pods 上。这些 Pods 可以是实现同一个应用程序的多个实例,或者是实现不同服务的多个应用程序实例。

如果一个 Service 要访问另一个 Service,它可以通过使用另一个 Service 的虚拟 IP 地址和端口号来进行调用。对于请求,Kubernetes 的 DNS 服务可以将 Service 名称解析为对应的虚拟 IP 地址。

例如,如果 ServiceA 要访问 ServiceB,它可以通过向 ServiceB.namespace.svc.cluster.local 进行请求来实现。

在设计应用程序时,需要注意内部服务之间的相互调用可能会影响系统的整体性能和可用性。因此,在设计内部服务架构时需要认真考虑性能和可靠性的因素。

k8s服务发现原理

  • endpoint endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。

  • endpoint controller

endpoint controller是k8s集群控制器的其中一个组件,其功能如下:

负责生成和维护所有endpoint对象的控制器 负责监听service和对应pod的变化 监听到service被删除,则删除和该service同名的endpoint对象 监听到新的service被创建,则根据新建service信息获取相关pod列表,然后创建对应endpoint对象 监听到service被更新,则根据更新后的service信息获取相关pod列表,然后更新对应endpoint对象 监听到pod事件,则更新对应的service的endpoint对象,将podIp记录到endpoint中

Ingress helm安装

一、安装Helm

二、下载ingress

三、安装ingress

  1. 修改values.yaml

  1. 安装ingress

四、使用ingress

  1. Ingress配置文件

kubernetes.io/ingressClass: "nginx":使用ingressClass: "nginx",告诉ingress实现的配置 rules: 一个rules可以有多个host host : 访问ingress的域名 path : 类似于nginx的location配置,同一个host可以配置多个path backend:描述Service和ServicePort的组合。对ingress匹配主机和路径的HTTP与HTTPS请求将被转发到后端Pod

  1. 创建一个nginx的Deployment

ConfigMap

一、介绍 ConfigMap

ConfigMap 是一种API对象,用来将非加密数据保存到键值对中。可以用作环境变量、命令行参数、存储卷中的配置文件

二、创建 ConfigMap

1. 命令行方式创建

2. 文件夹方式创建

3. 键值对方式创建

4. Yaml方式创建

三、使用 ConfigMap

Pod的使用方式:

    1. 将ConfigMap中的数据设置为容器的环境变量

    1. 将ConfigMap中的数据设置为命令行参数

    1. 使用Volume将ConfigMap作为文件或目录挂载

    1. 编写代码在Pod中运行,使用Kubernetes API 读取ConfgMap

1. 配置到容器的环境变量

2. 设置为命令行参数

3. 挂载方式

注意:

  • ConfigMap必须在Pod使用它之前创建

  • 使用envFrom时,将会自动忽略无效的键

  • Pod只能使用同一个命名空间的ConfigMap

4. 热更新

  • 使用 ConfigMap 挂载的 Env 不会同步更新 (可以通过滚动更新 pod 的方式来强制重新挂载 ConfigMap 或者 先将副本数设置为 0,然后再扩容)

  • 使用 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新

Secret

一、介绍 Secret

用户存储和管理一些敏感数据,比如密码、token、秘钥等敏感信息。 用户可以通过在Pod的容器里挂载 Volume 的方式或者 环境变量的方式访问到 Secret 保存的信息

二、三种类型 Secret

  • Opaque: base64加密,存储密码、密钥等;但数据也可以通过base64 –decode解码得到原始数据,加密性很弱。

  • Servuce Account: 用来访问 Kubernetes API, 由Kubernetes自动创建,并且自动挂载到Pod的 /run/secrets/kubernetes.io/serviceaccount 目录中。

  • kubernetes.io/dockerconfigjson: 用来存储私有docker registry的认证信息。

1、 Opaque类型

Opaque 类型的数据是一个 map 类型,要求value是base64编码。

注意: 创建的 Secret 对象,它里面的内容仅仅是经过了转码,而并没有被加密。在真正的生产环境中,你需要在 Kubernetes 中开启 Secret 的加密插件,增强数据的安全性。

2、 Service Account类型

Service Account 对象的作用,就是 Kubernetes 系统内置的一种“服务账户”,它是 Kubernetes 进行权限分配的对象。比如, Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作,而 Service Account B,则可以有 Kubernetes API 的所有操作权限。

3、 kubernetes.io/dockerconfigjson类型

用来创建用户docker registry认证的Secret,直接使用kubectl create命令创建即可

如何使用?

三、创建 Secret

1. 文件方式创建

2. 文件夹方式创建

3. 键值对方式创建

4. Yaml方式创建

5. 键值对+文件创建

四、使用 Secret

1. 挂载方式

2. 配置变量方式

3. 热更新

同 ConfigMap 更新方式一有

  • 挂载 volume 方式支持热更新

  • 变量的方式除非强制更新 或者 副本变0,扩容

Volume

emptyDir

emptyDri介绍

当 Pod 被分配给节点时,首先创建 emptyDir 卷,并且只要该 Pod 在该节点上运行,该卷就会存在。正如卷的名 字所述,它最初是空的。Pod 中的容器可以读取和写入 emptyDir 卷中的相同文件,尽管该卷可以挂载到每个容 器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时, emptyDir 中的数据将被永久删除

emptyDir用法

  • 暂存空间,例如用于基于磁盘的合并排序

  • 用作长时间计算崩溃恢复时的检查点

  • Web服务器容器提供数据时,报错内容管理器容器提取的文件

hostPath

hostPath介绍

将主机节点的文件系统中的文件或目录挂载到集群中

hostPath用法

  • 运行需要访问 Docker 内部的容器;使用 /var/lib/docker 的 hostPath

  • 在容器中运行 cAdvisor;使用 /dev/cgroups 的 hostPath

  • 允许 pod 指定给定的 hostPath 是否应该在 pod 运行之前存在,是否应该创建,以及它应该以什么形式存在

hostPath类型

hostPath注意

由于每个节点上的文件都不同,具有相同配置(例如从 podTemplate 创建的)的 pod 在不同节点上的行为可能会有所不同 当 Kubernetes 按照计划添加资源感知调度时,将无法考虑 hostPath 使用的资源 在底层主机上创建的文件或目录只能由 root 写入。您需要在特权容器中以 root 身份运行进程,或修改主机上的文件权限以便写入 hostPath 卷

Cronjob

Cronjob从名字上可以看到,它就是一个计划任务,与Linux中的crontab无异,其格式基本上都crontab一样,

现在编写一个Cronjob资源对象来执行job: Cronjob 在Kubernetes1.8版本之前使用的API版本是batch/v2alpha1, 需要在API Server启动时启用此功能:

在版本>1.8后,API版本已转为batch/v1beta1,并且默认启用。

创建并查看任务状态:

然后,每隔一分钟执行kubectl get cronjob hello 查看任务状态,发现的确是每分钟调度了一次。

找出由CronJob资源对象创建出来的Pod

找到对应的Pod后,查看它的日志:

如果不需要这个CronJob,删除之:

污点与容忍

Taint 在一类服务器上打上污点,让不能容忍这个污点的 Pod 不能部署在打了污点的服务器上 Master 节点不应该部署系统 Pod 之外的任何 Pod 每个节点可以打上多个污点

operator****可以定义为: Equal:表示key是否等于value,默认 Exists:表示key是否存在,此时无需定义value

tain 的 effect 定义对 Pod 排斥效果: NoSchedule:仅影响调度过程,对现存的Pod对象不产生影响; NoExecute:既影响调度过程,也影响显著的Pod对象;不容忍的Pod对象将被驱逐 PreferNoSchedule: 表示尽量不调度

打上节点污点标记

Pod调度到污点

如果仍然希望某个 pod 调度到 taint 节点上,则必须在 Spec 中做出Toleration定义,才能调度到该节点

  • 如果 operator 的值是 Exists,则 value 属性可省略

  • 如果 operator 的值是 Equal,则表示其 key 与 value 之间的关系是 equal(等于)

  • 如果不指定 operator 属性,则默认值为 Equal

  • 空的 key 如果再配合 Exists 就能匹配所有的 key 与 value,也是是能容忍所有 node 的所有 Taints

  • 空的 effect 匹配所有的 effect

取消节点污点标记

初始化容器 init containner

优先级最高,先于其他容器启动,主要做一些初始化配置,如下载配置文件、注册信息、证书等

例如:

在初始化容器中把 init container test 写入到/work_dir/index.html下,并把/work_dir挂载到/usr/share/nginx/html, 那么当访问Nginx首页时显示的内容为init container test

Node 亲和性

    1. 硬亲和性: 必须满足条件 matchExpressions : 匹配表达式,这个标签可以指定一段,例如pod中定义的key为zone,operator为In(包含那些),values为 foo和bar。就是在node节点中包含foo和bar的标签中调度 matchFields : 匹配字段 和上面的意思 不过他可以不定义标签值,可以定义

[root@localhost ~]# cat node-affinity-1.yaml

发现按匹配的标签分配到指定的 Node 上面

修改匹配 Node 的 label value 指

再次查看,匹配不上回一直Pending

    1. 软亲和性: 能满足最好,不满足也可以

修改 node-affinity-1.yaml

部署再次查看,就算是匹配不上Node label,还是会生成Pod

Pod 亲和性

Pod亲和性场景,我们的k8s集群的节点分布在不同的区域或者不同的机房,当服务A和服务B要求部署在同一个区域或者同一机房的时候,我们就需要亲和性调度了。

labelSelector : 选择跟那组Pod亲和 namespaces : 选择哪个命名空间 topologyKey : 指定节点上的哪个键

亲和性

让两个POD标签处于一处

反亲和性

让pod和某个pod不处于同一node,和上面相反

临时容器 debug

服务拓扑 Topology

服务拓扑(Service Topology)可以让一个服务基于集群的 Node 拓扑进行流量路由。 例如,一个服务可以指定流量是被优先路由到一个和客户端在同一个 Node 或者在同一可用区域的端点。拓扑感知的流量路由

一个集群中,其 Node 的标签被打为其主机名,区域名和地区名。 那么就可以设置 Service 的 topologyKeys 的值

  • 只定向到同一个 Node 上的端点,Node 上没有端点存在时就失败: 配置 ["kubernetes.io/hostname"]。

  • 偏向定向到同一个 Node 上的端点,回退同一区域的端点上,然后是同一地区, 其它情况下就失败:配置 ["kubernetes.io/hostname", "topology.kubernetes.io/zone", "topology.kubernetes.io/region"]。 这或许很有用,例如,数据局部性很重要的情况下。

  • 偏向于同一区域,但如果此区域中没有可用的终结点,则回退到任何可用的终结点: 配置 ["topology.kubernetes.io/zone", "*"]。

前提条件

  • Kubernetes 1.17 或更新版本

  • Kube-proxy 以 iptables 或者 IPVS 模式运行

  • 启用端点切片

约束条件

  • 服务拓扑和 externalTrafficPolicy=Local 不兼容,但是在同一个集群的不同 Service 上是可以分别使用这两种特性的,只要不在同一个 Service 上就可以。

  • 有效的拓扑键目前只有:kubernetes.io/hostname、topology.kubernetes.io/zone 和 topology.kubernetes.io/region,但是未来会推广到其它的 Node 标签。

  • 拓扑键必须是有效的标签,并且最多指定16个

  • 通配符:"*",如果要用,则必须是拓扑键值的最后一个值

仅节点本地端点

仅路由到节点本地端点的一种服务。如果节点上不存在端点,流量则被丢弃

首选节点本地端点

首选节点本地端点,如果节点本地端点不存在,则回退到集群范围端点的一种服务:

仅地域或区域端点

首选地域端点而不是区域端点的一种服务。 如果以上两种范围内均不存在端点, 流量则被丢弃。

优先选择节点本地端点、地域端点,然后是区域端点

优先选择节点本地端点,地域端点,然后是区域端点,最后才是集群范围端点的 一种服务。

开启服务拓扑

要启用服务拓扑功能,需要为所有 Kubernetes 组件启用 ServiceTopology 和 EndpointSlice 特性门控:

RBAC权限管理

启用 RBAC

二进制安装的

**kubeadm安装的

1.6版本以上默认开启 RBAC

相关资源对象

  • Rule: 规则, 是一一组属于不同 API Group 资源上的一组操作对象

  • Subject: 主题,对应在集群中尝试操作的对象,集群中定义了3种类型的主题资源:  - User Account: 这是有外部独立服务进行管理的,对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的 API 来进行管理  - Group: 关联多个用户,集群中有一些默认创建的组,比如cluster-admin

    • Service Account: 通过Kubernetes API 来管理的一些用户帐号,和 namespace 进行关联的,适用于集群内部运行的应用程序,需要通过 API 来完成权限认证

  • Role: 角色,用于定义某个命名空间的角色的权限

  • RoleBinding: 命名空间权限,将角色中定义的权限赋予一个或者一组用户,针对命名空间执行授权。

  • ClusterRole: 集群角色,用于定义整个集群的角色的权限。

  • ClusterRoleBinding: 集群权限,将集群角色中定义的权限赋予一个或者一组用户,针对集群范围内的命名空间执行授权

RBAC的使用

参考: https://cloud.tencent.com/developer/article/1684417

Ingress

单个Service + Ingress

** YAML内容 **

部署

查看

客户端测试

多个 Servcie + Ingress

Ingress-nginx 域名重定向

实现目的:通过访问一个域名重定向到指定域名或者链接 访问 xxxx.com 重定向到 www.baidu.com

Ingress-nginx 黑白名单

  • Annotations:只对指定的ingress生效

  • ConfigMap:全局生效

  • 黑名单可以使用ConfigMap去配置,白名单建议使用Annotations去配置。

白名单

黑名单

Ingress-nginx 匹配请求头

Ingress-nginx 速率限制

Ingress-nginx 的基本认证

Ingress-nginx SSL配置

Ingress-nginx配置了SSL,默认会自动跳转到https的网页

禁用https强制跳转

Ingress-nginx 自定义错误页面

github地址:https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/customization/custom-errors/custom-default-backend.yaml

修改ds配置文件,添加这个

ingress-nginx 配置多host指向相同后端

Ingress-nginx 实现灰度金丝雀发布

https://www.cnblogs.com/heian99/p/14608416.html

https://www.cnblogs.com/ssgeek/p/14149920.html#1%E3%80%81%E9%94%99%E8%AF%AF%E9%A1%B5%E9%9D%A2%E7%8A%B6%E6%80%81%E7%A0%81

Ratel 一键K8s资料管理

参考: https://github.com/dotbalo/ratel-doc

安装说明

参数解析:

  • serverName: 集群别名

  • serverAddress: Kubernetes APIServer地址

  • serverAdminUser: Kubernetes管理员账号(需要配置basic auth)

  • serverAdminPassword: Kubernetes管理员密码

  • serverAdminToken: Kubernetes管理员Token // 暂不支持

  • serverDashboardUrl: Kubernetes官方dashboard地址,1.x版本需要添加/#!,2.x需要添加/#

  • kubeConfigPath: Kubernetes kube.config路径(绝对路径)

  • harborConfig: 对于多集群管理的情况下,可能会存在不同的harbor仓库,配置此参数可以在拷贝资源的时候自动替换harbor配置 注意: kubeConfigPath 通过secret挂载到容器的/mnt目录或者其他目录

创建Secret

创建RBAC

**[root@k8s-master-1 ratel]# cat ratel-rbac.yaml **

部署 ratel

Service和Ingress配置

**[root@k8s-master-1 ratel]# cat ratel-ingress.yaml **

访问ratel

注意:如果没有安装 ingress controller,需要把type: ClusterIP改成type: NodePort,然后通过主机IP+Port进行访问

Ceph

官方网站

https://rook.io/

Rook安装要求(三选一)

  • 原始设备(无分区或格式化文件系统)

  • 原始分区(无格式化文件系统)

  • block模式下存储类可用的 PV

  • rook已经使用csi方式挂载ceph,flex方式已逐渐被淘汰。但是使用csi方式有一个大坑,就是kernel>4.10才能正常使用,否则会报很多奇怪的错误

  • ceph要求3+节点,所以我为了使用master节点,把master的污点取消了。

查看是否

Ceph部署

当前版本 v1.6.7

查看

Rook 工具箱

要验证集群是否处于健康状态,需使用Rook 工具箱

Ceph验证健康

创建块存储

测试wordpress

修改本机host主机,访问域名: k8s.wordpress.com

operator 部署 redis-cluster 集群

参考: https://github.com/ucloud/redis-cluster-operator

Helm 部署 Redis-cluster

安装 redis-cluster-operator

查看存储

部署 redis 持久化存储,动态自动分配

查看部署

测试数据

进入 pod 写入一条测试数据,并模拟关闭一个 redis 节点服务器

进入另一个 pod ,查看是否存在

扩容缩容

扩容

缩容

Helm 部署 RabbitMQ

添加仓库

查看RabbitMQ版本

安装指定 RabbitMQ 版本

浏览器访问

卸载保留历史记录

升级

扩容

删除

模拟测试

Helm 部署 Zookeeper + Kafka

参考: https://docs.bitnami.com/tutorials/deploy-scalable-kafka-zookeeper-cluster-kubernetes/

准备工作

添加仓库

动态PV (Rook-ceph)

选择版本

下载helm包到本地,在线安装可不用下载

安装zookeeper + kafka

安装方法参考bitnami官网:https://docs.bitnami.com/tutorials/deploy-scalable-kafka-zookeeper-cluster-kubernetes/

在线安装


kafka3.x 版本在线安装

注: 这里有个坑,kafka 最新版本可能不兼容zookeeper,一定要使用kafka与zookeeper对应的版本

离线安装

zookeeper安装

kafka安装

检查

测试集群

新开一个窗口,进入kafka的pod,启动一个生产者,输入消息;在消费者端可以收到消息

查看启动消费者窗口

卸载应用

扩容|缩容

扩容 Apache Kafka 到 7 个节点, 缩容修改 replicaCount 即可

扩容 Apache Zookeeper 部署到 5 个节点,缩容修改 replicaCount 即可

Helm 部署 ELK

前提条件

  • Helm

  • Persistent Volumes (需要存在默认动态存储,因为ES中没有指定 storageClassName)

安装ES

如果没有指定默认存储的话,下载修改

安装 kibana

配置ingress

也可以下载下来,修改 value.yaml 开启 ingress

安装filebeat

Helm 自定义构建 Chart

1. 创建 Helm-chart

2.编写 mychart 应用描述信息

3.编写应用部署信息<变量>

4.检查依赖和摸版配置是否正确

Helm 的 Harbor 仓库

  • harbor 安装的时候 默认没有helm charts的仓库

  • harbor 版本 v1.9.3, helm 版本 3.3.4

安装完成之后登录页面上就会有了 helm charts 了,页面上也可以直接上传charts

1、安装插件

  • 在线安装

  • 离线安装

2、创建 Helm-charts

3、打包 Helm-charts

4、添加 Harbor 仓库

5、上传到 Harbor 仓库

6、部署 Harbor 仓库中 Helm-charts

加–dry-run表示做调试,–debug表示输出部署过程; 如:helm install test-nginx mycharts/mynginx –debug

7、滚动升级

例如我想镜像版本从 1.16.0 升级到 1.16.1,但是仓库中只有1.16.0版本,那我就再做一个上传进去

这里我们发现,镜像拉取失败,原来的还是在一直运行中,说明当新的 pod 没有运行正常之前,原来的pod不会删除掉

8、版本回滚

9、删除

Helm 的 kubeapps UI

为Helm提供web UI界面管理

1. 部署kubeapps

2.ingress-nginx对外提供服务

访问 kubeapps.com

需要token登陆,因此我们需要创建sa并为其附加 cluster-admin 的权限

或者

命令行 + -o yaml --dry-run 得出 Yaml 内容

查看 token令牌

添加自己的 helm charts 仓库

3.自行探索,点点点

  • 支持创建命名空间

  • 支持自动更新|回滚

  • 管理 Helm charts 很方便

  • 其他....

Jenkins

环境信息

  • 系统版本: CentOS 7

  • 推荐的硬件配置: 1GB+可用内存 50 GB+ 可用磁盘空间

  • 软件配置: Java 8—无论是Java运行时环境(JRE)还是Java开发工具包(JDK)都可以。

Java环境

官网下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 需注册登录下载 也可以 rpm 方式安装,我这里采用二进制方式

  • yum 安装方式: centos7

Jenkins 安装方式

官方文档: https://www.jenkins.io/zh/doc/ 其他 war 包下载版本地址: http://mirrors.jenkins.io/war-stable/

docker启动

war 方式启动

rpm 方式启动

清华源下载( RPM 推荐):https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat/

配置jenkins

Jenkins目录介绍

Last updated