Kubernetes核心概念基本操作

1.1 Namespace命名空间

1.1.1 Namespace核心概念

Kubernetes 的 Namespace(命名空间)是一种用于创建逻辑隔离分区的机制,它的主要作用是用来实现多套环境的资源隔,它允许用户在同一个物理集群中模拟出多个虚拟集群的效果。以下是 Namespace 的一些关键特点和用途:

  • 资源隔离:Namespace 允许你将集群内的资源划分为不同的组,每个组内的资源是相互隔离的。这可以防止不同组之间的资源冲突,提高集群的安全性。

  • 多租户支持:通过为每个租户分配一个独立的 Namespace,Kubernetes 可以支持多租户部署。每个租户只能在自己的 Namespace 内创建和管理资源,无法访问其他 Namespace 的资源。

  • 资源配额:Kubernetes 允许你为每个 Namespace 设置资源配额(Resource Quotas),限制该 Namespace 可以使用的资源总量(如 CPU、内存等)。这有助于防止资源的过度使用,并确保关键应用有足够的资源可用。

  • 命名空间的生命周期管理:Namespace 有其生命周期,可以被创建、配置、删除等。通过管理 Namespace 的生命周期,可以更好地控制资源的分配和使用。

  • 默认命名空间:在 Kubernetes 中,default 是一个特殊的 Namespace,如果没有明确指定 Namespace,所有的资源默认会被创建在 default Namespace 中。

  • 授权和访问控制:Kubernetes 的 RBAC(基于角色的访问控制)机制允许你为不同的 Namespace 设置不同的权限,控制用户对资源的访问。

  • 网络隔离:虽然 Kubernetes 的 Namespace 主要用于逻辑隔离,但也可以与网络策略(Network Policies)结合使用,实现一定程度的网络隔离。

  • 监控和日志:在 Namespace 级别进行监控和日志记录可以简化管理,因为你可以针对特定的 Namespace 进行资源使用分析和问题排查。

  • 部署和测试:Namespace 常用于开发、测试和生产环境的隔离。例如,开发团队可以在自己的 Namespace 中部署和测试新的应用版本,而不会影响到生产环境。

  • 清理资源:Namespace 可以方便地用于资源的批量删除。当你需要删除一个项目或应用的所有资源时,只需删除对应的 Namespace 即可。

image-20240507094734904

kubernetes在集群启动之后,会默认创建几个namespace

[root@K8s-master ~]# kubectl get namespaces 
NAME              STATUS   AGE
default           Active   2d19h  #创建资源时没有指定特定的Namespace,会被自动分配到 default Namespace中
kube-node-lease   Active   2d19h  #集群节点之间的心跳维护,v1.13开始引入
kube-public       Active   2d19h  #此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system       Active   2d19h  #所有由Kubernetes系统创建的资源都处于这个命名空间

1.1.2 基本操作

1.1.2.1 查看
[root@K8s-master ~]# kubectl get namespaces 
NAME              STATUS   AGE
default           Active   2d19h
kube-node-lease   Active   2d19h
kube-public       Active   2d19h
kube-system       Active   2d19h
[root@K8s-master ~]# kubectl get ns  #ns为简写
NAME              STATUS   AGE
default           Active   2d19h
kube-node-lease   Active   2d19h
kube-public       Active   2d19h
kube-system       Active   2d19h
[root@K8s-master ~]# kubectl get ns default  #查看指定的命名空间
NAME      STATUS   AGE
default   Active   2d19h
[root@K8s-master ~]# kubectl get ns default -o yaml  #-o指定查看格式
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2024-05-04T06:23:23Z"
  labels:
    kubernetes.io/metadata.name: default
  name: default
  resourceVersion: "199"
  uid: 6568a7d2-64a2-484f-a01d-aa914ad9f8f0
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
[root@K8s-master ~]# kubectl get ns default -o json
{
    "apiVersion": "v1",
    "kind": "Namespace",
    "metadata": {
        "creationTimestamp": "2024-05-04T06:23:23Z",
        "labels": {
            "kubernetes.io/metadata.name": "default"
        },
        "name": "default",
        "resourceVersion": "199",
        "uid": "6568a7d2-64a2-484f-a01d-aa914ad9f8f0"
    },
    "spec": {
        "finalizers": [
            "kubernetes"
        ]
    },
    "status": {
        "phase": "Active"
    }
}
[root@K8s-master ~]# kubectl describe ns default   #查看详情
Name:         default
Labels:       kubernetes.io/metadata.name=default
Annotations:  <none>
Status:       Active
​
No resource quota.
​
No LimitRange resource.
1.1.2.2 创建删除
[root@K8s-master ~]# kubectl create ns test
namespace/test created
[root@K8s-master ~]# kubectl delete ns test
namespace "test" deleted
[root@K8s-master ~]# vim test.yml  #yaml文件创建
---
apiVersion: v1
kind: Namespace
metadata:
  name: test
​
[root@K8s-master ~]# kubectl apply -f test.yml 
namespace/test created
[root@K8s-master ~]# kubectl get ns test
NAME   STATUS   AGE
test   Active   10s
[root@K8s-master ~]# kubectl delete ns test
namespace "test" deleted

1.2 Pod最小调度单元

  • Pod 在 Kubernetes 中是最基本的部署单元,它是一个逻辑实体,用于封装一个或多个容器(通常是 Docker 容器),这些容器共享网络和存储资源。Pod 的设计目的是作为运行应用程序的一个单元,使得容器可以作为一个整体进行管理。

1.2.1 Pod 的核心概念

特性描述
共享资源Pod 内的容器共享网络和存储资源,如存储卷和网络接口。
协同工作Pod 支持运行协同工作的容器,它们可以作为一个整体运行。
生命周期管理Pod 内的容器要么同时运行,要么同时停止,便于统一管理。
环境隔离每个 Pod 拥有独立的 IP 地址和运行环境,实现资源隔离。
易于部署和管理Pod 作为部署单元,简化了容器化应用程序的部署和管理。
服务发现和负载均衡Pod 可以被 Kubernetes 服务发现,支持负载均衡。
健康检查Kubernetes 可以对 Pod 进行健康检查,并在必要时重启容器。
标签和选择器Pod 可以被赋予标签,与选择器结合使用,实现基于标签的管理。

image-20240507100835180

kubernetes在集群启动之后,集群中的各个组件也都是以Pod方式运行的。

[root@K8s-master ~]# kubectl get pod -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-74586cf9b6-96v5x             1/1     Running   0          2d19h
coredns-74586cf9b6-f5q7h             1/1     Running   0          2d19h
etcd-k8s-master                      1/1     Running   0          2d19h
kube-apiserver-k8s-master            1/1     Running   0          2d19h
kube-controller-manager-k8s-master   1/1     Running   0          2d19h
kube-flannel-ds-6gqmv                1/1     Running   0          2d18h
kube-flannel-ds-g7zcj                1/1     Running   0          2d18h
kube-flannel-ds-hh52b                1/1     Running   0          2d18h
kube-proxy-glhml                     1/1     Running   0          2d18h
kube-proxy-klcs2                     1/1     Running   0          2d18h
kube-proxy-x9v8k                     1/1     Running   0          2d19h
kube-scheduler-k8s-master            1/1     Running   0          2d19h
​
- coredns:提供集群内部的 DNS 服务。
- etcd:用于存储集群状态的分布式键值存储。
- kube-apiserver:API 服务器,对外提供 Kubernetes API。
- kube-controller-manager:控制器管理器,负责各种控制器的运行。
- kube-flannel-ds:Flannel 是一个网络插件,提供覆盖网络。
- kube-proxy:负责实现 Kubernetes 服务的网络代理。
- kube-scheduler:调度器,负责 Pod 的调度。

1.2.2 Pod的基本操作

1.2.2.1 创建并运行
  • kubernetes没有提供单独运行Pod的命令,都是通过Pod控制器来实现的

  • 命令格式: kubectl run (pod控制器名称) [参数]

    • kubectl run (pod控制器名称):这是创建 Pods 的基本命令格式,其中 pod控制器名称 是您希望给这个 Pod 控制器(通常是 Deployment 或 Pod)的名称。

    • --image:指定用于创建 Pod 的容器镜像的名称。这个参数是必须的,因为 Kubernetes 需要知道使用哪个镜像来运行容器。

    • --port:指定容器内部的端口,以便 Kubernetes 可以知道如何将容器的端口映射到 Pod 上。这通常用于服务发现和负载均衡。

    • --namespace:指定 Pod 应该创建在哪个 Kubernetes Namespace 中。如果不指定,默认是在 default Namespace。

    • --replicas:指定创建的 Pod 副本数量。对于 Deployment 类型的控制器,默认为 1。

    • --labels:为 Pod 添加标签,以便于后续的查询和选择。

    • --env:设置环境变量,传递给容器的配置信息。

    • --restart:设置重启策略,如 AlwaysOnFailureNever

    • --overrides:用于指定一个 JSON 格式的字符串,其中包含一个或多个字段,用于覆盖生成的 Pod 模板。

[root@K8s-master ~]# kubectl run nginx --image=nginx --port=80 --namespace test  #拉圈一个Nginx镜像
pod/nginx created
[root@K8s-master ~]# kubectl get pod -n test
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          10s
[root@K8s-master ~]# kubectl get pod -n test -o wide
NAME    READY   STATUS    RESTARTS   AGE     IP           NODE          NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          2m40s   10.244.2.3   k8s-node-02   <none>           <none>
1.2.2.2 访问Pod
[root@K8s-master ~]# curl 10.244.2.3   #只能再集群内部访问
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
​
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
​
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
1.2.2.3 删除指定Pod
[root@K8s-master ~]# kubectl delete pod nginx -n test
pod "nginx" deleted
[root@K8s-master ~]# kubectl get pods -n test
No resources found in test namespace.
1.2.2.4 配置写法
[root@K8s-master ~]# vim nginx.yml
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: test
spec:
  containers:
    - image: nginx
      name: pod
      ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
​
[root@K8s-master ~]# kubectl apply -f nginx.yml 
pod/nginx created
[root@K8s-master ~]# kubectl get pod -n test
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          14s

1.3 Label标签

在 Kubernetes 中,Label(标签)是一种附加到资源(如 Pods、Services、Deployments 等)上的键值对,用于标识资源的特征或属性。Label 的设计目的主要是为了帮助用户以灵活和强大的方式来组织和选择资源。

1.3.1 Label特性

  • 键值对:Label 是由一个键(Key)和一个值(Value)组成的,例如 environment=production

  • 资源标识:Label 允许用户为资源定义自定义标识符,这些标识符可以用于区分和选择资源。

  • 选择器(Selectors):Kubernetes 中的选择器可以根据 Label 来选择一组资源。例如,一个 Deployment 可以定义一个选择器来指定它应该管理哪些带有特定 Label 的 Pods。

  • 批量操作:通过 Label,用户可以轻松地对带有相同 Label 的资源执行批量操作,如启动、停止或更新一组 Pods。

  • 组织和分类:Label 可以用于不同的目的,比如环境(开发、测试、生产)、应用程序版本、服务所有者等。

  • 动态查询:Kubernetes 提供了基于 Label 的查询功能,允许用户动态查询带有特定 Label 的资源。

  • 无需预定义:与某些系统不同,Kubernetes 不要求预定义 Label。用户可以根据自己的需要自由地添加和使用 Label。

  • 不唯一性:单个资源可以有多个 Label,且 Label 本身不要求唯一性。

  • 命名空间内有效:Label 在定义它们的命名空间内有效,不同命名空间的资源可以有相同的 Label。

  • 用于服务发现:在某些情况下,Label 可以用于服务发现,尤其是当结合服务选择器(Service Selectors)时。

1.3.2 Label 的使用场景:

  • 版本标签:用于标识资源的版本,如 version: releaseversion: stable

  • 环境标签:用于标识资源所属的环境,如 environment: devenvironment: testenvironment: prod

  • 架构标签:用于标识资源在系统架构中的角色,如 tier: frontendtier: backend

1.3.3 Label Selector标签选择器

  • Label Selector 用于查询和筛选具有特定标签的资源对象。

1.3.3.1 基于等式的 Label Selector:
  • name = slave:选择所有包含键为 name 且值为 slave 的 Label 的对象。

  • env != production:选择所有包含键为 env 且值不等于 production 的 Label 的对象。

1.3.3.2 基于集合的 Label Selector:
  • name in (master, slave):选择所有包含键为 name 且值为 masterslave 的 Label 的对象。

  • name not in (frontend):选择所有包含键为 name 且值不等于 frontend 的 Label 的对象。

1.3.3.3 合多个 Label Selector:
  • 可以使用多个 Label Selector 进行组合,使用逗号 , 分隔。

  • 例如:name=slave,env!=productionname not in (frontend),env!=production

1.3.3 Label基本操作

1.3.3.1 设置更新Label
[root@K8s-master ~]# kubectl label pod nginx version=1.0 -n test  #为Pod打标签
pod/nginx labeled
[root@K8s-master ~]# kubectl label pod nginx version=2.0 -n test --overwrite   #更新标签
pod/nginx labeled
1.3.3.2 查看标签
[root@K8s-master ~]# kubectl get pod nginx -n test --show-labels
NAME    READY   STATUS    RESTARTS   AGE   LABELS
nginx   1/1     Running   0          18m   version=2.0
1.3.3.3 筛选标签
[root@K8s-master ~]# kubectl get pod -n test -l version!=2.0 --show-labels  #筛选把版本不为2.0的
No resources found in test namespace.
[root@K8s-master ~]# kubectl get pod -n test -l version=2.0 --show-labels   #筛选把版本为2.0的
NAME    READY   STATUS    RESTARTS   AGE   LABELS
nginx   1/1     Running   0          21m   version=2.0
1.3.3.4 删除标签
[root@K8s-master ~]# kubectl label pod nginx version- -n test
pod/nginx unlabeled
[root@K8s-master ~]# kubectl get pod nginx -n test --show-labels
NAME    READY   STATUS    RESTARTS   AGE   LABELS
nginx   1/1     Running   0          25m   <none>

1.3.4 Label配置文件编写

[root@K8s-master ~]# vim nginx.yml
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: test
  labels:
    env: "test"
    version: "3.0"
spec:
  containers:
    - image: nginx
      name: pod
      ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
[root@K8s-master ~]# kubectl apply -f nginx.yml 
pod/nginx created
[root@K8s-master ~]# kubectl get pod -n test --show-labels
NAME    READY   STATUS    RESTARTS   AGE   LABELS
nginx   1/1     Running   0          70s   env=test,version=3.0

1.4 Deployment控制器

  • 在 Kubernetes 中,虽然 Pod 是最小的控制单元,但直接操作 Pod 并不是常见的做法。相反,Kubernetes 通常使用 Pod 控制器(Pod Controller)来管理和维护 Pod。Pod 控制器是一种高层次的 API 对象,它负责确保容器运行在 Pod 中的副本数量始终符合用户定义的预期状态。

  • Deployment 是 Kubernetes 中最常用的 Pod 控制器之一,它提供了一种声明式更新 Pod 的方法。

image-20240507112202600

1.4.1 Deployment特性

  • 声明式管理:用户可以声明他们希望 Pod 达到的状态,而无需了解如何达到该状态的具体细节。

  • 自动滚动更新:Deployment 支持无停机更新(zero-downtime updates),即滚动更新。在更新过程中,旧版本的 Pods 会逐渐被新版本的 Pods 替换。

  • 副本保证:确保指定数量的 Pod 副本始终运行。如果由于故障导致 Pod 终止,Deployment 会自动创建新的 Pod 来替换。

  • 版本控制和回滚:Deployment 会自动保存历史版本,用户可以选择回滚到之前的版本。

  • 健康检查:可以配置健康检查来确定何时 Pod 准备好接收流量,以及何时 Pod 应该被替换。

  • 水平扩展:Deployment 允许用户根据需要手动扩展 Pod 的副本数量,或者配置自动扩展规则。

  • 标签和选择器:Deployment 使用标签来选择要管理的 Pod。选择器确保 Deployment 管理与指定标签匹配的 Pod。

  • 环境隔离:不同的 Deployment 可以用于不同的环境,如开发、测试和生产环境,每个环境可以有不同的配置。

  • 资源配额和限制:可以为 Deployment 配置资源配额和限制,以控制 Pod 使用的资源。

  • 策略和调度:可以为 Deployment 指定调度策略,例如亲和性规则或污点容忍,以控制 Pod 在集群中的调度方式。

1.4.2 基本操作

  • 命令格式: kubectl run deployment名称 [参数]

  • 参数

    • --image:指定用于创建 Pod 的容器镜像的名称。这个参数是必需的,因为 Kubernetes 需要知道使用哪个镜像来运行容器。

    • --port:指定容器内部的端口,这样 Kubernetes 可以知道如何将容器的端口映射到 Pod 上。这通常用于服务发现和负载均衡。

    • --replicas:指定创建的 Pod 副本数量。这是为了确保高可用性,即使某些 Pod 发生故障,也能保证服务的持续性。

    • --namespace:指定 Deployment 应该创建在哪个 Kubernetes Namespace 中。如果不指定,Deployment 默认会被创建在 default Namespace。

    • --labels:为 Deployment 添加标签,以便于后续的查询和选择。

    • --env:设置环境变量,传递给容器的配置信息。

    • --restart:设置重启策略,如 AlwaysOnFailureNever

    • --overrides:用于指定一个 JSON 格式的字符串,其中包含一个或多个字段,用于覆盖生成的 Pod 模板。

1.4.2.1 创建运行Deployment
[root@K8s-master ~]# kubectl create deployment nginx-01 --image nginx --port 80 --replicas 3 -n test
deployment.apps/nginx-01 created
1.4.2.2 查看
[root@K8s-master ~]# kubectl get deployments.apps -n test  #3个都运行起来了
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
nginx-01   3/3     3            3           98s
[root@K8s-master ~]# kubectl get pod -n test
NAME                        READY   STATUS    RESTARTS   AGE
nginx                       1/1     Running   0          28m
nginx-01-6c7d9d55d9-2cvw5   1/1     Running   0          13s
nginx-01-6c7d9d55d9-tqx5t   1/1     Running   0          13s
nginx-01-6c7d9d55d9-vdhrj   1/1     Running   0          13s
[root@K8s-master ~]# kubectl get deployments.apps -n test -o wide
NAME       READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES   SELECTOR
nginx-01   3/3     3            3           4m51s   nginx        nginx    app=nginx-01
# UP-TO-DATE:成功升级的副本数量
# AVAILABLE:可用副本的数量
[root@K8s-master ~]# kubectl describe deployments.apps nginx-01 -n test  #查看详细信息
1.4.2.3 删除
[root@K8s-master ~]# kubectl delete pod nginx-01-6c7d9d55d9-2cvw5 -n test  #删除其中一个Pod
pod "nginx-01-6c7d9d55d9-2cvw5" deleted
[root@K8s-master ~]# kubectl get pod -n test  #立马会再重启一个Pod
NAME                        READY   STATUS    RESTARTS   AGE
nginx                       1/1     Running   0          38m
nginx-01-6c7d9d55d9-flvcz   1/1     Running   0          57s
nginx-01-6c7d9d55d9-tqx5t   1/1     Running   0          109s
nginx-01-6c7d9d55d9-vdhrj   1/1     Running   0          109s
[root@K8s-master ~]# kubectl delete deployments.apps nginx-01 -n test  #删除控制器
deployment.apps "nginx-01" deleted

1.4.3 配置文件编写

[root@K8s-master ~]# vim nginx.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: test
spec:
  replicas: 3
  selector:
    matchLabels:
      run: nginx
  template:
    metadata:
      labels:
        run: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          protocol: TCP
          
[root@K8s-master ~]# kubectl apply -f deploy-nginx.yml 
deployment.apps/nginx created
[root@K8s-master ~]# kubectl get pod -n test --show-labels
NAME                     READY   STATUS    RESTARTS   AGE     LABELS
nginx                    1/1     Running   0          50m     env=test,version=3.0
nginx-7b59b97bcf-dlzsk   1/1     Running   0          2m15s   pod-template-hash=7b59b97bcf,run=nginx
nginx-7b59b97bcf-lt4rl   1/1     Running   0          2m15s   pod-template-hash=7b59b97bcf,run=nginx
nginx-7b59b97bcf-qvpqf   1/1     Running   0          2m15s   pod-template-hash=7b59b97bcf,run=nginx
属性描述
apiVersionKubernetes API 的版本,这里是 apps/v1
kind资源类型,这里是 Deployment
metadata资源的元数据,包括名称和命名空间。
nameDeployment 的名称,这里是 nginx
namespaceDeployment 所在的命名空间,这里是 test
spec资源的规格说明,定义了 Deployment 的期望状态。
replicas期望的 Pod 副本数量,这里是 3
selector用于选择要管理的 Pods 的标签选择器。
matchLabels匹配的标签,这里是 run: nginx
templatePod 模板,定义了 Deployment 创建的 Pod 的规格。
metadataPod 的元数据,包括标签。
labelsPod 的标签,这里是 run: nginx
specPod 的规格,定义了 Pod 内部的容器设置。
containersPod 中的容器列表。
name容器的名称,这里是 nginx
image容器使用的镜像,这里是 nginx
ports容器需要暴露的端口列表。
containerPort容器内部的端口号,这里是 80
protocol端口使用的协议,这里是 TCP

1.5 Service

1.5.1 Service介绍

  • 在 Kubernetes 架构中,Service 是一种核心的抽象概念,用于定义访问一组具有相同功能的 Pods 的策略。Service 为 Pods 提供了一种稳定和统一的访问方法,无论 Pods 的数量如何变化,或者它们的 IP 地址如何变化,Service 都保持不变。

  • Service可以看作是一组同类Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。

  • 在 Kubernetes 集群中,每个 Pod 被分配一个唯一的 IP 地址(Pod IP),用于 Pod 之间的网络通信。然而,Pod IP 地址确实存在一些限制,这可能会导致服务访问和管理上的困难,为了解决这些问题,Kubernetes 引入了 Service 这一抽象

    • Pod IP 的变化:当 Pod 被删除并重新创建时(例如,由于故障、缩放操作或部署更新),它将获得一个新的 IP 地址。这意味着如果直接使用 Pod IP 来通信,客户端需要处理 IP 地址变化的情况。

    • Pod IP 的可见性:Pod IP 是虚拟的,并且只在 Kubernetes 集群内部可见。这意味着从集群外部无法直接访问 Pod。

image-20240507120633140

[root@K8s-master ~]# kubectl get pod -n test -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE          NOMINATED NODE   READINESS GATES
nginx                    1/1     Running   0          4h40m   10.244.2.5    k8s-node-02   <none>           <none>
nginx-7b59b97bcf-dlzsk   1/1     Running   0          3h52m   10.244.2.11   k8s-node-02   <none>           <none>
nginx-7b59b97bcf-lt4rl   1/1     Running   0          3h52m   10.244.2.10   k8s-node-02   <none>           <none>
nginx-7b59b97bcf-qvpqf   1/1     Running   0          3h52m   10.244.1.7    k8s-node-01   <none>           <none>
​
#这里nginx-7b59b97bcf-qvpqf的IP为10.244.1.7
[root@K8s-master ~]# kubectl delete pod nginx-7b59b97bcf-qvpqf -n test   #删除这个Pod
pod "nginx-7b59b97bcf-qvpqf" deleted
[root@K8s-master ~]# kubectl get pod -n test -o wide  
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE          NOMINATED NODE   READINESS GATES
nginx                    1/1     Running   0          4h42m   10.244.2.5    k8s-node-02   <none>           <none>
nginx-7b59b97bcf-dlzsk   1/1     Running   0          3h54m   10.244.2.11   k8s-node-02   <none>           <none>
nginx-7b59b97bcf-lt4rl   1/1     Running   0          3h54m   10.244.2.10   k8s-node-02   <none>           <none>
nginx-7b59b97bcf-xxhfv   1/1     Running   0          41s     10.244.1.8    k8s-node-01   <none>           <none>
​
#自动生成Pod nginx-7b59b97bcf-xxhfv的IP变为10.244.1.8

1.5.2 基本操作

1.5.2.1 搭建集群内部可访问的Service
[root@K8s-master ~]# kubectl expose deployment nginx --name=svc-nginx-01 --type=ClusterIP --port=80 --target-port=80 -n test
service/svc-nginx-01 exposed
[root@K8s-master ~]# kubectl get service svc-nginx-01 -n test -o wide
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE   SELECTOR
svc-nginx-01   ClusterIP   10.110.170.62   <none>        80/TCP    80s   run=nginx
# 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的
# 可以通过这个IP访问当前service对应的POD
[root@K8s-master ~]# curl http://10.110.170.62
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
​
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
​
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
1.5.2.2 搭建集群外部可访问的Service
  • 上面创建的Service的type类型为ClusterIP,这个ip地址只用集群内部可访问

  • 如果需要创建外部也可以访问的Service,需要修改type为NodePort

[root@K8s-master ~]# kubectl expose deployment nginx --name=svc-nginx-02 --type=NodePort --port=80 --target-port=80 -n test
service/svc-nginx-02 exposed
[root@K8s-master ~]# kubectl get service svc-nginx-02 -n test -o wide
NAME           TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE   SELECTOR
svc-nginx-02   NodePort   10.108.6.6   <none>        80:31690/TCP   28s   run=nginx
[root@K8s-master ~]# curl http://192.168.110.21:31690
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
​
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
​
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
  • ClusterIP:

    • 服务仅在 Kubernetes 集群内部可访问。

    • 通过集群内部的 IP 地址进行访问。

    • 这是默认的服务类型。

  • ExternalName:

    • 服务不直接暴露任何 Pod,而是指向外部的 DNS 名称。

    • kubedns 或类似的 DNS 服务会返回一个 CNAME 记录,指向这个外部名称。

    • 这种方式通常用于将服务映射到外部服务上,比如指向一个外部数据库或 API。

  • LoadBalancer:

    • 服务将通过外部负载均衡器暴露给外部访问(如果云服务提供商支持)。

    • 除了提供 ClusterIP 类型的内部访问外,还会分配一个外部可访问的地址。

    • 这通常用于让外部用户能够访问集群中的服务。

  • NodePort:

    • 服务将在集群中所有节点的特定端口上暴露。

    • 结合了 ClusterIP 类型,允许集群外部通过节点的 IP 地址和指定端口访问服务。

    • 这种方式适用于需要从集群外部访问服务,但不希望或不需要使用外部负载均衡器的情况。

1.5.2.3 删除Service
[root@K8s-master ~]# kubectl delete service svc-nginx-01 -n test
service "svc-nginx-01" deleted
[root@K8s-master ~]# kubectl delete service svc-nginx-02 -n test
service "svc-nginx-02" deleted

1.5.3 配置文件编写

[root@K8s-master ~]# vim svc-nginx.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nginx
  namespace: test
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    run: nginx
  type: NodePort
  
[root@K8s-master ~]# kubectl apply -f svc-nginx.yaml 
service/svc-nginx created
[root@K8s-master ~]# kubectl get service -n test
NAME        TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
svc-nginx   NodePort   10.102.4.48   <none>        80:31832/TCP   27s

1.6 Kubernetes开启IPVS

Kubernetes 开启 IPVS(IP Virtual Server)主要是因为 IPVS 提供了一些关键优势,这些优势对于大规模生产环境来说非常重要:

  • 高性能:IPVS 作为内核空间的一部分,可以提供比用户空间的代理更高的吞吐量和更低的延迟。这是因为所有的网络操作都在内核空间中完成,减少了上下文切换的开销。

  • 更好的扩展性:IPVS 支持大量的并发连接,这对于处理成千上万的 Pod 和服务的 Kubernetes 集群来说是必要的。

  • 负载均衡:IPVS 支持多种负载均衡算法,如轮询(round-robin)、最少连接(least-connection)、源地址哈希(source IP hash)等,这允许 Kubernetes 根据需要选择最合适的算法。

  • 会话保持:IPVS 可以实现会话保持功能,确保来自同一客户端的请求总是被定向到后端的同一个 Pod,这对于维护状态的应用程序非常重要。

  • 健康检查:IPVS 可以与 Kubernetes 的健康检查机制集成,自动将流量从不健康的后端 Pod 重定向到健康的 Pod。

  • 安全性:IPVS 运行在内核空间,相比用户空间的网络服务,更不容易受到外部攻击。

  • 直接服务器响应(DSR):IPVS 支持直接服务器响应模式,可以减少数据包的复制开销,提高效率。

  • 节省资源:由于 IPVS 是内核模块,它比用户空间的负载均衡器更节省资源。

[root@K8s-master ~]# ipvsadm -Ln   #默认没有开启
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

1.6.1 加载内核模快

[root@K8s-master ~]# lsmod | grep ip_vs
ip_vs_sh               12288  0 
ip_vs_ftp              12288  0 
nf_nat                 57344  5 ip6table_nat,xt_nat,iptable_nat,xt_MASQUERADE,ip_vs_ftp
ip_vs_sed              12288  0 
ip_vs_dh               12288  0 
ip_vs_lblcr            12288  0 
ip_vs_lblc             12288  0 
ip_vs_wrr              12288  0 
ip_vs_rr               12288  0 
ip_vs_wlc              12288  0 
ip_vs_lc               12288  0 
ip_vs                 200704  20 ip_vs_wlc,ip_vs_rr,ip_vs_dh,ip_vs_lblcr,ip_vs_sh,ip_vs_lblc,ip_vs_wrr,ip_vs_lc,ip_vs_sed,ip_vs_ftp
nf_conntrack          188416  6 xt_conntrack,nf_nat,xt_nat,nf_conntrack_netlink,xt_MASQUERADE,ip_vs
nf_defrag_ipv6         24576  2 nf_conntrack,ip_vs
libcrc32c              12288  5 nf_conntrack,nf_nat,nf_tables,xfs,ip_vs

1.6.2 修改kube-proxy配置

[root@K8s-master ~]# kubectl edit configmap kube-proxy -n kube-system    
    mode: "ipvs"  #修改此处,默认为空

1.6.3 删除所有kube-proxy的pod

[root@K8s-master ~]# kubectl get pod -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-74586cf9b6-96v5x             1/1     Running   0          3d2h
coredns-74586cf9b6-f5q7h             1/1     Running   0          3d2h
etcd-k8s-master                      1/1     Running   0          3d2h
kube-apiserver-k8s-master            1/1     Running   0          3d2h
kube-controller-manager-k8s-master   1/1     Running   0          3d2h
kube-flannel-ds-6gqmv                1/1     Running   0          3d
kube-flannel-ds-g7zcj                1/1     Running   0          3d
kube-flannel-ds-hh52b                1/1     Running   0          3d
kube-proxy-glhml                     1/1     Running   0          3d1h
kube-proxy-klcs2                     1/1     Running   0          3d1h
kube-proxy-x9v8k                     1/1     Running   0          3d2h
kube-scheduler-k8s-master            1/1     Running   0          3d2h
[root@K8s-master ~]# kubectl delete pod kube-proxy-glhml kube-proxy-klcs2 kube-proxy-x9v8k -n kube-system
pod "kube-proxy-glhml" deleted
pod "kube-proxy-klcs2" deleted
pod "kube-proxy-x9v8k" deleted
[root@K8s-master ~]# kubectl get pod -n kube-system   #会重新生成新的Pod
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-74586cf9b6-96v5x             1/1     Running   0          3d2h
coredns-74586cf9b6-f5q7h             1/1     Running   0          3d2h
etcd-k8s-master                      1/1     Running   0          3d2h
kube-apiserver-k8s-master            1/1     Running   0          3d2h
kube-controller-manager-k8s-master   1/1     Running   0          3d2h
kube-flannel-ds-6gqmv                1/1     Running   0          3d
kube-flannel-ds-g7zcj                1/1     Running   0          3d
kube-flannel-ds-hh52b                1/1     Running   0          3d
kube-proxy-bwxdq                     1/1     Running   0          31s
kube-proxy-rvfgk                     1/1     Running   0          31s
kube-proxy-tm4pt                     1/1     Running   0          31s
kube-scheduler-k8s-master            1/1     Running   0          3d2h

1.6.4 查看

[root@K8s-master ~]# kubectl logs kube-proxy-bwxdq -n kube-system | grep ipvs
I0507 08:40:20.093060       1 server_others.go:269] "Using ipvs Proxier"
I0507 08:40:20.093080       1 server_others.go:271] "Creating dualStackProxier for ipvs"
[root@K8s-master ~]# kubectl logs kube-proxy-rvfgk -n kube-system | grep ipvs
I0507 08:40:19.845750       1 server_others.go:269] "Using ipvs Proxier"
I0507 08:40:19.845811       1 server_others.go:271] "Creating dualStackProxier for ipvs"
[root@K8s-master ~]# kubectl logs kube-proxy-tm4pt -n kube-system | grep ipvs
I0507 08:40:20.310143       1 server_others.go:269] "Using ipvs Proxier"
I0507 08:40:20.310171       1 server_others.go:271] "Creating dualStackProxier for ipvs"
[root@K8s-master ~]# ipvsadm -Ln    #默认调度算法为轮询
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.110.21:31832 rr
  -> 10.244.1.8:80                Masq    1      0          0         
  -> 10.244.2.10:80               Masq    1      0          0         
  -> 10.244.2.11:80               Masq    1      0          0         
TCP  10.96.0.1:443 rr
  -> 192.168.110.21:6443          Masq    1      0          0         
TCP  10.96.0.10:53 rr
  -> 10.244.1.2:53                Masq    1      0          0         
  -> 10.244.1.3:53                Masq    1      0          0         
TCP  10.96.0.10:9153 rr
  -> 10.244.1.2:9153              Masq    1      0          0         
  -> 10.244.1.3:9153              Masq    1      0          0         
TCP  10.102.4.48:80 rr
  -> 10.244.1.8:80                Masq    1      0          0         
  -> 10.244.2.10:80               Masq    1      0          0         
  -> 10.244.2.11:80               Masq    1      0          0         
TCP  10.244.0.0:31832 rr
  -> 10.244.1.8:80                Masq    1      0          0         
  -> 10.244.2.10:80               Masq    1      0          0         
  -> 10.244.2.11:80               Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.1.2:53                Masq    1      0          0         
  -> 10.244.1.3:53                Masq    1      0          0         
  • 11
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值