K8s运维日常操作
1.可扩展性高:K8s可以自动管理容器的扩展和缩容,使得项目能够应对高流量的压力。
2.高可用性:K8s可以自动保证容器的高可用性,在容器故障时自动重启容器。
3.资源管理:K8s可以自动管理容器的资源(如 CPU 和内存),避免资源浪费。
4.方便维护:K8s可以方便地管理容器的版本和更新,使得项目的维护变得简单。
5.支持微服务: K8s 支持微服务架构,可以将一个大型应用拆分成多个独立的服务,提高可维护性和可扩展性。
2. Kubernetes架构
Kubernetes主要由以下几个核心组件组成:
etcd:保存了整个集群的状态;
apiserver:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
controller manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
scheduler:负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
kubelet:负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
Container runtime:负责镜像管理以及Pod和容器的真正运行(CRI);
kube-proxy:负责为Service提供cluster内部的服务发现和负载均衡;
除了核心组件,还有一些推荐的Add-ons:
kube-dns:负责为整个集群提供DNS服务
Ingress Controller:为服务提供外网入口
Heapster:提供资源监控
Dashboard:提供GUI
Federation:集群联邦提供跨可用区的集群
Fluentd-elasticsearch:提供集群日志采集、存储与查询
一旦调度器将 Pod 分派给某个节点,kubelet 就通过容器运行时开始为 Pod 创建容器。容器的状态有三种:Waiting(等待)、Running(运行中)和 Terminated(已终止)。
要检查 Pod 中容器的状态,你可以使用 kubectl describe pod
每种状态都有特定的含义:
Waiting (等待)
如果容器并不处在 Running 或 Terminated 状态之一,它就处在 Waiting 状态。 处于 Waiting 状态的容器仍在运行它完成启动所需要的操作:例如, 从某个容器镜像仓库拉取容器镜像,或者向容器应用 Secret 数据等等。 当你使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时,你也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因。
Running(运行中)
Running 状态表明容器正在执行状态并且没有问题发生。 如果配置了 postStart 回调,那么该回调已经执行且已完成。 如果你使用 kubectl 来查询包含 Running 状态的容器的 Pod 时, 你也会看到关于容器进入 Running 状态的信息。
Terminated(已终止)
处于 Terminated 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。 如果你使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时, 你会看到容器进入此状态的原因、退出代码以及容器执行期间的起止时间。
如果容器配置了 preStop 回调,则该回调会在容器进入 Terminated 状态之前执行。
Kubernetes系统中的另一个非常重要的概念,Namespace在很多情况下用于实现多租户的资源隔离。Nameaspace通过将集群内部的资源对象“分配”到不同的Namespce中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享使用整个集群的资源的同时还能被分别管理。
2.Deployment无状态
是Kubernetes v1.2引入的概念,引入的目的是为了更好地解决Pod的编排问题。为此,Deployment在内部使用了Replica Set来实现目的,无论从Deployment的作用与目的,它的YAML定义,还是从它的具体命令行操作来看,我们都可以把它看作RC的一次升级,两者相似度超过90%。
Deployment相对于RC的一个最大升级是我们随时知道当前Pod“部署”的进度。实际上由于一个Pod的创建、调度、绑定节点及在目标Node上启动对应的容器这一完整过程需要一定的时间,所以我们期待系统启动N个Pod副本的目标状态,实际上是一个连续变化的“部署过程”导致的最终状态。
Deployment的典型使用场景有以下几个。
创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程。
检查Deployment的状态来看部署动作是否完成(Pod副本的数量是否达到预期的值)。
更新Deployment以创建新的Pod(比如镜像升级)。
如果当前Deployment不稳定,则回滚到一个早先的Deployment版本。
暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后再恢复Deployment,进行新的发布。
扩展Deployment以应对高负载。
查看Deployment的状态,以此作为发布是否成功的指标。
清理不再需要的旧版本ReplicaSets。
容器名称和ip每次重启变动的
3.StatefulSet有状态
在Kubernetes系统中,Pod的管理对象RC、Deployment、DaemonSet和Job都是面向无状态的服务。但现实中有很多服务是有状态的,特别是一些复杂的中间件集群,例如MySQL集群、MongoDB集群、Kafka集群、Zookeeper集群等,这些应用集群有以下一些共同点。
每个节点都有固定的身份ID,通过这个ID,集群中的成员可以相互发现并且通信。
集群的规模是比较固定的,集群规模不能随意变动。
集群里的每个节点都是有状态的,通常会持久化数据到永久存储中。
如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损。
如果用RC/Deployment控制Pod副本数的方式来实现上述有状态的集群,则我们会发现第一点是无法满足的,因为Pod的名字是随机产生的,Pod的IP地址也是在运行期才确定且可能有变动的,我们事先无法为每个Pod确定唯一不变的ID,为了能够在其他节点上恢复某个失败的节点,这种集群中的Pod需要挂接某种共享存储,为了解决这个问题,Kubernetes从v1.4版本开始引入了PetSet这个新的资源对象,并且在v1.5版本时更名为StatefulSet,StatefulSet从本质上来说,可以看作Deployment/RC的一个特殊变种,它有如下一些特性。
StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员。假设StatefulSet的名字叫kafka,那么第一个Pod叫kafak-0,第二个Pod叫kafak-1,以此类推。
StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经时运行且准备好的状态。
StatefulSet里的Pod采用稳定的持久化存储卷,通过PV/PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷(为了保证数据的安全)。
每次重启名称和ip不变
4.DaemonSet守护进程集
DaemonSet保证在每个Node上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型的应用包括:
日志收集,比如fluentd,logstash等
系统监控,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等
系统程序,比如kube-proxy, kube-dns, glusterd, ceph等
5.Service(服务)
Service也是Kubernetes里的最核心的资源对象之一,Kubernetes里的每个Service其实就是我们经常提起的微服务架构中的一个“微服务”,之前我们所说的Pod、RC等资源对象其实都是为这节所说的“服务”------Kubernetes Service作“嫁衣”的。下图显示了Pod、RC与Service的逻辑关系。
Kubernetes的Service定义了一个服务的访问入口地址,前端的应用(Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,Service与其后端Pod副本集群之间则是通过Label Selector来实现“无缝对接”的。而RC的作用实际上是保证Service的服务能力和服务质量始终处于预期的标准。
6.Volume(存储卷)
Volume是Pod中能够被多个容器访问的共享目录。Kubernetes的Volume概念、用途和目的与Docker的Volume比较类似,但两者不能等价。首先,Kubernetes中的Volume定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下;其次,Kubernetes中的Volume中的数据也不会丢失。最后,Kubernetes支持多种类型的Volume,例如Gluster、Ceph等先进的分布式文件系统。
7.PV/PVC/StorageClass
PersistentVolume(PV)是集群中已由管理员配置的一段网络存储。 集群中的资源就像一个节点是一个集群资源。 PV是诸如卷之类的卷插件,但是具有独立于使用PV的任何单个pod的生命周期。 该API对象捕获存储的实现细节,即NFS,iSCSI或云提供商特定的存储系统。
PersistentVolumeClaim(PVC)是用户存储的请求。 它类似于pod。 Pod消耗节点资源,PVC消耗光伏资源。 荚可以请求特定级别的资源(CPU和内存)。 权利要求可以请求特定的大小和访问模式(例如,可以一旦读/写或只读许多次安装)。
虽然PersistentVolumeClaims允许用户使用抽象存储资源,但是常见的是,用户需要具有不同属性(如性能)的PersistentVolumes,用于不同的问题。 群集管理员需要能够提供多种不同于PersistentVolumes的PersistentVolumes,而不仅仅是大小和访问模式,而不会使用户了解这些卷的实现细节。 对于这些需求,存在StorageClass资源。
StorageClass为管理员提供了一种描述他们提供的存储的“类”的方法。 不同的类可能映射到服务质量级别,或备份策略,或者由群集管理员确定的任意策略。 Kubernetes本身对于什么类别代表是不言而喻的。 这个概念有时在其他存储系统中称为“配置文件”
8.Secret 保密字典
Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。
Secret有三种类型:
Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/Kubernetes.io/serviceaccount目录中;
Opaque:base64编码格式的Secret,用来存储密码、密钥等;
Kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
9.ConfigMap配置项
ConfigMap用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap跟secret很类似,但它可以更方便地处理不包含敏感信息的字符串。
10.CronJob定时任务
CronJob即定时任务,就类似于Linux系统的crontab,在指定的时间周期运行指定的任务。在Kubernetes 1.5,使用CronJob需要开启batch/v2alpha1 API,即–runtime-config=batch/v2alpha1。.Namespace
11.Ingress路由
通常情况下,service和pod的IP仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到service在Node上暴露的NodePort上,然后再由kube-proxy将其转发给相关的Pod。
Ingress可以给service提供集群外部访问的URL、负载均衡、SSL终止、HTTP路由等。为了配置这些Ingress规则,集群管理员需要部署一个Ingress controller,它监听Ingress和service的变化,并根据规则配置负载均衡并提供访问入口。
kubectl get pods -n yxyw #查看名字空间下的所有 Pod。
kubectl get secret -n yxyw #查看yxyw命名空间密钥
kubectl get configmap -n yxyw #查看yxyw命名空间配置文件
kubectl get pv -A #查看所有命名空间pv
kubectl get pvc -A #查看所有命名空间pvc
kubectl get svc -A #查看所有命名空间service
kubectl get ingress -A #查看所有ingress域名
kubectl top pods -n yxyx #查看命名空间下所有pod的内存和cpu
kubectl describe pod osale-im -n yxyw #查看pod im的信息
kubectl describe ingress gyxtest.gemdale.com-ingress -n yxyw #查看ingress域名的信息
kubectl describe configmap nginx-gyx-nginx-conf -n yxyw #查看配置文件信息
kubectl get configmap nginx-gyx-nginx-conf -o yaml -n yxyw #输出配置文件启动模板
kubectl get secret gem-acr-p-a01-registry.cn-shenzhen.com-secret -o yaml -n yxyw #输出密钥模板
kubectl get secret -n devops #查出dashboad的密钥名称
kubectl get secret cluster-admin-token-mbmgg -o yaml -n devops #输出集群密钥
通过命令行找出dashboard的域名和密钥
kubectl get ingress -A
kubectl get ingress -o yaml kubernetes-dashboard-test.gemdale.com-ingress -n devops #查看ingress域名
kubectl get secret -n devops #找出密钥
kubectl get secret admin-token-4t89n -o yaml -n devops
kubectl rollout restart deployment osale-im -n yxyw #滚动重启 Deployment
kubectl exec -it osale-im-8875fd54-gdhxn -n yxyw – bash #命令行进入pod
kubectl logs -f osale-im-8875fd54-gdhxn -n yxyw #查看实时日志
kubectl logs osale-im-8875fd54-gdhxn -n yxyw #查看最新输出的日志
kubectl delete pods -n yxyw osale-im-8875fd54-gdhxn #删除pod组件,还会重启一个
kubectl delete deployment osale-im-8875fd54-gdhxn -n yxyw #删除之后不会在重启了,直接强制删除
kubectl cp osale-im-8875fd54-gdhxn:/gemdale/osale-im-0.0.1-SNAPSHOT.jar ./osale-im-0.0.1-SNAPSHOT.jar -n yxyw #拷贝pod内文件
kubectl delete deploy `kubectl get deploy -n yxyw-dev | awk '{print $1}' | grep dev` -n yxyw-dev #删除所有-dev的pod
kubectl delete service `kubectl get svc -n yxyw-dev | grep dev | awk '{print $1}'` -n yxyw-dev #删除所有-dev的service
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get svc -n default #查看访问端口
10.0.21.21:prot
kubectl delete svc nginx -n default
kubectl delete deployment nginx -n default
6.营销业务微服务Deployment模板解析
https://flow.aliyun.com/pipelines/2250688/current osale-im-k8s.test流水线
apiVersion: apps/v1
kind: Deployment
metadata:
name: @APP_NAME@
labels:
app: @APP_NAME@
spec:
replicas: @REPLICAS@
revisionHistoryLimit: 10
selector:
matchLabels:
app: @APP_NAME@
template:
metadata:
labels:
app: @APP_NAME@
armsPilotAutoEnable: "on"
armsPilotCreateAppName: @APP_NAME@
one-agent.jdk.version: "OpenJDK11"
spec:
imagePullSecrets:
- name: gem-acr-p-a01-registry1.cn-shenzhen.com-secret
containers:
- name: @APP_NAME@
image: ${IMAGE}
ports:
- containerPort: @targetPort@
protocol: TCP
imagePullPolicy: IfNotPresent
readinessProbe:
tcpSocket:
port: @targetPort@
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:
tcpSocket:
port: @targetPort@
initialDelaySeconds: 15
periodSeconds: 20
resources:
limits:
cpu: @LIMIT_CPU@
memory: @LIMIT_MEMORY@
requests:
cpu: @REQUEST_CPU@
memory: @REQUEST_MEMORY@
volumeMounts:
- name: logs
mountPath: /gemdale/logs
- name: data
mountPath: /gemdata/share/
volumes:
- name: logs
hostPath:
type: DirectoryOrCreate
path: /data/logs/test/@APP_NAME@
- name: data
hostPath:
type: DirectoryOrCreate
path: /gemdata/share/
###############################
---
apiVersion: v1
kind: Service
metadata:
name: @APP_NAME@
labels:
app: @APP_NAME@
spec:
ports:
- port: @port@
targetPort: @targetPort@
@NodePort@
selector:
app: @APP_NAME@
type: @PORT_TYPE@
kubectl get deploy osale-im -o yaml -n yxyw