Node
Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。
Annotations
原文链接
Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象,Annotations 则是用来记录一些附加信息,用来辅助应用部署、安全策略以及调度策略等。比如 deployment 使用 annotations 来记录 rolling update 的状态。
Label
原文链接
Label 是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上(key 最长不能超过 63 字节,value 可以为空,也可以是不超过 253 字节的字符串)。
Label 不提供唯一性,并且实际上经常是很多对象(如 Pods)都使用相同的 label 来标志具体的应用。
Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如 ReplicaSet 和 Service 用 label 来选择一组 Pod)。Label Selector 支持以下几种方式:
- 等式,如 app=nginx 和 env!=production
- 集合,如 env in (production, qa)
- 多个 label(它们之间是 AND 关系),如 app=nginx,env=test
Service
它提供了服务程序和外部的各种组件通信的能力:
1 Service 有固定的IP和端口
2 Service 背后是pod在工作
Kubernetes 会给Service分配一个静态 IP 地址,Service自动管理、维护后面动态变化的 Pod 集合,当客户端访问 Service,它就根据某种策略,把流量转发给后面的某个 Pod。
Service使用了iptables技术,每个节点上的kube-proxy组件自动维护iptables规则。
客户端不需要关心Pod的具体地址,只要访问Service的固定IP地址。
Service会根据iptables规则转发请求给后端的Pod。
支持多种services:
- NodePort: NodePort服务监听节点上的一个端口并将请求转发给Pod。把Service通过端口号暴露到集群中的节点(Node)主机。
- ClusterIP:CusterIP是默认的Service的IP地址,是一个虚拟IP地址(类似Swarm,分配了VIP)。只能kubernetes集群内部访问使用,外部网络无法ping通。服务在cluster内部创建一个虚拟IP,以实现不同服务之间的通信,比如一组前端服务器到一组后端服务器。
- LoadBalancer:LoadBalancer需要搭配云厂商(第三方)的负载均衡器来使用。它在支持的云供应商中为我们的应用程序提供一个负载平衡器。
- ExternalName:ExternalName的服务将service映射到 DNS CNAME(不常用)。
NodePort
NodePort 服务可以将节点上的端口映射到pod上。
这里理清三个端口:
1 pod会有一个端口 这个pod服务的端口
2 Service会有一个端口,Service的端口,背后可能有多个pod,相当于是一个统一入口。
3 这个节点上提供外部访问有一个端口,节点端口只能在一个有效的范围内,默认情况下是30,000到32,767
#监控节点的变化
kubectl get pods -w
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: NodePort
ports:
- port: 80 #这个端口必须要有
targetPort: 80 #默认和port一致
nodePort: 30008 #默认随机一个端口
selector:
app: myapp #这个选择器会取选对应的pod作为这个Service的pod
CusterIP
web应用程序一般有不同种类的部分,所有单元都分配了一个IP地址。但是这些IP不是静态的。这些组件随时可能出现故障,并且创建新的pod。因此,不能依赖这些IP地址进行应用程序之间的内部通信。
每个service都在集群内获得一个IP和分配给它的名称,这是其他路径访问该service时应使用的名称。这种类型的service称为ClusterIP。
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
type: ClusterIP #默认就是ClusterIP
ports:
- port: 80
targetPort: 80
selector:
app: myapp
type: backend
Headless Service 无头服务
如果我们希望做一个读写分离,web服务器发起的写请求需要直达主数据库。
但在Kubernetes中,将集群中的一个应用程序指向另一个应用程序的方式是通过service。
如果有一个web服务器, 为了访问数据库服务器, 需要为数据库创建了一个服务。服务充当负载平衡器,进入服务的流量在部署中的所有Pod之间保持平衡。该服务有一个ClusterIP和关联的DNS名称。任何其他应用程序(例如web服务器)都可以使用此DNS名称访问数据库。
所以我们需要一种服务, 它不会对请求进行负载平衡, 而是为我们提供一个DNS条目来访问每个pod。这就是headless service无头服务。
headless service的创建方式与普通Service类似, 但它没有自己的IP(如ClusterIP), 它不执行任何负载平衡。它所做的只是使用Pod名称和subdomain为每个Pod创建DNS条目。
创建一个headless service时,Service发现这些Pod是有状态应用,需要有稳定的网络标识,所以就会为Pod创建出一个新的域名,格式是Pod名.服务名.名字空间.svc.cluster.local
。e.g.redis-0.redis-h.default.svc.cluster.local
.这个域名也可以简写成“Pod名.服务名”。
Namespace
Kubernetes在集群首次启动时,自动创建默认名称空间default namespace。Namespace 主要起到限制起到隔离资源的作用。
Kubernetes在内部创建了一组pod和service,如网络方案、DNS服务等。为了将这些与用户隔离开来,防止意外删除或修改这些服务,Kubernetes在集群启动时创建的另一个名为kube-system的名称空间下创建了这些服务。
Kubernetes自动创建的第三个名称空间被称为kube-public,创建应向所有用户开放的资源的地方。
将Kubernetes集群用于企业或生产目的时,可能要考虑使用名称空间。例如,在开发和生产环境中使用同一个集群,但同时在它们之间隔离资源,可以为它们各自创建一个不同的名称空间。在开发环境中工作时,就不会意外地修改生产环境中的资源。
apiVersion: v1
kind: Namespace
metadata:
name: dev
#通过yml方式创建
kubectl create -f namespace-dev.yml
#通过命令创建
kubectl create namespace dev
#查看命令空间,查看当前集群有哪些命名空间
kubectl get ns
集群内部可以通过下面这个规则进行通信
一个名字空间里的资源也可以简单地以name通信。如果要连接另一个名字空间的服务,必须将名称空间的名称附加到服务的名称上。例如,对于默认名称空间中的web pod,要连接到dev环境或名称空间中的数据库,使用servicename.namespace.svc.cluster.local格式:dbservice.dev.svc.cluster.local。
#获取某个namespace下的pods
kubectl get pods --namespace=dev
#下面这两条命令都是一样的都是获取所有pod对应的命令空间
kubectl get pods --all-namespaces
kubectl get pods -A
资源配额
kubectl create -f resource-quota.yml
resource-quota.yml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: dev #指定限制的namespace
spec:
hard:
pods: "10" #限制pod数量最多是10个
requests.cpu: "4" #限制cpu申请的时候为4个
requests.memory: 5Gi #限制内存
limits.cpu: 10 #使用限制
limits.memory: 10Gi #使用限制
这里申请和使用是有区别的,安装Request取申请但是使用的时候最大可以到limits
切换命名空间
#将当前的命令空间切换为dev $(kubectl config current-context)获取当前的命令空间
kubectl config set-context $(kubectl config current-context) --namespace=dev