Kubernetes 常见资源的基础操作

发布于 2023-12-29 12:03:18 字数 16324 浏览 32 评论 0

一. Namespace

Namespace 是 kubernetes 系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离

默认情况下,kubernetes 集群中的所有的 Pod 都是可以相互访问的。但是在实际中,可能不想让两个 Pod 之间进行互相的访问,那此时就可以将两个 Pod 划分到不同的 namespace 下。kubernetes 通过将集群内部的资源分配到不同的 Namespace 中,可以形成逻辑上的“组”,以方便不同的组的资源进行隔离使用和管理。

可以通过 kubernetes 的授权机制,将不同的 namespace 交给不同租户进行管理,这样就实现了多租户的资源隔离。此时还能结合 kubernetes 的资源配额机制,限定不同租户能占用的资源,例如 CPU 使用量、内存使用量等等,来实现租户可用资源的管理。

在集群启动后,会有几个默认的 namespace:

[root@node01 ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   18h #所有未指定 namespace 的资源都会被分配到 default 命名空间中	
kube-node-lease   Active   18h #集群节点间的心跳维护,从 v1.13 开始引入
kube-public       Active   18h #此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system       Active   18h #所有由 Kubernetes 系统创建的资源都处于这个命名空间

下面来看 Namespace 资源的具体操作

(1)查看 namespace

kubectl get namespace 
kubectl get ns  

#查看指定 Namespace
kubectl get ns [名称]

#指定输出格式
kubectl get ns [名称] -o [wide|json|yaml]

#查看 namespace 详情
kubectl describe ns [名称]

[root@node01 ~]# kubectl describe ns kube-system 
Name:         kube-system
Labels:       <none>
Annotations:  <none>
Status:       Active #Active 表示命名空间正在使用,Terminating 表示正在删除该命名空间

No resource quota.#resource quota 针对命名空间做的资源限制

No LimitRange resource. #LimitRange 针对命名空间中的每个组件做资源限制

(2)新增 namespace

kubectl create ns [名称]

(3)删除 namespace

kubectl delete ns [名称]

(4)声明式配置

首先准备一个 yaml 文件:ns-dev.yaml

apiVersion: v1
kind: Namespace
metadata: 
  name: dev

二. Pod

Pod 是 kubernetes 集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于 Pod 中 Pod 可以认为是容器的封装,一个 Pod 中可以存在一个或者多个容器。

Kubernetes 在集群启动之后,集群中的各个组件也都是以 Pod 方式运行的。可以通过下面命令查看:

[root@node01 ~]# kubectl get pod -n kube-system
NAME                             READY   STATUS    RESTARTS   AGE
coredns-9d85f5447-56t9j          1/1     Running   0          18h
coredns-9d85f5447-88x6h          1/1     Running   0          18h
etcd-node01                      1/1     Running   0          18h
kube-apiserver-node01            1/1     Running   0          18h
kube-controller-manager-node01   1/1     Running   0          18h
kube-flannel-ds-amd64-9sbgq      1/1     Running   0          155m
kube-flannel-ds-amd64-plfll      1/1     Running   0          155m
kube-flannel-ds-amd64-wwmvj      1/1     Running   0          155m
kube-proxy-gkwlk                 1/1     Running   0          18h
kube-proxy-mkggt                 1/1     Running   0          18h
kube-proxy-r6chd                 1/1     Running   0          18h
kube-scheduler-node01            1/1     Running   1          18h

(1)创建并运行

Kubernetes 没有提供单独运行 Pod 的命令,都是通过 Pod 控制器来实现的

# 命令格式:kubectl run [pod 控制器名称] [参数]
# --image 镜像版本
# --port  暴露端口
# --namespace 命名空间

kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace=dev

(2)查看 Pod 信息

# 查看 Pod 基本信息
[root@node01 ~]# kubectl get pod -n dev
NAME                     READY   STATUS    RESTARTS   AGE
nginx-64777cd554-8rdmn   1/1     Running   0          25s

# 查看 Pod 详细信息
[root@node01 ~]# kubectl describe pod nginx-64777cd554-8rdmn -n dev
Name:         nginx-64777cd554-8rdmn
Namespace:    dev
Priority:     0
Node:         node03/192.168.0.103
Start Time:   Sun, 04 Jul 2021 16:38:12 +0800
Labels:       pod-template-hash=64777cd554
              run=nginx
Annotations:  <none>
Status:       Running
IP:           10.244.2.5
IPs:
  IP:           10.244.2.5
Controlled By:  ReplicaSet/nginx-64777cd554
Containers:
  nginx:
    Container ID:    docker://12ca94abb0735a3d640c139bcb53d46c2834b0d9e405dad090ad26f832fa66f5 
    Image:          nginx:1.17.1
    Image ID:       docker- pullable://nginx@sha256 :b4b9b3eee194703fc2fa8afa5b7510c77ae70cfba567af1376a573a967c03dbb
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sun, 04 Jul 2021 16:38:13 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-fpxdb (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-fpxdb:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-fpxdb
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events: # Pod 启动过程中发生的事件
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned dev/nginx-64777cd554-8rdmn to node03
  Normal  Pulled     52m        kubelet, node03    Container image "nginx:1.17.1" already present on machine
  Normal  Created    52m        kubelet, node03    Created container nginx
  Normal  Started    52m        kubelet, node03    Started container nginx

(3)访问 Pod

#获取 IP 
[root@node01 ~]# kubectl get pod -n dev -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
nginx-64777cd554-8rdmn   1/1     Running   0          10m   10.244.2.5   node03   <none>           <none>

# 访问 Pod
[root@node01 ~]# curl 10.244.2.5:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
......

(4)删除 Pod

# 删除指定 Pod
[root@node01 ~]# kubectl delete pod nginx-64777cd554-8rdmn -n dev
pod "nginx-64777cd554-8rdmn" deleted

# 此时虽然显示删除成功,但是再查询,发现又新产生了一个
[root@node01 ~]# kubectl get pod -n dev 
NAME                     READY   STATUS    RESTARTS   AGE
nginx-64777cd554-479kh   1/1     Running   0          24s

直接删除 Pod 后,又会重新生成一个 Pod 是因为 Pod 控制器会监控 Pod 状况,一旦发现 Pod 死亡,会立即重建。

如果想要真正删除 Pod,则需要将 Pod 控制器删除即可,删除 Pod 控制器后,它所控制的 Pod 也会自动删除:

# 查看 Pod 控制器
[root@node01 ~]# kubectl get deployment -n dev
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           15m

# 删除 Pod 控制器
[root@node01 ~]# kubectl delete deployment nginx -n dev
deployment.apps "nginx" deleted

三. Label

Label 是 kubernetes 系统中的一个重要概念。它的作用就是在资源上添加标识,用来对它们进行区分和选择。Label 的特点:

  • 一个 Label 会以 kev/value 键值对的形式附加到各种对象上,如 Node、Pod、Service 等等
  • 一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源对象上去
  • Label 通常在资源对象定义时确定,当然也可以在对象创建后动态添加或者删除

可以通过 Label 实现资源的多维度分组,以便方便灵活地进行资源分配、调度、配置、部署等管理工作。

一些常用的 Label 示例如下:

  • 版本标签:“version”:”release”,“version”:”stable”
  • 环境标签:“env”:”dev”,“env”:”test”

标签定义完毕之后,还要考虑到标签的选择,这就是 Label Selector。Label Selector 用于查询和筛选拥有某些标签的资源对象。

(1)为 Pod 打标签

# 命令格式:kubectl label pod [pod 名称] [-n 命名空间] [key=value]
[root@node01 ~]# kubectl label pod nginx-64777cd554-vblj9 -n dev version=1.0
pod/nginx-64777cd554-vblj9 labeled

(2)查看 Pod 上的标签

[root@node01 ~]# kubectl get pod -n dev --show-labels
NAME                     READY   STATUS    RESTARTS   AGE    LABELS
nginx-64777cd554-vblj9   1/1     Running   0          6m7s   pod-template-hash=64777cd554,run=nginx,version=1.0

(3)更新标签

kubectl label pod nginx-64777cd554-vblj9 -n dev version=1.0 --overwrite

(4)删除标签

# 在 key 后面紧跟一个-号即可删除标签
[root@node01 ~]# kubectl label pod nginx-64777cd554-vblj9 -n dev version-
pod/nginx-64777cd554-vblj9 labeled

(5)通过标签筛选(Label Selector)

通过 Label 进行筛选我们需要使用到 Label Selector,当前有两种 Label Selector:

  • 基于等式的 Label Selector

name=slave :选择所有 Label 信息中包含 key=“name”且 value=“slave”的资源对象。

env!=production :选择所有 Label 信息中存在 key 为“env”,但是这个 Label 的 value 不等于 production 的资源对象。

  • 基于集合的 Label Selector

name in (master,slave)

env not in (production,test)

标签选择器可以同时使用多个,多个 Label Selector 之间使用逗号分割:

name=slave,env not in (production,test)

#使用-l 参数指定标签信息进行筛选
kubel get pod -l "version=1.0" -n dev --show-labels

#删除指定标签的 Pod
[root@node01 ~]# kubectl delete pod -l env=test -n dev
pod "nginx-64777cd554-vblj9" deleted
pod "nginx1-79d7bd676b-4tjpt" deleted

(6)声明式配置

apiVersion: apps/v1
kind: Pod
metadata:
  name: nginx
  namespace: dev
  labels:
  	version: "3.0"
  	env: "test"

四. Deployment

在 Kubernetes 中,Pod 是最小的控制单元,但是 Kubernetes 很少直接控制 Pod,一般都是通过 Pod 控制器来完成对 Pod 的管理。Pod 控制器用于 Pod 的管理,确保 Pod 资源符合预期的状态,当 Pod 的资源出现故障时,会尝试进行重启或重建 Pod。

在 Kubernetes 中 Pod 控制器种类很多种,本节只介绍一种:Deployment

Deployment 通过 Label Selector 去关联需要管理的 Pod,每个 Deployment 会定一个 Label Selector,只有满足 Selector 的 Pod 才会被 Deployment 所管理,假如我们通过kubectl run 命令创建一个副本个数为 3 的 Deployment(--replicas=3),这样三个 Pod 都会带上类似于run:nginx 的标签。如果我们将其中一个 Pod 的run:nginx 标签删除,那么 Deployment 将不再认为这个 Pod 归属它管理,此时 Pod 资源不符合副本数为 3 个的预期状态,Deployment 会自动创建一个新的 Pod。

(1)创建 Deployment

当我们使用 kubectl run 命令时,就会默认创建一个 Deployment 用于管理 Pod:

# --replicas=3 代表 Deployment 会维持 3 个 nginx 实例(副本数量)
[root@node01 ~]# kubectl run nginx --image=nginx:1.17.1 --port=80 --replicas=3 -n dev
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx created

(2)查看 Deployment

# 查看 deployment 和 pod
[root@node01 ~]# kubectl get deployment,pod -n dev --show-labels
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE     LABELS
deployment.apps/nginx   3/3     3            3           6m57s   run=nginx

NAME                         READY   STATUS    RESTARTS   AGE     LABELS
pod/nginx-64777cd554-br6cb   1/1     Running   0          6m57s   pod-template-hash=64777cd554,run=nginx #可以看到所有 Pod 副本上都会带上“run=nginx”的标签
pod/nginx-64777cd554-f55xb   1/1     Running   0          6m57s   pod-template-hash=64777cd554,run=nginx
pod/nginx-64777cd554-zsl9j   1/1     Running   0          6m57s   pod-template-hash=64777cd554,run=nginx

# 查看 Deployment 详细信息
[root@node01 ~]# kubectl describe deployment nginx -n dev
Name:                   nginx
Namespace:              dev
CreationTimestamp:      Sun, 04 Jul 2021 20:25:12 +0800
Labels:                 run=nginx
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               run=nginx #Selector 用于指明只要带有“run=nginx”标签的 Pod 就会被它管理
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=nginx
  Containers:
   nginx:
    Image:        nginx:1.17.1
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-64777cd554 (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  4m41s  deployment-controller  Scaled up replica set nginx-64777cd554 to 3

(3)删除 Deployment

[root@node01 ~]# kubectl delete deployment nginx -n dev
deployment.apps "nginx" deleted

(4)声明式配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: dev
spec:
  replicas: 3
  selector:
    matchLabels: 
      run: nginx #指明 Deployment 的选择器,表示只有标注了“run=nginx”的 Pod 才会被管理
  template:
    metadata:
      labels:
        run: nginx #指明 Pod 的标签
    spec:
      containers:
      - image: nginx:1.17.1
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP

五. Service

通过上面的讲解,已经能够利用 Deployment 来创建一组 Pod 来提供具有高可用性的服务了。

虽然每个 Pod 都会分配一个单独的 IP,然而却存在如下两个问题:

  • Pod IP 会随着 Pod 的重建而发生变化
  • Pod IP 仅仅是集群内可见的虚拟 IP,外部无法访问

这样外部如果需要访问这个服务就会非常困难。因此 Kubernetes 设计了 Service 来解决这个问题。

Service 可以看做是一组同类 Pod 对外提供的访问接口。接祖 Service,应用可以方便地实现服务发现和负载均衡。

(1)创建 Service

#命令格式:kubectl expose deployment [Pod 控制器名称] --name=[service 名称] --type-ClusterIP --port=[service 端口] --target-port=[目标端口] -n [命名空间]
[root@node01 ~]# kubectl expose deployment nginx --name=svc-nginx --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx exposed

需要注意的是,这里我们将 Service Type 设置为 ClusterIP ,它会为 Service 分配一个集群 IP,这个 IP 也是集群中的虚拟 IP,只有加入集群的节点才能通过这个 IP 访问,如果我们想要在集群外部访问,也就是对外提供服务,我们需要使用 NodePort 类型。

[root@node01 ~]# kubectl expose deployment nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx2 exposed
[root@node01 ~]# kubectl get service -n dev
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
svc-nginx    ClusterIP   10.109.216.54   <none>        80/TCP         6m57s
svc-nginx2   NodePort    10.101.198.54   <none>        80:31447/TCP   12s

此时我们就可以通过集群中任意一台节点的 IP 加上 31447 端口,就能访问到我们创建的 Nginx 服务。

(2)查看 Service

[root@node01 ~]# kubectl get service -n dev
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
svc-nginx   ClusterIP   10.109.216.54   <none>        80/TCP    37s

(3)删除 Service

[root@node01 ~]# kubectl delete service svc-nginx -n dev
service "svc-nginx" deleted

(4)声明式配置

apiVersion: apps/v1
kind: Service
metadata:
  name: svc-nginx
  namespace: dev
spec:
  clusterIP: 10.109.179.231 #IP 可省略,省略后会自动申请
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
  	run: nginx
  type: ClusterIP

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

丑疤怪

暂无简介

文章
评论
27 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文