k8s及常用对象简介

发布于:2024-06-30 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、k8s是什么

应用程序早期部署形式

早期,各个应用程序在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界,这会导致资源分配问题。 例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况, 结果可能导致其他应用程序的性能下降。一种解决方案是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展, 并且维护许多物理服务器的成本很高。
作为解决方案,引入了虚拟化。虚拟化技术允许你在单个物理服务器的 CPU 上运行多个虚拟机(VM)。 虚拟化允许应用程序在 VM 之间隔离,并提供一定程度的安全,因为一个应用程序的信息 不能被另一应用程序随意访问。虚拟化技术能够更好地利用物理服务器上的资源,并且因为可轻松地添加或更新应用程序而可以实现更好的可伸缩性,降低硬件成本等等。

容器的引入

容器类似于 VM,但是它们具有被放宽的隔离属性,可以在应用程序之间共享操作系统(OS)。 因此,容器被认为是轻量级的。容器与 VM 类似,具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。

k8s的作用

Kubernetes 提供了一个可弹性运行分布式系统的框架,用于管理运行应用程序的容器。它可以提供服务发现和负载均衡、存储编排、自动部署和回滚、自我修复等。

二、k8s中的常用对象

1、Node

Node是k8s集群中相对于Master而言的工作主机。Node可以是一台物理主机,也可以是一台虚拟机。在每个Node上运行用于启动和管理Pid的服务Kubelet,并能够被Master管理。

获取node信息

kubectl get nodes
kubectl describe node nodeName

2、Namespace

namespace(命名空间)相当于一个虚拟集群,为资源提供了一个范围,资源的名称需要在namespace内是唯一的。namespace不能相互嵌套,每个 Kubernetes 资源只能在一个namespace中。

namespace的使用

查看namespace

kubectl get ns

获取详细信息:

kubectl describe namespaces <name>

创建namespace:

kubectl create namespace namespace-name

删除namespace

kubectl delete namespaces namespace-name

3、Pod

Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod 是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。

生命周期

Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度到某个节点,Pod 会一直在该节点运行,直到 Pod 停止或者被终止。
Pod 自身不具有自愈能力。如果 Pod 被调度到某节点而该节点之后失效,Pod 会被删除;类似地,Pod 无法在因节点资源耗尽或者节点维护而被驱逐期间继续存活。Kubernetes使用控制器来管理这些相对而言可随时丢弃的 Pod 实例。

pod的使用

创建pod

kubectl apply -f my-pod.yaml

查看pod基本信息

kubectl get podName -n namespace1
kubectl get pods -A | grep xxx

查看pod更多信息

kubectl get podName -n test1-ns -o wide

查看pod的yaml

kubectl get podName -n test1-ns -o yaml

查看pod运行详情信息

kubectl describe podName -n namespace1

删除pod

kubectl delete podName -n test1-ns

查看pod日志
-f :监听pod日志
–tail:输出最近的20条日志

kubectl logs -f podName --tail=20 -n namespace1

进入pod

kubectl exec -it podName -n namespace1 – /bin/bash

4、DaemonSet

DaemonSet确保全部(或者某些)节点上运行一个Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod。当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
DaemonSet常用于在每个节点上运行集群守护进程、在每个节点上运行日志收集守护进程和在每个节点上运行监控守护进程等。

DaemonSet的使用

资源模板testds.yaml信息如下:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: testds
  namespace: test1-ns
spec:
  selector:
    matchLabels:
      app: testds
  template:
    metadata:
      labels:
        app: testds
    spec:
      # 污点容忍配置 添加此配置后,ds可以运行到 master 节点
      # taint节点打上污点 再给pod加toleration 使其可以被调度到被taint的节点上
      #tolerations:
      #- key: node-role.kubernetes.io/master
      #  operator: Exists
      #  effect: NoSchedule
      affinity:
        nodeAffinity:
          # 节点亲和性选择策略(强制) 
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: nvidia.kubernetes.io/gpu
                operator: In
                values:
                - TeslaT4
                - TeslaP4  
      #域名配置
      hostAliases:
      - ip: 10.20.66.111
        hostnames:
        - testnode01      
      containers:
      - name: testds
        # 镜像地址
        image: xxxxxx/testds:V1.0.0-20240627
        imagePullPolicy: IfNotPresent
        # 所需资源
        resources:
          requests:
            cpu: 300m
            memory: 300Mi
          limits:
            cpu: 3000m
            memory: 6000Mi
        # 端口映射
        ports:
        - name: test-port
          containerPort: 9111
          hostPort: 31111
          protocol: TCP
        - name: test-port2
          containerPort: 1555
          hostPort: 30555
          protocol: UDP
        # 环境变量
        env:
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        # 磁盘映射 
        volumeMounts:
        - name: testds-log
          # 容器内地址
          mountPath: /home/log/testds/
      volumes:
      - name: testds-log
        # 宿主机地址
        hostPath:
          path: /home/log/testds/
          # 不存在type或type为空:不检查; 为Directory:目录必须存在; DirectoryOrCreate:目录不存在则新建。
          type: DirectoryOrCreate

创建/更新命令:

kubectl apply -f testds.yaml

查看详细信息

kubectl describe ds-name -n namespace-name

修改DeamonSet (可以看到某些describe看不到的信息)

kubectl edit DaemonSet ds-name -n namespace-name

5、Deployment

Deployment 通过管理 ReplicaSet 来确保任何时间都有指定数量的 Pod 副本在运行。Deployment运行无状态应用程序,如果需要进行升级,则需要替换副本集。

创建deploy

新建一个deploy模板 deploy-nginx.yaml,内容如下:
其实deployment的yaml和daemonset的差别,除了kind不同,就只多了.spec.replicas

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    # 自定义标签
    app: nginx-deploy-test
  # 资源名称
  name: nginx-test-1
  namespace: test1
spec:
  # pod 副本数量
  replicas: 3
  # 模板选择器
  selector:
    matchLabels:
      # 选择下方声明的 template
      app: nginx-test
  template:
    metadata:
      labels:
        app: nginx-test
    spec:
      containers:
      - image: nginx
        name: nginx

创建/更新命令:

kubectl apply -f deploy-nginx.yaml

以上示例中:
1、创建名为nginx-test-1(由 .metadata.name 字段标明)的 deployment
2、该deployment创建三个(由 replicas 字段标明)Pod副本
3、selector 字段定义 Deployment 如何查找要管理的 Pods。 在这里,选择在 Pod 模板中定义的标签(app: nginx-test)。
4、spec.selector.matchLabels 字段是 {key,value} 键值对映射。 在 matchLabels 映射中的每个 {key,value} 映射等效于 matchExpressions 中的一个元素, 即其 key 字段是 “key”,operator 为 “In”,values 数组仅包含 “value”。 在 matchLabels 和 matchExpressions 中给出的所有条件都必须满足才能匹配

注意:
如果没有现成的模板,可以使用 --dry-run 快速生成一个deploy资源模板

kubectl create deploy nginx-test --image=nginx --dry-run=client --replicas=3 -oyaml -n test1

6、ReplicaSet

ReplicaSet可以看作是Deployment控制器的底层组件,专注于维护Pod的副本数量,确保集群中的Pod实例始终符合用户定义的期望状态。

7、StatefulSet

StatefulSet 其实我并没有用过,但还是简单介绍下。
StatefulSet用来管理有状态应用的工作负载Api对象。StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符,因此适用于数据库和分布式系统等有状态应用的部署。和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。

创建StatefulSet

创建资源模板信息 web.yaml 其中包括 一个 headless-service(无头服务)和 一个 StatefulSet
svc 的 name 必须与 sts 的 spec.serviceName 相等,否则无法通过路由规则找到容器服务
这里为了方便就挂载了一个空目录,如果有自己的 storageClass 也可以使用

apiVersion: v1
kind: Service
metadata:
  # must be equal sts .spec.serviceName
  name: nginx-sn
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  # must be equal headless-svc metadata.name
  serviceName: "nginx-sn"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: nginx-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: nginx-volume
        # 为了演示方便,挂载个空目录
        emptyDir: {}

创建/更新命令依旧使用kubectl apply -f web.yaml
说明:
直接删除sts对应的pods时,sts会重新调度生成一个新的pod(pod ip会变,但是编号不变)。比如删除的是po/web-0,sts会重新调度生成一个web-0。
sts 也可以修改对应的副本数,新生成的pod 编号会依次递增。
假设现在有三个pod 分别为:web-0、web-1、web-2,如果删除web-1,sts会重新调度生成一个新的web-1,之前的pod保持不变

8、更新操作——kubectl patch

要更新一个已创建的比如deployment 可以用kubectl patch
比如指定它的nodeSelector
kubectl patch deployment test-server --patch '{"spec": {"template": {"spec": {"nodeSelector": {"kubernetes.io/hostname": "worker1"}}}}}' -n test-ns
这样看可能看着眼晕,我们给它展开,它其实是这么个格式:

kubectl patch deployment <deployment-name> -n <namespace> --patch '
{
  "spec": {
    "template": {
      "spec": {
        "nodeSelector": {
          "kubernetes.io/hostname": "worker1"
        }
      }
    }
  }
}
'

又或者加域名配置:

kubectl patch deployment <deployment-name> -n <namespace> --type='json' -p='[
  {
    "op": "add",
    "path": "/spec/template/spec/hostAliases",
    "value": [
      {
        "ip": "127.0.0.1",
        "hostnames": ["example.com"]
      },
      {
        "ip": "10.20.30.40",
        "hostnames": ["foo.bar", "baz.qux"]
      }
    ]
  }
]'