Kubernetes 常见资源的基础操作
一. 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 技术交流群。

上一篇: Kubernetes 资源管理
下一篇: 谈谈自己对于 AOP 的了解
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论