使用Kubernetes部署第一个应用

目录

前提条件

启动集群

部署 nginx 应用

创建 YAML 文件

应用 YAML 文件

查看部署结果

理解Pods

相关命令

公布应用程序

问题背景

Kubernetes Service(服务)概述

服务和标签

为Deployment 创建一个 Service

伸缩应用程序

Scaling(伸缩)应用程序

将Deployment扩容到4个副本

将Deployment缩容到2个副本

滚动更新应用

滚动更新概述

滚动更新步骤

滚动更新Deployment

删除部署资源

相关命令

删除部署资源


前提条件

  • 完成 Kubernetes 集群的安装,可参考Kubernetes集群搭建

  • 了解Kubernetes常用命令,可参考Kubernetes常用命令

启动集群

启动ikuai,启动三个虚拟机,确保Kubernetes集群正常可用。

[root@k8s-master01 ~]# kubectl get node
NAME           STATUS   ROLES           AGE     VERSION
k8s-master01   Ready    control-plane   7h52m   v1.31.1
k8s-node01     Ready    <none>          7h24m   v1.31.1
k8s-node02     Ready    <none>          7h22m   v1.31.1

部署 nginx 应用

在 k8s 上进行部署前,首先需要了解一个基本概念 Deployment

Deployment 译名为 部署 。在k8s中,通过发布 Deployment,可以创建应用程序 (docker image) 的实例 (docker container),这个实例会被包含在称为 Pod 的概念中,Pod 是 k8s 中最小可管理单元。

在 k8s 集群中发布 Deployment 后,Deployment 将指示 k8s 如何创建和更新应用程序的实例,master 节点将应用程序实例调度到集群中的具体的节点上。

创建应用程序实例后,Kubernetes Deployment Controller 会持续监控这些实例。如果运行实例的 worker 节点关机或被删除,则 Kubernetes Deployment Controller 将在群集中资源最优的另一个 worker 节点上重新创建一个新的实例。这提供了一种自我修复机制来解决机器故障或维护问题。

创建 YAML 文件

创建nginx-deployment.yaml文件

# 创建专门的目录,方便管理yaml文件
[root@k8s-master01 ~]# mkdir 1
[root@k8s-master01 ~]# cd 1
​
# 创建nginx-deployment.yaml
[root@k8s-master01 1]# vi nginx-deployment.yaml

内容如下:

apiVersion: apps/v1	#与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment	#该配置的类型,使用的是 Deployment
metadata:	        #译名为元数据,即 Deployment 的一些基本属性和信息
  name: nginx-deployment	#Deployment 的名称
  labels:	    #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
    app: nginx	#为该Deployment设置key为app,value为nginx的标签
spec:	        #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
  replicas: 1	#使用该Deployment创建一个应用程序实例
  selector:	    #标签选择器,与上面的标签共同作用,目前不需要理解
    matchLabels: #选择包含标签app:nginx的资源
      app: nginx
  template:	    #这是选择或创建的Pod的模板
    metadata:	#Pod的元数据
      labels:	#Pod的标签,上面的selector即选择包含标签app:nginx的Pod
        app: nginx
    spec:	    #期望Pod实现的功能(即在pod中部署)
      containers:	#生成container,与docker中的container是同一种
      - name: nginx	#container的名称
        image: nginx:alpine	#使用镜像nginx:alpine创建container,该container默认80端口可访问  

应用 YAML 文件

应用yaml文件创建deployment

[root@k8s-master01 1]# kubectl apply -f nginx-deployment.yaml

查看部署结果

[root@k8s-master01 1]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           10s
​
​
[root@k8s-master01 1]# kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-9c65654f4-xj7j2   1/1     Running   0          47s

分别查看到一个名为 nginx-deployment 的 Deployment 和一个名为 nginx-deployment-xxxxxxx 的 Pod,Pod的状态是Running状态。

至此已经成功在k8s上部署了一个nginx应用程序。

理解Pods

Pods 是 Kubernetes 中最小的可部署和可管理的单元。部署应用,其实就是部署Pod。

image.png

Pod 是一个k8s中一个抽象的概念,用于存放一组 container(可包含一个或多个 container 容器,即图上正方体),以及这些 container (容器)的一些共享资源。这些资源包括:

  • 共享存储,称为卷(Volumes),即图上紫色圆柱

  • 网络,每个 Pod(容器组)在集群中有个唯一的 IP,pod(容器组)中的 container(容器)共享该IP地址

  • container(容器)的基本信息,例如容器的镜像版本,对外暴露的端口等

Pod中的容器共享 IP 地址和端口空间(同一 Pod 中的不同 container 使用的端口不能相互冲突),始终位于同一位置并共同调度,并在同一节点上的共享上下文中运行。(同一个Pod内的容器可以使用 localhost + 端口号互相访问)。

Pod一般存在于Node节点中,一个Node可以有多个Pod,下图显示一个 Node节点上含有4个 Pod。

image.png

相关命令

  • kubectl get - 显示资源列表

    # kubectl get 资源类型
    ​
    # 获取类型为Deployment的资源列表
    kubectl get deployments
    ​
    # 获取类型为Pod的资源列表
    kubectl get pods
    ​
    # 获取类型为Node的资源列表
    kubectl get nodes  

    操作过程

    [root@k8s-master01 1]# kubectl get deployments
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   1/1     1            1           29m
    ​
    [root@k8s-master01 1]# kubectl get pods
    NAME                               READY   STATUS    RESTARTS   AGE
    nginx-deployment-9c65654f4-xj7j2   1/1     Running   0          4m47s
    ​
    [root@k8s-master01 1]# kubectl get nodes
    NAME           STATUS   ROLES           AGE   VERSION
    k8s-master01   Ready    control-plane   25d   v1.31.1
    k8s-node01     Ready    <none>          25d   v1.31.1
    k8s-node02     Ready    <none>          25d   v1.31.1
    ​

    名称空间

    在命令后增加 -A--all-namespaces 可查看所有 名称空间中 的对象,使用参数 -n 可查看指定名称空间的对象,例如

    # 查看所有名称空间的 Deployment
    kubectl get deployments -A
    kubectl get deployments --all-namespaces
    # 查看 kube-system 名称空间的 Deployment
    kubectl get deployments -n kube-system  

    并非所有对象都在名称空间里

    操作过程

    [root@k8s-master01 1]# kubectl get deployments -A
    NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    default       nginx-deployment          1/1     1            1           31m
    kube-system   calico-kube-controllers   1/1     1            1           25d
    kube-system   calico-typha              1/1     1            1           25d
    kube-system   coredns                   2/2     2            2           25d
    myns1         my-dep                    3/3     3            3           2d5h
    ​
    [root@k8s-master01 1]# kubectl get deployments --all-namespaces
    NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    default       nginx-deployment          1/1     1            1           32m
    kube-system   calico-kube-controllers   1/1     1            1           25d
    kube-system   calico-typha              1/1     1            1           25d
    kube-system   coredns                   2/2     2            2           25d
    myns1         my-dep                    3/3     3            3           2d5h
    ​
    [root@k8s-master01 1]# kubectl get deployments -n kube-system 
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    calico-kube-controllers   1/1     1            1           25d
    calico-typha              1/1     1            1           25d
    coredns                   2/2     2            2           25d
    
    
    
    
  • kubectl describe - 显示有关资源的详细信息

    # kubectl describe 资源类型 资源名称
    ​
    #查看名称为nginx的Deployment的信息
    kubectl describe deployment nginx  
    ​
    #查看名称为nginx-XXXXXX的Pod的信息,可以查看到pod ip等信息
    kubectl describe pod nginx-XXXXXX
    ​

    操作过程

    [root@k8s-master01 1]# kubectl describe deployment nginx-deployment
    Name:                   nginx-deployment
    Namespace:              default
    CreationTimestamp:      Wed, 09 Oct 2024 23:39:57 +0800
    Labels:                 app=nginx
    Annotations:            deployment.kubernetes.io/revision: 2
    Selector:               app=nginx
    Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
    StrategyType:           RollingUpdate
    MinReadySeconds:        0
    RollingUpdateStrategy:  25% max unavailable, 25% max surge
    Pod Template:
      Labels:  app=nginx
      Containers:
       nginx:
        Image:         nginx:alpine
        Port:          <none>
        Host Port:     <none>
        Environment:   <none>
        Mounts:        <none>
      Volumes:         <none>
      Node-Selectors:  <none>
      Tolerations:     <none>
    Conditions:
      Type           Status  Reason
      ----           ------  ------
      Available      True    MinimumReplicasAvailable
      Progressing    True    NewReplicaSetAvailable
    OldReplicaSets:  nginx-deployment-75b5b48df5 (0/0 replicas created)
    NewReplicaSet:   nginx-deployment-9c65654f4 (1/1 replicas created)
    Events:
      Type    Reason             Age   From                   Message
      ----    ------             ----  ----                   -------
      Normal  ScalingReplicaSet  35m   deployment-controller  Scaled up replica set nginx-deployment-75b5b48df5 to 1
      Normal  ScalingReplicaSet  10m   deployment-controller  Scaled up replica set nginx-deployment-9c65654f4 to 1
      Normal  ScalingReplicaSet  10m   deployment-controller  Scaled down replica set nginx-deployment-75b5b48df5 to 0 from 1
    [root@k8s-master01 1]# 
    ​
    [root@k8s-master01 1]# kubectl describe pod nginx-deployment-9c65654f4-xj7j2
    Name:             nginx-deployment-9c65654f4-xj7j2
    Namespace:        default
    Priority:         0
    Service Account:  default
    Node:             k8s-node01/192.168.204.102
    Start Time:       Thu, 10 Oct 2024 00:04:49 +0800
    Labels:           app=nginx
                      pod-template-hash=9c65654f4
    Annotations:      cni.projectcalico.org/containerID: ad5ba24cae9654b42af7b5581095ee1c3246bc77e64ea42d08200653f148ade6
                      cni.projectcalico.org/podIP: 10.244.85.197/32
                      cni.projectcalico.org/podIPs: 10.244.85.197/32
    Status:           Running
    IP:               10.244.85.197
    IPs:
      IP:           10.244.85.197
    Controlled By:  ReplicaSet/nginx-deployment-9c65654f4
    Containers:
      nginx:
        Container ID:   docker://5aa9bed2c3ae7ed772d7dc04420d4d79951dbacdb758bc013aa3c03a710ca138
        Image:          nginx:alpine
        Image ID:       docker-pullable://nginx@sha256:2140dad235c130ac861018a4e13a6bc8aea3a35f3a40e20c1b060d51a7efd250
        Port:           <none>
        Host Port:      <none>
        State:          Running
          Started:      Thu, 10 Oct 2024 00:04:50 +0800
        Ready:          True
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8962w (ro)
    Conditions:
      Type                        Status
      PodReadyToStartContainers   True 
      Initialized                 True 
      Ready                       True 
      ContainersReady             True 
      PodScheduled                True 
    Volumes:
      kube-api-access-8962w:
        Type:                    Projected (a volume that contains injected data from multiple sources)
        TokenExpirationSeconds:  3607
        ConfigMapName:           kube-root-ca.crt
        ConfigMapOptional:       <nil>
        DownwardAPI:             true
    QoS Class:                   BestEffort
    Node-Selectors:              <none>
    Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
    Events:
      Type    Reason     Age    From               Message
      ----    ------     ----   ----               -------
      Normal  Scheduled  8m40s  default-scheduler  Successfully assigned default/nginx-deployment-9c65654f4-xj7j2 to k8s-node01
      Normal  Pulled     8m39s  kubelet            Container image "nginx:alpine" already present on machine
      Normal  Created    8m39s  kubelet            Created container nginx
      Normal  Started    8m38s  kubelet            Started container nginx
    [root@k8s-master01 1]# 
  • kubectl logs - 查看pod中的容器的打印日志(和命令docker logs 类似),方便定位pod的问题。

    # kubectl logs Pod名称
    ​
    # -f表示持续监听日志,按ctrl+c退出监听,可以curl pod的ip,再次查看日志,会多一条出访问日志
    kubectl logs -f nginx-pod-XXXXXXX  

    操作过程

    [root@k8s-master01 1]# kubectl logs nginx-deployment-9c65654f4-xj7j2
    /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
    /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
    10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
    10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
    /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
    /docker-entrypoint.sh: Configuration complete; ready for start up
    2024/10/09 16:04:51 [notice] 1#1: using the "epoll" event method
    2024/10/09 16:04:51 [notice] 1#1: nginx/1.27.2
    2024/10/09 16:04:51 [notice] 1#1: built by gcc 13.2.1 20240309 (Alpine 13.2.1_git20240309) 
    2024/10/09 16:04:51 [notice] 1#1: OS: Linux 5.14.0-427.33.1.el9_4.x86_64
    2024/10/09 16:04:51 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1073741816:1073741816
    2024/10/09 16:04:51 [notice] 1#1: start worker processes
    2024/10/09 16:04:51 [notice] 1#1: start worker process 30
    2024/10/09 16:04:51 [notice] 1#1: start worker process 31
    2024/10/09 16:04:51 [notice] 1#1: start worker process 32
    2024/10/09 16:04:51 [notice] 1#1: start worker process 33
    ​
  • kubectl exec - 在pod中的容器环境内执行命令(和命令docker exec 类似)

    # kubectl exec Pod名称 操作命令
    ​
    # 进入名称为nginx-pod-xxxxxx的Pod中运行bash,注意需要镜像支持bash命令
    kubectl exec -it nginx-pod-xxxxxx -- bash  
    ​
    # 不进入Pod,在名称为nginx-pod-xxxxxx的Pod中运行命令
    kubectl exec -it nginx-pod-xxxxxx -- command  

    操作

    # 注意,执行bash命令,需要镜像支持bash命令,nginx:alpline不支持bash命令,如果需要验证,可以把镜像缓存支持bash命令的镜像,例如:nginx:1.27.2
    [root@k8s-master01 1]# kubectl exec -it nginx-deployment-9c65654f4-xj7j2 -- bash
    root@nginx-deployment-9c65654f4-xj7j2:/# ls
    bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
    boot  etc  lib   media  opt  root  sbin  sys  usr
    root@nginx-deployment-9c65654f4-xj7j2:/# exit
    exit
    [root@k8s-master01 1]# 
    [root@k8s-master01 1]# kubectl exec -it nginx-deployment-9c65654f4-xj7j2 -- date
    Wed Oct  9 16:23:16 UTC 2024
    [root@k8s-master01 1]# kubectl exec -it nginx-deployment-9c65654f4-xj7j2 -- ls /usr/share/nginx/html
    50x.html    index.html

公布应用程序

问题背景

Deployment部署应用程序只能在集群内部访问,集群外部无法访问。

通过kubectl describe pod-name命令查看pod ip

[root@k8s-master01 ~]# kubectl describe pod nginx-deployment-9c65654f4-xj7j2
...
IP:               10.244.85.197
...

这里查看的pod ip为:10.244.85.197

在集群任意一台机器命令访问pod ip:端口号,都可以访问到pod nginx服务。

[root@k8s-master01 ~]# curl 10.244.85.200:80
<!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>

但在集群外部访问,例如:使用Windows的浏览器访问,却访问不到。

通过Deployment部署的应用程序,只能集群内部机器使用Pod IP进行访问,集群外部不能访问,如果Pod所在机器出现故障,Deployment重启Pod,Pod IP会变化。为了解决Pod IP可能变化同时还要让外部能访问的问题,这时就需要使用Kubernetes Service来公开应用程序。

Kubernetes Service(服务)概述

事实上,Pod(容器组)有自己的 生命周期。当 node(节点)故障时,节点上运行的 Pod(容器组)也会消失。然后,Deployment可以通过创建新的 Pod(容器组)来动态地将群集调整回原来的状态,以使应用程序保持运行。

举个例子,假设有一个后端程序,具有 3 个运行时副本。这 3 个副本是可以替换的(无状态应用),即使 Pod消失并被重新创建,或者副本数由 3 增加到 5,前端系统也无需关注后端副本的变化。由于 Kubernetes 集群中每个 Pod都有一个唯一的 IP 地址,我们需要一种机制,为前端系统屏蔽后端系统的 Pod在销毁、创建过程中所带来的 IP 地址的变化。

Kubernetes 中的 Service(服务) 提供了这样的一个抽象层,它选择具备某些特征的 Pod并为它们定义一个访问方式。Service使 Pod之间的相互依赖解耦(原本从一个 Pod 中访问另外一个 Pod,需要知道对方的 IP 地址)。一个 Service选定哪些 Pod通常由 LabelSelector(标签选择器) 来决定。

在创建Service的时候,通过设置配置文件中的 spec.type 字段的值,可以以不同方式向外部暴露应用程序:

  • ClusterIP(默认)

    在群集中的内部IP上公布服务,这种方式的 Service(服务)只在集群内部可以访问到。

  • NodePort

    使用 NAT 在集群中每个的同一端口上公布服务。这种方式下,可以通过访问集群中任意节点+端口号的方式访问服务 <NodeIP>:<NodePort>。此时 ClusterIP 的访问方式仍然可用。

  • LoadBalancer

    在云环境中(需要云供应商可以支持)创建一个集群外部的负载均衡器,并为使用该负载均衡器的 IP 地址作为服务的访问地址。此时 ClusterIP 和 NodePort 的访问方式仍然可用。

Service是一个抽象层,它通过 LabelSelector 选择了一组 Pod,把这些 Pod 的指定端口公布到到集群外部,并支持负载均衡和服务发现。

  • 公布 Pod 的端口以使其可访问

  • 在多个 Pod 间实现负载均衡

  • 使用 Label 和 LabelSelector

服务和标签

图中有两个服务Service A(黄色虚线)和Service B(蓝色虚线) 

  •  Service A 将请求转发到 IP 为 10.10.10.1 的Pod上
  •  Service B 将请求转发到 IP 为 10.10.10.2、10.10.10.3、10.10.10.4 的Pod上

Service 将外部请求路由到一组 Pod 中,它提供了一个抽象层,使得 Kubernetes 可以在不影响服务调用者的情况下,动态调度容器组(在容器组失效后重新创建容器组,增加或者减少同一个 Deployment 对应容器组的数量等)。

Service使用 Labels、LabelSelector(标签和选择器) (opens new window)匹配一组 Pod。Labels(标签)是附加到 Kubernetes 对象的键/值对,其用途有多种:

  • 将 Kubernetes 对象(Node、Deployment、Pod、Service等)指派用于开发环境、测试环境或生产环境

  • 嵌入版本标签,使用标签区别不同应用软件版本

  • 使用标签对 Kubernetes 对象进行分类

下图体现了 Labels(标签)和 LabelSelector(标签选择器)之间的关联关系

  • Deployment B 含有 LabelSelector 为 app=B 通过此方式声明含有 app=B 标签的 Pod 与之关联

  • 通过 Deployment B 创建的 Pod 包含标签为 app=B

  • Service B 通过标签选择器 app=B 选择可以路由的 Pod

Labels(标签)可以在创建 Kubernetes 对象时附加上去,也可以在创建之后再附加上去。任何时候都可以修改一个 Kubernetes 对象的 Labels(标签)

为Deployment 创建一个 Service

创建nginx的Deployment中定义了Labels,如下:

metadata:   #译名为元数据,即Deployment的一些基本属性和信息
  name: nginx-deployment    #Deployment的名称
  labels:   #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组
    app: nginx  #为该Deployment设置key为app,value为nginx的标签  

此前的 nginx-deployment.yaml已经有labels设置,所以不需要改动。

创建文件 nginx-service.yaml

[root@k8s-master01 1]# vi nginx-service.yaml  

文件内容如下:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service	#Service 的名称
  labels:     	#Service 自己的标签
    app: nginx	#为该 Service 设置 key 为 app,value 为 nginx 的标签
spec:	    #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
  selector:	    #标签选择器
    app: nginx	#选择包含标签 app:nginx 的 Pod
  ports:
  - name: nginx-port	#端口的名字
    protocol: TCP	    #协议类型 TCP/UDP
    port: 80	        #集群内的其他容器组可通过 80 端口访问 Service
    nodePort: 32600   #通过任意节点的 32600 端口访问 Service
    targetPort: 80	#将请求转发到匹配 Pod 的 80 端口
  type: NodePort	#Serive的类型,ClusterIP/NodePort/LoaderBalancer 
 

应用nginx-service.yaml

应用nginx-service.yaml创建service

[root@k8s-master01 1]# kubectl apply -f nginx-service.yaml

查看service

查看到名称为 nginx-service 的服务,类型为NodePort,端口映射关系为pod的80端口映射到主机的32600端口。

[root@k8s-master01 1]# kubectl get services -o wide
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE   SELECTOR
kubernetes      ClusterIP   10.0.0.1       <none>        443/TCP        25d   <none>
nginx-service   NodePort    10.12.211.39   <none>        80:32600/TCP   28s   app=nginx

访问服务

访问集群任意机器IP:主机端口

命令访问测试

curl <任意节点的 IP>:32600  
  • 主机端口用上一步查看到映射的主机端口,需要根据实际情况修改
  • 如果集群在云上需要在云服务商的安全组开放对应主机端口的访问

操作过程

# master01机器
[root@k8s-master01 1]# curl localhost:32600
<!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>
​
# node01机器
[root@k8s-node01 ~]# curl localhost:32600
<!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>
​
​
# node02机器
[root@k8s-node02 ~]# curl localhost:32600
<!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>
​
​

浏览器访问测试

image.png

image.png

image.png

伸缩应用程序

Scaling(伸缩)应用程序

我们发布的 Deployment 只创建了一个 Pod 来运行我们的应用程序。当流量增加时,我们需要对应用程序进行伸缩操作以满足系统性能需求。

伸缩 的实现可以通过更改 nginx-deployment.yaml 文件中部署的 replicas(副本数)来完成,例如:

spec:
  replicas: 4   

下图中,Service A 只将访问流量转发到 IP 为 10.0.0.5 的Pod上。

image.png

修改了 Deployment 的 replicas 为 4 后,Kubernetes 又为该 Deployment 创建了 3 新的 Pod,这 4 个 Pod 有相同的标签。因此Service A通过标签选择器与新的 Pod建立了对应关系,将访问流量通过负载均衡在 4 个 Pod 之间进行转发。如下图所示。

image.png

将Deployment扩容到4个副本

修改 nginx-deployment.yaml 文件

将 spec.replicas 的值修改为 4

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
 

执行命令

[root@k8s-master01 1]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment configured

查看结果

[root@k8s-master01 1]# watch kubectl get pods -o wide  

滚动更新持续一段时间后,4个pods都变为Running状态。

image.png

按Ctrl+C返回命令行。

访问Nginx服务

[root@k8s-master01 1]# curl localhost:32600
<!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>
​

查看pod日志

[root@k8s-master01 1]# kubectl logs -f nginx-deployment-9c65654f4-dcvtj
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/10/10 03:16:59 [notice] 1#1: using the "epoll" event method
2024/10/10 03:16:59 [notice] 1#1: nginx/1.27.2
2024/10/10 03:16:59 [notice] 1#1: built by gcc 13.2.1 20240309 (Alpine 13.2.1_git20240309) 
2024/10/10 03:16:59 [notice] 1#1: OS: Linux 5.14.0-427.33.1.el9_4.x86_64
2024/10/10 03:16:59 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1073741816:1073741816
2024/10/10 03:16:59 [notice] 1#1: start worker processes
2024/10/10 03:16:59 [notice] 1#1: start worker process 30
2024/10/10 03:16:59 [notice] 1#1: start worker process 31
2024/10/10 03:16:59 [notice] 1#1: start worker process 32
2024/10/10 03:16:59 [notice] 1#1: start worker process 33
192.168.204.101 - - [10/Oct/2024:08:02:42 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.76.1" "-"
192.168.204.101 - - [10/Oct/2024:08:02:55 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.76.1" "-"
​

再多次访问32600,观察日志输出变化

[root@k8s-master01 1]# curl localhost:32600

可以看到访问几次,日志才发生变化,说明每次都由不同的pod提供服务,达到多个pod分担访问压力的效果,实现了访问的负载均衡。

感兴趣可以同时访问多个pod日志,再多次访问32600端口,观察多个pod日志的变化情况。

将Deployment缩容到2个副本

修改 nginx-deployment.yaml

[root@k8s-master01 1]# vi nginx-deployment.yaml

修改spec.replicas由4改为2,如下

spec:  
  replicas: 2 

应用部署文件

[root@k8s-master01 1]# kubectl apply -f nginx-deployment.yaml 
deployment.apps/nginx-deployment configured
​

监听pod变化

[root@k8s-master01 1]# watch kubectl get pods -o wide 

image.png

看到只有两个pod了,实现了部署缩容。

滚动更新应用

滚动更新概述

用户期望应用程序始终可用,为此开发者/运维者在更新应用程序时要分多次完成。在 Kubernetes 中,这是通过 Rolling Update 滚动更新完成的。Rolling Update滚动更新 通过使用新版本的 Pod 逐步替代旧版本的 Pod 来实现 Deployment 的更新,从而实现零停机。新的 Pod 将在具有可用资源的 Node(节点)上进行调度。

Kubernetes 更新多副本的 Deployment 的版本时,会逐步的创建新版本的 Pod,逐步的停止旧版本的 Pod,以便使应用一直处于可用状态。这个过程中,Service 能够监视 Pod 的状态,将流量始终转发到可用的 Pod 上。

此前,我们将应用程序 Scale Up(扩容)为多个实例,这是执行更新而不影响应用程序可用性的前提。默认情况下,Rolling Update 滚动更新 过程中,Kubernetes 逐个使用新版本 Pod 替换旧版本 Pod(最大不可用 Pod 数为 1、最大新建 Pod 数也为 1)。这两个参数可以配置为数字或百分比。在Kubernetes 中,更新是版本化的,任何部署更新都可以恢复为以前的(稳定)版本。

滚动更新步骤

1.原本 Service A 将流量负载均衡到 4 个旧版本的 Pod (当中的容器为 绿色)上

image.png

2.更新完 Deployment 部署文件中的镜像版本后,Master 节点选择了一个 Node节点,并根据新的镜像版本创建 Pod(紫色容器)。新 Pod 拥有唯一的新的 IP。同时,master 节点选择一个旧版本的 Pod 将其移除。

此时,Service A 将新 Pod 纳入到负载均衡中,将旧Pod移除

image.png

3.同步骤2,再创建一个新的 Pod 替换一个原有的 Pod

image.png

4.如此 Rolling Update 滚动更新,直到所有旧版本 Pod 均移除,新版本 Pod 也达到 Deployment 部署文件中定义的副本数,则滚动更新完成

image.png

滚动更新允许以下操作:

  • 将应用程序从准上线环境升级到生产环境(通过更新容器镜像)

  • 回滚到以前的版本

  • 持续集成和持续交付应用程序,无需停机

滚动更新Deployment

按照上一节的方法,将pod扩容到4个

image.png

修改 nginx-deployment.yaml 文件

修改文件中 image 镜像的标签,如下所示

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.27.2   #使用镜像nginx:1.27.2替换原来的nginx:alpine
        ports:
        - containerPort: 80

执行命令

kubectl apply -f nginx-deployment.yaml

查看过程及结果

执行命令,可观察到 pod 逐个被替换的过程。

watch kubectl get pods -l app=nginx

注意:如果之前已经有1.27.2镜像,替换过程会比较快,执行watch命令的较晚的话,可能看不多替换过程或者只能看到部分替换过程。要看到全部替换过程,可以先执行这个watch命令,在执行kubectl apply命令。

原来的nginx-deployment-9c65654f4相关的pods从4个变为只有1个;新的nginx-deployment-75b5b48df5相关pods,有两个pod已经创建好了,有两个pod正在容器创建。

image.png

k2cjr已经创建成功如下

image.png

已经新的pods全部创建成功,可以观察到pod名称都是新的pod了。

image.png

查看ip也都变化了

image.png

​浏览器访问

image.png

删除部署资源

相关命令

删除 Deployment

Deployment 是用于管理应用的 Pod 副本数量和更新策略的资源对象。通过删除 Deployment,会自动删除其管理的 Pod。

kubectl delete deployment <deployment_name>

删除 Service

如果应用使用了 Service 来暴露服务,那么也需要删除对应的 Service。

kubectl delete service <service_name>

删除其他相关资源

根据应用的具体配置,可能还需要删除其他相关的资源,如 ConfigMap、Secret 等。

kubectl delete configmap <configmap_name>
kubectl delete secret <secret_name>

查看是否已删除成功

可以使用 kubectl get 命令来确认相关资源是否已被成功删除。例如:

kubectl get deployment <deployment_name>
kubectl get service <service_name>
kubectl get configmap <configmap_name>
kubectl get secret <secret_name>

如果资源已被成功删除,上述命令将不会返回对应的资源信息。

强制删除

如果在删除过程中遇到问题,例如 Pod 处于 Terminating 状态无法正常删除,可以使用强制删除的方式。

kubectl delete pod <pod_name> --force --grace-period=0

这种方式会立即删除 Pod,而不会等待其正常的终止流程完成。但在使用强制删除时需要谨慎,因为可能会导致数据丢失或其他未预期的问题。

命名空间删除

如果应用部署在特定的命名空间中,并且希望彻底删除该命名空间及其内的所有资源,可以使用以下命令:

kubectl delete namespace <namespace_name>

这将删除指定命名空间下的所有 Deployment、Service、Pod 等资源。

在执行删除操作时,请确保你有足够的权限,并且仔细确认要删除的资源,以免误删导致数据丢失或服务中断。

删除部署资源

查看部署的资源

# 查看deployment资源
[root@k8s-master01 1]# kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   4/4     4            4           25h
​
# 查看service资源
[root@k8s-master01 1]# kubectl get service
NAME            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.0.0.1      <none>        443/TCP        59d
nginx-service   NodePort    10.3.21.175   <none>        80:32600/TCP   107m
​

删除service

# 删除service资源
[root@k8s-master01 1]# kubectl delete service nginx-service
service "nginx-service" deleted
​
# 查看service资源
[root@k8s-master01 1]# kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP   59d
​

删除deployment资源

# 删除deployment资源
[root@k8s-master01 1]# kubectl delete deployment nginx-deployment
deployment.apps "nginx-deployment" deleted
​
# 查看deployment资源
[root@k8s-master01 1]# kubectl get deployment
No resources found in default namespace.
​

完成!enjoy it!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用 Maven 创建 jar / war 项目

使用 Maven 创建 jar 项目 maven-archetype-quickstart 这个Archetype&#xff0c;基本内容包括&#xff1a; 一个包含junit依赖声明的 pom.xml 、src/main/java主代码目录及一个名为App的类 、src/test/java测试代码目录及一个名为 AppTest的测试用例maven-archetype-webapp 一…

HDR视频技术之四:HDR 主要标准

HDR 是 UHD 技术中最重要维度之一&#xff0c;带来新的视觉呈现体验。 HDR 技术涉及到采集、加工、传输、呈现等视频流程上的多个环节&#xff0c;需要定义出互联互通的产业标准&#xff0c;以支持规模化应用和部署。本文整理当前 HDR 应用中的一些代表性的国际标准。 1 HDR 发…

Ubuntu中使用多版本的GCC

我的系统中已经安装了GCC11.4&#xff0c;在安装cuda时出现以下错误提示&#xff1a; 意思是当前的GCC版本过高&#xff0c;要在保留GCC11.4的同时安装GCC9并可以切换&#xff0c;可以通过以下步骤实现&#xff1a; 步骤 1: 安装 GCC 9 sudo apt-get update sudo apt-get ins…

dubbo-go框架介绍

框架介绍 什么是 dubbo-go Dubbo-go 是 Apache Dubbo 的 go 语言实现&#xff0c;它完全遵循 Apache Dubbo 设计原则与目标&#xff0c;是 go 语言领域的一款优秀微服务开发框架。dubbo-go 提供&#xff1a; API 与 RPC 协议&#xff1a;帮助解决组件之间的 RPC 通信问题&am…

DataGear 5.2.0 发布,数据可视化分析平台

DataGear 企业版 1.3.0 已发布&#xff0c;欢迎体验&#xff01; http://datagear.tech/pro/ DataGear 5.2.0 发布&#xff0c;图表插件支持定义依赖库、严重 BUG 修复、功能改进、安全增强&#xff0c;具体更新内容如下&#xff1a; 重构&#xff1a;各模块管理功能访问路径…

2023年3月GESPC++一级真题解析

一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 题目123456789101112131415答案BAACBDDAADBCDBC 1.以下不属于计算机输入设备的有&#xff08; &#xff09;。 A &#xff0e;键盘 B &#xff0e;音箱 C &#xff0e;鼠标 D &#xff0e;传感器 【答案】 …

RabbitMQ2:介绍、安装、快速入门、数据隔离

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

vue2.0 luoyi框架 代码漏洞检查问题

检查出在element ui存在漏洞 经过在elemen-ui.common.js文件中查找没发现eval函数 后发现是打包之后生成的产物 解决方法 在vue.config.js文件中进行打包配置 configureWebpack: {devtool: source-map, // 禁用 eval&#xff0c;使用 source-map 进行源码映射},

管家婆财贸ERP BR035.回款利润明细表

最低适用版本: 财贸系列 23.5 插件简要功能说明: 报表统计销售单/销售退货单/销售发票回款情况更多细节描述见下方详细文档插件操作视频: 进销存类定制插件--回款利润明细表 插件详细功能文档: 1. 应用中心增加报表【回款利润明细表】 a. b. 查询条件: ⅰ. 日期区间:…

学习QT第二天

QT6示例运行 运行一个Widgets程序运行一个QT Quick示例 工作太忙了&#xff0c;难得抽空学点东西。-_-||| 博客中有错误的地方&#xff0c;请各位道友及时指正&#xff0c;感谢&#xff01; 运行一个Widgets程序 在QT Creator的欢迎界面中&#xff0c;点击左侧的示例&#xf…

【图像检测】深度学习与传统算法的区别(识别逻辑、学习能力、泛化能力)

识别逻辑 深度学习 使用了端到端的学习策略&#xff0c;直接学习从图像到检测结果的映射关系&#xff0c;自动提取特征&#xff0c;并且根据特征与特征之间的关系&#xff0c;计算出检测结果。 传统算法 则是人工提取特征&#xff0c;比如边缘特征&#xff0c;直线特征&#x…

2024数学建模亚太赛【C题】赛题详细解析

目录 &#x1f4d1;一、竞赛时间 &#x1f5dd;️二、奖项设置 ✏️三、选题思路 &#x1f50d;阶段一&#xff1a;【数据预处理与探索性分析】 1.【数据清洗与预处理】 2.【探索性数据分析&#xff08;EDA&#xff09;】 &#x1f50d;阶段二&#xff1a;【时间序列建模…

移远通信推出全新5G RedCap模组RG255AA系列,以更高性价比加速5G轻量化大规模商用

11月20&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;正式推出其全新5G RedCap模组RG255AA系列。该系列模组支持5G NR独立组网&#xff08;SA&#xff09;和LTE Cat 4双模通信&#xff0c;具有高性能高集成度、低功耗、小尺寸、高性价比等优势&#…

任务中断的两套API函数(改进FormISR的实时性)资源管理_互斥操作的本质(解决DH11经常出错的问题)

任务中断的两套API函数 为什么需要两套 API 在任务函数中&#xff0c;我们可以调用各类 API 函数&#xff0c;比如队列操作函数&#xff1a;xQueueSendToBack。 但是在 ISR 中使用这个函数会导致问题&#xff0c;应该使用另一个函数&#xff1a;xQueueSendToBackFromISR&…

基于SpringBoot+Vue的高校社团管理系统

摘要 随着高校社团活动日益丰富多样&#xff0c;传统人工管理模式弊端凸显&#xff0c;迫切需要信息化的社团管理系统。本文介绍了基于 SpringBoot Vue 开发的高校社团管理系统。在技术选型方面&#xff0c;SpringBoot 作为后端框架&#xff0c;凭借其强大的自动配置功能&…

vscode插件Todo tree

# 需求 &#xff1a; 将注释形成可视化列表 快速找到相关代码位置 免搜索 # 使用步骤 1. 安装todo tree 插件 2. 使用 todo tree 按快捷键 ctrlshiftp 输入 todo tree:add tag 添加你打注释的开头关键字 比如 // 这是一条注释 示例可以添加搜索tag为 //空格 3. t…

Windows Server 2022 Web2

载入靶机&#xff0c;看到相关描述&#xff1a; 进入虚拟机发现桌面有phpstudy和解题两个软件&#xff1a; 先点击“解题.exe”&#xff1a; 1.攻击者的IP地址&#xff08;两个&#xff09;&#xff1f; 2.攻击者的webshell文件名&#xff1f; 3.攻击者的webshell密码&#x…

学习Prompt Turning

传统的微调因为代价很高&#xff0c;而且一旦权重很大&#xff0c;这种fine 微微的意思是调不动模型的&#xff0c;所以需要这种提示词调 mindnlp直接有 peft config peft_config PromptTuningConfig(task_type“SEQ_CLS”, num_virtual_tokens10) 方便我们进行prompt tunin…

分类算法——基于heart数据集实现

1 heart数据集——描述性统计分析 import matplotlib.pyplot as plt import pandas as pd# Load the dataset heart pd.read_csv(r"heart.csv", sep,)# Check the columns in the DataFrame print(heart.columns)aheart.loc[:, y].value_counts() print(a) heart.l…

POA-CNN-SVM鹈鹕算法优化卷积神经网络结合支持向量机多特征分类预测

分类预测 | Matlab实现POA-CNN-SVM鹈鹕算法优化卷积神经网络结合支持向量机多特征分类预测 目录 分类预测 | Matlab实现POA-CNN-SVM鹈鹕算法优化卷积神经网络结合支持向量机多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现POA-CNN-SVM鹈鹕算法…