k8s基础篇-服务发布入门

Label & Selector 

概念:

Label:对k8s中各种资源进行分类、分组,添加一个具有特别属性的一个标签。

Selector:通过一个过滤的语法进行查找到对应标签的资源。

定义Label

 现在有三个节点,一个master,两个node。举例:给k8s-node01添加一个address=beijing的标签

[root@k8s-master ~]# kubectl label node k8s-node01 address=beijing
node/k8s-node01 labeled

然后,可以通过Selector对其筛选

[root@k8s-master ~]# kubectl get nodes -l   address=beijing       
NAME         STATUS   ROLES    AGE     VERSION
k8s-node01   Ready    <none>   2d23h   v1.22.2

 

最后,在Deployment或其他控制器中指定将Pod部署到该节点: 

containers:
  ......
dnsPolicy: ClusterFirst
nodeSelector:
  address: beijing
restartPolicy: Always

删除k8s-node01的address标签

kubectl label node k8s-node01 address-

[root@k8s-master ~]# kubectl get nodes -l address=beijing
No resources found

  

给某个namespace中的pod打标签,这里我定义的namespace是my-first-ns

先查看一下该namespace下的pods

[root@k8s-master ~]# kubectl  get pods  -n my-first-ns
NAME                        READY   STATUS    RESTARTS      AGE
ngx-dep3-6d4cf56db6-bnc49   1/1     Running   1 (43m ago)   23h
ngx-dep3-6d4cf56db6-bv2ml   1/1     Running   1 (43m ago)   23h
ngx-dep3-6d4cf56db6-nn55b   1/1     Running   1 (43m ago)   23h

 

给 ngx-dep3-6d4cf56db6-bnc49 这个pod打一个name=test的标签

[root@k8s-master ~]# kubectl  label pods ngx-dep3-6d4cf56db6-bnc49  name=test  -n my-first-ns   
pod/ngx-dep3-6d4cf56db6-bnc49 labeled

 过滤

[root@k8s-master ~]# kubectl  get pods  -l name=test -n my-first-ns                               
NAME                        READY   STATUS    RESTARTS      AGE
ngx-dep3-6d4cf56db6-bnc49   1/1     Running   1 (44m ago)   23h

 修改标签,和添加一样,只是需要加一个--overwrite参数,现在我把刚才添加的name=test 这个标签改成name=test111

[root@k8s-master ~]# kubectl  label pods ngx-dep3-6d4cf56db6-bnc49  name=test111  -n my-first-ns   --overwrite
pod/ngx-dep3-6d4cf56db6-bnc49 labeled

再次过滤

[root@k8s-master ~]# kubectl  get pods  -l name=test111 -n my-first-ns
NAME                        READY   STATUS    RESTARTS      AGE
ngx-dep3-6d4cf56db6-bnc49   1/1     Running   1 (50m ago)   23h

--show-labels用法

[root@k8s-master ~]# kubectl  get pods -n my-first-ns --show-labels
NAME                        READY   STATUS    RESTARTS      AGE   LABELS
ngx-dep3-6d4cf56db6-bnc49   1/1     Running   1 (51m ago)   23h   app=nginx,name=test111,pod-template-hash=6d4cf56db6
ngx-dep3-6d4cf56db6-bv2ml   1/1     Running   1 (51m ago)   23h   app=nginx,pod-template-hash=6d4cf56db6
ngx-dep3-6d4cf56db6-nn55b   1/1     Running   1 (51m ago)   23h   app=nginx,pod-template-hash=6d4cf56db6

多条件多虑,例如,我再给ngx-dep3-6d4cf56db6-bv2ml 这个pod加一个name=test222的标签,然后我想把name=test111 和 name=test222两个pod都过滤出来,应该怎么做呢?话不多说,直接点

[root@k8s-master ~]# kubectl  get pods -n my-first-ns -l 'name in (test111,test222)'   
NAME                        READY   STATUS    RESTARTS      AGE
ngx-dep3-6d4cf56db6-bnc49   1/1     Running   1 (54m ago)   23h
ngx-dep3-6d4cf56db6-bv2ml   1/1     Running   1 (54m ago)   23h

 取反,如果我想过滤name不等于test111,怎么做呢

[root@k8s-master ~]# kubectl  get pods -n my-first-ns -l  name!=test111
NAME                        READY   STATUS    RESTARTS      AGE
ngx-dep3-6d4cf56db6-bv2ml   1/1     Running   1 (60m ago)   23h
ngx-dep3-6d4cf56db6-nn55b   1/1     Running   1 (60m ago)   23h

 

如果想获取name标签既不为test111,又不为test222的pod,只需要将两个条件用逗号,连接即可

kubectl  get pods -n my-first-ns -l  name!=test111,name!=test222
NAME                        READY   STATUS    RESTARTS      AGE
ngx-dep3-6d4cf56db6-nn55b   1/1     Running   1 (61m ago)   23h

  

在k8s上是如何发布服务的?

 

 

什么是service

Service可以简单的理解为逻辑上的一组Pod(通过selector选择)。一种可以访问Pod的策略,而且其他Pod可以通过这个Service访问到这个Service代理的Pod。相对于Pod而言,它会有一个固定的名称,一旦创建就固定不变。

pod内部是可以通过service名字去访问的。例如当前namespace下有个service,名字叫nginx-svc,提供的端口是888,访问方式如下

这里使用busybox镜像去测试,先启动busybox容器(busybox容器常用的命令比较全)

 

kubectl run busybox --rm=true --image=busybox --restart=Never -it

访问  wget  http://nginx-svc:888

如果是跨namespace的访问,需要加.namespace名字
例如,访问default名称空间下的nginx-svc,应该这样写  wget  http://nginx-svc:8888.default

 

 

定义一个service

这里定义一个名字为nginx-svc的service

[root@k8s-master ~]# cat nginx-svc.yml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  namespace: my-first-ns
spec:
  selector:
    app: nginx # 通过这个selector过滤当前namespace下的pod,也就是要代理的pod
  type: ClusterIP
  sessionAffinity: None
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  ports:
  - name: nginx    #  serviced的端口名称,如果有多个端口,不能重复
    protocol: TCP  #  协议
    port: 888      #  service自己的端口
    targetPort: 80 #  后端pod的端口
  
  - name: http     #  再定义一个端口
    protocol: TCP  
    port: 889
    targetPort: 80

 创建service

kubectl  apply   -f    nginx-svc.yaml

 

查看service下代理的pod

[root@k8s-master ~]# kubectl  get  endpoints   nginx-svc
NAME        ENDPOINTS                                               AGE
nginx-svc   10.244.1.4:80,10.244.2.6:80,10.244.2.7:80 + 3 more...   17h

 

使用service代理k8s外部服务

有些场景下,需要通过某个固定的名称而非IP去访问外部的应用,例如中间件等。

或者希望service指向另一个namespace或者其它集群中的服务

或者某个项目正在迁移至k8s集群,但是部分应用仍然在集群外部

此时可以使用service代理至k8s集群外部的服务

现在,首先定义一个代理外部服务的service,因为代理的是外部的服务,所以不需要匹配内部的pod,其它的和普通的service是一样的

[root@k8s-master ~]# cat nginx-svc-external.yml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-external
  namespace: my-first-ns
spec:
  #selector:
  #  app: nginx # 因为是代理外部服务,所以不需要匹配pod
  type: ClusterIP
  sessionAffinity: None
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  ports:
  - name: nginx    #  serviced的端口名称,如果有多个端口,不能重复
    protocol: TCP  #  协议
    port: 888      #  service自己的端口
    targetPort: 80 #  后端pod的端口
  
  - name: http     #  再定义一个端口
    protocol: TCP  
    port: 889
    targetPort: 80

  

不同的是,之前创建的service会有一个同名的endpoint,但是这个是是一个没有selector的service,就不会自动创建endpoin。那怎么去连接外部呢?只需要自己手动创建一个endpoint即可(和service同名)

现在就来手动创建一个endpoint

首先,导出一个现有的endpoint并生成一个yaml文件

kubectl  get endpoints nginx-svc -o yaml >  nginx-ep-external.yaml

修改一下nginx-ep-external.yaml,最后如下:

[root@k8s-master ~]# cat nginx-ep-external.yaml 
apiVersion: v1
kind: Endpoints
metadata:
  name: nginx-svc-external
  namespace: my-first-ns
  labels:
    app: nginx-svc-external
subsets:
- addresses:
  - ip: 182.61.200.7  # 这里是代理的外部的IP(www.baidu.com的IP)
  ports:
  - name: http
    port: 80
    protocol: TCP

  

创建endpoint

 kubectl  apply -f nginx-ep-external.yaml 

 

查看是否创建成功

[root@k8s-master ~]# kubectl  get  endpoints  nginx-svc-external
NAME                 ENDPOINTS            AGE
nginx-svc-external   182.61.200.7:80     2m14s

可以看到,一个和service同名的endpoint就已经创建好了

测试

使用service的IP测试

 

 修改service

kubectl edit svc nginx-svc-external  # 例如修改 nginx-svc-external 这个service

 

修改完之后,执行

kubectl  replace -f  nginx-svc-external.yaml

 

 

 

使用service反代外部域名

创建一个反代外部域名的service

[root@k8s-master ~]# cat nginx-svc-externalname.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-externalname
  labels:
    app: nginx-svc-externalname
  namespace: my-first-ns
spec:
  type: ExternalName
  externalName: www.baidu.com

然后执行kubectl apply  -f  nginx-svc-externalname.yaml 

  

查看创建的service

 

这种service并没有IP,所以只能通过service名字去访问。但是有个问题,直接访问会报403,因为跨域了,在使用时要注意

 

service常用类型

前面在创建service的时候,我们发现type有的是ClusterIP,有的是ExternalName,那么它们都有什么区别?常用service类型有哪些呢?

ClusterIP: 在集群内部使用,也是默认的类型。可以在pod内部和node上访问,外部不能访问

ExternalName:代理外部域名。通过service名字访问,解析service名称即可解析到对应的ExternalName上。用的不多

NodePort:在所有安装了kube-proxy的节点上打开一个端口,此端口可以代理至后端的Pod,然后集群外部可以通过节点的IP地址和NodePort的端口号访问到集群的Pod的服务。NodePort 端口范围默认是30000~32767

创建一个nodePort类型的service

[root@k8s-master ~]# cat nginx-svc-nodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-nodeport
  namespace: my-first-ns
spec:
  selector:
    app: nginx # 通过这个selector过滤当前namespace下的pod,也就是要代理的pod
  type: NodePort
  sessionAffinity: None
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  ports:
  - name: nginx    #  serviced的端口名称,如果有多个端口,不能重复
    protocol: TCP  #  协议
    port: 888      #  service自己的端口
    targetPort: 80 #  后端pod的端口
    nodePort: 32000 # node的端口,如果不指定,随机生成(32000~32767范围内)

创建后,就可以通过http://nodeIp:32000访问了

 

LoadBalance:使用云服务商的负载均衡器公开服务

 

什么是ingress

通俗来讲,ingress和之前提到的ServiceDeployment一样,也是一个k8s的一种资源类型,ingress用于实现用域名的方式访问k8s内部应用。

ingress 的请求流程大概如下:

 

 

使用helm安装ingress

ingress简单使用

ingress多域名使用

k8s 1.22 + 版本的ingress配置

附加知识点

 

如何进入一个pod呢?

kubectl  exec -it ngx-dep3-6d4cf56db6-bnc49  -- sh
ngx-dep3-6d4cf56db6-bnc49  是pod的ID

  

 

posted @ 2021-09-27 15:34  羊脂玉净瓶  阅读(200)  评论(0)    收藏  举报