K8S声明式API和控制器模式

K8S是Kubernetes的简称,它是一个开源的容器编排系统,用于自动化应用容器的部署、扩展和管理。

Kubernetes的核心组件:

  1. Master节点:Master节点包含了控制Kubernetes集群的组件。这些组件包括kube-apiserver、kube-controller-manager和kube-scheduler。
  2. Worker节点:Worker节点运行应用容器,并包含必要的组件来运行这些容器,包括kubelet和kube-proxy。
  3. Etcd:Etcd是一个分布式的键值存储系统,用于保存Kubernetes所有的集群数据。
  4. Kube-apiserver:Kube-apiserver是Kubernetes API的主要实现,它用于暴露Kubernetes API。
  5. Kube-controller-manager:Kube-controller-manager负责运行Kubernetes控制器,如节点控制器、副本控制器等。
  6. Kube-scheduler:Kube-scheduler负责在集群中的Worker节点上调度Pods。
  7. Kubelet:Kubelet负责在每一个Worker节点上启动、停止和维护Pods。
  8. Kube-proxy:Kube-proxy为Kubernetes Service实现网络代理,这是每个节点上的网络规则,允许网络请求从外部网络到达Pods。

以上这些是Kubernetes的主要组件,每一个都有它自己的特定的职责,并共同工作以保持集群的健康状态。这种架构设计使Kubernetes能够提供高度的可扩展性和可靠性,以满足不同的复杂应用部署需求。

在声明式API中,您定义资源的期望状态并将其提交给Kubernetes API服务器。Kubernetes控制器管理器会持续监视提交的资源定义,并采取行动以使实际状态与期望状态一致。

下面是使用Kubernetes声明式API创建资源的示例:

Pod是Kubernetes的最小可部署单元,它包含一个或多个容器。在Pod中的容器会共享存储和网络。

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: myapp
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
  • apiVersion: v1:指定你正在使用的Kubernetes API的版本来创建这个服务。
  • kind:Pod:定义正在创建的Kubernetes对象的种类,在这个案例中,是一个Pod。
  • metadata: name:nginx-pod:元数据字段被用来命名服务对象为"myapp"。
  • spec: selector: app:myapp:这个字段被用来选择服务将路由流量的Pod。在这种情况下,它选择带有标签 "app=myapp" 的Pod。
  • spec: containers: - name: nginx:在Pod规范中,定义一个名为 "nginx" 的容器。
  • image: nginx:1.14.2:指定应该为容器使用版本为1.14.2的nginx镜像。
  • kind: Pod

Deployment是一种抽象资源对象,用于定义和管理应用程序的副本数量和更新策略,以实现应用程序的高可用性和弹性。它提供了一种简单的方式来部署和扩展应用程序,并自动处理副本的创建、更新和回滚等操作。

yaml 复制代码
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
        image: nginx:1.14.2
        ports:
        - containerPort: 80
  • apiVersion: apps/v1:指定用于创建Deployment对象的API版本。
  • kind: Deployment:定义正在创建的Kubernetes对象的种类,在这种情况下,是Deployment。
  • metadata: name: nginx-deployment:元数据字段用于将Deployment对象命名为"nginx-deployment"。
  • spec: replicas: 3:在spec字段下,规定应有3个Pod的副本。
  • selector: matchLabels: app: nginx:此字段用于选择Deployment管理的Pod。在这种情况下,它正在选择带有标签"app=nginx"的pods。
  • template: metadata: labels: app: nginx:它正在为创建新的Pods定义一个模板。在这里,任何新创建的Pods将带有"app=nginx"的标签。
  • spec: containers: - name: nginx:在Pod spec中,它定义了一个名为"nginx"的容器。
  • image: nginx:1.14.2:指定应该为容器使用nginx版本1.14.2的镜像。
  • ports: - containerPort: 80:它声明nginx容器应该暴露端口80。

Service是Kubernetes提供的一种抽象,它定义了访问Pod的统一方式,如负载均衡和服务发现。

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  • apiVersion: v1:指定您正在使用的Kubernetes API的版本来创建此服务。
  • kind: Service:定义正在创建的Kubernetes对象的类型,在这种情况下,是一个服务。
  • metadata: name: my-service:元数据字段用于将服务对象命名为"my-service"。
  • spec: selector: app: MyApp:此字段用于选择服务将路由流量的Pods。在这种情况下,它正在选择带有标签"app=MyApp"的Pods。
  • ports: - protocol: TCP:此字段指定服务将路由TCP流量。
  • port: 80:这是可以访问服务的端口。
  • targetPort: 9376:这是服务将路由流量的Pods上的端口。被这个服务选中的Pods应该在这个端口上监听他们的应用程序。

Ingress是一种API对象,允许外部访问集群内的服务。它充当流量路由器和负载均衡器,根据Ingress资源中定义的规则将传入的流量定向到相应的服务。它提供了一种配置HTTP和HTTPS路由、虚拟主机和SSL/TLS终止的方式。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /echo
            pathType: Prefix
            backend:
              service:
                name: echo-server
                port:
                  number: 80
  • apiVersion: networking.k8s.io/v1:指定创建Ingress时使用的API版本。
  • kind: Ingress:定义要创建的Kubernetes对象的类型,即Ingress。
  • metadata: name: my-ingress:元数据字段用于将Ingress对象命名为"my-ingress"。
  • spec: rules:该字段指定Ingress的路由规则。
  • host: example.com:此规则匹配主机头设置为"example.com"的请求。
  • http: paths:该字段定义要匹配规则的HTTP路径。
  • path: /echo:该规则匹配路径为"/echo"的请求。
  • pathType: Prefix:路径匹配类型,设置为"Prefix"以匹配具有给定前缀的路径。
  • backend: service:该字段指定要将流量路由到的后端服务。
  • name: echo-server:流量将被定向到的Service的名称。
  • port: number: 80:应该处理流量的Service的目标端口。

IngressClass是一个资源,定义了Ingress控制器的类别。它允许你指定控制器的实现细节和处理Ingress资源的配置选项。Ingress控制器使用这些信息来确定它们应该处理的Ingress规则。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: my-ingress-class
spec:
  controller: my-ingress-controller
  parameters:
    apiGroup: networking.k8s.io/v1
    kind: IngressClass
    name: my-ingress-class
  • apiVersion: networking.k8s.io/v1:指定创建IngressClass时使用的API版本。
  • kind: IngressClass:定义要创建的Kubernetes对象的类型,即IngressClass。
  • metadata: name: my-ingress-class:元数据字段用于将IngressClass对象命名为"my-ingress-class"。
  • spec: controller: my-ingress-controller:指定应处理与此类关联的Ingress对象的Ingress控制器的名称。
  • parameters: apiGroupkindname:这些字段定义了特定于Ingress控制器的其他参数。

Ingress Controller是负责处理Ingress资源并管理集群中服务的入站流量的组件。它通常作为一个单独的进程运行,并与底层基础架构交互以配置必要的路由规则。

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kong-ingress-controller
  namespace: kong
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kong-ingress-controller
  template:
    metadata:
      labels:
        app: kong-ingress-controller
    spec:
      containers:
      - name: kong-ingress-controller
        image: kong/kubernetes-ingress-controller:1.4
        env:
        - name: KONG_PROXY_LISTEN
          value: "0.0.0.0:8000, 0.0.0.0:8443 ssl"
        - name: KONG_ADMIN_LISTEN
          value: "0.0.0.0:8444 ssl"
        - name: KONG_DATABASE
          value: "postgres"
        - name: KONG_PG_HOST
          value: "kong-database.default.svc.cluster.local"
        - name: KONG_PG_USER
          value: "kong"
        - name: KONG_PG_PASSWORD
          value: "kong"
        - name: KONG_PG_DATABASE
          value: "kong"
  • replicas:指示要运行的Kong Ingress Controller副本(Pod)数量。
  • selector:指定用于选择由此部署控制的Pod的标签。
  • metadata
    • labels:用于标识由此部署控制的Pod的标签。
    • spec
    • containers:指定在Pod中运行的容器。
      • name:指定容器的名称。
      • image:指定Kong Ingress Controller的容器镜像。
      • env:指定容器的环境变量。
        • KONG_PROXY_LISTEN:定义Kong应监听传入请求的IP地址和端口。
        • KONG_ADMIN_LISTEN:定义Kong管理界面的IP地址和端口。
        • KONG_DATABASE:指定Kong的后端数据库(例如:"postgres"、"cassandra"等)。
        • KONG_PG_HOST:指定Kong使用的PostgreSQL数据库的主机名。
        • KONG_PG_USER:指定连接到PostgreSQL数据库的用户名。
        • KONG_PG_PASSWORD:指定连接到PostgreSQL数据库的密码。
        • KONG_PG_DATABASE:指定Kong使用的PostgreSQL数据库的名称。

我们通过一个deployment来部署一个nginx服务器

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-container
          image: nginx:latest
          ports:
            - containerPort: 80

在此示例中,我们定义了一个名为my-deployment的Deployment资源,有三个副本。Deployment管理一组Pod,每个Pod基于给定的模板创建。模板指定了一个名为my-container的容器,它使用nginx:latest镜像在端口80上运行。

使用kubectl命令应用配置

复制代码
kubectl apply -f deployment.yaml

kubectl apply命令将deployment.yaml文件提交给Kubernetes API服务器。服务器处理YAML文件并创建所需的Deployment和相关资源。

检查Deployment的状态:

arduino 复制代码
kubectl get deployment my-deployment

kubectl get命令检索Deployment的当前状态。您应该会看到类似以下的输出:

vbnet 复制代码
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-deployment   3/3     3            3           1m

输出表示Deployment有三个副本,所有副本都已准备就绪并可用。

更新Deployment: 修改deployment.yaml文件,将副本数从3更改为5:

ini 复制代码
kubectl scale deployment my-deployment --replicas=5

使用与之前相同的kubectl apply命令应用更新后的配置:

复制代码
kubectl apply -f deployment.yaml

Kubernetes控制平面检测到期望状态的更改,并采取必要的操作进行调和将副本数扩展为5。

vbnet 复制代码
    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    my-deployment   5/5     5            5           2m

通过使用Kubernetes声明式API,您可以使用配置文件定义和管理Kubernetes资源的期望状态,并将其存储在ETCD中,K8S中控制器用于监控集群中资源状态的变化,通过调协将资源的实际运行状态不断向期望状态靠拢,所以当控制器发现期望副本数变为5时,而集群中应用副本数实际状态为3,就会创建2个pod以达到实际状态与期望状态相匹配。

Reference

相关推荐
我命由我123452 小时前
Java 泛型 - Java 泛型通配符(上界通配符、下界通配符、无界通配符、PECS 原则)
java·开发语言·后端·java-ee·intellij-idea·idea·intellij idea
szhf782 小时前
SpringBoot Test详解
spring boot·后端·log4j
无尽的沉默2 小时前
SpringBoot整合Redis
spring boot·redis·后端
摸鱼的春哥2 小时前
春哥的Agent通关秘籍07:5分钟实现文件归类助手【实战】
前端·javascript·后端
Victor3563 小时前
MongoDB(2)MongoDB与传统关系型数据库的主要区别是什么?
后端
JaguarJack3 小时前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端·php·服务端
BingoGo3 小时前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端
Victor3563 小时前
MongoDB(3)什么是文档(Document)?
后端
牛奔5 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
想用offer打牌10 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp