使用Kubernetes部署第一个应用

news2024/11/24 4:22:58

目录

前提条件

启动集群

部署 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!

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

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

相关文章

第T8周:Tensorflow实现猫狗识别(1)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 具体实现 &#xff08;一&#xff09;环境 语言环境&#xff1a;Python 3.10 编 译 器: PyCharm 框 架: &#xff08;二&#xff09;具体步骤 from absl.l…

使用 OpenAI 进行数据探索性分析(EDA)

探索性数据分析&#xff08;Exploratory Data Analysis, 简称 EDA&#xff09;是数据分析中不可或缺的环节&#xff0c;帮助分析师快速了解数据的分布、特征和潜在模式。传统的 EDA 通常需要手动编写代码或使用工具完成。现在&#xff0c;通过 OpenAI 的 GPT-4 模型&#xff0c…

力扣-Hot100-栈【算法学习day.40】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…

低速接口项目之串口Uart开发(四)——UART串口实现FPGA内部AXILITE寄存器的读写控制

本节目录 一、设计背景 二、设计思路 三、逻辑设计框架 四、仿真验证 五、上板验证 六、往期文章链接本节内容 一、设计背景 通常&#xff0c;芯片手册或者IP都会提供一系列的用户寄存器以及相关的定义&#xff0c;用于软件开发人员进行控制底层硬件来调试&#xff0c;或封装…

记录第一次安装laravel项目

window系统 Laravel中文文档&#xff1a;https://laravel-docs.catchadmin.com/docs/11/getting-started/installation 1.使用composer安装全局laravel composer global require laravel/installer2.安装完成后在命令行输入laravel&#xff0c;如果报错&#xff1a;laravel不是…

PDF电子发票信息转excel信息汇总

PDF电子发票信息提取&#xff0c;支持将pdf发票文件夹下的剩所有发票&#xff0c;转为excel格式的信息&#xff0c;对于发票量比较大&#xff0c;不好统计&#xff0c;需要一个一个去统计的情况&#xff0c;可节省2个点以上的时间&#xff0c;一次下载&#xff0c;终身有效。 使…

性能优化(二):ANR

介绍 ANR全称Application Not Responding&#xff0c;意思就是程序未响应。如果一个应用无法响应用户的输入&#xff0c;系统就会弹出一个ANR对话框&#xff0c;用户可以自行选择继续等待亦或者是停止当前程序。 Android系统会监控程序的响应状况&#xff0c;一旦出现下面情况…

Idea修改Commit Changes模式、idea使用git缺少部分Commit Changes

文章目录 一、模式一1、页面效果如下2、如何打开为这种样式&#xff1f; 二、模式二1、页面效果如下2、如何打开为这种样式&#xff1f; 三、总结 前言&#xff1a;Idea中代码提交到git库时的commit Change有两种模式&#xff0c;每种模式的界面及功能都不太一样。 Commit Cha…

【UE5】在材质中计算模型在屏幕上的比例

ViewProperty节点有很多有意思的变量 例如用 ViewProperty 的 tan ⁡ ( FOV / 2 ) \tan(\text{FOV} / 2) tan(FOV/2) 输出&#xff0c;用它计算模型占屏幕的比例。 &#xff08;常用于for运算的次数优化&#xff0c;也可以用于各种美术效果&#xff09; ScaleOnScreen Obje…

【STM32】MPU6050简介

文章目录 MPU6050简介MPU6050关键块带有16位ADC和信号调理的三轴MEMS陀螺仪具有16位ADC和信号调理的三轴MEMS加速度计I2C串行通信接口 MPU6050对应的数据手册&#xff1a;MPU6050 陀螺仪加速度计 链接: https://pan.baidu.com/s/13nwEhGvsfxx0euR2hMHsyw?pwdv2i6 提取码: v2i6…

vue3 在哪些方便做了性能提升?

概要 Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式框架。vue2版本阶段已经证明了它的易用性和流行性&#xff0c;说明它已经足够优秀在构建前端应用领域&#xff0c;而vue3的推出更是将性能提升做了最大的优化&#xff0c;更加易用、灵活、高效&…

Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)

1、前言 在 Vue 3 项目中结合 vue-i18n 和 Element Plus 实现中英文切换是一个常见的需求。下面是一个详细的步骤指南&#xff0c;帮助你完成这个任务。 安装引入 1. 安装依赖 首先&#xff0c;你需要安装 vue-i18n 和 Element Plus。 npm install vue-i18nnext element-p…

【YOLOv8】安卓端部署-1-项目介绍

【YOLOv8】安卓端部署-1-项目介绍 1 什么是YOLOv81.1 YOLOv8 的主要特性1.2 YOLOv8分割模型1.2.1 YOLACT实例分割算法之计算掩码1.2.1.1 YOLACT 的掩码原型与最终的掩码的关系1.2.1.2 插值时的目标检测中提取的物体特征1.2.1.3 coefficients&#xff08;系数&#xff09;作用1.…

基于Spring Boot+Unipp的博物馆预约小程序(协同过滤算法、二维码识别)【原创】

&#x1f388;系统亮点&#xff1a;协同过滤算法、二维码识别&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框…

Spring Boot 3 【八】整合实现高可用 Redis 集群

一、引言 在当今快速发展的软件开发领域&#xff0c;系统的性能和可靠性至关重要。Springboot 3 整合 Redis 7 集群具有多方面的重大意义。 首先&#xff0c;随着业务的不断发展&#xff0c;数据量呈爆炸式增长&#xff0c;单个 Redis 服务器往往难以满足存储和处理需求。Red…

网络安全-企业环境渗透2-wordpress任意文件读FFmpeg任意文件读

一、 实验名称 企业环境渗透2 二、 实验目的 【实验描述】 操作机的操作系统是kali 进入系统后默认是命令行界面 输入startx命令即可打开图形界面。 所有需要用到的信息和工具都放在了/home/Hack 目录下。 本实验的任务是通过外网的两个主机通过代理渗透到内网的两个主机。…

如何创建一个网站?初学者的分步指南

在当今数字化时代&#xff0c;即便你对 Web 开发、设计或编码一窍不通&#xff0c;也能轻松搭建属于自己的网站。无论你是想为个人打造展示平台&#xff0c;还是为企业建立线上形象&#xff0c;只要掌握正确的方法&#xff0c;借助合适的工具与资源&#xff0c;就能在短时间内完…

OceanBase V4.x应用实践:如何排查表被锁问题

DBA在日常工作中常常会面临以下两种常见情况&#xff1a; 业务人员会提出问题&#xff1a;“表被锁了&#xff0c;导致业务受阻&#xff0c;请帮忙解决。” 业务人员还会反馈&#xff1a;“某个程序通常几秒内就能执行完毕&#xff0c;但现在却运行了好几分钟&#xff0c;不清楚…

MongoDB进阶篇-索引(索引概述、索引的类型、索引相关操作、索引的使用)

文章目录 1. 索引概述2. 索引的类型2.1 单字段索引2.2 复合索引2.3 其他索引2.3.1 地理空间索引&#xff08;Geospatial Index&#xff09;2.3.2 文本索引&#xff08;Text Indexes&#xff09;2.3.3 哈希索引&#xff08;Hashed Indexes&#xff09; 3. 索引相关操作3.1 查看索…

Ubuntu20.04 Rk3588 交叉编译ffmpeg7.0

firefly 公司出的rk3588的设备&#xff0c;其中已经安装了gcc 交叉编译工具&#xff0c;系统版本是Ubuntu20.04。 使用Ubuntu20.04 交叉编译ffmpeg_ubuntu下配置ffmpeg交叉编译器为arm-linux-gnueabihf-gcc-CSDN博客文章浏览阅读541次。ubuntu20.04 交叉编译ffmpeg_ubuntu下配…