k8s学习之路 | Day11 k8s 对象(一)


官方阅读文档:https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/kubernetes-objects/

k8s 对象

  • k8s 里面操作的资源实体,就是 k8s 的对象

    • 可以使用 yaml来声明
    • 可以直接使用kubectl命令来创建
    • 比如 pod、service、deploy、node…
  • 操作 k8s 对象,无论是什么操作(创建、修改、删除),都是需要使用 kubetnetes API

    • kubectl也是调用的必要的kubernetes API
    • 也可以在程序中使用客户端库来直接调用kubernetes API
  • 在 Kubernetes 系统中,Kubernetes 对象 是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。 比较特别地是,它们描述了如下信息:

    • 哪些容器化应用正在运行(以及在哪些节点上运行)
    • 可以被应用使用的资源
    • 关于应用运行时表现的策略,比如重启策略、升级策略以及容错策略
  • Kubernetes 对象是“目标性记录” —— 一旦创建该对象,Kubernetes 系统将不断工作以确保该对象存在。 通过创建对象,你就是在告知 Kubernetes 系统,你想要的集群工作负载状态看起来应是什么样子的, 这就是 Kubernetes 集群所谓的 期望状态(Desired State)

对象规约(Spec)与状态(Status)

每一个 k8s 对象几乎都包含了2个嵌套的对象字段,他们负责管理对象的配置

  • 对象spec(规约):必须在创建对象时设置其内容,描述你所希望对象的期望状态
#比如你要运行一个pod,通过kubectl run 来操作的
#这个时候对于 nginx-demo 这个pod来说,你的期望状态就是运行一个pod,利用镜像nginx
kubectl run nginx-demo --image=nginx:1.21-alpine
  • 对象status(状态):描述了当前对象的当前状态,是由系统组件设置并随时更新的,在任何时刻,k8s 的控制平面都会一直积极地管理着对象的实际状态,并让它达到期望状态(spec)
  • kubelet就是做一件事情:对象的specstatus最终一致性

描述 k8s 对象

创建 Kubernetes 对象时,必须提供对象的 spec,用来描述该对象的期望状态, 以及关于对象的一些基本信息(例如名称)等

  • 推荐使用yaml文件来描述 k8s 对象
  • kubectl 在发起 API 请求时,会将文件信息转换成 JSON 格式

获取具体对象的yaml文件

如何获取已存在的 k8s 对象的 yaml描述文件呢?从下面这个例子能看到

  • spec: 当前pod对象的期望状态
  • status: 当前pod对象的当前状态
[root@k8s-01 ~]# kubectl get pod -oyaml nginx-demo
apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/podIP: 192.168.0.31/32
    cni.projectcalico.org/podIPs: 192.168.0.31/32
  creationTimestamp: "2023-02-20T04:29:18Z"
  labels:
    run: nginx-demo
  name: nginx-demo
  namespace: default
  resourceVersion: "77219"
  uid: 94ffbebd-0ac1-40bf-a890-ce08e827d024
spec:
  containers:
  - image: nginx:1.21-alpine
    imagePullPolicy: IfNotPresent
    name: nginx-demo
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-b48j8
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: k8s-03
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-b48j8
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2023-02-20T04:29:18Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2023-02-20T04:29:20Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2023-02-20T04:29:20Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2023-02-20T04:29:18Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://feaa5652cb9a820627fc37b182345e08bc5f0b0224ec5393b715c9fcba6aa2ae
    image: nginx:1.21-alpine
    imageID: docker-pullable://nginx@sha256:eb05700fe7baa6890b74278e39b66b2ed1326831f9ec3ed4bdc6361a4ac2f333
    lastState: {}
    name: nginx-demo
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2023-02-20T04:29:19Z"
  hostIP: 192.168.204.55
  phase: Running
  podIP: 192.168.0.31
  podIPs:
  - ip: 192.168.0.31
  qosClass: BestEffort
  startTime: "2023-02-20T04:29:18Z"

一个 k8s 对象示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2 # 镜像的标签信息
        ports:
        - containerPort: 80

如何使用yaml文件

kubectl apply -f test.yaml
kubectl delete -f test.yaml

image-20230220125823173

描述对象文件的必要字段信息

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类别
  • metadata - 帮助唯一标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec - 你所期望的该对象的状态

Kubernetes API 参考

如何编写任意资源的 yaml 文件?

通过任意存在的对 象资源反向推理yaml文件

  1. 比如我通过kubectl run创建了一个 pod 资源
##这个操作就会最终启动一个pod
kubectl run tomcat --image=tomcat

image-20230220130751307

  1. 随便在集群里面找一个 pod,将yaml输出出来,只需要除了status状态的内容,比如我将上面的pod通过yaml输出出来
###将集群中的任意一个pod通过yaml输出
kubectl get pod tomcat -o yaml

###得到内容
apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/podIP: 192.168.0.33/32
    cni.projectcalico.org/podIPs: 192.168.0.33/32
  creationTimestamp: "2023-02-20T05:07:04Z"
  labels:
    run: tomcat
  name: tomcat
  namespace: default
  resourceVersion: "80605"
  uid: eceea838-23c9-4cd8-b175-834f5ca034ec
spec:
  containers:
  - image: tomcat
    imagePullPolicy: Always
    name: tomcat
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-xfngv
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: k8s-03
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-xfngv
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap: 
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
  1. 将上面输出出来的yaml修改一下镜像和说明信息,就可以直接拿来用了,
###将上面输出的yaml文件稍微修改一下
apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/podIP: 192.168.0.33/32
    cni.projectcalico.org/podIPs: 192.168.0.33/32
  creationTimestamp: "2023-02-20T05:07:04Z"
  labels:
    run: nginx
  name: nginx
  namespace: default
  resourceVersion: "80605"
  uid: 3808fb74-f56e-4969-b74c-52a8ceb6ea9d
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: nginx
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-xfngv
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: k8s-03
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-xfngv
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap: 
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
## 尝试一下行不行
kubectl apply -f test.yaml

##这种方法是可行的,但是不知道其他字段信息与其他资源有重复,会不会有问题,这个后面深究一下

image-20230220132646979

干跑一遍对象资源输出为yaml文件

  1. 不会实际产生k8s资源对象
##比如我要deploy一次
kubectl create deploy my-nginx --image=nginx --dry-run -oyaml

##然后形成了yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: my-nginx
  name: my-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
##k8s集群环境中也不会正式生成该资源对象信息
##这个方法挺靠谱一点

image-20230220133301071

  1. 尝试修改一下上面的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: tomcat
  name: tomcat
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: tomcat
    spec:
      containers:
      - image: tomcat
        name: tomcat
        resources: {}
        
##部署一下
kubectl apply -f test.yaml

image-20230220133740967

能够描述的资源类型

kubectl api-resourcesKIND字段

image-20230220133835727

apiVersion: apps/v1			## 同一资源多个版本(kubectl api-resources 中的APIVERSION字段)
kind: Deployment			## 资源类型 kubectl api-resources
metadata:					## 每一个资源定义一些元数据信息
  creationTimestamp: null
  labels:
    app: tomcat
  name: tomcat
spec:						## 资源的规约(期望状态:自定义):镜像名称、版本、环境变量等
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: tomcat
    spec:
      containers:
      - image: tomcat
        name: tomcat
        resources: {}

k8s 对象 yaml 的构成

image-20230220134455795

typeMeta

  1. 对于 kind,通过kubectl api-resources字段中的KIND字段,要写什么?比如pod
kubectl api-resources | grep -E 'pod|KIND'

image-20230220134800908

  1. 所以对于pod来说,我们自己写的话,前段部分的内容就可以写成
kind: Pod
apiVersion: v1

metadata

元数据信息,这个地方到底能写一些什么元数据信息呢?

##比如给这次pod写上一个名字
metadata:
  name: nginx-demo-pod

spec

容器的期望状态

spec:	# 指定期望状态
  containers:	# 指定要启动一个什么样的容器
  - image: nginx	# 指定镜像
    name: nginx-demo-pod	# 指定容器名称

status

这段信息是 k8s 集群自己实时更新的信息,不需要我们来指定,只要资源变化,kubelet 会请求 api-server 保存最新的资源状态信息。

最简单的一个描述文件

kind: Pod
apiVersion: v1
metadata:
  name: nginx-demo-pod
spec:	# 指定期望状态
  containers:	# 指定要启动一个什么样的容器
  - image: nginx	# 指定镜像
    name: nginx-demo-pod	# 指定容器名称

image-20230220140108592

管理 k8s 对象

管理技术作用于建议的环境支持的写者学习难度
指令式命令活跃对象(kubectl 命令系列开发项目1+最低
指令式对象配置单个文件(单个yaml文件)生产项目1中等
声明式对象配置文件目录(多个yaml文件的多个目录kustomize生产项目1+最高
  • 同一个资源对象应该只使用一种方式管理,否则可能会出现不可预期的结果

指令式命令

使用指令式命令时,用户可以在集群中的活动对象上进行操作。用户将操作传给 kubectl 命令作为参数或标志。

  • 例如
kubectl create deployment nginx --image nginx

与对象配置相比的优点:

  • 命令用单个动词表示。
  • 命令仅需一步即可对集群进行更改。

与对象配置相比的缺点:

  • 命令不与变更审查流程集成。
  • 命令不提供与更改关联的审核跟踪。
  • 除了实时内容外,命令不提供记录源。
  • 命令不提供用于创建新对象的模板。

指令式对象配置

在指令式对象配置中,kubectl 命令指定操作(创建,替换等),可选标志和至少一个文件名。指定的文件必须包含 YAML 或 JSON 格式的对象的完整定义。

  • 例如
kubectl create -f nginx.yaml
kubectl delete -f nginx.yaml -f redis.yaml
kubectl replace -f nginx.yaml

与指令式命令相比的优点:

  • 对象配置可以存储在源控制系统中,比如 Git。
  • 对象配置可以与流程集成,例如在推送和审计之前检查更新。
  • 对象配置提供了用于创建新对象的模板。

与指令式命令相比的缺点:

  • 对象配置需要对对象架构有基本的了解。
  • 对象配置需要额外的步骤来编写 YAML 文件。

与声明式对象配置相比的优点:

  • 指令式对象配置行为更加简单易懂。
  • 从 Kubernetes 1.5 版本开始,指令对象配置更加成熟。

与声明式对象配置相比的缺点:

  • 指令式对象配置更适合文件,而非目录。
  • 对活动对象的更新必须反映在配置文件中,否则会在下一次替换时丢失。

声明式对象配置

使用声明式对象配置时,用户对本地存储的对象配置文件进行操作,但是用户未定义要对该文件执行的操作。 kubectl 会自动检测每个文件的创建、更新和删除操作。 这使得配置可以在目录上工作,根据目录中配置文件对不同的对象执行不同的操作。

  • 例如
kubectl diff -f configs/
kubectl apply -f configs/
kubectl diff -R -f configs/
kubectl apply -R -f configs/
  • 与指令式对象配置相比的优点:

    • 对活动对象所做的更改即使未合并到配置文件中,也会被保留下来。
    • 声明性对象配置更好地支持对目录进行操作并自动检测每个文件的操作类型(创建,修补,删除)。
  • 与指令式对象配置相比的缺点:

    • 声明式对象配置难于调试并且出现异常时结果难以理解。
    • 使用 diff 产生的部分更新会创建复杂的合并和补丁操作。

对象名称

  • 集群中的每一个对象都有一个名称来标识在同类资源中的唯一性

  • 每个 Kubernetes 对象也有一个 UID 来标识在整个集群中的唯一性

  • 在同一个名称空间 中只能有一个名为 myapp-1234 的 Pod,但是可以命名一个 Pod 和一个 Deployment 同为 myapp-1234

  • 对于用户提供的非唯一性的属性,Kubernetes 提供了标签(Label)和 注解(Annotation)机制

名称规则

  1. 依据命名规则,Kubernetes对象的名字应该:

  2. 最长不超过 253个字符

  3. 必须由小写字母、数字、减号 - 、小数点 . 组成

  4. 某些资源类型有更具体的要求

UID

UID 是由 Kubernetes 系统生成的,唯一标识某个 Kubernetes 对象的字符串。Kubernetes集群中,每创建一个对象,都有一个唯一的 UID。用于区分多次创建的同名对象(如前所述,按照名字删除对象后,重新再创建同名对象时,两次创建的对象 name 相同,但是 UID 不同。)

名称空间

在 Kubernetes 中,名称空间(Namespace) 提供一种机制,将同一集群中的资源划分为相互隔离的组。 同一名称空间内的资源名称要唯一,但跨名称空间时没有这个要求。 名称空间作用域仅针对带有名称空间的对象,例如 Deployment、Service 等, 这种作用域对集群访问的对象不适用,例如 StorageClass、Node、PersistentVolume 等。

默认的名称空间

[root@k8s-01 ~]# kubectl get namespace
NAME                   STATUS   AGE
default                Active   8d
kube-node-lease        Active   8d
kube-public            Active   8d
kube-system            Active   8d
kubernetes-dashboard   Active   4d21h
[root@k8s-01 ~]#
  • default :默认名称空间,如果 Kubernetes 对象中不定义 metadata.namespace 字段,该对象将放
    在此名称空间下
  • kube-system :Kubernetes系统创建的对象放在此名称空间下
  • kube-public :此名称空间自动在安装集群是自动创建,并且所有用户都是可以读取的(即使是那些
    未登录的用户)。主要是为集群预留的,例如,某些情况下,某些Kubernetes对象应该被所有集群
    用户看到。

如何使用名称空间

  1. 基于环境的隔离,(开发环境?测试环境?生产环境?)

  2. 基于产品线的名称空间隔离,(安卓?ios?)

  3. 基于团队的隔离

如何创建?

老办法了

  1. kubectl create namespace test1 --dry-run=client -oyaml

  2. 得到输出内容

apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: null
  name: test1
spec: {}
  1. 根据内容创建2个名称空间
##第一个
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: null
  name: test1
spec: {}

##第二个
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: null
  name: test2
spec: {}

##创建
kubectl apply -f test1.yaml
kubectl apply -f test2.yaml

image-20230220145202736

  1. 分别在这2个名称空间部署一次
## test1
kind: Pod
apiVersion: v1
metadata:
  name: nginx-demo-pod
  namespace: test1	#不写就是default
spec:	# 指定期望状态
  containers:	# 指定要启动一个什么样的容器
  - image: nginx	# 指定镜像
    name: nginx-demo-pod	# 指定容器名称
    
## test2
kind: Pod
apiVersion: v1
metadata:
  name: nginx-demo-pod
  namespace: test2	#不写就是default
spec:	# 指定期望状态
  containers:	# 指定要启动一个什么样的容器
  - image: nginx	# 指定镜像
    name: nginx-demo-pod	# 指定容器名称
    
##分别部署
kubectl apply -f test1.yaml
kubectl apply -f test2.yaml

image-20230220154615836

测试不同名称空间的网络互通情况

  • pod 之间应该是可以互通的

image-20230220155155413

查询k8s 资源是否存在名称空间

# 存在名称空间的资源输出
kubectl api-resources --namespaced=true

# 不存在名称空间的资源输出
kubectl api-resources --namespaced=false
  • 其实就是kubectl api-resources 的【NAMESPACED】字段为:true/false
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值