组件详细介绍
NameSpace
在 Kubernetes 中,名字空间(Namespace) 提供一种机制,将同一集群中的资源划分为相互隔离的组。 同一名字空间内的资源名称要唯一,但跨名字空间时没有这个要求。 名字空间作用域仅针对带有名字空间的对象,例如 Deployment、Service 等, 这种作用域对集群访问的对象不适用,例如 StorageClass、Node、PersistentVolume 等
:kubectl get namespace
NAME STATUS AGE
default Active 1d # Kubernetes 包含这个名字空间,以便于你无需创建新的名字空间即可开始使用新集群。
kube-node-lease Active 1d # 该名字空间包含用于与各个节点关联的 Lease(租约)对象。 节点租约允许 kubelet 发送心跳, 由此控制面能够检测到节点故障
kube-public Active 1d # 所有的客户端(包括未经身份验证的客户端)都可以读取该名字空间。 该名字空间主要预留为集群使 用,以便某些资源需要在整个集群中可见可读。 该名字空间的公共属性只是一种约定而非要求。
kube-system Active 1d # 该名字空间用于 Kubernetes 系统创建的对象。集群组件(controller scheduler service)
操作
namespace 缩写为 ns
# 列出集群中的所有名字空间。
kubectl get namespaces
# 通过下列命令获取特定名字空间的摘要:
kubectl get namespaces <name>
# 下面的命令获取详细信息:
kubectl describe namespaces <name>
# 根据配置文件创建/删除命令空间
kubectl create/delete -f ./my-namespace.yaml
# 直接创建
kubectl create namespace <insert-namespace-name-here>
# 删除名字空间使用命令:会删除名字空间下的 所有内容 !
kubectl delete namespaces/ns <insert-some-namespace-name>
# my-namespace.yaml
apiVersion: v1
kind: NameSpace
meatdata:
name: dev
Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod(就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的 “逻辑主机”,其中包含一个或多个应用容器, 这些容器相对紧密地耦合在一起。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于在同一逻辑主机上运行的云应用。
除了应用容器,Pod 还可以包含在 Pod 启动期间运行的 Init 容器。 你也可以在集群支持临时性容器的情况下, 为调试的目的注入临时性容器。
Pod 的共享上下文包括一组 Linux 名字空间、控制组(cgroup)和可能一些其他的隔离方面, 即用来隔离容器的技术。 在 Pod 的上下文中,每个独立的应用可能会进一步实施隔离。
Pod 类似于共享名字空间并共享文件系统卷的一组容器
操作
Pod 通常不是直接创建的,而是使用工作负载资源(Pod控制器)创建的。
重启 Pod 中的容器不应与重启 Pod 混淆。 Pod 不是进程,而是容器运行的环境。 在被删除之前,Pod 会一直存在。
# 命令式对象管理创建
# --image 镜像
# --port 端口
# --namespace 命名空间
kubectl run nginxpod --image=nginx:1.17.1 --port=80 --namspace dev
# 访问Pod 访问其中运行的容器 获取ip地址和端口
kubectl get pod pod-name -n dev - wide && curl pod_ip:port
# 删除 注意:执行此命令时,当删除当前pod,pod控制器会立即新建一个pod 需要删除pod控制器
kubectl delete pod pod-name -n dev
# 查看pod控制器
kubectl get deploy -n dev
# 删除pod控制器
kubectl delete deploy pod-contrlloer-name -n dev
# 配置文件操作 命令式对象配置 此种方式不存在pod控制器
# 创建一个pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
# 横杠为数组配置
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
# 创建和删除
kubectl create -f pod-nginx.yaml
kubectl delete -f pod-nginx.yaml
Label
标签(Labels) 是附加到 Kubernetes 对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。
场景:不同的namespace之间无法通信,如果在k8s系统中部署一个网站,网站的前端和后端是需要通信的,就可以使用labels来给前端和后端应用分别打上不同的标签,之后在使用标签选择器来选择不同的pod
标签选择器
label用于给某个资源对象定义标识
label Selector 用于查询和筛选拥有某些标签的资源对象
基于等值的标签选择器
基于等值或基于不等值的需求允许按标签键和值进行过滤。 匹配对象必须满足所有指定的标签约束,尽管它们也可能具有其他标签。 可接受的运算符有 =
、==
和 !=
三种。 前两个表示相等(并且是同义词),而后者表示不相等。例如:
environment = production
tier != frontend
前者选择所有资源,其键名等于 environment
,值等于 production
。 后者选择所有资源,其键名等于 tier
,值不同于 frontend
,所有资源都没有带有 tier
键的标签。 可以使用逗号运算符来过滤 production
环境中的非 frontend
层资源:environment=production,tier!=frontend
。
基于等值的标签要求的一种使用场景是 Pod 要指定节点选择标准。 例如,下面的示例 Pod 选择带有标签 “accelerator=nvidia-tesla-p100
”。
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "registry.k8s.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
基于集合的标签选择器
基于集合的标签需求允许你通过一组值来过滤键。 支持三种操作符:in
、notin
和 exists
(只可以用在键标识符上)。例如:
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- 第一个示例选择了所有键等于
environment
并且值等于production
或者qa
的资源。 - 第二个示例选择了所有键等于
tier
并且值不等于frontend
或者backend
的资源,以及所有没有tier
键标签的资源。 - 第三个示例选择了所有包含了有
partition
标签的资源;没有校验它的值。 - 第四个示例选择了所有没有
partition
标签的资源;没有校验它的值。
类似地,逗号分隔符充当与运算符。因此,使用 partition
键(无论为何值)和 environment
不同于 qa
来过滤资源可以使用 partition, environment notin (qa)
来实现。
基于集合的标签选择算符是相等标签选择算符的一般形式,因为 environment=production
等同于 environment in (production)
;!=
和 notin
也是类似的。
基于集合的要求可以与基于相等的要求混合使用。例如:partition in (customerA, customerB),environment!=qa
操作
给pod添加标签
# 添加label
kubectl label pod nginx-pod vesion=1.0 -n dev
# 更新label
kubectl label pod nginx-pod version=2.0 -n dev --overwrite
# 查看label
kubectl label pod nginx-pod -n dev --show-labels
# 筛选label
kubectl get pod -n dev -l "version=2.0" --show-labels
kubectl get pod -n dev -l "version!=2.0" --show-labels
# 删除label
kubectl label pod nginx-pod -n dev version-
给节点添加标签
# 列出集群中的节点, 包括这些节点上的标签:
kubectl get nodes --show-labels
# 从节点中选择一个,为它添加标签:
kubectl label nodes <your-node-name> disktype=ssd
# 验证选择的节点确实带有 disktype=ssd 标签:
kubectl get nodes --show-labels
Deployment
一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。
负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。
用于pod的管理,确保pod资源符合预期的状态,当pod资源出现故障时,尝试进行重启或者重建pod
操作
命令式对象管理
# 命令格式: kubectl create deployment 名称 [参数]
# --image 指定pod的镜像
# --port 指定端口
# --replicas 指定创建pod数量
# --namespace 指定namespace
[root@master ~]# kubectl run nginx --image=nginx:latest --port=80 --replicas=3 -n dev
deployment.apps/nginx created
# 查看创建的Pod
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx-5ff7956ff6-6k8cb 1/1 Running 0 19s
nginx-5ff7956ff6-jxfjt 1/1 Running 0 19s
nginx-5ff7956ff6-v6jqw 1/1 Running 0 19s
# 查看deployment的信息
[root@master ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 2m42s
# UP-TO-DATE:成功升级的副本数量
# AVAILABLE:可用副本的数量
[root@master ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 2m51s nginx nginx:latest run=nginx
# 查看deployment的详细信息
[root@master ~]# kubectl describe deploy nginx -n dev
# 删除
[root@master ~]# kubectl delete deploy nginx -n dev
deployment.apps "nginx" deleted
命令式对象配置
创建一个deploy-nginx.yaml,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
# 副本数量 3
replicas: 3
selector:
# 选择器
matchLabels:
run: nginx
# pod模板
template:
metadata:
# 标签
labels:
run: nginx
spec:
containers:
- image: nginx:latest
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
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx1 exposed
# 查看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.109.179.231 <none> 80/TCP 3m51s run=nginx
# 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的
# 可以通过这个IP访问当前service对应的POD
[root@master ~]# curl 10.109.179.231:80
创建集群外部可访问的service
# 上面创建的Service的type类型为ClusterIP,这个ip地址只用集群内部可访问
# 如果需要创建外部也可以访问的Service,需要修改type为NodePort
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx2 exposed
# 此时查看,会发现出现了NodePort类型的Service,而且有一对Port(80:31928/TC)
[root@master ~]# kubectl get svc svc-nginx2 -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx2 NodePort 10.100.94.0 <none> 80:31928/TCP 9s run=nginx
# 接下来就可以通过集群外的主机访问 节点IP:31928访问服务了
# 例如在的电脑主机上通过浏览器访问下面的地址
http://192.168.90.100:31928/
删除Service
[root@master ~]# kubectl delete svc svc-nginx-1 -n dev
service "svc-nginx-1" deleted
配置方式
# 创建一个svc-nginx.yaml,内容如下:
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev
spec:
clusterIP: 10.109.179.231 #固定svc的内网ip
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
type: ClusterIP
然后就可以执行对应的创建和删除命令了:
创建:kubectl create -f svc-nginx.yaml
删除:kubectl delete -f svc-nginx.yaml