07--kubernetes.deploy与service

news2024/11/15 8:47:25

前言:这一章主要是deploy与service的配置及其原理,以及一些细节上的补充,同时还会附上镜像拉取策略和容器健康检查的一些操作实例,内容比较多,建议根据目录查看。

1、镜像拉取策略

IfNotPresent:在镜像已经存在的情况下,kubelet将不再去拉取镜像,仅当本地缺失时才会从仓库中拉取,这是默认的镜像拉取策略。

Alaways:每次创建Pod都会重新拉取一次镜像,无论本地是否有镜像。

Never:Pod不会主动拉取这个镜像,即使无法创建pod,也仅使用本地镜像。

注意:对于标签为latest的镜像文件,其默认的镜像获取策略即为Always,而对于其他标签的镜像,其默认策略则为IfNotPresent。

下面演示一下这三种镜像拉取策略配置:

1)使用always策略下载镜像

[root@k8s-master1 imagePullPolicy]# pwd
/root/pod.yaml.d/imagePullPolicy
[root@k8s-master1 imagePullPolicy]# vim always-test.yaml
[root@k8s-master1 imagePullPolicy]# cat always-test.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: always-pod
spec:
  nodeName: k8s-node1
  containers:
    - name: nginx
      image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:latest
      imagePullPolicy: Always

此时两个node上都有该镜像

创建pod,并查看创建详情

[root@k8s-master1 imagePullPolicy]# kubectl apply -f always-test.yaml 
pod/always-pod created
[root@k8s-master1 imagePullPolicy]# kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
always-pod   1/1     Running   0          64s
[root@k8s-master1 imagePullPolicy]# kubectl describe pod always-pod

创建详情能看到重新拉取镜像的过程

2)使用IfNotPresent策略下载镜像

[root@k8s-master1 imagePullPolicy]# kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
always-pod   1/1     Running   0          6m14s
[root@k8s-master1 imagePullPolicy]# kubectl delete pod always-pod
pod "always-pod" deleted
[root@k8s-master1 imagePullPolicy]# cat always-test.yaml > ifnotpresent-test.yaml


[root@k8s-master1 imagePullPolicy]# vim ifnotpresent-test.yaml 
[root@k8s-master1 imagePullPolicy]# cat ifnotpresent-test.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: ifnotpresent-pod
spec:
  nodeName: k8s-node1
  containers:
    - name: nginx
      image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:latest
      imagePullPolicy: IfNotPresent

创建pod,并查看创建详情

[root@k8s-master1 imagePullPolicy]# kubectl apply -f ifnotpresent-test.yaml 
pod/ifnotpresent-pod created
[root@k8s-master1 imagePullPolicy]# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
ifnotpresent-pod   1/1     Running   0          2s
[root@k8s-master1 imagePullPolicy]# kubectl describe pod ifnotpresent-pod

 创建详情,因为node上本身保存有该镜像,所以并没有拉取镜像过程

3)使用Never策略下载镜像

[root@k8s-master1 imagePullPolicy]# kubectl delete pod ifnotpresent-pod
pod "ifnotpresent-pod" deleted
[root@k8s-master1 imagePullPolicy]# cat always-test.yaml > never-test.yaml


[root@k8s-master1 imagePullPolicy]# vim never-test.yaml 
[root@k8s-master1 imagePullPolicy]# cat never-test.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: never-pod
spec:
  nodeName: k8s-node1
  containers:
    - name: nginx
      image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:latest
      imagePullPolicy: Never

此时创建pod,详情如下

删除创建的pod以及node节点保存的镜像文件,再次创建,情况如下,创建失败报错

2、Deployment

Deployment 是一种用于定义和管理多个副本应用的新一代对象,相比于 Replication Controller,它提供了更完善的功能,使用起来更加简便。其主要功能包括:

  • 保证一定数量的副本始终可用,以防某个 Pod 故障导致服务中断。
  • Pod 定义发生变化时进行滚动更新(Rolling Update),第一个更新成功方可更新第二个,否则自动终止更新。

Deployment 通过“控制器”模式(controller pattern)管理 Pod。例如,当请求创建三个 Tomcat Pod 时,Deployment 记录这一请求并确保集群中始终保持三个副本。如果一个 Pod 被删除,Deployment 会自动创建一个新的 Pod 以维持副本数量,从而保证应用程序的高可用性。

Deployment 通过标签管理副本。例如:

Deployment 副本:3(标签选择器:app: tomcat)
Tomcat Pods:
tomcat-pod1(标签:app: tomcat)
tomcat-pod2(标签:app: tomcat)
tomcat-pod3(标签:app: tomcat)

Deployment 实际上管理这些带有特定标签的 Pod,确保 Pod 数量与预期一致。

Deployment 的使用流程如下:

    1、使用 YAML 文件创建 Deployment。
    2、Deployment 的创建过程细分为以下步骤:
        用户通过 kubectl 创建 Deployment。
        Deployment 创建一个 ReplicaSet。
        ReplicaSet 创建 Pod。

对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字

2.1、deployment操作演示

[root@k8s-master1 ~]# mkdir deployment.yaml.d
[root@k8s-master1 ~]# cd deployment.yaml.d/
[root@k8s-master1 deployment.yaml.d]# vim deployment.yaml
[root@k8s-master1 deployment.yaml.d]# cat deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
spec:
  selector:      #标签选择器
    matchLabels:
      app: nginx    #标签
  replicas: 2    #创建两个pod
  template:
    metadata:
      labels:
        app: nginx    #标签
    spec:
      containers:
      - name: nginx
        image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1
        ports:
        - containerPort: 80
        volumeMounts:
         - name: nginx-vol
           mountPath: "/usr/share/nginx/html"
      volumes:
      - name: nginx-vol
        emptyDir: {}    #这里挂一个空文件

创建deployment,并查看相关资源对象

[root@k8s-master1 deployment.yaml.d]# kubectl apply -f deployment.yaml 
deployment.apps/nginx-deployment created

[root@k8s-master1 deployment.yaml.d]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-65f474ff44-84lqh   1/1     Running   0          18s
nginx-deployment-65f474ff44-gmhld   1/1     Running   0          18s

[root@k8s-master1 deployment.yaml.d]# kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           49s

[root@k8s-master1 deployment.yaml.d]# kubectl get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           56s

此时外部访问pod_ip结果为403(空目录覆盖了原有文件)

尝试删除一个pod,deployment会瞬间创建一个新的pod

[root@k8s-master1 deployment.yaml.d]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-65f474ff44-84lqh   1/1     Running   0          4m33s
nginx-deployment-65f474ff44-gmhld   1/1     Running   0          4m33s
[root@k8s-master1 deployment.yaml.d]# kubectl delete pod nginx-deployment-65f474ff44-84lqh
pod "nginx-deployment-65f474ff44-84lqh" deleted
[root@k8s-master1 deployment.yaml.d]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-65f474ff44-gmhld   1/1     Running   0          5m5s
nginx-deployment-65f474ff44-kgwnl   1/1     Running   0          15s

想要删除这两个pod只能删除控制器有两种方式:

  • kubectl删除控制器yaml文件
  • kubectl delete deployment nginx-deployment

2.2、deployment扩容

首先创建一个replicas: 1的deployment,并应用

[root@k8s-master1 deployment.yaml.d]# vim deployment.yaml
[root@k8s-master1 deployment.yaml.d]# cat deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1
        ports:
        - containerPort: 80
        volumeMounts:
         - name: nginx-vol
           mountPath: "/usr/share/nginx/html"
      volumes:
      - name: nginx-vol
        emptyDir: {}
[root@k8s-master1 deployment.yaml.d]# kubectl apply -f deployment.yaml 
deployment.apps/nginx-deployment created
[root@k8s-master1 deployment.yaml.d]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-65f474ff44-454mt   1/1     Running   0          3s
[root@k8s-master1 deployment.yaml.d]# kubectl get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           43

此时因为业务需要对整体进行扩容,只需将replicas改为2,重新应用,即可完成扩容,取消/增减卷挂载同样操作即可。

[root@k8s-master1 deployment.yaml.d]# vim deployment.yaml
[root@k8s-master1 deployment.yaml.d]# kubectl apply -f deployment.yaml 
deployment.apps/nginx-deployment configured
[root@k8s-master1 deployment.yaml.d]# kubectl get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           2m36s
[root@k8s-master1 deployment.yaml.d]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-65f474ff44-298fb   1/1     Running   0          7s
nginx-deployment-65f474ff44-454mt   1/1     Running   0          2m38s

虽然批量操作很方便,但这里会引出一个问题,新建/重建pod都会产生的IP地址变化,转发规则不能及时修改,这时就要引出另一种资源对象service。

2.3、Replication Controller(补充了解)

Replication Controller(简称rc)用来管理Pod的副本,保证集群中存在指定数量的Pod副本。集群中副本的数量大于指定数量,则会停止指定数量之外的多余容器数量,反之,则会启动少于指定数量个数的容器,保证数量不变。Replication Controller是实现弹性伸缩、动态扩容的核心。

RC 的主要功能点:
确保pod数量:指定某个服务在Kubernetes中有相应数量的Pod在运行;
确保pod健康:当pod不健康,运行出错或者无法提供服务时,会杀死不健康pod并重新创建,保持pod数量一致;
弹性伸缩:当业务高峰期的时候可以设置扩增pod数量,配合监控就可以做自动伸缩了;

实操演示:

[root@k8s-master1 deployment.yaml.d]# vim nginx-rc.yaml
[root@k8s-master1 deployment.yaml.d]# cat nginx-rc.yaml
---
apiVersion: v1
kind: ReplicationController
metadata:
 name: my-nginx
spec:
 replicas: 2
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1
       ports:
       - containerPort: 80


rc无需声明标签选择器

 创建rc

[root@k8s-master1 deployment.yaml.d]# kubectl apply -f nginx-rc.yaml 
replicationcontroller/my-nginx created
[root@k8s-master1 deployment.yaml.d]# kubectl get rc
NAME       DESIRED   CURRENT   READY   AGE
my-nginx   2         2         2       18s
[root@k8s-master1 deployment.yaml.d]# kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
my-nginx-bl97r   1/1     Running   0          66s
my-nginx-c8g9t   1/1     Running   0          66s

 注意:

DeploymentReplicationController (RC) 在 Kubernetes 中都用于管理 Pod 的副本,但有以下区别:

  1. 功能:

    • Deployment 提供了更高级的功能,如滚动更新、回滚、版本控制等。
    • ReplicationController 主要负责确保一定数量的 Pod 副本在任何时候都在运行,但没有内置的更新策略。
  2. 更新策略:

    • Deployment 支持滚动更新和回滚,可以方便地管理应用版本的升级。
    • ReplicationController 不支持滚动更新,更新应用需要手动替换或删除旧的 RC。
  3. 声明式管理:

    • Deployment 是声明式的,用户定义期望的状态,Kubernetes 自动处理变化以达到这个状态。
    • ReplicationController 更倾向于命令式管理,需要手动进行管理和调整。

基于以上差距deployment几乎完全取代RC成为更好用的pod控制器。

3、Service

在解释Kubernetes Service之前,先了解其使用场景:

  • 客户端访问K8S集群中的Pod时,需要知道Pod的IP和端口。如何在不知道Pod地址的情况下快速连接Pod?
  • 若某节点上的Pod发生故障,K8S会感知并重启该Pod,但重启后的Pod IP会发生变化。客户端如何感知并保持对Pod的访问?
  • 如果多个Pod组成Pod组,如何实现负载均衡?

为解决这些问题,K8S引入了Service的概念。Kubernetes Service是管理具有相同功能的一组Pod的资源对象,其具体作用如下:

  • 通过Pod的Label Selector访问Pod组。
  • Service的IP保持不变(Headless Service除外),确保访问接口的稳定性,并屏蔽Pod IP变化的影响,实现自动更新。建议使用ServiceName进行访问。
  • Service通过kube-proxy利用iptables/ipvsadm提供负载均衡能力,实现反向代理,将请求转发到合适的Pod。

这里可选择程序有两个iptables,ipvsadm

iptables 与 IPVS 都是基于 Netfilter 实现的,但因为定位不同,二者有着本质的差别:iptables 是为防火墙而设计的;IPVS 则专门用于高性能负载均衡,并使用更高效的数据结构(Hash 表),允许几乎无 限的规模扩张。 与 iptables 相比,IPVS 拥有以下明显优势:

  • 1. 为大型集群提供了更好的可扩展性和性能;
  • 2. 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权等);
  • 3. 支持服务器健康检查和连接重试等功能;
  • 4. 可以动态修改 ipset 的集合,即使 iptables 的规则正在使用这个集合。

Service工作流程(nodeport实操结束有简单版) 

1.master上的kube-apiserver会处理service的创建,以及Service与通过label匹配与Pod绑定而产生的endpoints对象,并将这些元数据内容存储到etcd中。

2.node上的kube-proxy通过实时监听kube-apiserver上service以及endpoints的变化情况来感知相关事件并更新本地的service和endpoint的映射关系;同时node上的kubedns/coredns服务也会同时将service的域名信息与IP的对应关系存储起来供dns解析之用。

3.kube-proxy将从apiserver获取到的service和endpoint的映射关系保存在本地的iptables/ipvs中供后续查询使用

4.client发起对服务的访问,首先kubedns/coredns将服务名称解析成一个虚拟IP(ClusterIP)

5.然后使用这个IP去iptables/ipvs中去找service和endpoint的映射关系

6.找到映射关系后,通过iptables/ipvs的负载均衡算法(典型也是最简单的就是roundrobin算法)匹配到一个合适的Pod进行访问即可


注意:service提供针对pod的负载均衡的能力,但是只提供4层负载均衡的能力,而没有7层功能,只能到ip层面。

 

service的类型:

K8S中Service分为四类,分别是ClusterIP,NodePort,LoadBalancer以及ExternalName。

如下图所示:

其中绿色的代表从外向内的访问模式;蓝色的代表从内向外的访问模式,黄色代表集群内部的访问模式。

 3.1、ClusterIP

  • 默认类型,自动分配一个仅可在内部访问的虚拟IP。应用方式:内部服务访问(如被tomcat访问的mysql)
  • 这是K8S默认的服务类型,只能在K8S中进行服务通信。在ClusterIP中,K8S会在Service创建完毕后提供一个内部IP作为ClusterIP,K8S内部服务可以通过ClusterIP或者ServiceName来访问该服务。

 操作如下:

[root@k8s-master1 deployment.yaml.d]# vim nginx-dep.yaml
[root@k8s-master1 deployment.yaml.d]# cat nginx-dep.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-dep
spec:
 selector:
   matchLabels:
     app: nginx
 replicas: 2
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1
       ports:
       - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-clusterip
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80


[root@k8s-master1 deployment.yaml.d]# kubectl apply -f nginx-dep.yaml 
deployment.apps/nginx-dep created
service/nginx-svc-clusterip created

[root@k8s-master1 deployment.yaml.d]# kubectl get svc
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes            ClusterIP   10.96.0.1       <none>        443/TCP   11d
nginx-svc-clusterip   ClusterIP   10.100.124.42   <none>        80/TCP    15s

[root@k8s-master1 deployment.yaml.d]# kubectl get endpoints
NAME                  ENDPOINTS                       AGE
kubernetes            192.168.188.101:6443            11d
nginx-svc-clusterip   10.244.1.23:80,10.244.2.17:80   34s

[root@k8s-master1 deployment.yaml.d]# kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
nginx-dep-5c5f7b5898-8vtrt   1/1     Running   0          56s   10.244.1.23   k8s-node1   <none>           <none>
nginx-dep-5c5f7b5898-bzdh2   1/1     Running   0          56s   10.244.2.17   k8s-node2   <none>           <none>

此时这两个pod只能在集群内部(node,pod)完成访问 

3.2、NodePort

在ClusterIP的基础之上,为集群内的每台物理机绑定一个端口,外网通过任意节点的物理机IP:端口来访问服务。应用方式:外服访问服务

操作如下:

1)暴露nginx端口

首先创建deployment

[root@k8s-master1 deployment.yaml.d]# vim deployment.yaml 
[root@k8s-master1 deployment.yaml.d]# cat deployment.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx:1.20.1
        ports:
        - containerPort: 80
[root@k8s-master1 deployment.yaml.d]# kubectl apply -f deployment.yaml 
deployment.apps/nginx-deployment created

创建service文件并以nodeport的方式暴露端口

[root@k8s-master1 deployment.yaml.d]# vim nginx-svc.yaml
[root@k8s-master1 deployment.yaml.d]# cat nginx-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: mysvc
spec:
  type: NodePort  #类型
  ports:
    - port: 8080  #ClusterIP的端口(可以理解为service产生的ip)
      nodePort: 30001  #node节点暴露的端口
      targetPort: 80    #pod的端口
  selector:   #选择器
    app: nginx

创建svc(service)

[root@k8s-master1 deployment.yaml.d]# kubectl apply -f nginx-svc.yaml 
service/mysvc created
[root@k8s-master1 deployment.yaml.d]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          11d
mysvc        NodePort    10.104.115.196   <none>        8080:30001/TCP   13s
[root@k8s-master1 deployment.yaml.d]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
nginx-deployment-5c5f7b5898-25jxx   1/1     Running   0          11m   10.244.1.20   k8s-node1   <none>           <none>
nginx-deployment-5c5f7b5898-r2dfb   1/1     Running   0          11m   10.244.2.14   k8s-node2   <none>           <none>
[root@k8s-master1 deployment.yaml.d]# kubectl get endpoints
NAME         ENDPOINTS                       AGE
kubernetes   192.168.188.101:6443            11d
mysvc        10.244.1.20:80,10.244.2.14:80   34m

service的工作原理:

如上文所示:

svc产生的CLUSTER-IP10.104.115.196
pod的ip10.244.1.20,10.244.2.14
node的ip192.168.188.102,192.168.188.103

根据文件配置node暴露出来的端口号为30001(可选范围30000-32767),pod此时提供nginx服务端口为默认的80,与其映射(对接)CLUSTER-IP端口为8080(可在正常范围内随意设置但不可重复)。

 浏览器访问node的30001端口,请求会被转发到CLUSTER-IP的8080端口,然后被转发到名为endpoint的地址池内,地址池内包含标签为app:nginx的pod的ip+端口号,在地址池内pod的选择默认为轮询转发。

此时访问node的30001端口可以直接访问pod内nginx服务

 2)暴露tomcat端口

[root@k8s-master1 deployment.yaml.d]# kubectl delete svc mysvc
service "mysvc" deleted
[root@k8s-master1 deployment.yaml.d]# kubectl delete deploy nginx-deployment
deployment.apps "nginx-deployment" deleted

[root@k8s-master1 deployment.yaml.d]# vim tomcat_deploy_svc.yaml
[root@k8s-master1 deployment.yaml.d]# cat tomcat_deploy_svc.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment
  namespace: default
spec:
  selector:
    matchLabels:
      app: tomcat
  replicas: 2
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: tomcat
        image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/tomcat:8.5.100-jre8
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  type: NodePort
  ports:
    - port: 9527
      nodePort: 30002
      targetPort: 8080
  selector:
    app: tomcat

创建deploy和svc

[root@k8s-master1 deployment.yaml.d]# kubectl apply -f tomcat_deploy_svc.yaml

物理机浏览器访问node的30002端口(服务已经正常搭建,这个镜像为精简版所以显示404)

3.3、LoadBalancer

在NodePort基础之上,提供外部负载均衡器与外网统一IP,此IP可以将请求转发到对应服务上。这个是各个云厂商提供的服务。应用方式:公网访问服务。这个因为没有公网ip所以这里只给出配置方式

apiVersion: v1
kind: Service
metadata:
  name: loadbalance-test
spec:
  ports:
  - name: loadbalance-port
    #service对外提供的端口
    port: 80
    # 代理的容器的端口 
    targetPort: 80
    # 在物理机上开辟的端口,从30000开始
    nodePort: 32138
  selector:
    app: nginx
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip:  云厂商LoadbalanceIP

外部访问时直接访问公网IP即可直达服务。

3.4、ExternalName

引入集群外部的服务,可以在集群内部通过别名方式访问

(通过serviceName.namespaceName.svc.cluster.local访问)

apiVersion: v1
kind: Service
metadata:
  name: service-ext
spec:
  type: ExternalName
  # 引入外部服务
  externalName: baidu.com

3.5、Headless Service

上面我们讲解了service的使用方法和实现逻辑,主要就是代理一组pod容器提供负载均衡以及反向代理服务。但是有时候我们不需要这种负载均衡,比如下面的两个场景:

  • K8S部署某个kafka集群,此时就不需要service来负载均衡,客户端需要的是一组pod所有ip的列表。
  • 客户端自己处理负载均衡的逻辑,比如K8S部署两个mysql,客户端自己处理负载请求,或者根本不处理这种负载,就要两套mysql然后手动控制读写请求。

基于上面的两个场景,K8S提供了headless serivce功能,字面意思是无头service,其实就是该service不显式的对外提供IP。

headless service一般结合StatefulSet控制器来部署有状态的应用,比如大数据组件或者nosql数据库等,这种分布式的系统需要headless service来获取所有节点ip的列表供业务场景使用。

4、容器监控检查及恢复机制

在 k8s 中,可以为 Pod 里的容器定义一个健康检查"探针"(Probe)。kubelet 就会根据这个 Probe 的返回值决定这个容器的状态,而不是直接以容器是否运行(来自 Docker 返回的信息)作为依据。这种机制,是生产环境中保证应用健康存活的重要手段。

[root@k8s-master1 deployment.yaml.d]# vim test-liveness-exec.yaml
[root@k8s-master1 deployment.yaml.d]# cat test-liveness-exec.yaml
---
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: test-liveness-exec
spec:
  containers:
  - name: liveness
    image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx
    args:       #传参执行下面命令
    - /bin/sh
    - -c  
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 50
    livenessProbe:    #探针,健康检查
      exec:    #类型
        command:  #命令
        - cat 
        - /tmp/healthy  #结合下面的参数,每隔五秒查看文件是否存在,如果不在了pod异常
      initialDelaySeconds: 5   #健康检查,在容器启动 5 s 后开始执行
      periodSeconds: 5

创建并观察pod状态(注意看重启位置数字变化)

[root@k8s-master1 deployment.yaml.d]# kubectl apply -f test-liveness-exec.yaml
[root@k8s-master1 deployment.yaml.d]# kubectl get pod

刚创建
NAME                 READY   STATUS    RESTARTS   AGE
test-liveness-exec   1/1     Running   0          18s


删除文件命令启动后

NAME                 READY   STATUS    RESTARTS   AGE
test-liveness-exec   1/1     Running   1          75s

查看pod事件

Events:
  Type     Reason     Age                  From                Message
  ----     ------     ----                 ----                -------
  Normal   Scheduled  4m7s                 default-scheduler   Successfully assigned default/test-liveness-exec to k8s-node1
  Normal   Pulled     4m6s                 kubelet, k8s-node1  Successfully pulled image "registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx" in 634.594286ms
  Normal   Pulled     2m54s                kubelet, k8s-node1  Successfully pulled image "registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx" in 588.01354ms
  Normal   Created    99s (x3 over 4m6s)   kubelet, k8s-node1  Created container liveness
  Normal   Started    99s (x3 over 4m6s)   kubelet, k8s-node1  Started container liveness
  Normal   Pulled     99s                  kubelet, k8s-node1  Successfully pulled image "registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx" in 604.298548ms
  Warning  Unhealthy  54s (x9 over 3m34s)  kubelet, k8s-node1  Liveness probe failed: cat: /tmp/healthy: No such file or directory
  Normal   Killing    54s (x3 over 3m24s)  kubelet, k8s-node1  Container liveness failed liveness probe, will be restarted

注意:

  • Kubernetes 中并没有 Docker 的 Stop 语义。所以虽然显示 Restart(重启),但实际却是重新创建了容器。
  • Pod 的恢复过程,永远都是发生在当前节点上,而不会跑到别的节点上去。事实上,一旦一个 Pod 与一个节点(Node)绑定,除非这个绑定发生了变化(pod.spec.node 字段被修改),否则它永远都不会离开这个节点。

http get方式探针

通过http访问主页面查看容器状态是否健康

配置如下

---
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
    - name: liveness-exec-container
      image: registry.cn-chengdu.aliyuncs.com/liumuquan_app/nginx
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 80
          name: http #名称
      livenessProbe:  #探针,健康检查
        httpGet:
          port: http #与上方名称对应
          path: /index.html    #使用http访问的路径,作为检查标准
        initialDelaySeconds: 1
        periodSeconds: 3

创建pod查看详情

[root@k8s-master1 deployment.yaml.d]# kubectl describe pod liveness-httpget-pod

 登陆容器将容器内的检测文件(nginx主页移除)

[root@k8s-master1 deployment.yaml.d]# kubectl exec -it  liveness-httpget-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

root@liveness-httpget-pod:/# mv /usr/share/nginx/html/index.html 111.txt

移除后自动退出,容器已经重建
root@liveness-httpget-pod:/# command terminated with exit code 137
[root@k8s-master1 deployment.yaml.d]# 

再次查看pod详情

[root@k8s-master1 deployment.yaml.d]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
liveness-httpget-pod   1/1     Running   1          6m48s

 此时再次登陆查看,发现文件又出现了,证明并非“RESTART”,而是重建

[root@k8s-master1 deployment.yaml.d]# kubectl exec -it  liveness-httpget-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@liveness-httpget-pod:/# ls /usr/share/nginx/html/
50x.html  index.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2078309.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新迪天工®看图,专业的三维CAD看图工具

替代专业CAD软件&#xff0c;方便查看各种三维和二维CAD图纸 新迪天工看图是一款功能强大的三维模型和二维图纸查看工具&#xff0c;能帮助制造企业以较低的成本、较高的数据安全性实现产品设计数据的跨业务浏览和交互。 应用场景 1、设计图纸评审 可直接对三维模型和二维…

【MATLAB源码-第255期】基于matlab的长鼻浣熊优化算法(COA)无人机三维路径规划,输出做短路径图和适应度曲线.

操作环境&#xff1a; MATLAB 2022a 1、算法描述 长鼻浣熊优化算法&#xff08;Coati Optimization Algorithm&#xff0c;COA&#xff09;是一种新兴的群体智能优化算法&#xff0c;其灵感来源于长鼻浣熊在自然界中的觅食行为。长鼻浣熊是一种生活在美洲热带和亚热带森林中…

Redis中的数据类型及应用场景(面试版)

五种常用数据类型介绍 Redis中存储的都是key-value对结构的数据&#xff0c;其中key都是字符串类型&#xff0c;value有5种常用的数据类型&#xff1a; 字符串 string 哈希 hash 列表 list 集合 set 有序集合 sorted set / zset 各种数据类型特点 解释说明&#xff1a; …

DP10RF001支持200MHz~960MHz(G)FSK/OOK调制无线抄表工业传感无线遥控

简介 DP10RF001是一款工作于 200MHz~960MHz 范围内的低功耗、高性能、单片集成的(G)FSK/OOK无线收发芯片。内部集成完整的射频接收机、射频发射机、频率综合器、调制解调器&#xff0c;只需配备简单、低成本的外围器件就可以获得良好的收发性能。 芯片支持灵活可设的数据包格式…

6U VPX总线架构:搭载飞腾D2000/FT2000 + FPGA-K7(赛灵思)

"CPU FPGA" 结构是指一种结合了中央处理器&#xff08;CPU&#xff09;和现场可编程门阵列&#xff08;FPGA&#xff09;的系统架构。这种架构利用了CPU的通用计算能力和FPGA的并行处理能力&#xff0c;可以提供高效能、低延迟和高灵活性的计算平台。 K7是 Xilinx 7…

Linux进程信号——信号的捕捉、保存、处理

文章目录 信号的基本概念信号保存block位图pending位图handler数组 信号处理sigset_tsigemptysetsigfillsetsigaddset sigdelsetsigismembersigprocmask 捕捉信号 信号的基本概念 信号递达&#xff1a;实际处理信号的动作信号未决&#xff1a;信号从产生到递达之间的状态信号阻…

比人还毒舌的AI上线了!

前段时间社交媒体上很火的毒舌版AI&#xff0c;上线后异常火爆&#xff0c;网友把各路名人的账号输入&#xff0c;川普&#xff0c;马斯克等一干名人被吐槽得体无完肤。 现在这个功能国内也有了&#xff0c;推出了微博版的AI嘴替&#xff0c;微博上的名人纷纷中招。 体验地址&a…

如何修改注解里面的属性值

说明&#xff1a;Java中&#xff0c;注解里的属性值在编译时就已经固定了&#xff0c;是无法通过AOP或者反射技术直接去修改的。本文介绍如何通过动态代理的方式来修改属性值。 搭建环境 首先&#xff0c;创建一个简单的Spring Boot项目&#xff0c;pom.xml文件如下&#xff…

声音事件检测DESED 数据集介绍

DESED dataset contains:DESED Domestic Environment sound event detection; 家庭环境声音事件检测&#xff1b; 1. 数据 Content内容 DESED dataset contains:DESED 数据集包含&#xff1a; Domestic Environment sound event detection; 家庭环境声音事件检测&#xff1…

[学习笔记]在不同项目中切换Node.js版本

文章目录 使用 Node Version Manager (NVM)安装 NVM使用 NVM 安装和切换 Node.js 版本为项目指定 Node.js 版本 使用环境变量指定 Node.js安装多个版本的 Node.js设置环境变量验证配置使用 npm 脚本切换 在开发中&#xff0c;可能会遇到不同的Vue项目需要不同的Node.js&#xf…

各个版本jdk新特性

jdk8新特性 方法引用&#xff1a;方法引用允许直接通过方法的名称来引用已经存在的方法&#xff0c;简化了函数式接口的实现。默认方法&#xff08;Default Methods&#xff09;&#xff1a;默认方法允许在接口中定义具有默认实现的方法&#xff0c;以便接口的实现类可以继承该…

uniapp-Vue项目如何实现国际化,实现多语言切换,拒绝多套开发,一步到位,看这篇就够

一 安装 找到自己的项目,输入cmd进入命令行,输入安装命令,点击回车进行下载: npm install vue-i18nnext 下载完将在项目的配置文件中看到: 二 使用 2.1 在项目中创建一个文件夹如:lang 用于存放不同语言的包。这些语言文件通常为JSON格式 2.2 在项目main.js文件中引入并初…

YoloV8损失函数篇(代码加理论)

首先yolov8中loss的权重可以在ultralytics/cfg/default.yaml修改 损失函数定义ultralytics/utils/loss.py 回归分支的损失函数 DFL(Distribution Focal Loss)&#xff0c;计算anchor point的中心点到左上角和右下角的偏移量IoU Loss&#xff0c;定位损失&#xff0c;采用CIoU…

开源网络安全大模型 - SecGPT

网络安全大模型是指使用大量数据和参数来训练的人工智能模型&#xff0c;它可以理解和生成与网络安全相关的内容&#xff0c;例如漏洞报告、利用代码、攻击场景等。 目前各家网络安全厂商也纷纷跟进在大模型方面的探索&#xff0c;但可供广大从业者研究的特有网络安全大模型…

2013-2023年 中国MOD17A3H植被净初级生产力(NPP)数据

中国MOD17A3H植被净初级生产力&#xff08;NPP&#xff09;数据是基于NASA的MODIS卫星遥感数据计算得出的&#xff0c;这些数据对于评估生态系统碳收支、碳循环以及气候变化的影响具有重要意义。NPP数据可以反映植被通过光合作用固定大气中二氧化碳并转化为有机物质的能力&…

OpenStack组件介绍(2)

cinder 提供块存储服务&#xff0c;管理openstack中的块存储资源&#xff0c;为云平台提供持久的块存储服务&#xff0c;通过驱动的方式可以接入不同种类的后端存储。 cinder对接nfs 关闭防火墙和selinux [rootlocalhost yum.repos.d]# systemctl stop firewalld [rootlocal…

对想学习人工智能或者大模型技术从业者的建议

“ 技术的价值在于应用&#xff0c;理论与实践相结合才能事半功倍” 写这个关于AI技术的公众号也有差不多五个月的时间了&#xff0c;最近一段时间基本上都在保持日更状态&#xff0c;而且写的大部分都是关于大模型技术理论和技术方面的东西。‍‍‍‍‍‍‍‍‍ 然后最近一段…

网络安全售前入门04——审计类产品了解

目录 1.前言 2.数据库审计介绍 2.1产品架构功能 2.2应用场景 2.3部署形式 2.4产品价值 2.5选型依据 1.前言 为方便初接触网络安全售前工作的小伙伴了解网安行业情况,我制作一系统售前入门(安全产品,安全服务,法律法规等)文章介绍,希望能给初进网安职场的小伙伴提供…

STL中的stack与queue

前言&#xff1a; stack与queue是STL中的容器适配器&#xff0c;而不是容器。何为适配器&#xff1f;给手机充电的充电器就是一种适配器&#xff0c;将高电压变成低电压。适配器是用来做转化的&#xff0c;不用来直接管理数据&#xff0c;而是在其他容器的基础上去封装转换。 …

WordNet介绍——一个英语词汇数据库

传统语义知识库最常见的更新方法是依赖人工手动更新&#xff0c;使用这种更新方法的语义知识库包括最早的 WordNet、FrameNet和 ILD&#xff0c;以及包含丰富内容的 ConceptNet和 DBPedia。此类语义知识库的特点是以单词作为语义知识库的基本构成元素&#xff0c;以及使用预先设…