NamespacePodLabelDeploymentService资源的使用及介绍,意在边使用边了解、学习。

Namespace

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

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

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

kubernetes子集群启动之后,会默认创建几个namespace

查看namespace

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

下面来看namespace资源的具体操作:

查看

查看具体的namespace

[root@master ~]# kubectl get ns default
NAME STATUS AGE
default Active 2d

查看namespace具体信息

[root@master ~]# kubectl describe ns default
Name: default
Labels: <none>
Annotations: <none>
Status: Active # Active表示命名空间正在使用中 Terminating表示正在删除命名空间

# ResourceQuota 针对namespace做的资源限制
# LimitRange针对namespace中的每个组件做的资源限制
No resource quota.
No LimitRange resource.

创建

创建一个namespace

[root@master ~]# kubectl create ns dev
namespace/dev created

删除

[root@master ~]# kubectl delete ns dev
namespace "dev" deleted

配置方式

创建一个yaml文件

ns-dev.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev

使用命令可以创建、删除

kubectl create -f ns-dev.yaml
kubectl delete -f ns-dev.yaml

Pod

Pod是kubernetes集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于Pod中

Pod可以认为是容器的封装,一个Pod中可以存在一个或者多个容器。

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

[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6955765f44-67n2l 1/1 Running 3 2d20h
coredns-6955765f44-6w2pt 1/1 Running 3 2d20h
etcd-master 1/1 Running 3 2d20h
kube-apiserver-master 1/1 Running 3 2d20h
kube-controller-manager-master 1/1 Running 3 2d20h
kube-proxy-v6hr4 1/1 Running 3 2d20h
kube-proxy-w4jm2 1/1 Running 3 2d20h
kube-proxy-xdvtr 1/1 Running 3 2d20h
kube-scheduler-master 1/1 Running 3 2d20h

创建并运行

kubernetes没有使用单独运行Pod的命令,都是通过Pod控制器来实现的

kubectl run (pod控制器名称) [参数]
--image # 指定Pod的镜像
--port # 指定端口
--namespace # 指定namespace

例如:

[root@master ~]# kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace dev
deployment.apps/nginx created

查看Pod信息

获取Pod信息

[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx-64777cd554-gjdxm 1/1 Running 0 12m

查看指定Pod详细信息

[root@master ~]# kubectl describe pod nginx-64777cd554-gjdxm -n dev
Name: nginx-64777cd554-gjdxm
Namespace: dev
Priority: 0
Node: node2/192.168.52.133
Start Time: Fri, 24 Feb 2023 14:24:54 +0800
Labels: pod-template-hash=64777cd554
run=nginx
Annotations: <none>
Status: Running
IP: 10.244.2.7
IPs:
IP: 10.244.2.7
Controlled By: ReplicaSet/nginx-64777cd554
Containers:
nginx:
Container ID: docker://b345c9a0661fd8035f403593f1c6d2d03c754445232ca90efa4fda7650b96ebf
Image: nginx:1.17.1
Image ID: docker-pullable://nginx@sha256:b4b9b3eee194703fc2fa8afa5b7510c77ae70cfba567af1376a573a967c03dbb
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 24 Feb 2023 14:24:55 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-xp9r4 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-xp9r4:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-xp9r4
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:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned dev/nginx-64777cd554-gjdxm to node2
Normal Pulled 6m48s kubelet, node2 Container image "nginx:1.17.1" already present on machine
Normal Created 6m48s kubelet, node2 Created container nginx
Normal Started 6m47s kubelet, node2 Started container nginx

访问指定Pod

获取Pod

[root@master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-64777cd554-gjdxm 1/1 Running 0 16m 10.244.2.7 node2

访问Pod

[root@master ~]# curl 10.244.2.7:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

删除指定Pod

删除指定Pod

[root@master ~]# kubectl delete pod nginx-64777cd554-gjdxm -n dev
pod "nginx-64777cd554-gjdxm" deleted

再次查看Pod,发现又产生了一个

[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx-64777cd554-gftqq 1/1 Running 0 41s

这是因为当前Pod是由Pod控制器创建的,控制器会监控Pod状况,一旦发生Pod死亡,会立即重建,此时想要删除Pod,必须删除Pod控制器。

新版本已更改,在自定义namespace中执行RUN命令,不会自动创建Deployment,即删除之后不会重建

使用CREATE命令,会自动创建Deployment。在默认命名空间执行RUN命令则会创建pod控制器

[root@master ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 21m

接下来,删除此Pod控制器

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

稍等片刻,再查询Pod,发现Pod被删除了

[root@master ~]# kubectl get pods -n dev
No resources found in dev namespace.

配置方式

创建一个yaml文件,内容如下

pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:1.17.1
imagePullPolicy: IfNotPresent
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP

使用下面命令创建删除

kubectl create -f pod-nginx.yaml
kubectl delete -f pod-nginx.yaml

使用该方式创建的pod也没有Deployment

Label

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

Label的特点:

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

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

一些常用的Label如下:

  • 版本标签:"version":"release"、”version":"stable"……
  • 环境标签:"environment":"dev""environment":"test""environment":"pro"
  • 架构标签:"tier":"frontend""tier":"backend"

标签定义完毕之后,还要考虑标签的选择,这就要使用到Label Selector,即:

  1. Label用于给某个资源对象定义标识

  2. Label Selector用于查询和筛选拥有某些标签的资源对象

当前有两种Label Selector:

  • 基于等式的Label Selector

    name = slave:选择所有包含Label中key=”name”,且value=”slave”的对象

    env != production:选择所哟包括Label中的key=”env”,且value!=”production”的对象

  • 基于集合的Label Selector

    name in (master, slave):选择所有包含Label中key=”name”且value=”master”或”slave”的对象

    name not in (frontend):选择所有包含Label中key=”name”且value不等于”frontend”的对象

标签的选择可以使用多个,此时将多个Label Selector进行组合,使用逗号分隔即可。例如

name=slave, env!=production
name not in (frontend), env!=production

添加标签

查看pod资源的标签

[root@master ~]# kubectl get pod -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 21s <none>

为pod资源打标签

[root@master ~]# kubectl label pod nginx version=2.0 -n dev
pod/nginx labeled

再次查看

[root@master ~]# kubectl get pod -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 2m23s version=2.0

更新标签

更新并再次查看:

[root@master ~]# kubectl label pod nginx -n dev version=3.0 --overwrite
pod/nginx labeled
[root@master ~]# kubectl get pod -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 5m21s version=3.0

筛选标签

列出所有标签

[root@master ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 9m5s version=3.0
nginx01 1/1 Running 0 82s version=1.0
nginx02 1/1 Running 0 54s <none>

筛选标签,-l "version=3.0"

[root@master ~]# kubectl get pods -l "version=3.0" -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 9m58s version=3.0

[root@master ~]# kubectl get pods -l "version!=3.0" -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx01 1/1 Running 0 3m15s version=1.0
nginx02 1/1 Running 0 2m47s <none>

去除标签

使用labelName-删除标签:

[root@master ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 12m tier=back,version=3.0
nginx01 1/1 Running 0 5m8s version=1.0
nginx02 1/1 Running 0 4m40s <none>

[root@master ~]# kubectl label po nginx -n dev tier-
pod/nginx labeled

[root@master ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 13m version=3.0
nginx01 1/1 Running 0 6m11s version=1.0
nginx02 1/1 Running 0 5m43s <none>

配置方式

创建一个yaml文件,内容如下

pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx:1.17.1
imagePullPolicy: IfNotPresent
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP

使用下面命令更新标签

kubectl apply -f pod-nginx.yaml

Deployment

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

​ 在kubernetes中Pod控制器到的种类有很多,这里只介绍一种:Deployment

命令操作

命令格式

kubectl run deployment名称 [参数]
# --image 指定pod的镜像
# --port 指定端口
# --replicas 指定创建pod数量
# --namespace

创建Deployment

新版本K8s(1.18以上),在自定义namespace中执行RUN命令不会创建pod控制器,应使用CREATE命令。

在默认命名空间执行RUN命令则会创建pod控制器:

kubectl create deployment nginx --image=nginx --replicas=3 -n dev

使用命令创建pod

kubectl run nginx --image=nginx:1.17.1 --port=80 --replicas=3 -n dev

查看Deployment

使用describe查看详细信息:

[root@master ~]# kubectl describe deploy nginx -n dev
Name: nginx
Namespace: dev
CreationTimestamp: Sat, 25 Feb 2023 10:10:16 +0800
Labels: run=nginx
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=nginx
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 4m18s deployment-controller Scaled up replica set nginx-64777cd554 to 3

查看pod的label

[root@master ~]# kubectl get pods -n dev --show-labels
NAME LABELS
nginx-64777cd554-8d4gr pod-template-hash=64777cd554,run=nginx
nginx-64777cd554-dw5rr pod-template-hash=64777cd554,run=nginx
nginx-64777cd554-gnhwg pod-template-hash=64777cd554,run=nginx

删除Deployment

删除deployment之后,pods也会被删除

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

配置方式

创建一个yaml文件,内容如下

deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template: # pod模板
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx:1.17.1
name: nginx
ports:
- containerPort: 80
protocol: TCP

使用下面命令创建删除

kubectl create -f deploy-nginx.yaml
kubectl delete -f deploy-nginx.yaml

Service

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

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

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

这样对于访问这个服务带来了难度。因此,kubernetes设计了Service来解决这个问题。

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

创建集群内部能访问的Service

暴露Service

kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev

查看Service

[root@master ~]# kubectl get svc svc-nginx1 -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx1 ClusterIP 10.108.19.184 <none> 80/TCP 2m36s run=nginx

访问Service

[root@master ~]# curl 10.108.19.184:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

创建集群外部能访问的Service

上面创建的Service的type类型为ClusterIP,这个IP地址只能在集群内部可访问

如果需要创建外部可以访问的Service,需要修改type为NodePort

kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev

查看Service

[root@master ~]# kubectl get svc -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx1 ClusterIP 10.108.19.184 <none> 80/TCP 7m50s run=nginx
svc-nginx2 NodePort 10.111.68.23 <none> 80:31076/TCP 26s run=nginx

访问:

http://192.168.52.100:31076

删除Service

[root@master ~]# kubectl delete svc svc-nginx1 -n dev
service "svc-nginx1" deleted

配置方式

创建一个yaml文件,内容如下:

sac-nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev
spec:
clusterIP: 10.109.179.231
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
type: ClusterIP

使用下面命令创建删除

kubectl create -f svc-nginx.yaml
kubectl delete -f svc-nginx.yaml

小结

小结

​ 至此,已经掌握了Namespace、Pod、Deployment、Service资源的基本操作,有了这些操作,就可以在kubernetes集群中实现一个服务的简单部署和访问了,但是如果想要更好的使用kubernetes,就需要深入学习这几种资源的细节和原理。