K8S实战笔记--4(部署应用 + 公布应用 + 服务伸缩与滚动更新 + 节点描述)

K8S实战笔记–3中,我们已对YAML文件的编写以及容器生命周期有了一定的了解,现将从部署应用程序开始,从编写YAML与操作Kuboard的角度来学习对Kubernetes的具体操作。

1. 部署应用程序

本次实验以部署Nginx为例。我们可以使用传统的YAML方法部署应用,或直接使用Kuboard借助图形化界面进行部署。

1.1 使用YAML

kubectl api-versions可以从查看当前K8S集群支持的apiVersion版本。首先创建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:1.7.9	#使用镜像nginx:1.7.9创建container,该container默认80端口可访问

使用kubectl get pods可以查看Pod状态;使用kubectl describe pod nginx可以查看Pod运行情况:

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  2m   default-scheduler  Successfully assigned default/nginx-deployment-746fbb99df-29mpn to k8sworker
  Normal  Pulling    2m   kubelet            Pulling image "nginx:1.7.9"
  Normal  Pulled     2m   kubelet            Successfully pulled image "nginx:1.7.9" in 13.126408886s
  Normal  Created    2m   kubelet            Created container nginx
  Normal  Started    2m   kubelet            Started container nginx

可以看到包括拉取镜像在内的一系列操作都已完成。由于我们创建的控制器类型是Deployment,所以我们也可以使用kubectl get deployments来查看当前已有的Deployment。现在我们已经有了一个运行在default名称空间下的Pod,里面运行了一个Nginx容器,登录Kuboard,可以查看当前Pod的详细信息。

1.2 使用Kuboard

使用Web图形化界面部署应用相比YAML而言要简单许多。

  1. 登录Kuboard,选择要操作的集群;
  2. 使用管理员身份(ServiceAccount kuboard-admin)访问集群,选择切换到default名称空间下;
  3. 在“常用操作”中选择创建工作负载,在“基本信息”中选择控制器类型为Deployment,将服务分层选为展现层,填入服务名称,在此处我们可以定义弹性伸缩范围,本次选择1个副本;
  4. 在“容器信息”中,我们可以定义容器名、镜像、拉取策略、命令、环境变量以及容器端口等;
  5. 保存并应用

此时我们通过Kuboard创建了一个运行的Nginx的工作负载,在Kuboard中,点击代理,可以直接测试部署结果。

2. 公布应用程序

我们已经了解到,Service通过将请求路由到一组Pod的方式,动态地调度Pod。在部署应用程序中,我们通过含有标签app = Nginx的Deployment创建出了含有此标签的Pod,接下来为了使此Pod包含的服务可以被外界访问到,需要创建一个Service来链接此Pod。

2.1 使用YAML

Service的类型有以下三种,主要体现在YAML的type字段中:

  1. ClusterIP:type的默认值。这种类型的发布只在集群的内部IP上公布服务,只能在集群内部访问到;
  2. NodePort:在集群中每个节点的同一端口上公布服务,可以通过节点IP + 端口号的方式访问服务,此时集群内也可以访问该服务;
  3. LoadBalancer:使用云主机作为服务的访问地址,此时集群内以及端口发布仍然可用。

创建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: 30090   #通过任意节点的 32600 端口访问 Service
    targetPort: 80	#将请求转发到匹配 Pod 的 80 端口
  type: NodePort	#Serive的类型,ClusterIP/NodePort/LoaderBalancer

此时我们已通过端口发布的方式向外界公布了我们的服务,使用kubectl get serivces可以查看集群中已存在的Service。在开放云主机端口后,我们也可以通过节点IP + 端口号的方式在浏览器查看到服务的运行情况。

2.2 使用Kuboard

  1. 在工作负载中选择“编辑”;
  2. 在“服务/应用路由”栏下填写服务端口、节点端口与容器端口;
  3. 保存

3. 服务伸缩与滚动更新

通常我们为增加应用的可用性,防止流量增加时出现服务繁忙的状况,我们需要设置服务的弹性伸缩。在K8S中,服务的伸缩通过改变Pod的副本数目来实现。

在使用YAML时,我们只需要在详细描述中修改副本数目即可:

spec:
  replicas: 3

若使用Kuboard,可以在相应的工作负载中查看当前副本数目的图形化表示,使用加减按钮可以便捷地修改副本数目。在拥有大于1个副本数目时,我们就可以实施对应用程序的滚动更新。我们在之前的学习中了解到通过Deployment管理RS可以很好地避免由不同机制引起的兼容性问题,其中就包括滚动更新,在实际的应用场景中,用户有时要求应用程序是随时可用的,这需要开发与运维人员将应用程序的更新迭代分为多次进行。在K8S中,Service将流量均衡到符合副本数目的旧版本Pod中,在更新YAML中的镜像版本或在Kuboard中配置“调整镜像版本”后,K8S会使用新版本的Pod逐个替换旧版本的Pod,即每次新建一个新版本Pod并删除一个旧版本Pod,保证Pod的最大新建数目与最大不可用数目都为1,直到Pod全部更新完成为止。回滚版本也是相同的原理,此时无需考虑停机。

4. 节点描述

在K8S中,一台节点(node)代表一个工作机器,每个节点都由master组件管理,包含并运行了Pod所需的服务。以下以master节点为例,描述节点相关内容。

节点通过kubelet收集这些信息,可以使用kubectl describe命令查看,输出如下:

[root@k8smaster ~]# kubectl describe node k8smaster
Name:               k8smaster
Roles:              master
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=k8smaster
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/master=
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 172.19.191.190/20
                    projectcalico.org/IPv4IPIPTunnelAddr: 10.100.16.128
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Mon, 17 Jul 2023 10:16:53 +0800
Taints:             node-role.kubernetes.io/master:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  k8smaster
  AcquireTime:     <unset>
  RenewTime:       Sun, 23 Jul 2023 15:12:11 +0800
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Sun, 23 Jul 2023 15:08:46 +0800   Sun, 23 Jul 2023 15:08:46 +0800   CalicoIsUp                   Calico is running on this node
  MemoryPressure       False   Sun, 23 Jul 2023 15:07:41 +0800   Mon, 17 Jul 2023 10:16:48 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Sun, 23 Jul 2023 15:07:41 +0800   Mon, 17 Jul 2023 10:16:48 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Sun, 23 Jul 2023 15:07:41 +0800   Mon, 17 Jul 2023 10:16:48 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Sun, 23 Jul 2023 15:07:41 +0800   Mon, 17 Jul 2023 10:17:32 +0800   KubeletReady                 kubelet is posting ready status
Addresses:
  InternalIP:  172.19.191.190
  Hostname:    k8smaster
Capacity:
  cpu:                2
  ephemeral-storage:  41152812Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3733564Ki
  pods:               110
Allocatable:
  cpu:                2
  ephemeral-storage:  37926431477
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3631164Ki
  pods:               110
System Info:
  Machine ID:                 20200914151306980406746494236010
  System UUID:                7F940571-2A55-438F-AE29-CF050E00A217
  Boot ID:                    38057d4b-c304-49eb-86b5-18213478a629
  Kernel Version:             3.10.0-1127.19.1.el7.x86_64
  OS Image:                   CentOS Linux 7 (Core)
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  docker://19.3.11
  Kubelet Version:            v1.19.5
  Kube-Proxy Version:         v1.19.5
PodCIDR:                      10.100.0.0/24
PodCIDRs:                     10.100.0.0/24
Non-terminated Pods:          (13 in total)
  Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
  kube-system                 calico-kube-controllers-6c89d944d5-ppb9f    0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d4h
  kube-system                 calico-node-nkj7x                           250m (12%)    0 (0%)      0 (0%)           0 (0%)         6d4h
  kube-system                 coredns-59c898cd69-9xtxz                    100m (5%)     0 (0%)      70Mi (1%)        170Mi (4%)     6d4h
  kube-system                 coredns-59c898cd69-mfprl                    100m (5%)     0 (0%)      70Mi (1%)        170Mi (4%)     6d4h
  kube-system                 etcd-k8smaster                              0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d4h
  kube-system                 kube-apiserver-k8smaster                    250m (12%)    0 (0%)      0 (0%)           0 (0%)         6d4h
  kube-system                 kube-controller-manager-k8smaster           200m (10%)    0 (0%)      0 (0%)           0 (0%)         6d4h
  kube-system                 kube-proxy-kphhp                            0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d4h
  kube-system                 kube-scheduler-k8smaster                    100m (5%)     0 (0%)      0 (0%)           0 (0%)         6d4h
  kuboard                     kuboard-agent-2-5c7475f4d-d9nfs             0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d4h
  kuboard                     kuboard-agent-74c4d97bc6-btgbz              0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d4h
  kuboard                     kuboard-etcd-4wvkw                          0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d4h
  kuboard                     kuboard-v3-59ccddb94c-pnmmn                 0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d4h
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                1 (50%)     0 (0%)
  memory             140Mi (3%)  340Mi (9%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-1Gi      0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)
Events:
  Type    Reason                   Age                    From        Message
  ----    ------                   ----                   ----        -------
  Normal  Starting                 145m                   kubelet     Starting kubelet.
  Normal  NodeHasSufficientMemory  145m (x8 over 145m)    kubelet     Node k8smaster status is now: NodeHasSufficientMemory
  Normal  NodeHasNoDiskPressure    145m (x8 over 145m)    kubelet     Node k8smaster status is now: NodeHasNoDiskPressure
  Normal  NodeHasSufficientPID     145m (x7 over 145m)    kubelet     Node k8smaster status is now: NodeHasSufficientPID
  Normal  NodeAllocatableEnforced  145m                   kubelet     Updated Node Allocatable limit across pods
  Normal  Starting                 143m                   kube-proxy  Starting kube-proxy.
  Normal  Starting                 4m40s                  kubelet     Starting kubelet.
  Normal  NodeHasSufficientMemory  4m39s (x8 over 4m39s)  kubelet     Node k8smaster status is now: NodeHasSufficientMemory
  Normal  NodeHasNoDiskPressure    4m39s (x7 over 4m39s)  kubelet     Node k8smaster status is now: NodeHasNoDiskPressure
  Normal  NodeHasSufficientPID     4m39s (x8 over 4m39s)  kubelet     Node k8smaster status is now: NodeHasSufficientPID
  Normal  NodeAllocatableEnforced  4m39s                  kubelet     Updated Node Allocatable limit across pods
  Normal  Starting                 3m27s                  kube-proxy  Starting kube-proxy.
[root@k8smaster ~]# 

在如上节点信息中,节点的主要状态被包含在如下几个字段中:

  1. Address:描述节点IP,主要包括:
    • Hostname:与终端执行hostname的值相同,也可用参数--hostname-override覆盖;
    • InternalIP:从节点内部可以访问的IP地址;
    • ExternalIP:可以从集群外访问的内网IP地址,在本次实验中,此字段为空。
  2. Conditions:描述了节点状态,常见的状态包括:
    • NetworkUnvaliable:如果节点的网络配置有问题,则此字段为True,否则为False

    • MemoryPressure:如果节点内存紧张,则此字段为True,否则为False

    • DiskPressure:如果节点磁盘紧张,则此字段为True,否则为False

    • PIDPressure:如果节点进程过多,则此字段为True,否则为False

    • Ready:如果节点是健康的,且能够接受新的Pod,则此字段为True,否则为False
      未在上文输出中出现的字段如:OutOfDisk:表明节点上空白磁盘空间短缺,无法接受增加新的节点,此时此字段为True

      Ready类型的Status持续为UnknowFalse超过pod-eviction-timeout限制的时间后,控制器会对该节点上的所有Pod实行删除操作。pod-eviction-timeoutkube-controller-manager的一个参数,默认值为5。但在某些情况下,APIServer无法与该node上的kubelet进行通信(例如该node网络发生了故障),此时无法将删除Pod的指令下达到该node的kubelet上,需要等到通信恢复后,该node的kubelet才会接收并执行这些指令。于是,出现了即使已经下达了删除Pod的指令,但Pod仍在这个失联的node上运行。

      如何处理这种情况?在K8Sv1.5以前,控制器会强制删除APIServer上这些运行在已失联节点上的Pod,但在K8Sv1.5及以后的版本,直到控制器确认这些Pod已停止运行之前,不会对其进行强制删除,如此,在该失联的node上执行docker ps命令,就会发现这些Pod仍然在运行,而在APIServer中,他们的状态早已变为终止(Terminating)或未知(Unknow),此时只能通过手动执行kubectl delete命令来从APIServer中删除已失联的节点,该节点上的所有Pod都会被删除。

      在K8Sv1.12中,条件化的污点(TaintNodesByCondition)特性进入Beta阶段,此时node lifecycle controller将自动创建该 Condition对应的污点。相应地,调度器在选择合适的节点时,不再关注节点的Condition,而是检查节点的污点和 Pod 的容忍。有关污点的学习,我们会在后续内容中提到。

  3. Capacity&AllocatableCapacity描述了节点资源总量,Allocatable描述了该节点上可分派给普通Pod的资源总数。包括CPU、内存、可调度最大Pod数量;
  4. Info:包含了节点的基本信息,如Linux版本、K8S版本、Docker版本、操作系统名称等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值