掘金 后端 ( ) • 2024-04-04 11:44

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

kubernetes-cluster-architecture.svg

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中的容器会共享存储和网络。

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

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的统一方式,如负载均衡和服务发现。

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终止的方式。

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规则。

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资源并管理集群中服务的入站流量的组件。它通常作为一个单独的进程运行,并与底层基础架构交互以配置必要的路由规则。

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服务器

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的状态:

kubectl get deployment my-deployment

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

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-deployment   3/3     3            3           1m

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

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

kubectl scale deployment my-deployment --replicas=5

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

kubectl apply -f deployment.yaml

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

    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    my-deployment   5/5     5            5           2m

image.png

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

Reference