k8s从入门到实践

k8s从入门到实践

介绍

Kubernetes(简称k8s)和Docker Swarm是两个流行的容器编排工具,它们都可以帮助用户管理和部署分布式应用,尤其是基于容器的应用。以下是两者的主要特点和对比:

  • Kubernetes (k8s)
    • 开源项目:由Google发起,现在由Cloud Native Computing Foundation (CNCF)管理。
      成熟度与社区支持:拥有庞大的开发者社区和生态系统,高度活跃且持续更新迭代,支持众多云服务提供商以及企业内部部署。
    • 功能丰富:提供了丰富的特性集,包括服务发现、自动伸缩、滚动更新、故障恢复、存储卷管理、网络策略、资源调度等。
    • 复杂性:因为其强大的功能和设计目标,Kubernetes的架构和配置相对复杂,对初学者而言学习曲线较陡峭。
    • 可扩展性:可通过CRDs(自定义资源定义)进行扩展,支持各种第三方插件和API以适应更复杂的场景需求。
  • Docker Swarm
    • 原生集成:作为Docker官方开发的集群解决方案,与Docker Engine紧密集成,使用标准的Docker API,对熟悉Docker的用户更为友好。
    • 易用性:相比Kubernetes,Swarm在设置和操作上相对简单,适合轻量级和中小规模的部署场景。
    • 功能范围:虽然也提供基本的服务发现、负载均衡、节点管理等功能,但整体功能集相较于Kubernetes略显简化。
    • 自动化能力:Swarm支持服务复制、滚动更新等基础的自动化运维功能,但在高级调度策略和弹性伸缩方面不如Kubernetes灵活强大。
  • 总结起来,Kubernetes适用于需要大规模、复杂环境和高度自动化运维的企业级应用场景,而Docker Swarm则更适合快速搭建和管理小型或中型容器化应用集群的团队。随着技术发展,虽然Swarm仍然在维护,但Kubernetes因其广泛接受度和丰富生态,在行业中的采用率更高。

基本概念

Kubernetes(k8s)部署工作流程中,涉及多个核心概念和组件。以下是一些基本概念的详解:

  • Pod:
    Pod是Kubernetes中运行容器的基本单元,它代表集群中能够运行应用或服务的一个抽象。一个Pod可以包含一个或多个紧密相关的容器,这些容器共享存储卷、网络命名空间和其他资源。
  • Deployment:
    Deployment是一种声明式更新策略对象,用于管理Pod副本集及其滚动更新、回滚等生命周期操作。通过创建Deployment,你可以指定期望的Pod数量以及Pod的模板定义。
  • 副本集(ReplicaSet):
    副本集中的Pod是无状态的,每个Pod实例之间可以互换。ReplicaSet由Deployment控制,确保任何时刻都有指定数量的Pod副本处于Running状态。当Pod由于各种原因终止时,ReplicaSet会自动创建新的Pod以保持预期的副本数量。
  • 状态集(StatefulSet)
    状态集适用于需要持久化存储和稳定网络标识的有状态应用,如数据库集群、分布式文件系统等。状态集中的Pod是有状态的,每个Pod都有唯一的网络标识符(hostname),并且拥有持久化的存储卷。
  • Service:
    Kubernetes Service是一个抽象层,它定义了一种访问Pod的方式,即使Pod可能会动态地创建或销毁。它提供了负载均衡功能,并且可以通过标签选择器来找到关联的Pod提供服务。
  • ConfigMap & Secret
    ConfigMap用来存储非敏感的应用配置数据,而Secret则用于保存敏感信息如密码、密钥等。两者都可以挂载到Pod中作为环境变量或者文件使用,使得应用程序的配置与代码分离,便于管理和更新。
  • Volume:
    Volume是持久化存储的一种方式,它可以将主机的目录或云存储系统映射到Pod内的容器中,使得容器的数据可以在容器重启后得以保留。
  • Label & Selector
    Label是对Kubernetes对象(如Pod、Service等)进行分类和标识的关键字/值对。Selector则是根据特定的label来查找匹配的对象,例如Deployment使用selector来确定应该管理哪些Pod,Service使用selector来决定将请求路由给哪些Pod。
  • Namespace:
    Namespace为Kubernetes集群内部提供了逻辑上的隔离,允许在一个物理集群内运行多个独立的虚拟集群,每个namespace都有自己的资源分配和名称空间。
  • Horizontal Pod Autoscaler (HPA)
    HPA可以根据CPU使用率或自定义度量指标自动调整Pod的数量,以满足资源需求的变化。
  • Ingress Controller
    Ingress是集群对外暴露HTTP/HTTPS服务的一种方式,它定义了如何将外部请求路由到集群内部的服务。Ingress Controller负责实现Ingress规则并提供负载均衡功能。

部署流程示例

整个部署工作流程通常包括编写YAML文件定义上述资源,然后使用kubectl apply命令将资源配置应用到集群,最后监控和维护这些资源的状态。

  1. 编写YAML/JSON资源定义文件
# MySQL数据库Deployment和Service
---
apiVersion: apps/v1
kind: Deployment # Deployment是一种声明式更新策略对象,用于管理Pod副本集及其滚动更新、回滚等生命周期操作。通过创建Deployment,你可以指定期望的Pod数量以及Pod的模板定义。
metadata:
  name: mysql-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
        volumeMounts:
        - mountPath: /var/lib/mysql
          name: mysql-persistent-storage
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
  - port: 3306
    targetPort: 3306
  clusterIP: None # 如果仅集群内部使用,设置为None;否则,可设置为ClusterIP、NodePort或LoadBalancer

---

# Redis Deployment和Service
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:latest
        ports:
        - containerPort: 6379
        volumeMounts:
        - mountPath: /data
          name: redis-persistent-storage
      volumes:
      - name: redis-persistent-storage
        persistentVolumeClaim:
          claimName: redis-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379
  clusterIP: None # 根据实际需求调整服务类型

---

# Nginx Deployment和Service
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:stable-alpine
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: nginx-config-volume
      volumes:
      - name: nginx-config-volume
        configMap:
          name: nginx-configmap

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer # 对外暴露HTTP服务,可以是NodePort或LoadBalancer类型
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

---

# 微服务文件服务Deployment和Service(假设名为file-service)
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: file-service-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: file-service
  template:
    metadata:
      labels:
        app: file-service
    spec:
      containers:
      - name: file-service
        image: your-file-service-image:latest
        ports:
        - containerPort: 8080 # 根据实际端口调整
        env:
        - name: DB_HOST
          value: mysql-service
        - name: REDIS_HOST
          value: redis-service
        - name: OTHER_SERVICE_CONFIG # 其他环境变量...

---
apiVersion: v1
kind: Service
metadata:
  name: file-service-service
spec:
  selector:
    app: file-service
  ports:
  - port: 8080
    targetPort: 8080

# 定时任务服务类似上述方式进行定义...

k8s特性分析

服务发现

它允许系统中的组件无需知道彼此的具体网络位置(例如IP地址和端口),即可相互通信。

自动伸缩

  1. 水平自动伸缩 (Horizontal Pod Autoscaling, HPA): HPA可以根据CPU使用率、内存使用率或其他自定义度量标准来动态调整Deployment、ReplicaSet或StatefulSet中的Pod数量。当监控到的目标资源使用率超过或低于设定阈值时,HPA控制器会相应地增加或减少Pod的副本数。
   apiVersion: autoscaling/v2beta2
   kind: HorizontalPodAutoscaler
   metadata:
     name: my-app-hpa
     namespace: default
   spec:
     scaleTargetRef:
       apiVersion: apps/v1
       kind: Deployment
       name: my-app-deployment
     minReplicas: 2 # 最小副本数
     maxReplicas: 10 # 最大副本数
     metrics:
     - type: Resource
       resource:
         name: cpu
         targetAverageUtilization: 50 # 目标CPU使用率为50%
# 在这个示例中,Kubernetes将监控my-app-deployment的平均CPU使用率,并保持在50%左右。如果CPU使用率高于50%,HPA将增加Pod的副本数量;反之,如果低于50%,则可能减少副本数量,但始终保持至少2个副本。
  1. 垂直自动伸缩 (Vertical Pod Autoscaling, VPA): VPA可以自动调整单个Pod的资源请求(如CPU和内存)。它分析Pod的资源利用率历史记录并基于这些数据动态更新Pod的资源请求,确保Pod能够得到足够的资源而又不会过度分配。
   apiVersion: "autoscaling.k8s.io/v1"
   kind: VerticalPodAutoscaler
   metadata:
     name: my-app-vpa
     namespace: default
   spec:
     targetRef:
       apiVersion: "apps/v1"
       kind: Deployment
       name: my-app-deployment
     updatePolicy:
       updateMode: "Auto" # 自动模式下,VPA会自动调整Pod资源请求

滚动更新

在Kubernetes(k8s)中,滚动更新是一种升级应用的策略,它允许您在不停止服务的情况下逐步替换集群中的Pod。通过这种方法,可以确保在整个更新过程中始终有部分Pod运行旧版本的应用程序,另一部分Pod运行新版本的应用程序,从而实现业务连续性和零停机时间。

滚动更新详细说明:

  • 操作方式: 当您更改了Deployment或StatefulSet资源对象的Pod模板(例如更新镜像标签),Kubernetes会自动触发滚动更新过程。更新过程是增量式的,每次只更新一部分Pod,而不是一次性替换所有Pod。
  • 更新策略
    • maxUnavailable:定义在更新过程中最多可以有多少比例或数量的Pod不可用。
    • maxSurge:定义在更新过程中可以额外创建多少比例或数量的Pod来加快更新速度。
    • 生命周期钩子: Kubernetes支持预停止(preStop)和后启动(postStart)等生命周期钩子,可以在Pod被终止前执行清理任务或者在Pod启动时执行初始化任务。
  • 回滚机制: 如果新的Pod无法正常启动或健康检查失败,Kubernetes能够自动回滚到更新前的状态,以保持服务稳定。
  • 进度追踪: 更新过程中,您可以观察到每个Pod的状态变化,并且控制平面会监控整个更新流程,确保满足用户指定的更新策略
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 3 # 假设我们希望有3个副本
  selector:
    matchLabels:
      app: MyApp
  template:
    metadata:
      labels:
        app: MyApp
    spec:
      containers:
      - name: my-app-container
        image: registry.example.com/my-app:v1 # 老版本镜像
        ports:
        - containerPort: 80
      strategy:
        type: RollingUpdate # 指定滚动更新策略类型
        rollingUpdate:
          maxUnavailable: 1 # 允许最多一个Pod不可用
          maxSurge: 1 # 在更新期间最多增加一个额外的Pod

# 若要进行滚动更新,只需修改容器镜像为新版本:
# 将上面的 "image: registry.example.com/my-app:v1" 改为 "image: registry.example.com/my-app:v2"

故障恢复

在Kubernetes(k8s)中,故障恢复是通过一系列内置机制实现的,这些机制确保了即使在节点或Pod出现故障时,也能自动进行恢复以保持集群服务的高可用性和稳定性。以下是Kubernetes中主要的故障恢复机制

  • 自我修复能力
    健康检查和就绪探针:Kubernetes使用liveness probe和readiness probe来监控Pod的状态。如果一个Pod不健康(liveness probe失败),Kubernetes会重新启动该Pod;如果Pod未准备好处理请求(readiness probe失败),则不会将其流量分发到该Pod,直到它通过健康检查。
     apiVersion: v1
     kind: Pod
     metadata:
       name: my-app-pod
     spec:
       containers:
       - name: my-app-container
         image: my-app:v1
         ports:
           - containerPort: 80
         livenessProbe: # 健康检查
           httpGet:
             path: /health
             port: 80
           initialDelaySeconds: 30
           periodSeconds: 10
         readinessProbe: # 就绪探针
           httpGet:
             path: /ready
             port: 80
           initialDelaySeconds: 5
           periodSeconds: 10
    
  • 副本集和状态集
    • 副本集(ReplicaSet):用于确保指定数量的Pod实例始终运行。当某个Pod因任何原因终止时,ReplicaSet将创建新的Pod来替换它。
    • 状态集(StatefulSet):对于需要稳定唯一标识符和持久存储的应用程序,StatefulSet会在保证有序更新和缩放的同时,提供Pod的故障恢复功能
  • 节点失败
    当节点(构成k8s集群的单个物理或虚拟计算设备)由于硬件故障、网络中断、软件错误等原因无法正常工作时,kubelet无法向API服务器发送心跳,则节点会被标记为不可调度,并且其上的Pod会被重新调度到健康的节点上运行。
  • 网络策略和负载均衡
    网络策略和服务资源可以确保即使某些Pod因为故障而不可达,客户端仍然可以通过Service的IP地址访问到后端正常工作的Pod,从而实现服务级别的故障恢复。
  • 持久化存储
    使用持久卷(PersistentVolume)和持久卷声明(PersistentVolumeClaim),数据可以在Pod重启或节点失效时得以保留,确保应用的数据完整性。
  • 资源限制和QoS
    Kubernetes通过设置资源限制和质量等级(QoS)对Pod进行管理和优化,避免资源不足导致的系统级问题,并优先保证重要Pod的资源供应。
    综上所述,Kubernetes通过多个层次的设计和自动化控制实现了从Pod级别到整个集群层面的故障恢复机制,确保应用程序能够在面临各种故障场景时快速恢复并继续提供服务。

存储卷管理

在Kubernetes(k8s)中,存储卷管理是其核心特性之一,用于提供持久化存储解决方案。通过存储卷管理功能,用户可以将集群外部的存储资源以统一、可移植的方式挂载到Pod中的容器内,使得容器应用能够安全地存储和访问数据,即使在Pod被重新调度或终止时也能保留数据。
Kubernetes存储卷的主要特点与功能

  • 持久化存储: 存储卷是一种抽象,它允许Pod中的容器共享或独立使用同一块存储空间。当Pod因任何原因被删除或重启时,存储卷的数据不会丢失,从而实现应用数据的持久化。
  • 多种存储类型支持: Kubernetes支持多种类型的存储系统,包括本地存储(Local)、网络存储(如NFS、iSCSI等)、云提供商特定的存储服务(如AWS EBS、GCP Persistent Disk、Azure Disk、Azure File等)以及分布式文件系统(如CephFS、GlusterFS、Cinder、RBD等)
  • 动态存储供应:
    PersistentVolume (PV):是由集群管理员配置和提供的存储资源。
    PersistentVolumeClaim (PVC):是由用户创建的请求存储资源的对象,PVC会绑定到合适的PV上,实现动态供应存储。
  • 存储卷的生命周期管理:存储卷的生命周期管理包括创建、使用、删除和回收。Kubernetes提供多种存储卷管理工具,包括存储卷管理器、存储卷挂载器和存储卷挂载器,用于管理存储卷的生命周期。
  • 多容器共享存储: 同一个Pod内的多个容器可以共享同一个存储卷,方便了容器之间的数据共享和通信。
  • 临时存储: 除了持久化存储,Kubernetes还支持临时存储卷,例如emptyDir,这种类型的卷只存在于Pod的生命周期内,当Pod被删除时,该卷上的数据也会随之消失。
  • 其他特殊用途的存储卷: 如 downwardAPI 可以将Pod元信息写入卷;configMap 和 secret 可以将配置信息和敏感信息作为卷挂载到容器内部。

网络策略

在Kubernetes(k8s)中,网络策略(NetworkPolicy)是一种用于控制集群内Pod之间网络流量的机制。它允许管理员定义特定的规则来决定哪些Pod可以与指定的目标Pod进行通信,从而实现对集群内部网络访问的细粒度控制。
网络策略的主要功能和特性:

  • 基于标签选择器的规则制定: 网络策略通过匹配目标Pod的标签来应用规则,允许或拒绝来自带有特定标签Pod的流量。
  • 方向性控制: 规则可以针对流入(ingress)或流出(egress)流量设置,分别控制进入Pod的流量和从Pod发出的流量。
  • 协议与端口过滤: 网络策略可以基于TCP、UDP或SCTP协议,并且可以指定端口号,以精确地控制网络流量。
  • 源IP地址段限制: 支持基于IP CIDR范围来指定允许或拒绝特定源IP地址段的流量。
  • 多规则组合: 一个网络策略可以包含多个规则,这些规则可以并行执行,共同构建复杂的网络访问控制策略。
  • 第三方网络插件支持: Kubernetes本身并不直接提供网络策略的实施,而是依赖于支持网络策略功能的网络插件,如Calico、Cilium、Romana等。
    网络策略示例
# 该策略仅允许来自具有app=backend标签的Pod访问具有app=frontend标签的Pod的80端口:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-backend-to-frontend
spec:
  podSelector:
    matchLabels:
      app: frontend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 80

在这个例子中,如果有一个Pod被标记为app=frontend,那么只有同样被标记为app=backend的Pod才能向其80端口发起连接请求。其他未匹配此策略的Pod将无法访问这个前端服务。

资源协调

在Kubernetes(k8s)中,资源调度是整个集群管理系统的核心功能之一。它负责将Pod(包含一个或多个容器的最小可部署单元)分配到集群中的适当节点上运行,以实现高效、稳定和安全的服务部署。以下是关于Kubernetes资源调度的详细说明:

  • 调度过程:
    当用户创建一个新的Pod时,该Pod会被提交至Kubernetes API Server。
    调度器(kube-scheduler)会持续监听API Server,并处理未被调度的Pod。
    调度器根据一系列预定义策略对所有节点进行评估,包括但不限于:
    资源需求匹配:确保目标节点有足够的CPU、内存等资源供Pod使用。
    标签亲和性/反亲和性(NodeAffinity):基于节点标签选择特定的节点。
    污点与容忍度(Taints and Tolerations):控制哪些Pod可以被调度到带有特定污点标记的节点上。
    Pod间亲和性和反亲和性(Inter-Pod Affinity/Anti-Affinity):确保Pod与其他Pod在物理位置上的分布关系。
  • 调度算法:
    Kubernetes调度器采用了多阶段决策框架,每个阶段可以包含多个插件,这些插件用于执行不同的调度策略和约束条件。
    **预选阶段(Predicates)**筛选出满足基本条件的节点列表。
    **打分阶段(Priorities)**为通过预选阶段的节点打分,根据得分高低确定最终调度节点。
  • 扩展性与自定义调度:
    用户可以根据实际需求编写自定义调度器插件来扩展默认的调度策略。
    通过配置调度器组件,可以调整调度策略参数,以适应不同业务场景。
  • 调度约束与优化:
    考虑Pod之间的依赖关系,如服务发现、数据同步等。
    考虑节点区域可用区分布以实现跨地域容灾和负载均衡。
    对于有状态应用,调度器还会考虑StatefulSet内的有序调度需求。
  • 动态调度与再调度:
    当集群环境发生变化,例如节点故障、新增节点或资源利用率不均时,Kubernetes能够重新评估并调整已部署的Pod。
    在Pod无法正常运行、节点出现故障或需要进行滚动更新等情况下,Kubernetes会触发自动的Pod重新调度。
    综上所述,Kubernetes资源调度是一个复杂而灵活的过程,旨在通过综合考量各种因素,在大规模分布式环境中实现高效且稳定的容器编排和服务管理。

你可能感兴趣的:(kubernetes,容器,云原生)