k8s及常用指令使用总结

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: k8s及常用指令使用总结

一、Kubernetes 是什么?

Kubernetes (K8S) 是由Google设计的用于自动化部署、大规模可伸缩、管理容器化应用程序的开源的容器编排引擎,目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。

传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。

新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。

容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在build或release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更“透明”,这更便于监控和管理。

K8S 名词解释 #

使用腾讯云容器服务 TKE,会涉及到以下基本概念:

集群(Cluster):是指容器运行所需云资源的集合,包含了若干台云服务器、负载均衡器等云资源。

节点(Node):节点可以是一个虚拟机或者物理机器,取决于所在的集群配置,每个节点包含运行 Pods 所需的服务。

实例(Pod):由相关的一个或多个容器构成一个实例,这些容器共享相同的存储和网络空间。

工作负载(Workloads):Kubernetes 资源对象,用于管理 Pod 副本的创建、调度以及整个生命周期的自动控制。

Service:由多个相同配置的实例(Pod)和访问这些实例(Pod)的规则组成的微服务。

Ingress:Ingress 是用于将外部 HTTP(S)流量路由到服务(Service)的规则集合。

镜像仓库:用于存放 Docker 镜像,Docker 镜像用于部署容器服务。

常用指令

# 查看所有 pod 列表,  -n 后跟 namespace, 查看指定的命名空间
kubectl get pods
kubectl get pods -n game-demo  
NAME                             READY   STATUS    RESTARTS   AGE
game-dirsvr-1-6bd769896b-9vz58    2/2     Running   0          5d1h
game-gamesvr-1-5b585b7fdc-vl7wr   2/2     Running   0          32m

一旦pod状态损坏后,CrashLoopBackOff,就进不了pod查看日志

kubectl get pods -n game-demo
NAME                           READY   STATUS             RESTARTS   AGE
game-dirsvr-77c78ddc-r85bd      0/1     CrashLoopBackOff   165        14h
game-gamesvr-6c7f448bc6-2ttnh   1/1     Running            0          14h
kubectl exec -n gamioo-demo --stdin --tty ooxxooxx  -- /bin/bash
# 通过bash获得 pod 中某个容器的TTY,相当于登录容器
kubectl exec -it <pod-name> -c <container-name> -- bash
kubectl exec -n game-demo -it gamesvr-1-7f9f9f8bfb-hrwdn  -c gamesvr-1 -- bash
# 执行 pod 的 date 命令
kubectl exec <pod-name> -- date
kubectl exec <pod-name> -- bash
kubectl exec <pod-name> -- ping 10.24.51.9
kubectl exec  gamesvr-1-666dd5f8c8-d9lb6 -n gamioo-demo -c gamesvr-1  -- date
Sun Jul 11 23:09:08 CST 2021
# 查看 Pod 详情:
kubectl describe node 172.17.0.11
# 显示 Pod 的详细信息, 特别是查看 pod 无法创建的时候的日志
kubectl describe pod <pod-name> -n <namespace>
kubectl describe pod gamesvr-1-666dd5f8c8-d9lb6 -n gamioo-demo
# 根据 yaml 创建资源, apply 可以重复执行,create 不行
kubectl create -f pod.yaml -n <namespace>
kubectl apply -f pod.yaml -n <namespace>
kubectl apply -f pod.yaml -n <namespace>

patch 更新 api 对象,使用策略性合并补丁更新一个 Deployment过补丁,您可以避免定义整个对象,只需要定义您希望更改的部分。通过策略性合并补丁,您只需要定义新增的元素就可以更新一个列表。列表中已有的元素仍然保留,新增的元素和已有的元素会被合并。上述例子中,最终结果的 containers 列表中既有原先的 nginx 容器,也有新增的 redis 容器。

如果能保证pod.yaml是最新的,那整个过程就不需要先apply,再patch,否则就变成了先部署老版本,再打patch新的版本上去的过程。

kubectl patch deployment <container-name> -n <namespace> -patch  "json content"
kubectl patch deployment dirsvr-1 -n gamioo-demo -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"build\":\"$REVISION-$DEPLOY_DATE\"}}}}}}"
# 等价命令
kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)"
kubectl patch deployment patch-demo --patch $'spec:\n template:\n  spec:\n   containers:\n   - name: patch-demo-ctr-2\n     image: redis'
#如何传值
kubectl patch deployment patch-demo --patch "$(cat patch-file.json)"
kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "patch-demo-ctr-2","image": "redis"}]}}}}'
#删除 k8s 中的 StatefulSet
kubectl delete statefulset gamesvr-1-1 -n gamioo-demo
#查看更新结果
kubectl get deployment gamesvr-1 -n gamioo-demo --output yaml
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: gamesvr-1
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: gamesvr-1
        build: 7ac2d40-1625837884
# 查看容器的日志
kubectl logs <pod-name>
kubectl logs -f <pod-name> # 实时查看日志
kubectl logs  <pod-name>  -c <container_name> # 若 pod 只有一个容器,可以不加 -c 
#查看最近的10行日志
kubectl logs --tail  10  gamesvr-1-666dd5f8c8-d9lb6 -n gamioo-demo -c gamesvr-1 
# 仅输出pod nginx中最近的20条日志
kubectl logs --tail=20 nginx
# 输出pod nginx中最近一小时内产生的所有日志
kubectl logs --since=1h nginx

如果kubectl logs后没有任何输出,试试使用get pod,然后会发现这很有可能是一个新启动的Pod,因此可以尝试检查一些上一次挂掉的Pod的日志。

kubectl logs gamesvr-1-666dd5f8c8-d9lb6 -n gamioo-demo -c gamesvr-1  --previous
# 查看集群的所有节点信息
kubectl get node --show-labels
NAME          STATUS   ROLES    AGE    VERSION         LABELS
172.17.0.10   Ready    <none>   101d   v1.18.4-tke.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/instance-type=S5.LARGE8,beta.kubernetes.io/os=linux,cloud.tencent.com/node-instance-id=ins-8helzjev,failure-domain.beta.kubernetes.io/region=sh,failure-domain.beta.kubernetes.io/zone=200005,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.17.0.10,kubernetes.io/os=linux,node.kubernetes.io/instance-type=S5.LARGE8,topology.kubernetes.io/region=sh,topology.kubernetes.io/zone=200005
172.17.0.11   Ready    <none>   101d   v1.18.4-tke.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/instance-type=S5.LARGE8,beta.kubernetes.io/os=linux,cloud.tencent.com/node-instance-id=ins-2qrbqrvz,failure-domain.beta.kubernetes.io/region=sh,failure-domain.beta.kubernetes.io/zone=200005,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.17.0.11,kubernetes.io/os=linux,node.kubernetes.io/instance-type=S5.LARGE8,topology.kubernetes.io/region=sh,topology.kubernetes.io/zone=200005
172.17.0.5    Ready    <none>   101d   v1.18.4-tke.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/instance-type=S5.LARGE8,beta.kubernetes.io/os=linux,cloud.tencent.com/node-instance-id=ins-1sw1t7xn,failure-domain.beta.kubernetes.io/region=sh,failure-domain.beta.kubernetes.io/zone=200005,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.17.0.5,kubernetes.io/os=linux,node.kubernetes.io/instance-type=S5.LARGE8,topology.kubernetes.io/region=sh,topology.kubernetes.io/zone=200005
172.17.0.6    Ready    <none>   101d   v1.18.4-tke.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/instance-type=S5.LARGE8,beta.kubernetes.io/os=linux,cloud.tencent.com/node-instance-id=ins-kf266cv9,failure-domain.beta.kubernetes.io/region=sh,failure-domain.beta.kubernetes.io/zone=200005,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.17.0.6,kubernetes.io/os=linux,node.kubernetes.io/instance-type=S5.LARGE8,topology.kubernetes.io/region=sh,topology.kubernetes.io/zone=200005
172.17.0.8    Ready    <none>   101d   v1.18.4-tke.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/instance-type=S5.LARGE8,beta.kubernetes.io/os=linux,cloud.tencent.com/node-instance-id=ins-ifbkpk7j,failure-domain.beta.kubernetes.io/region=sh,failure-domain.beta.kubernetes.io/zone=200005,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.17.0.8,kubernetes.io/os=linux,node.kubernetes.io/instance-type=S5.LARGE8,topology.kubernetes.io/region=sh,topology.kubernetes.io/zone=200005

整合两个指令:

kubectl exec -n gamioo-demo --stdin --tty $(kubectl get pods -n gamioo-demo | grep gamesvr | awk -F' ' '{print $1}') -- /bin/bash

如果起不来,排查如下:

kubectl logs --tail  10  gamioo-accountsvr-6dc4869f44-snb2v -n gamioo-demo -c gamioo-accountsvr
//输出尾部的事件信息
kubectl describe pod gamioo-accountsvr --namespace=gamioo-demo 
kubectl delete deployment gamioo-accountsvr -n gamioo-demo
kubectl get pods -n gamioo-demo
kubectl get deployment  gamioo-accountsvr -n gamioo-demo --output yaml
#启动异常,没有日志时看这个
kubectl -n gamioo-demo get event
> kubectl describe pod logger
Name:         logger-68d7466799-r5pbf
Namespace:    platform-server
Priority:     0
Node:         10.100.0.120/10.100.0.120
Start Time:   Thu, 05 Jan 2023 17:08:22 +0800
Labels:       app=logger
              build=f943d61
              pod-template-hash=68d7466799
Annotations:  tke.cloud.tencent.com/networks-status:
                [{
                    "name": "tke-route-eni",
                    "interface": "eth1",
                    "ips": [
                        "10.100.0.91"
                    ],
                    "mac": "42:f8:10:dc:c7:24",
                    "default": true,
                    "dns": {}
                }]
Status:       Running
IP:           10.100.0.91
IPs:
  IP:           10.100.0.91
Controlled By:  ReplicaSet/logger-68d7466799
Containers:
  logger:
    Container ID:  docker://c621f177db202632ae44e800e389d8611f7d095c9c1c04c851c2320d60f7eddc
    Image:         ccr.ccs.tencentyun.com/yorha-kf-demo/platform-logger:0.4.138.0
    Image ID:      docker-pullable://ccr.ccs.tencentyun.com/yorha-kf-demo/platform-logger@sha256:fd98232214f4437b40480e260a6c375008b1605f189e80814cddd00afa3e29d0
    Port:          4001/TCP
    Host Port:     0/TCP
    Args:
      test
      10.100.0.127:8848
    State:          Running
      Started:      Thu, 05 Jan 2023 17:08:24 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      memory:                        2048M
      tke.cloud.tencent.com/eni-ip:  1
    Requests:
      memory:                        1024M
      tke.cloud.tencent.com/eni-ip:  1
    Environment:
      TZ:         Asia/Shanghai
      PROC_NAME:  logger
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-v9btc (ro)
Readiness Gates:
  Type                                                 Status
  cloud.tencent.com/load-balancer-backendgroup-ready   True
Conditions:
  Type                                                 Status
  cloud.tencent.com/load-balancer-backendgroup-ready   True
  Initialized                                          True
  Ready                                                True
  ContainersReady                                      True
  PodScheduled                                         True
Volumes:
  kube-api-access-v9btc:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Burstable
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  8m47s  default-scheduler  Successfully assigned platform-server/logger-68d7466799-r5pbf to 10.100.0.120
  Normal  Pulling    8m46s  kubelet            Pulling image "ccr.ccs.tencentyun.com/yorha-kf-demo/platform-logger:0.4.138.0"
  Normal  Pulled     8m46s  kubelet            Successfully pulled image "ccr.ccs.tencentyun.com/yorha-kf-demo/platform-logger:0.4.138.0" in 306.22646ms
  Normal  Created    8m45s  kubelet            Created container logger
  Normal  Started    8m45s  kubelet            Started container logger

目前热更流水线是打了新的镜像,里面包含要增量更新的class文件,再执行命令的。

可以支持直接把文件打入到指定pod的指定目录的命令

kubectl cp

如何将k8容器中文件下载到本地

kubectl cp -n namespace pod:path localpath

kubectl cp -n platform-server  platform-system-58746bb8d9-4x6b5:/gamioo/log/system/white.log ./white.log

工作负载:

Deployment:启动时先启动新的pod,然后再关闭老的pod

StatefulSet:标识固定,先关闭老的pod,然后再开启新的pod

Replicaset:通过定义一个Deployment控制器会创建一个新的ReplicaSet控制器,然后再通过ReplicaSet创建pod。一般来说,删除Deployment控制器,同时会删除Deployment控制器下对应的ReplicaSet控制器和pod资源。

是pod控制器类型的一种实现,用于确保由其管控的pod对象副本数在任一时刻都能精确满足期望的数量。ReplicaSet控制器资源启动后会查找集群中匹配其标签选择器的pod资源对象,当前活动对象的数量与其期望的数量不吻合时,多则删除,少则通过pod模板创建以补足,等pod资源副本数量符合期望值后即进入下一轮和解循环。

默认情况下,将保留 10 个旧的 ReplicaSet,但其理想值取决于新 Deployment 的频率和稳定性,我们可以通过

修改spec.revisionHistoryLimit 的值去改变,

apiVersion: apps/v1
kind: Deployment
# ...
spec:
  # ...
  revisionHistoryLimit: 0 # Default to 10 if not specified
  # ...

引用自 K8s 文档:«.spec.revisionHistoryLimit 是一个可选字段,它指定要保留以允许回滚的旧 ReplicaSets 的数量。这些旧的 ReplicaSet 会消耗 etcd 中的资源并挤占 kubectl get rs 的输出。每个 Deployment 修订版的配置都存储在其 ReplicaSets 中;因此,一旦旧的 ReplicaSet 被删除,您就无法回滚到 Deployment 的那个修订版。

一个pod相当于一个操作系统,容器(Container)相当于一个进程,一个pod可以有好多个进程

Q&A

1.进程启动比正常慢很多,可能原因是对CPU做了上下限限制,取消限制就行。

2. K8Spod资源调度经常调度到内存占用大的宿主机,而不是内存占用小的。

原因是因为容器调度策略默认以CPU为主,

kubernetes之镜像拉取策略ImagePullSecrets

2.如何自定义容器调度策略

DynamicScheduler 说明

如何使用

这样就可以按照内存权重优先来调度啦。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
Kubernetes API 容器
2022-10-13-k8s的操作指令
2022-10-13-k8s的操作指令
104 0
|
Kubernetes 容器 Perl
kubernetes指令集详细篇
kubernetes指令集详细篇
119 0
|
应用服务中间件 nginx Perl
Kubernetes----Kubernetes中通过指令式对象配置的方式管理对象
Kubernetes----Kubernetes中通过指令式对象配置的方式管理对象
80 0
|
Perl
Kubernetes----Kubernetes中通过指令式命令的方式方式管理对象
Kubernetes----Kubernetes中通过指令式命令的方式方式管理对象
123 0
|
8天前
|
Kubernetes 监控 Cloud Native
Kubernetes集群的高可用性与伸缩性实践
Kubernetes集群的高可用性与伸缩性实践
32 1
|
28天前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景
|
29天前
|
Kubernetes 持续交付 开发工具
ACK One GitOps:ApplicationSet UI简化多集群GitOps应用管理
ACK One GitOps新发布了多集群应用控制台,支持管理Argo CD ApplicationSet,提升大规模应用和集群的多集群GitOps应用分发管理体验。
|
1月前
|
Kubernetes Cloud Native 云计算
云原生之旅:Kubernetes 集群的搭建与实践
【8月更文挑战第67天】在云原生技术日益成为IT行业焦点的今天,掌握Kubernetes已成为每个软件工程师必备的技能。本文将通过浅显易懂的语言和实际代码示例,引导你从零开始搭建一个Kubernetes集群,并探索其核心概念。无论你是初学者还是希望巩固知识的开发者,这篇文章都将为你打开一扇通往云原生世界的大门。
123 17
|
1月前
|
Kubernetes 应用服务中间件 nginx
搭建Kubernetes v1.31.1服务器集群,采用Calico网络技术
在阿里云服务器上部署k8s集群,一、3台k8s服务器,1个Master节点,2个工作节点,采用Calico网络技术。二、部署nginx服务到k8s集群,并验证nginx服务运行状态。
581 1
|
1月前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
76 3
下一篇
无影云桌面