k8s study
在 Pod 中的容器之间共享进程命名空间#
启用进程命名空间共享时,容器中的进程对同一 Pod 中的所有其他容器都是可见的。#
你可以使用此功能来配置协作容器,比如日志处理 sidecar 容器, 或者对那些不包含诸如 shell 等调试实用工具的镜像进行故障排查
使用 Pod .spec 中的 shareProcessNamespace 字段可以启用进程命名空间共享#
理解进程命名空间共享#
Pod 共享许多资源,因此它们共享进程命名空间是很有意义的。 不过,有些容器可能希望与其他容器隔离,因此了解这些差异很重要:#
KubeSphere 是在 Kubernetes 之上构建的面向云原生应用的分布式操作系统,完全开源,支持多云与多集群管理,提供全栈的 IT 自动化运维能力,简化企业的 DevOps 工作流。它的架构可以非常方便地使第三方应用与云原生生态组件进行即插即用 (plug-and-play) 的集成#
###
KubeSphere 还开源了 KubeKey 帮助企业一键在公有云或数据中心快速搭建 Kubernetes 集群,提供单节点、多节点、集群插件安装,以及集群升级与运维。#
功能#
KubeSphere 作为开源的企业级全栈化容器平台,为用户提供了一个健壮、安全、功能丰富、具备极致体验的 Web 控制台。拥有企业级 Kubernetes 所需的最常见的功能,如工作负载管理,网络策略配置,微服务治理(基于 Istio),DevOps 项目 (CI/CD) ,安全管理,Source to Image/Binary to Image,多租户管理,多维度监控,日志查询和收集,告警通知,审计,应用程序管理和镜像管理、应用配置密钥管理等功能模块#
DevOps支持#
基于 Istio 的服务网络#
流量管理
金丝雀发布: 在现有的生产系统旁边创建一个全新的独立的生产环境,通过使新版本只对少数终端用户可用,这样可降低向推出新代码和功能的风险。如果新版本一切顺利,用户可以更改百分比,并逐渐用新版本替换旧版本。
蓝绿发布:允许用户同时运行一个应用程序的两个版本。蓝色代表当前应用程序版本,绿色代表经过功能和性能测试的新版本。一旦测试结果成功,就将应用程序流量从生产版本(蓝色)路由到新版本(绿色)。
流量镜像:流量镜像也叫作影子流量,是指通过一定的配置将线上的真实流量复制一份到镜像服务中去,我们通过流量镜像转发以达到在不影响线上服务的情况下对流量或请求内容做具体分析的目的,它的设计思想是只做转发而不接收响应(fire and forget),使团队能够以最小的风险进行生产变更。
断路器:允许用户设置服务内单个主机的呼叫限制,例如并发连接数或对该主机的呼叫失败次数。
可视化
分布式跟踪
多租户管理#
多租户
统一认证
授权系统
可观测性#
多维度监控
定制仪表盘
运维友好:标准接口
第三方兼容性
二级精度的多维度监控
排序
组件监控
子主题2
自定义告警策略和规则
准确的事件跟踪
增强审计安全性
多种通知方式
日志查询与收集#
多租户日志管理
多级日志查询
多种日志收集平台
落盘日志收集功能
应用程序管理和编排#
应用商店
应用资料库
应用程式范本
多种存储解决方案#
多种网络解决方案#
它还支持各种开源存储和网络解决方案以及云存储服务。例如,KubeSphere 为用户提供了功能强大的云原生工具负载均衡器插件 OpenELB,这是为 Kubernetes 集群开发的 CNCF 认证的负载均衡插件#
###
部署#
KubeKey 允许用户直接在基础架构上部署 Kubernetes,为 Kubernetes 集群提供高可用性。建议在生产环境至少配置三个主节点#
KubeKey#
export KKZONE=cn
curl -sfL https://get-kk.kubesphere.io | VERSION=v3.0.2 sh - chmod +x kk
./kk create cluster [--with-kubernetes version] [--with-kubesphere version]
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f
多节点安装#
与All in one 部署相似,需要自定义节点,修改配置config-sample.yaml
./kk create config [-f ~/myfolder/abc.yaml]
若要自定义 Kubernetes 相关参数,请参考 Kubernetes 集群配置
./kk create cluster -f config-sample.yaml
在 Kubernetes 上最小化安装 KubeSphere#
kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.3.1/kubesphere-installer.yaml
kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.3.1/cluster-configuration.yaml
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f
kubectl get svc/ks-console -n kubesphere-system
集群升级和扩展#
KubeKey 提供了一种简单的安装,管理和维护方式。它支持 Kubernetes 集群的滚动升级,以便集群服务在升级时始终可用。另外,也可以使用 KubeKey 将新节点添加到 Kubernetes 集群中以使用更多工作负载。#
启用可插拔组件#
对于大多数可插拔组件,您可以按照以下步骤来启用。如需启用 KubeEdge、容器组 IP 池以及服务拓扑图,请直接参照相应的教程#
无论是在 Linux 上还是在 Kubernetes 上安装 KubeSphere,安装后都可以在 KubeSphere 的 Web 控制台中检查已启用组件的状态#
在 Linux 上安装#
在 Linux 上安装 KubeSphere 时,您需要创建一个默认文件名为 config-sample.yaml 的配置文件。通过执行以下命令来修改文件#
在此文件中,将 enabled 的值从 false 改为 true。这是完整文件供您参考,修改完成后保存文件#
使用该配置文件创建集群:#
./kk create cluster -f config-sample.yaml
在 Kubernetes 上安装#
首先下载 cluster-configuration.yaml 文件,然后打开编辑。#
vi cluster-configuration.yaml
在该本地文件 cluster-configuration.yaml 中,将对应组件 enabled 的值从 false 改为 true。#
kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.3.1/kubesphere-installer.yaml#
kubectl apply -f cluster-configuration.yaml
在安装后启用可插拔组件#
以 admin 身份登录控制台。点击左上角的平台管理 ,然后选择集群管理#
点击定制资源定义,然后在搜索栏中输入 clusterconfiguration,点击搜索结果进入其详情页面#
在自定义资源中,点击 ks-installer 右侧的三个点,然后选择编辑 YAML#
在该配置文件中,将对应组件 enabled 的 false 更改为 true,以启用要安装的组件。完成后,点击确定以保存配置#
执行以下命令,使用 Web kubectl 来检查安装过程:#
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f
k8s名词解释#
pod#
集群上一组运行的容器#
Pod生命周期#
Pod 的 status 定义在 PodStatus 对象中,其中有一个 phase 字段。#
下面是 phase 可能的值: 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
Master#
Master是集群的控制节点#
node#
Master是集群的控制节点#
job#
job 是需要运行完成的确定性的或批量的任务#
Labels#
abels其实就一对 key/value ,其中key与value由用户自己指定。Label可以附加到各种资源对象上。例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label。#
ReplicationController#
RC是K8s系统中的核心概念之一,简单来说,它其实定义了一个期望的场景。即声明某种Pod的副本数量在任意时刻都符合某个预期值#
RC包括以下几个部分:
Pod期待的副本数 用于筛选目标Pod的Label Selector。 当Pod的副本数量小于预期数量时,用于创建新的Pod模板(template)
Deployment#
Deployment在内部使用了Replica Set来实现目的。Deployment相对于RC的一个最大升级是我们可以随时知道当前Pod部署的进度。#
Deployment的使用场景:
创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程。 检查Deployment的状态来看部署动作是否完成。 更新Deployment以创建新的Pod(比如镜像升级) 如果当前的Deployment不稳定,则回滚到早先的Deployment版本 拓展Deployment以应对高负载。 清理不在需要的旧版本ReplicaSets。
Service#
一个Service可以看成一组提供相同服务的Pod的对外访问接口#
Volume#
Kubernetes Volume具有明确的生命周期 - 与pod相同。在容器重新启动时能可以保留数据,当然,当Pod被删除不存在时,Volume也将消失#
Namespace#
命名空间#
子主题12#
Kubernetes 集群的组件#
控制平面组件(Control Plane Components)#
kube-apiserver #
kube-apiserver
API服务器为K8s集群资源操作提供唯一入口,并提供认证、授权、访问控制、API 注册和发现机制。 Kubernetes API 服务器的主要实现是 kube-apiserver。kube-apiserver 设计上考虑了水平伸缩,也就是说,它可通过部署多个实例进行伸缩。你可以运行 kube-apiserver 的多个实例,并在这些实例之间进行流量平衡。
etcd#
etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库(例如 Pod 的数量、状态、命名空间等)、API 对象和服务发现细节。在生产级k8s中etcd通常会以集群的方式存在,安全原因,它只能从 API 服务器访问。
etcd也是k8s生态的关键应用
kube-scheduler#
kube-scheduler 负责监视新创建、未指定运行Node的 Pods,决策出一个让pod运行的节点
例如,如果应用程序需要 1GB 内存和 2 个 CPU 内核,那么该应用程序的 pod 将被安排在至少具有这些资源的节点上。每次需要调度 pod 时,调度程序都会运行。调度程序必须知道可用的总资源以及分配给每个节点上现有工作负载的资源。
调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。
kube-controller-manager#
k8s在后台运行许多不同的控制器进程,当服务配置发生更改时(例如,替换运行 pod 的镜像,或更改配置 yaml 文件中的参数),控制器会发现更改并开始朝着新的期望状态工作。
从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。
控制器包括:
•节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应 •任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成 •端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod) •服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名 空间创建默认帐户和 API 访问令牌
cloud-controller-manager#
云控制器管理器使得你可以将你的集群连接到云提供商的 API 之上, 同时可以将云平台交互组件与本地集群中组件分离。
cloud-controller-manager 仅运行特定于云平台的控制回路。如果我们在自己的环境中运行 Kubernetes,大多数时候非混合云环境是用不到这个组件的。
与 kube-controller-manager 类似,cloud-controller-manager 将若干逻辑上独立的 控制回路组合到同一个可执行文件中,供你以同一进程的方式运行。你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力
下面的控制器都包含对云平台驱动的依赖:
•节点控制器(Node Controller): 用于在节点终止响应后检查云提供商以确定节点是否已被删除 •路由控制器(Route Controller): 用于在底层云基础架构中设置路由 •服务控制器(Service Controller): 用于创建、更新和删除云提供商负载均衡器
Node 组件#
kubelet#
kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器
kube-proxy#
kube-proxy 是集群中每个节点(node)上所运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发
容器运行时(Container Runtime)#
容器运行环境是负责运行容器的软件。
Kubernetes 支持许多容器运行环境,例如 containerd、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现
插件(Addons)#
插件使用 Kubernetes 资源(DaemonSet、 Deployment 等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system 命名空间
DNS#
尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。
集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。
Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。
Web 界面(仪表盘)#
Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除
容器资源监控#
容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供浏览这些数据的界面。
集群层面日志
集群层面日志#
集群层面日志机制负责将容器的日志数据保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口。
longhorn#
Longhorn 是用于 Kubernetes 的轻量级、可靠且功能强大的分布式块存储系统。#
Longhorn使用容器(containers)和微服务(microservices)实现分布式块存储。
Longhorn 为每个块设备卷(device volume)创建一个专用的存储控制器(storage controller), 并跨存储在多个节点上的多个副本同步复制该卷。 存储控制器(storage controller)和副本(replicas)本身是使用 Kubernetes 编排的。
Longhorn 设计有两层:数据平面(data plane)和控制平面(control plane)。#
Longhorn Engine 是存储控制器对应数据平面,Longhorn Manager 对应控制平面。
配置 Pod 以使用卷进行存储#
为 Pod 配置卷#
创建 Pod#
验证 Pod 中的容器是否正在运行,然后留意 Pod 的更改#
在另一个终端,用 Shell 连接正在运行的容器#
在你的 Shell 中,切换到 /data/redis 目录下,然后创建一个文件#
root@redis:/data# cd /data/redis/ root@redis:/data/redis# echo Hello > test-file
在你的 Shell 中,列出正在运行的进程#
root@redis:/data/redis# apt-get update root@redis:/data/redis# apt-get install procps root@redis:/data/redis# ps aux
在你的 Shell 中,结束 Redis 进程#
在你原先终端中,留意 Redis Pod 的更改。最终你将会看到和下面类似的输出#
此时,容器已经终止并重新启动。这是因为 Redis Pod 的 restartPolicy 为 Always。#
Kubernetes 中服务暴露的方式#
hostnetwork#
这是一种直接定义 Pod 网络的方式#
这种 Pod 的网络模式有一个用处就是可以将网络插件包装在 Pod 中然后部署在每个宿主机上,这样该 Pod 就可以控制该宿主机上的所有网络。#
缺点:每次启动这个Pod的时候都可能被调度到不同的节点上,所有外部访问Pod的IP也是变化的,而且调度Pod的时候还需要考虑是否与宿主机上的端口冲突,因此一般情况下除非您知道需要某个特定应用占用特定宿主机上的特定端口时才使用 hostNetwork: true 的方式
hostport#
这是一种直接定义 Pod 网络的方式。#
是直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过宿主机的 IP 加上来访问 Pod 了#
缺点:因为 Pod 重新调度的时候该Pod被调度到的宿主机可能会变动,这样就变化了,用户必须自己维护一个 Pod 与所在宿主机的对应关系。#
nodeport#
NodePort 在 kubenretes 里是一个广泛应用的服务暴露方式。Kubernetes 中的 service 默认情况下都是使用的 ClusterIP 这种类型,这样的 service 会产生一个 ClusterIP,这个 IP 只能在集群内部访问,要想让外部能够直接访问 service,需要将 service type 修改为 nodePort#
同时还可以给 service 指定一个 nodePort 值,范围是 30000-32767,这个值在 API server 的配置文件中,用– service-node-port-range 定义#
集群外就可以使用 kubernetes 任意一个节点的 IP 加上 30000 端口访问该服务了。kube-proxy 会自动将流量以 round-robin 的方式转发给该 service 的每一个 pod。#
缺点:所有 node 上都会开启端口监听,且需要记住端口号。#
loadbalancer#
LoadBalancer 只能在 service 上定义。这是公有云提供的负载均衡器,如 AWS、Azure、CloudStack、GCE 等。#
内部可以使用 ClusterIP 加端口来访问服务,如 19.97.121.42:8086。#
外部可以用以下两种方式访问该服务:
使用任一节点的 IP 加 30051 端口访问该服务 使用 EXTERNAL-IP 来访问,这是一个 VIP,是云供应商提供的负载均衡器 IP,如 10.13.242.236:8086。
缺点:需要云服务商支持#
Ingress#
Ingress 是自 kubernetes1.1 版本后引入的资源类型。必须要部署 Ingress controller 才能创建 Ingress 资源,Ingress controller 是以一种插件的形式提供。Ingress controller 是部署在 Kubernetes 之上的 Docker 容器。它的 Docker 镜像包含一个像 nginx 或 HAProxy 的负载均衡器和一个控制器守护进程。控制器守护程序从 Kubernetes 接收所需的 Ingress 配置。它会生成一个 nginx 或 HAProxy 配置文件,并重新启动负载平衡器进程以使更改生效。换句话说,Ingress controller 是由 Kubernetes 管理的负载均衡器。#
Kubernetes Ingress 提供了负载平衡器的典型特性:HTTP 路由,粘性会话,SSL 终止,SSL 直通,TCP 和 UDP 负载平衡等。目前并不是所有的 Ingress controller 都实现了这些功能,需要查看具体的 Ingress controller 文档。
外部访问 URL http://influxdb.kube.example.com/ping 访问该服务,入口就是 80 端口,然后 Ingress controller 直接将流量转发给后端 Pod,不需再经过 kube-proxy 的转发,比 LoadBalancer 方式更高效。#
缺点:80 端口暴露 必需通过域名引入,而且一次只能一条规则,很麻烦。#
但是在正常的虚拟机环境下,我们只需要一个 IP 地址+端口 即可访问服务
kube-proxy中iptables与ipvs对比#
Iptables模式#
在这种模式下,kube-proxy监视API Server中service和endpoint的变化情况。对于每个service,它都安装iptables规则,这些规则捕获到service的clusterIP和port的流量,并将这些流量随机重定向到service后端Pod。对于每个endpoint对象,它安装选择后端Pod的iptables规则。#
如果选择的第一个Pod没有响应,kube-proxy将检测到到第一个Pod的连接失败,并将自动重试另一个后端Pod
缺陷:#
iptables 因为它纯粹是为防火墙而设计的,并且基于内核规则列表,集群数量越多性能越差。
IPVS模式(NAT模式)#
在这种模式下,kube-proxy监听API Server中service和endpoint的变化情况,调用netlink接口创建相应的ipvs规则,并定期将ipvs规则与Kubernetes服 Services和Endpoints同步。保证IPVS状态。当访问Services时,IPVS将流量定向到后端pod之一。#
IPVS代理模式基于netfilter hook函数,该函数类似于iptables模式,但使用hash表作为底层数据结构,在内核空间中工作。这意味着IPVS模式下的kube-proxy使用更低的重定向流量。其同步规则的效率和网络吞吐量也更高。
说明:#
ipvs依赖iptables进行包过滤、SNAT、masquared(伪装)。 使用 ipset 来存储需要 DROP 或 masquared 的流量的源或目标地址,以确保 iptables 规则的数量是恒定的
ipvs和iptables都是基于netfilter的,他们的差别为:#
ipvs 为大型集群提供了更好的可扩展性和性能 ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权等等) ipvs 支持服务器健康检查和连接重试等功能
k8s 身份认证#
流程#
1.Kubernetes apiserver:对发出请求的用户身份认证,并对请求的 API 路径执行鉴权。#
2.Kubernetes apiserver:将请求转发到扩展 apiserver 3.扩展 apiserver:认证来自 Kubernetes apiserver 的请求 4.扩展 apiserver:对来自原始用户的请求鉴权 5.扩展 apiserver:执行
子主题2#
DevOps#
概述#
DevOps 是一系列做法和工具,可以使 IT 和软件开发团队之间的流程实现自动化。其中,随着敏捷软件开发日趋流行,持续集成 (CI) 和持续交付 (CD) 已经成为该领域一个理想的解决方案。在 CI/CD 工作流中,每次集成都通过自动化构建来验证,包括编码、发布和测试,从而帮助开发者提前发现集成错误,团队也可以快速、安全、可靠地将内部软件交付到生产环境。#
KubeSphere DevOps#
KubeSphere DevOps 项目支持源代码管理工具,例如 GitHub、Git 和 SVN。用户可以通过图形编辑面板 (Jenkinsfile out of SCM) 构建 CI/CD 流水线,或者从代码仓库 (Jenkinsfile in SCM) 创建基于 Jenkinsfile 的流水线。#
功能#
KubeSphere DevOps 系统为您提供以下功能:
独立的 DevOps 项目,提供访问可控的 CI/CD 流水线。 开箱即用的 DevOps 功能,无需复杂的 Jenkins 配置。 支持 Source-to-image (S2I) 和 Binary-to-image (B2I),快速交付镜像。 基于 Jenkinsfile 的流水线,提供一致的用户体验,支持多个代码仓库。 图形编辑面板,用于创建流水线,学习成本低。 强大的工具集成机制,例如 SonarQube,用于代码质量检查。
KubeSphere CI/CD 流水线工作流#
KubeSphere CI/CD 流水线基于底层 Kubernetes Jenkins Agent 而运行。这些 Jenkins Agent 可以动态扩缩,即根据任务状态进行动态供应或释放。Jenkins Controller 和 Agent 以 Pod 的形式运行在 KubeSphere 节点上。Controller 运行在其中一个节点上,其配置数据存储在一个持久卷声明中。Agent 运行在各个节点上,但可能不会一直处于运行状态,而是根据需求动态创建并自动删除。#
当 Jenkins Controller 收到构建请求,会根据标签动态创建运行在 Pod 中的 Jenkins Agent 并注册到 Controller 上。当 Agent 运行完任务后,将会被释放,相关的 Pod 也会被删除。
动态供应 Jenkins Agent#
动态供应 Jenkins Agent 有以下优势:#
资源分配合理:KubeSphere 动态分配已创建的 Agent 至空闲节点,避免因单个节点资源利用率高而导致任务排队等待。
高可扩缩性:当 KubeSphere 集群因资源不足而导致任务长时间排队等待时,您可以向集群新增节点。
高可用性:当 Jenkins Controller 故障时,KubeSphere 会自动创建一个新的 Jenkins Controller 容器,并将持久卷挂载至新创建的容器,保证数据不会丢失,从而实现集群高可用。
使用DevOps#
使用图形编辑面板创建流水线#
KubeSphere 中的图形编辑面板包含用于 Jenkins 阶段 (Stage) 和步骤 (Step) 的所有必要操作。您可以直接在交互式面板上定义这些阶段和步骤,无需创建任何 Jenkinsfile。
流水线概述
阶段 1:Checkout SCM:从 GitHub 仓库拉取源代码。
阶段 2:单元测试:待该测试通过后才会进行下一阶段。 阶段 3:代码分析:配置 SonarQube 用于静态代码分析。 阶段 4:构建并推送:构建镜像并附上标签 snapshot-$BUILD_NUMBER 推送至 Docker Hub,其中 $BUILD_NUMBER 是流水线活动列表中的记录的序列号。 阶段 5:制品:生成一个制品(JAR 文件包)并保存。 阶段 6:部署至开发环境:在开发环境中创建一个部署和一个服务。该阶段需要进行审核,部署成功运行后,会发送电子邮件通知。
-
步骤 4:编辑流水线
* 阶段 1:拉取源代码 (Checkout SCM)
* 阶段 2:单元测试
* 阶段 3:代码分析(可选)
亲和性与反亲和性#
提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。 亲和性和反亲和性扩展了你可以定义的约束类型#
节点亲和性 #
节点亲和性概念上类似于 nodeSelector, 它使你可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种:#
requiredDuringSchedulingIgnoredDuringExecution: 调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector, 但其语法表达能力更强。 preferredDuringSchedulingIgnoredDuringExecution: 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。
你可以使用 Pod 规约中的 .spec.affinity.nodeAffinity 字段来设置节点亲和性#
节点亲和性权重#
你可以为 preferredDuringSchedulingIgnoredDuringExecution 亲和性类型的每个实例设置 weight 字段,其取值范围是 1 到 100。 当调度器找到能够满足 Pod 的其他调度请求的节点时,调度器会遍历节点满足的所有的偏好性规则, 并将对应表达式的 weight 值加和#
Pod 间亲和性与反亲和性#
Pod 间亲和性与反亲和性使你可以基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到的节点,而不是基于节点上的标签。#
Pod 间亲和性与反亲和性的规则格式为“如果 X 上已经运行了一个或多个满足规则 Y 的 Pod, 则这个 Pod 应该(或者在反亲和性的情况下不应该)运行在 X 上”。 这里的 X 可以是节点、机架、云提供商可用区或地理区域或类似的拓扑域, Y 则是 Kubernetes 尝试满足的规则#
Pod 间亲和性与反亲和性的类型 #
与节点亲和性类似,Pod 的亲和性与反亲和性也有两种类型:#
requiredDuringSchedulingIgnoredDuringExecution亲和性配置 preferredDuringSchedulingIgnoredDuringExecution反亲和性配置
为容器分派扩展资源#
要请求扩展资源,需要在你的容器清单中包括 resources:requests 字段。 扩展资源可以使用任何完全限定名称,只是不能使用 *.kubernetes.io/。 有效的扩展资源名的格式为 example.com/foo,其中 example.com 应被替换为 你的组织的域名,而 foo 则是描述性的资源名称#
配置 Pod 使用投射卷作存储#
为 Pod 配置投射卷#
创建 Secret:#
创建 Pod#
确认 Pod 中的容器运行正常,然后监视 Pod 的变化#
在另外一个终端中,打开容器的 shell#
kubectl exec -it test-projected-volume -- /bin/sh
在 shell 中,确认 projected-volume 目录包含你的投射源#
为 Pod 或容器配置安全上下文#
安全上下文(Security Context)定义 Pod 或 Container 的特权与访问控制设置。 安全上下文包括但不限于:#
自主访问控制(Discretionary Access Control): 基于用户 ID(UID)和组 ID(GID) 来判定对对象(例如文件)的访问权限。 安全性增强的 Linux(SELinux): 为对象赋予安全性标签。 以特权模式或者非特权模式运行。 Linux 权能: 为进程赋予 root 用户的部分特权而非全部特权。 AppArmor:使用程序配置来限制个别程序的权能。
Seccomp:过滤进程的系统调用。
allowPrivilegeEscalation:控制进程是否可以获得超出其父进程的特权。 此布尔值直接控制是否为容器进程设置 no_new_privs标志。 当容器满足一下条件之一时,allowPrivilegeEscalation 总是为 true:
以特权模式运行,或者 具有 CAP_SYS_ADMIN 权能 readOnlyRootFilesystem:以只读方式加载容器的根文件系统。
配置 Pod 以使用 PersistentVolume 作为存储#
本文将向你介绍如何配置 Pod 使用 PersistentVolumeClaim 作为存储。 以下是该过程的总结:#
你作为集群管理员创建由物理存储支持的 PersistentVolume。你不会将该卷与任何 Pod 关联。
你现在以开发人员或者集群用户的角色创建一个 PersistentVolumeClaim, 它将自动绑定到合适的 PersistentVolume。
你创建一个使用以上 PersistentVolumeClaim 作为存储的 Pod
为 Pod 配置服务账号#
Kubernetes 提供两种完全不同的方式来为客户端提供支持,这些客户端可能运行在你的集群中, 也可能与你的集群的控制面相关, 需要向 API 服务器完成身份认证。#
服务账号(Service Account)为 Pod 中运行的进程提供身份标识, 并映射到 ServiceAccount 对象。当你向 API 服务器执行身份认证时, 你会将自己标识为某个用户(User)。Kubernetes 能够识别用户的概念, 但是 Kubernetes 自身并不提供 User API。
配置存活、就绪和启动探针#
给容器配置存活(Liveness)、就绪(Readiness)和启动(Startup)探针#
kubelet 使用存活探针来确定什么时候要重启容器。 例如,存活探针可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。#
kubelet 使用就绪探针可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。
kubelet 使用启动探针来了解应用容器何时启动。 如果配置了这类探针,你就可以控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探针不会影响应用的启动。 启动探针可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉
将 Pod 分配给节点#
给节点添加标签#
kubectl label nodes <your-node-name> disktype=ssd
验证你选择的节点确实带有 disktype=ssd 标签:#
kubectl get nodes --show-labels
创建一个将被调度到你选择的节点的 Pod #
Pod 配置文件描述了一个拥有节点选择器 disktype: ssd 的 Pod。这表明该 Pod 将被调度到有 disktype=ssd 标签的节点
创建一个会被调度到特定节点上的 Pod #
通过设置 nodeName 将某个 Pod 调度到特定的节点
用节点亲和性把 Pods 分配到节点#
给节点添加标签#
依据强制的节点亲和性调度 Pod#
清单描述了一个 Pod,它有一个节点亲和性配置 requiredDuringSchedulingIgnoredDuringExecution,disktype=ssd。 这意味着 pod 只会被调度到具有 disktype=ssd 标签的节点上
使用首选的节点亲和性调度 Pod#
清单描述了一个Pod,它有一个节点亲和性设置 preferredDuringSchedulingIgnoredDuringExecution,disktype: ssd。 这意味着 pod 将首选具有 disktype=ssd 标签的节点
为 Pod 配置用户名字空间#
在容器中以 root 用户运行的进程可以以不同的(非 root)用户在宿主机上运行;换句话说, 进程在用户名字空间内部拥有执行操作的全部特权,但在用户名字空间外部并没有执行操作的特权。#
你可以使用这个特性来减少有害的容器对同一宿主机上其他容器的影响。 有些安全脆弱性问题被评为 HIGH or CRITICAL,但当用户名字空间被启用时, 它们是无法被利用的。相信用户名字空间也能减轻一些未来的漏洞的影响。
在不使用用户名字空间的情况下,对于以 root 用户运行的容器而言,发生容器逃逸时, 容器将拥有在宿主机上的 root 特权。如果容器被赋予了某些权限,则这些权限在宿主机上同样有效。 当使用用户名字空间时这些都不可能发生。
创建静态 Pod#
静态 Pod 在指定的节点上由 kubelet 守护进程直接管理,不需要 API 服务器监管。 与由控制面管理的 Pod(例如,Deployment) 不同;kubelet 监视每个静态 Pod(在它失败之后重新启动)。静态 Pod 始终都会绑定到特定节点的 Kubelet 上。#
kubelet 会尝试通过 Kubernetes API 服务器为每个静态 Pod 自动创建一个镜像 Pod。 这意味着节点上运行的静态 Pod 对 API 服务来说是可见的,但是不能通过 API 服务器来控制。 Pod 名称将把以连字符开头的节点主机名作为后缀。
为容器的生命周期事件设置处理函数#
Kubernetes 支持 postStart 和 preStop 事件。 当一个容器启动后,Kubernetes 将立即发送 postStart 事件;在容器被终结之前, Kubernetes 将发送一个 preStop 事件。容器可以为每个事件指定一个处理程序。#
为容器和 Pod 分配内存资源#
指定内存请求和限制#
要为容器指定内存请求,请在容器资源清单中包含 resources:requests 字段。 同理,要指定内存限制,请包含 resources:limits#
超过容器限制的内存#
当节点拥有足够的可用内存时,容器可以使用其请求的内存。 但是,容器不允许使用超过其限制的内存。 如果容器分配的内存超过其限制,该容器会成为被终止的候选容器。 如果容器继续消耗超出其限制的内存,则终止容器。 如果终止的容器可以被重启,则 kubelet 会重新启动它,就像其他任何类型的运行时失败一样。#
该容器反复的在启动和失败
超过整个节点容量的内存#
内存请求和限制是与容器关联的,但将 Pod 视为具有内存请求和限制,也是很有用的。 Pod 的内存请求是 Pod 中所有容器的内存请求之和。 同理,Pod 的内存限制是 Pod 中所有容器的内存限制之和。#
Pod 的调度基于请求。只有当节点拥有足够满足 Pod 内存请求的内存时,才会将 Pod 调度至节点上运行
Pod 处于 PENDING 状态。 这意味着,该 Pod 没有被调度至任何节点上运行,并且它会无限期的保持该状态
如果你没有指定内存限制#
如果你没有为一个容器指定内存限制,则自动遵循以下情况之一:#
容器可无限制地使用内存。容器可以使用其所在节点所有的可用内存, 进而可能导致该节点调用 OOM Killer。 此外,如果发生 OOM Kill,没有资源限制的容器将被杀掉的可行性更大。
运行的容器所在命名空间有默认的内存限制,那么该容器会被自动分配默认限制。 集群管理员可用使用 LimitRange 来指定默认的内存限制。
为容器和 Pods 分配 CPU 资源#
指定 CPU 请求和 CPU 限制#
要为容器指定 CPU 请求,请在容器资源清单中包含 resources: requests 字段。 要指定 CPU 限制,请包含 resources:limits。#
设置超过节点能力的 CPU 请求#
CPU 请求和限制与都与容器相关,但是我们可以考虑一下 Pod 具有对应的 CPU 请求和限制这样的场景。 Pod 对 CPU 用量的请求等于 Pod 中所有容器的请求数量之和。 同样,Pod 的 CPU 资源限制等于 Pod 中所有容器 CPU 资源限制数之和。#
Pod 调度是基于资源请求值来进行的。 仅在某节点具有足够的 CPU 资源来满足 Pod CPU 请求时,Pod 将会在对应节点上运行
输出显示 Pod 状态为 Pending。也就是说,Pod 未被调度到任何节点上运行, 并且 Pod 将无限期地处于 Pending 状态
输出显示由于节点上的 CPU 资源不足,无法调度容器
如果不指定 CPU 限制#
如果你没有为容器指定 CPU 限制,则会发生以下情况之一:#
容器在可以使用的 CPU 资源上没有上限。因而可以使用所在节点上所有的可用 CPU 资源。
容器在具有默认 CPU 限制的名字空间中运行,系统会自动为容器设置默认限制。 集群管理员可以使用 LimitRange 指定 CPU 限制的默认值。
配置 Pod 的服务质量#
Guaranteed 如果Pod中所有Container的所有Resource的limit和request都相等且不为0,则这个Pod的QoS Class就是Guaranteed#
Best-Effort 如果Pod中所有容器的所有Resource的request和limit都没有赋值,则这个Pod的QoS Class就是Best-Effort#
Burstable 除了符合Guaranteed和Best-Effort的场景,其他场景的Pod QoS Class都属于Burstable。 当limit值未指定时,其有效值其实是对应Node Resource的Capacity#
创建包含两个容器的 Pod#
配置 Pod 使用 ConfigMap#
很多应用在其初始化或运行期间要依赖一些配置信息。 大多数时候,存在要调整配置参数所设置的数值的需求。 ConfigMap 是 Kubernetes 的一种机制,可让你将配置数据注入到应用的 Pod 内部。#
ConfigMap 概念允许你将配置清单与镜像内容分离,以保持容器化的应用程序的可移植性。 例如,你可以下载并运行相同的容器镜像来启动容器, 用于本地开发、系统测试或运行实时终端用户工作负载。
属主与依赖 #
Kubernetes 中很多对象通过属主引用 链接到彼此。属主引用(Owner Reference)可以告诉控制面哪些对象依赖于其他对象。 Kubernetes 使用属主引用来为控制面以及其他 API 客户端在删除某对象时提供一个清理关联资源的机会。 在大多数场合,Kubernetes 都是自动管理属主引用的。#
属主关系与某些资源所使用的标签和选择算符不同。 例如,考虑一个创建 EndpointSlice 对象的 Service。 Service 使用标签来允许控制面确定哪些 EndpointSlice 对象被该 Service 使用。 除了标签,每个被 Service 托管的 EndpointSlice 对象还有一个属主引用属性。 属主引用可以帮助 Kubernetes 中的不同组件避免干预并非由它们控制的对象。
##
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构