当前位置: 首页 > article >正文

使用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!


http://www.kler.cn/a/407674.html

相关文章:

  • 动态反馈控制器(DFC)和 服务率控制器(SRC);服务率和到达率简单理解
  • mybatis-plus方法无效且字段映射失败错误排查
  • 10-单表查询
  • 原生JS和CSS,HTML实现开屏弹窗
  • [UE5学习] 一、使用源代码安装UE5.4
  • leetcode 50个简单和中等难度的题
  • 华为机试HJ62 查找输入整数二进制中1的个数
  • GESP考试大纲
  • doris的安装部署
  • 用vite下载的react + TS的项目,组件会调用两次
  • Python 快速入门(上篇)❖ Python基础知识
  • 98. 验证二叉搜索树【 力扣(LeetCode) 】
  • 深挖`React`里程碑之作`AutoStore`与`helux`的渊源
  • 开源可视化工具对比:JimuReport VS DataEase
  • Android 设置 bottomnavigation 底部导航栏的样式
  • 【从零开始的LeetCode-算法】3233. 统计不是特殊数字的数字数量
  • 数据指标与标签在数据分析中的关系与应用
  • 计算机网络-VPN虚拟专用网络概述
  • Spring Framework 的版本历史和JDK、Springboot对应关系
  • 数据预处理——相关性分析详解
  • 实验室管理流程优化:Spring Boot技术实践
  • 数据结构第一讲
  • windows C#-取消任务列表(上)
  • 解决前端页面报错:Not allowed to load local resource
  • Linux高阶——1123—
  • 恋爱通信史之身份验证和不可抵赖性