[k8s]Kubernetes简介

news/2024/12/29 14:41:58/

文章目录

    • Kubernetes介绍
      • 术语
        • Label
      • StatefulSet
    • 存储类
      • Volume
      • Persistent Volume
    • IP地址
      • Node IP
      • Pod IP
      • Service Cluster IP
      • External IP
    • Pod
      • Pod定义
      • Pod生命周期与重启策略
      • NodeSelector(定向调度)
      • NodeAffinity(亲和性调度)
      • PodAffinity(Pod亲和性)
    • ConfigMap

容器管理工具可以完成容器的基础管理,但是容器的应用并不是只能进行简单应用部署的,可以使用容器完成企业中更加复杂的应用部署,当需要对多应用的系统进行部署时,就需要更加复杂的工具来完成对容器运行应用的编排,这就是容器编排部署工具。

Kubernetes介绍

k8s是一个轻便的和可扩展的开源平台,用于管理多个主机上的容器化的应用,让部署容器化的应用简单并且高效,提供了应用部署、规划、更新、维护的一种机制,能进行应用的自动化部署及扩缩容。
在这里插入图片描述

k8s集群是Master和Worker的模式:

  • Master节点上有kube-apiserver、kube-controller-mansger、kube-scheduler以及etcd进程,分别用于接收客户端请求并控制集群、资源对象的控制中心并监控容器健康、资源调度、资源对象数据存储等功能
  • Worker节点上有kubelet、kube-proxy、docker,分别用于管理Pod及Pod容器并定时向Master汇报节点资源信息、实现Service的透明代理及负载均衡、运行容器。

术语

k8s中概念与术语大多围绕资源对象(Resource Object),其一般包括几个通用属性:版本、类别(Kind)、名称、标签和注解。

  • 对象的名称要唯一;
  • 对象的标签很重要(如表明对象的特征、类别);
  • 注解通常用于对象属性的自定义扩展;

Label

Label(标签)是一个key=value的键值对,可以附加到任何资源上。例如Node,Pod,Service,RC等,一个资源对象可以定义多个Label,一个Label可以被添加到多个资源上,通常在资源定义时确定,也可在在对象创建后动态添加或删除。

给资源对象定义个Label,就相当于给他打了一个标签;随后,可通过Label Selector(标签选择器)查询或筛选拥有某些Label的资源对象。标签匹配:

  • {key}={value}:匹配所有拥有{key}={value}标签的资源;
  • {key}!={value}:匹配所有不具有{key}={value}标签的资源;
  • {key} in ({v1}, {v2}:匹配任意指定的标签;
  • {key} not in ({v1}, {v2}:匹配不具有指定的标签;
  • AND操作:通过逗号组合多个选择条件,如name=redis, env!=test

label定义在metadata中:

metadata:name: redislabels:name: redisapp: red-example

StatefulSet

StatefulSet用于有状态的中间件集群(每个节点有固定身份ID,规模固定,每个节点有状态且持久化数据到永久存储中):

  • StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来 发现集群内的其他成员。假设StatefulSet的名称为kafka,那么第1个Pod 叫kafka-0,第2个叫kafka-1,以此类推。
  • StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod 时,前n-1个Pod已经是运行且准备好的状态。
  • StatefulSet里的Pod采用稳定的持久化存储卷,通过PV或PVC来 实现,删除Pod时默认不会删除与StatefulSet相关的存储卷(为了保证数 据的安全)。

STS模式下的POD中,可通过{pod-name}.{service}来访问节点。

存储类

存储类对象包括Volume、PersistentVolume、PVC和StorageClass

Volume

Volume是Pod中能够被多个容器访问的共享目录,k8s的Volume定义在Pod上,然后被Pod的多个容器挂载到具体的文件目录下;与Pod的生命周期相同,与容器的生命周期无关,当容器终止或重启时,Volume中的数据也不会丢失。

先在Pod上声明一个Volume,然后在容器中引用该Volume并Mount到容器中的某个目录上

spec:volumes:- name: datavolemptyDir: {}containers:- name: test-volumeimage: tomcatvolumeMounts:- mountPath: /mydata-dataname: datavol

k8s提供了丰富的volume类型:

  • emptyDir:在Pod分配到Node时创建的,初始内容为空,无需指定宿主机上对应的目录文件,K8S自动分配,当Pod从Node上移除时,emptyDir中的数据也会被永久删除。可用于:
    • 临时空间
    • 长时间任务的中间过程CheckPoint的临时保存目录
    • 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)
    • 使用的是节点的存储介质,可通过设定emptyDir.medium为Memory以使用内存(会被记入容器的内存消耗,受到资源限制和配额机制的管理)
  • hostPath:在Pod上挂载宿主机上的文件或目录。可用于:
    volumes:
    - name: hostpathhostpath:path: "/path"
    
    • 容器生成的日志需要永久保存时
    • 需要访问宿主机上的Docker引擎内部数据结构的容器应用时,可以通过定义hostPath为宿主机/var/lib/docker目录,使容器内部应用可以直接访问Docker的文件系统。
  • NFS:使用NFS网络文件系统提供的共享目录存储数据时,需在系统中部署一个NFS Server。
    volumes:
    - name: nfs
    nfs:server: {nfs-server address}path: "/"
    

Persistent Volume

Persistent Volume(PV)和与之关联的Persistent Volume Claim(PVC)是一块网络存储,挂接到虚机上的‘网盘’。PV是K8s集群中某个网络存储中对应的的一块存储,与Volume相似,但有以下区别:

  • PV只能是网络存储,不属于任何Node,但可以在任何Node上访问。
  • PV并不是定义在Pod上的,而是独立于Pod之外定义的。
  • PV目前只有几种类型:GCE Persistent Disks、NFS、RBD、iSCSCI、AWS ElasticBlockStore、GlusterFS
apiVersion: v1
kind: PersistentVolume
metadata:name: pvtest
spec:capacity:storage: 5GiaccessModes:- ReadWriteOncenfs:server: {nfs-server address}path: /path

PV的accessModes属性,目前有以下几种类型:

  • ReadWriteOnce:读写权限,并且只能被单个Node挂载
  • ReadOnlyMany:只读权限,允许被多个Node挂载
  • ReadWriteMany:读写权限,允许被多个Node挂载

某个Pod想申请某种条件的PV,则首先需要定义一个Persistent Volume Claim(PVC)对象

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: myclaim
spec:accessModes:- ReadWriteOnceresources:requests:storage: 8Gi

然后,在Pod的Volume定义中引用上述PVC即可

volumes:
- name: pvtestpersistentVolumeClaim:claimName: myclaim

PV有以下几种状态:

  • Available:空闲状态
  • Bound:已经绑定到某个PVC上
  • Released:对应的PVC已经删除,但资源还没有被集群回收
  • Failed:PV自动回收失败。

IP地址

k8s中有三种网络(每种代表不同的寻址空间):

  • Node IP:Node节点IP地址,包含内部(集群节点间访问)和外部IP地址;
  • Pod IP:访问Pod(仅限集群内部访问),Pod挂掉重启后会改变;
  • Cluster IP:是访问Service的IP地址(仅能从内部访问);该服务提供通过标签管理Pod的功能(Pod重启后,IP地址改变,但标签不变);
  • External IP:提供从外部访问Service访问的功能;

Node IP

Node IP是k8s集群中每个节点物理网卡的IP地址(真实存在的),查询Node IP:

kubectl get nodes # 获取节点名称
kubectl describe node {node-name} # 显示node详情,其中Address下的InternalIP字段即为Node IP # 或直接查询
kubectl get nodes -o wide

Pod IP

是Docker Engine根据网桥的IP地址段分配的(通常为虚拟的二层网络)

kubectl get pods [-n admin] # 获取所有(admin空间下)的pod
kubectl describe pod [-n admin] {pod-name} # 获取pod的详情,IP字段即为分配的IP地址# 或直接查询
kubectl get pod [-n admin] -o wide

Service Cluster IP

Service是Kubernetes最核心的概念,通过创建Service,可以为一组具有相同功能的容器用用提供一个统一的入口地址,并且将请求进行负载分发到后端的各个容器应用上。

kubectl get svc [-n admin]  # 查询cluster IP

Service的Cluster IP(集群IP,是一个虚拟的IP):

  • 仅仅作用于kubernetes Service这个对象,并由Kubernetes管理和分配IP地址;
  • 无法被ping;
  • 只能结合Service Port组成一个具体的通信端口,单独的Cluster IP不具备TCP/IP通信的基础;

External IP

xternal IP是为了解决如何从外部访问service服务的,外部访问Service的方式有两种:

  • 通过设置nodePort映射到物理机,同时设置Service的类型为NodePort;
  • 通过设置LoadBalancer映射到云服务上提供的LoadBalancer地址(仅适用公用云)。

Pod

Kubernetes使用Pod来管理容器。每个Pod都有个一个特殊的Pause容器(称为‘根容器’),其对应的镜像属于Kubernetes平台一部分;除此之外,Pod还包含一个或多个用户业务容器。

  • Pod是调度(以及复制管理)的基本单位,让多个应用进程一起有效地调度和伸缩。
  • Pod中容器,共享PID、IPC、Network 和UTS namespace。

K8S对长时间运行容器的要求是:其主程序要一直在前台运行

Pod定义

定义包含一个容器的Pod:

apiVersion: v1
kind: Pod
metadata: # 定义Pod元数据nam: nginx-testlabels:app: nginx-test
spec: # 容器详细定义containers:- name: nginx-testimage: nginx:latestimagePullPolicy: IfNotPresentports:- containerPort: 80

containers是Pod中的容器列表:

spec:containers:  #容器列表- name: string  #容器名称image: string  #所用镜像imagePullPolicy: [Always|Never|IfNotPresent]  #镜像拉取策略command: [string]  #容器的启动命令列表args: [string]  #启动命令参数列表workingDir: string  #工作目录volumeMounts:  #挂载在容器内部的存储卷配置- name: string  #共享存储卷名称mountPath: string  #存储卷绝对路径readOnly: boolean  #是否只读ports:  #容器需要暴露的端口号列表- name: string  #端口名称containerPort: int  #容器监听端口hostPort: int  #映射宿主机端口protocol: string  #端口协议env:  #环境变量- name: stringvalue: string- name: INJECT_POD_IPvalueFrom:fieldRef:fieldPath: status.podIP- name: INJECT_SERVICE_ACCOUNTvalueFrom:fieldRef:fieldPath: spec.serviceAccountNameresources:  #资源限制limits:cpu: string  #单位是corememory: string  #单位是MiB、GiBlivenessProbe:  #探针,对Pod各容器健康检查的设置,如几次无回应,则会自动重启exec:command: [string]httpGet:path: stringport: numberhost: stringscheme: stringhttpHeaders:- name: stringvalue: stringtcpSocket:port: numberinitialDelaySeconds: 0  #启动后多久进行检测timeoutSeconds: 0  #超时时间periodSeconds: 0  #间隔时间successThreshold: 0  #failureThreshold: 0securityContext: #权限设置privileged: false  #是否允许创建特权模式的Podvolumes:- name: podinfodownwardAPI:items:- path: "labels"fieldRef:fieldPath: metadata.labels- path: "annotations"fieldRef:fieldPath: metadata.annotations

环境变量注入

  • 通过valueFrom,可把Pod或container信息注入到容器运行环境,方便获取;
  • 通过downwardAPI,可把Pod或container信息挂载为文件(如上,会挂载后会在目录下生成labels和annotations两个文件);

Pod生命周期与重启策略

系统为Pod定义了各种生命周期状态:

状态值说明
PendingPod已创建,但Pod内的容器(一个或多个)镜像还没创建(包括在下载过程中)
RunningPod内的所有容器以创建,且至少一个容器处于运行状态、启动状态或正在重启
SucceededPod内所有容器均成功执行后退出(且不会再重启)
FailedPod内所有容器均已退出(且至少一个退出状态为失败)
Unknown由于某些原因无法获取该Pod的状态(如网络通讯问题等)

Pod的重启策略(RestartPolicy)应用于Pod内的所有容器,包括:

  • 重启间隔为sync-frequency*2n(n为1、2、4、8…,最长为5分钟);成功重启10分钟后重置改间隔。
策略说明
Always容器失效时,kubelet自动重启改容器
OnFailure容器终止且退出码不为0时,重启
Never不会重启

NodeSelector(定向调度)

K8S的Scheduler服务负责Pod的调度(通常无法知道Pod最终会被调度到哪个节点上,但实际可通过标签来指定调度到的Node):

  • 给Node打标签:kubectl label nodes {node-name} {lbl-key}={lal-value}
  • 在Pod定义中添加nodeSelector设置:
apiVersion: apps/v1
kind: Deployment
metadata:name: redis-deploylabels:app: redis-app
spec:replicas: 2selector:matchLabels:app: redis-apptemplate:metadata:labels:app: redis-appspec:containers:- name: redis-podimage: kubeguide/redis-masterimagePullPolicy: IfNotPresentports:- containerPort: 6379# 选择有SSD硬盘的NodenodeSelector:disk-type: ssd

指定选择标签后,若未找到指定标签的Node,即使有其他空余Node,也无法正常调度。K8S还给Node预定义了一些标签:

  • kubernetes.io/hostname
  • kubernetes.io/os
  • kubernetes.io/arch

NodeAffinity(亲和性调度)

NodeAffinity为亲和性调度策略(用于替换NodeSelector):

  • RequiredDuringSchedulingIgnoredDuringExecution:必须满足指定规则(与NodeSelector类似,为硬限制);
  • PreferredDuringSchedulingIgnoreDuringExecution:优先满足,尝试调度指定Node(为软限制);
apiVersion: v1
kind: Pod
metadata:name: with-node-affinity
spec:affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: disk-typeoperator: Invalues:- ssdcontainers:- name: with-node-affinityimage: google/pause

NodeAffinity语法支持操作符有:In, NotIn, Exists, DoesNotExit, Gt, Lt;有多个matchExpressions时,需满足所有才匹配。

PodAffinity(Pod亲和性)

Affinity标识多个Pod在同一拓扑域中共存;而Anti Affinity标识多个Pod在同一拓扑域中互斥。K8S内置了一下常用拓扑域:

  • topology.kubernetes.io/region
  • topology.kubernetes.io/zone

要求新Pod与security=s1的Pod在同一Zone;但不与app=nginx的Pod在同一个Node;

apiVersion: v1
kind: Pod
metadata:name: anti-affinity
spec:affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: securityoperator: Invalues:- s1topologyKey: topology.kubernetes.io/zonepodAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- nginxtopologyKey: kubernetes.io/hostnamecontainers:- name: anti-affinityimage: k8s.gcr.io/pause:3.1

ConfigMap

ConfigMap是k8s的一个配置管理组件,可以将配置以key-value的形式传递(通常用来保存不需要加密的配置信息,加密信息则需用到Secret)主要用来应对以下场景:

  • 将配置信息和docker镜像解耦;
  • 多个服务共用配置的情况;

有三种常见创建方式:

  • 通过yaml/json文件创建(推荐): kubectl create -f configmap.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata: name: test-confnamespace: test
    data: # 两个键key1、confkey1:value1conf: |+SESSION_LIFETIME: 3600URL: "http://test-server:8080"
    
  • 通过–from-file创建:kubectl create configmap {cm-name} --from-file=app.properties (文件名作为key,整个内容作为键)
    key.1 = value-1
    key.2 = value-2
    
  • 通过key-value字符串创建:kubectl create configmap {cm-name} --from-literal=key1=value1 --from-literal=key2=value2

通过create方式创建若已存在,则报错;可通过以下方式更新(不存在时自动创建):

kubectl create configmap nginx-config --from-file first.yaml --from-file second.yaml -o yaml --dry-run=client | kubectl apply -f -

用户配置文件:

  • 将配置文件内容保存到ConfigMap中:key为文件名,value为文件内容;
  • 在Pod配置文件中,将ConfigMap定义为特殊的Volume进行挂载。当Pod创建时,ConfigMap中配置文件会自动还原到Node本地目录,并映射到Pod里;
  • 当ConfigMap内容修改后,K8s会自动重新获取,并更新节点上对应的文件。

http://www.ppmy.cn/news/98804.html

相关文章

抽奖中的分布式锁应用

开发抽奖时遇到的分布式锁问题,特此记录一下几种实现方案 背景 开发中遇到个抽奖需求,会根据当前奖池内道具数量随机道具并发送给用户。这里面涉及到超发的问题,需要使用到分布式锁,特此记录一下常用的几种方案。 “超发”&#…

线程之相关知识点总结

线程之相关知识点总结 线程的意义线程与进程的关系线程安全问题小结 线程的意义 进程解决了并发编程问题。然而由于进程消耗资源多且速度慢(进程重,重在"资源分配/回收"上)。 线程应运而生,线程也叫做轻量级进程&#x…

少年,你可听说过MVCC?

:切!这谁没听过,不就是多版本并发控制么~ 早在亘古时期,修真界就流传着一门mysql功法,将其修至小乘境界,足以纵横一方。。。不乏也有走火入魔者,为祸一方~ Serializable篇 强制事务排序&#…

一波三折,终于找到 src 漏洞挖掘的方法了【建议收藏】

0x01 信息收集 1、Google Hack 实用语法 迅速查找信息泄露、管理后台暴露等漏洞语法,例如: filetype:txt 登录 filetype:xls 登录 filetype:doc 登录 intitle:后台管理 intitle:login intitle:后台管理 inurl:admin intitle:index of /查找指定网站&…

redis复制机制

文章目录 1. Redis 复制机制2. 基本命令3. 修改配置文件4. 代码案例4.1 一主二仆4.2 薪火相传4.3 反客为主 5. Redis复制工作流程6. Redis 复制的缺点 1. Redis 复制机制 概念 : Redis 复制机制 能干的活 : 读写分离 : 写 就找 主机 master , 读就找从机…

使用FSL对DTI数据进行预处理

使用FSL对DTI数据进行预处理 一、topup处理二、eddy处理一、topup处理 为了校正磁场引起的畸变,对DTI的B0像分别采集了A>P和P>A的反向编码的两种B0像。利用AP和PA图像进行一个topup处理,校正畸变。 1、 使用dcm2niix将AP PA图像转为nii格式 假设转换后的图像为sub01_…

《数据库应用系统实践》------ 超市管理系统

系列文章 《数据库应用系统实践》------ 超市管理系统 文章目录 系列文章一、需求分析1、系统背景2、 系统功能结构(需包含功能结构框图和模块说明)3.系统功能简介 二、概念模型设计1.基本要素(符号介绍说明&#xff…

Collections提供的同步包装方法

Java同步容器类是通过synchronized(内置锁)来实现同步的容器,比如Vector、 HashTable以及SynchronizedList等容器。 线程安全的同步容器类主要有: Vector、 Stack、 HashTable等。 Collections提供的同步包装方法 Java提供一组包…