上节讲了创建无状态应用统一使用deployment的方式来去创建应用通过rs挂载你响应的pod,但是有一个问题不管是deployment还是replicaSet他们没有一个统一的ip地址,只有在每个pod上有IP,那我们要去访问一个对应的功能的时候,只能通过单个ip地址的方式去访问,这种方式会有问题,他无法实现高可用和负载均衡,如果我作为一个用户,我只能去访问某一个pod,如果这个pod宕机了,那我就访问不了,虽然deployment会主动给我们创建新的pod但是,有个问题我们pod本身的ip地址不是固定的,一旦pod重新创建了pod就变了,一定是变化的,一旦某一个pod因为意外情况宕机了,创建了个新的,或者因为人为去更新的时候,pod的ip地址会改变的,对应的pod地址会变,从我们以前学习的tcp/ip的访问模式来讲我们去访问一个资源的时候,我们是通过ip+端口号的方式去访问,这个固定的一个值,如果我们ip地址变了,就意味着访问不到了,以前ip就访问不到了,作为一个客户端只知道这个pod的ip知道他变了以后再访问就访问不了了,同样的情况下,我同时访问一个,只能访问一个,而且还做不了负载均衡和高可用!
基于上面说的问题k8s给我们提供了另外一种资源对象叫service
我们在创建集群的时候有三种网络,一个叫pod网络(每个pod都有个ip地址)第二个叫集群网络(service网络)
service网络意味着 我们在创建一个service 的时候,service上也会有个ip地址,这个service的ip地址是固定的,只要你这个service存在他就不会变化,service clust IP 理解为service ip
创建service后会自动给我们创建一个同名的endpoint,这个endpoint会直接和对应的pod关联,这些pod实际上是直接挂载到endpoint上的
然后我们去访问service的ip地址的时候
我们去访问服务的时候不需要去访问pod的ip直接访问service的ip地址,因为service的ip地址是固定的!
service本身只是一种规则,规则和产生和那些pod关联的规则,iptables和ipvs 就是lvs的规则
service在这起到的作用
1.高可用
2.负载均衡
在访问服务的时候,之前创建都是创建某一个deployment或者是pod
生产上不管pod有多少个,就算是一个deployment只有一个pod,你也需要在他之上创建一个service,然后和这个deployment关联,关联上以后未来访问的话都是通过servicer ip访问
就算是pod删除或更新了,更新和删除意味着pod的ip变化了,pod还是会自动的和endpoint关联
pod是如何和endpoint关联的?
靠的是标签选择器:label-selector
deployment控制pod也是通过标签选择器,但是service和deployment本身没有任何关系,deployment是为了创建pod,service是为了和某些pod关联,service和deployment没有任何关系
服务发布基础
Label和selector 标签和标签选择器
在service里面的标签选择器和pod控制器里面的标签选择器,他俩不太一样,在pod控制器里面标签选择器包含
pod控制器的标签选择器有两种如下
[root@k8s-master1 ~]# kubectl explain deployment.spec.selector
KIND: Deployment
VERSION: apps/v1
RESOURCE: selector <Object>
DESCRIPTION:
Label selector for pods. Existing ReplicaSets whose pods are selected by
this will be the ones affected by this deployment. It must match the pod
template's labels.
A label selector is a label query over a set of resources. The result of
matchLabels and matchExpressions are ANDed. An empty label selector matches
all objects. A null label selector matches no objects.
FIELDS:
matchExpressions <[]Object>
#第一种
matchExpressions is a list of label selector requirements. The requirements
are ANDed.
matchLabels <map[string]string>
#第二种
matchLabels is a map of {key,value} pairs. A single {key,value} in the
matchLabels map is equivalent to an element of matchExpressions, whose key
field is "key", the operator is "In", and the values array contains only
"value". The requirements are ANDed.
Service的标签选择器
[root@k8s-master1 ~]# kubectl explain service.spec.selector
KIND: Service
VERSION: v1
FIELD: selector <map[string]string>
#service的标签选择器没有哪两种方法,就是个映射,映射就和rc类似的 直接后面跟一组映射关系
DESCRIPTION:
Route service traffic to pods with label keys and values matching this
selector. If empty or not present, the service is assumed to have an
external process managing its endpoints, which Kubernetes will not modify.
Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
type is ExternalName. More info:
https://kubernetes.io/docs/concepts/services-networking/service/
这就是service标签选择器的使用方式相对来说比较简单一点
k8s上所有的资源对象都可以打标签
pod可以deployment可以打标签,service也可以打 node节点也可以打标签,给node节点打标签为了发布服务的时候把指定的应用发布到某个节点上去,比如我们
给node打标签方式
[root@k8s-master1 ~]# kubectl label nodes k8s-node1.guoguo.com disktype=ssd
node/k8s-node1.guoguo.com labeled
# nodes: 表示操作的对象类型是节点(node)
# k8s-node1.guoguo.com: 指定操作的节点名称
# disktype=ssd:给该节点添加标签disktype且标签值为ssd
[root@k8s-master1 ~]# kubectl get nodes -l disktype=ssd
NAME STATUS ROLES AGE VERSION
k8s-node1.guoguo.com Ready <none> 11d v1.26.3
#过滤出node节点标签为disktype=ssd的
这就是我给我的node节点打了一个标签,后面我想创建某个应用只想创建到带有这个标签的node节点上
这就是个简单的节点选择
写一个
有一个节点选择器 nodeSelector
[root@k8s-master1 ~]# kubectl explain deployment.spec.template.spec
KIND: Deployment
VERSION: apps/v1
RESOURCE: spec <Object>
DESCRIPTION:
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
PodSpec is a description of a pod.
FIELDS:
nodeSelector <map[string]string>
#节点选择器,这个就是通过标签来定义的
NodeSelector is a selector which must be true for the pod to fit on a node.
Selector which must match a node's labels for the pod to be scheduled on
that node. More info:
https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
os <Object>
Specifies the OS of the containers in the pod. Some pod and container
fields are restricted if this is set.
If the OS field is set to linux, the following fields must be unset:
-securityContext.windowsOptions
If the OS field is set to windows, following fields must be unset: -
spec.hostPID - spec.hostIPC - spec.hostUsers -
spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile -
spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy -
spec.securityContext.sysctls - spec.shareProcessNamespace -
spec.securityContext.runAsUser - spec.securityContext.runAsGroup -
spec.securityContext.supplementalGroups -
spec.containers[*].securityContext.seLinuxOptions -
spec.containers[*].securityContext.seccompProfile -
spec.containers[*].securityContext.capabilities -
spec.containers[*].securityContext.readOnlyRootFilesystem -
spec.containers[*].securityContext.privileged -
spec.containers[*].securityContext.allowPrivilegeEscalation -
spec.containers[*].securityContext.procMount -
spec.containers[*].securityContext.runAsUser -
spec.containers[*].securityContext.runAsGroup
[root@k8s-master1 deployment]# cat nginx-deployment-2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-node1
spec:
replicas: 10
selector:
matchLabels:
node: node1
template:
metadata:
name: nginx
labels:
node: node1
spec:
containers:
- name: nginx
image: images.guoguo.com/apps/nginx:1.22.1
ports:
- containerPort: 80
nodeSelector: #这是节点选择器
disktype: ssd #刚才我们给node1加了个标签 现在 我们选择这个标签就意味着 上面副本数量写的是10个pod 也就是说创建的10个pod都会运行在node1节点上
[root@k8s-master1 deployment]# kubectl apply -f nginx-deployment-2.yaml
deployment.apps/nginx-deployment-node1 created
#启动
[root@k8s-master1 deployment]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-node1-78c566f64c-6hl6n 1/1 Running 0 16s 192.26.131.183 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-8n6lv 1/1 Running 0 16s 192.26.131.178 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-bhgk7 1/1 Running 0 16s 192.26.131.186 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-dskfl 1/1 Running 0 16s 192.26.131.182 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-hld2r 1/1 Running 0 16s 192.26.131.187 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-ltxv4 1/1 Running 0 16s 192.26.131.179 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-r8jkk 1/1 Running 0 16s 192.26.131.181 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-w8vlk 1/1 Running 0 16s 192.26.131.185 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-wlgrh 1/1 Running 0 16s 192.26.131.184 k8s-node1.guoguo.com <none> <none>
nginx-deployment-node1-78c566f64c-zk6x8 1/1 Running 0 16s 192.26.131.180 k8s-node1.guoguo.com <none> <none>
以上全部都是运行在node1节点上的
用awk方式验证一下 这样看更易读
[root@k8s-master1 deployment]# kubectl get pods -owide | awk '{print $1,$2,$3,$7}'
NAME READY STATUS NODE
nginx-deployment-6888855468-hltbg 1/1 Running k8s-node2.guoguo.com
nginx-deployment-node1-78c566f64c-6hl6n 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-8n6lv 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-bhgk7 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-dskfl 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-hld2r 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-ltxv4 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-r8jkk 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-w8vlk 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-wlgrh 1/1 Running k8s-node1.guoguo.com
nginx-deployment-node1-78c566f64c-zk6x8 1/1 Running k8s-node1.guoguo.com
这种方式叫硬匹配,生产上会有很多方式,以后章节会讲
通过一个节点label 通过节点选择器的方式和标签关联 然后让pod运行在某个节点上
Selector选择器
选择器很多地方都有,这节主要讲service的选择器
查看标签的几个命令
#打印出pod的和他的所有标签
[root@k8s-master1 deployment]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-6888855468-hltbg 1/1 Running 0 3h43m app=nginx,env=dev,pod-template-hash=6888855468
nginx-deployment-node1-78c566f64c-6hl6n 1/1 Running 0 7m10s node=node1,pod-template-hash=78c566f64c
#只显示node=node1标签的pod
[root@k8s-master1 deployment]# kubectl get pods -l node=node1
NAME READY STATUS RESTARTS AGE
nginx-deployment-node1-78c566f64c-6hl6n 1/1 Running 0 8m25s
#这种是in 包含
[root@k8s-master1 deployment]# kubectl get pods -l 'node in (node1)'
NAME READY STATUS RESTARTS AGE
nginx-deployment-node1-78c566f64c-6hl6n 1/1 Running 0 9m34s
#比如还可以这样写
#意思是显示node标签内容是 node1 或node2 的都显示
[root@k8s-master1 deployment]# kubectl get pods -l 'node in (node1,node2)'
#意思是显示node标签内容是 node1 或node2 的都显示 并且打印出所有标签
[root@k8s-master1 deployment]# kubectl get pods -l 'node in (node1,node2)' --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-node1-78c566f64c-6hl6n 1/1 Running 0 12m node=node1,pod-template-hash=78c566f64c
nginx-deployment-node1-78c566f64c-8n6lv 1/1 Running 0 12m node=node1,pod-template-hash=78c566f64c
#对现有的deployment加个标签
[root@k8s-master1 deployment]# kubectl label deployments.apps nginx-deployment-node1 versinotallow=v1
deployment.apps/nginx-deployment-node1 labeled
#查看一下
[root@k8s-master1 deployment]# kubectl get deployments.apps --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
nginx-deployment 1/1 1 1 4h3m <none>
nginx-deployment-node1 10/10 10 10 15m version=v1
#删除标签
[root@k8s-master1 deployment]# kubectl label deployments.apps nginx-deployment-node1 version-
deployment.apps/nginx-deployment-node1 unlabeled
[root@k8s-master1 deployment]# kubectl get deployments.apps --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
nginx-deployment 1/1 1 1 4h7m <none>
nginx-deployment-node1 10/10 10 10 19m <none>
标签:Kubernetes,Service,labels,nginx,deployment,node1,pod,k8s,spec
From: https://blog.51cto.com/u_15971294/7156870