飞天使-k8s基础组件分析-服务与ingress

服务的介绍

服务的作用是啥? 
提供外部调用,保证podip的真实性

看看服务解决了什么问题? 
[root@k8s-01 chapter05]# cat web-rs.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

[root@k8s-01 chapter05]# kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-97499b967-jzxwg   1/1     Running   0          35h   10.244.1.2    k8s-02   <none>           <none>
web-dgn64               1/1     Running   0          76s   10.244.1.54   k8s-02   <none>           <none>
web-x4kkz               1/1     Running   0          76s   10.244.1.52   k8s-02   <none>           <none>
web-xx2md               1/1     Running   0          76s   10.244.1.53   k8s-02   <none>           <none>

rs控制数量为3,如果这3个换了呢,这些ip地址如何让客户端知道呢? 


pod 和服务之间的关系,依旧是标签来控制

[root@k8s-01 chapter05]# cat web-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx[root@k8s-01 chapter05]# kubectl apply -f web-svc.yaml 
service/my-service created
[root@k8s-01 chapter05]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        35h
my-service   ClusterIP   10.107.106.26    <none>        80/TCP         5s
nginx        NodePort    10.104.210.165   <none>        80:30001/TCP   35h

上面是创建了服务,服务创建之后,有一个ip
查看集群分配给服务的Ip
# kubectl get svc

#访问刚才创建的服务三种方式
创建一个Pod,访问服务的Ip
在k8s的任何一个节点访问
使用任何一个现有服务所属任何pod访问
下面图片有它的处理过程

查看服务和后面pod的ip地址信息
[root@k8s-01 chapter05]# kubectl describe svc my-service
Name:              my-service
Namespace:         default
Labels:            <none>
Annotations:       Selector:  app=nginx
Type:              ClusterIP
IP:                10.107.106.26
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.2:80,10.244.1.52:80,10.244.1.53:80 + 1 more...
Session Affinity:  None
Events:            <none>

#此处如果删除一个pod,查看service中的podip 也会随着变化


实验一: 配置 sessionAffinity: ClientIP
[root@k8s-01 chapter05]# cat web-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  sessionAffinity: ClientIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
    

[root@k8s-01 chapter05]# kubectl delete svc/my-service
service "my-service" deleted
[root@k8s-01 chapter05]# kubectl apply -f web-svc.yaml 
service/my-service created
[root@k8s-01 chapter05]# kubectl describe svc my-service
Name:              my-service
Namespace:         default
Labels:            <none>
Annotations:       Selector:  app=nginx
Type:              ClusterIP
IP:                10.104.130.27
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.2:80,10.244.1.52:80,10.244.1.53:80 + 1 more...
Session Affinity:  ClientIP
Events:            <none>

实验二:设置自定义的服务ip
[root@k8s-01 chapter05]# vim web-svc.yaml 
[root@k8s-01 chapter05]# kubectl apply -f web-svc.yaml 
service/my-service created
[root@k8s-01 chapter05]# kubectl describe svc web-service
Error from server (NotFound): services "web-service" not found
[root@k8s-01 chapter05]# cat web-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  clusterIP: 10.104.130.24
  sessionAffinity: ClientIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
[root@k8s-01 chapter05]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
nginx-97499b967-jzxwg   1/1     Running   0          35h
web-tsxck               1/1     Running   0          34m
web-x4kkz               1/1     Running   0          50m
web-xx2md               1/1     Running   0          50m
[root@k8s-01 chapter05]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        36h
my-service   ClusterIP   10.104.130.24    <none>        80/TCP         33s
nginx        NodePort    10.104.210.165   <none>        80:30001/TCP   35h




实验三: 创建没有选择器的服务
服务通常抽象访问Kubernetes pods,但是它也可以抽象访问其它类型的后端,比如:
比如使用外部的数据库集群
指向服务到不同的命名空间或其它kubernetes集群的服务

在上面任何一种情况下,都可以定义一个没有Pod选择器的服务,比如:
由于上面定义的服务没有选择器,对应的Endpoint对象也不会自动创建,因此需要手工的创建Endpoint.

kind: Endpoints



在这里插入图片描述

服务代理

Userspace
Iptables
Ipvs
以上三种模式,ipvs用的多

在这里插入图片描述

服务发现

查看某个pod的 环境变量
kubectl exec web-tsxck env

生产环境中要先创建服务在创建pod,否则pod里面的环境变量没有服务的变量


服务发现通过两种方式,1.环境变量 2. DNS

DNS的服务方式
一个完整的FQDN如下所示:
Backend-database.default.svc.cluster.local

进入到容器里面, 
kubectl exec -it web-sfe1d -- bash
curl http://my-service
curl http://my-service.default.svc.cluster.local
cat /etc/resolv.conf

连接集群外服务

一般是数据库,云数据库信息

查看服务的endpoints

[root@k8s-01 chapter05]# kubectl get endpoints
NAME         ENDPOINTS                                                 AGE
kubernetes   192.168.100.30:6443                                       37h
my-service   10.244.1.2:80,10.244.1.52:80,10.244.1.53:80 + 1 more...   80m
nginx        10.244.1.2:80,10.244.1.52:80,10.244.1.53:80 + 1 more...   37h

查看apiversion版本

[root@k8s-01 chapter05]# kubectl explain endpoints.apiVersion
KIND:     Endpoints
VERSION:  v1

FIELD:    apiVersion <string>

DESCRIPTION:
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources


[root@k8s-01 chapter05]# cat external-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  ports:
  - port: 80[root@k8s-01 chapter05]# cat external-endpoints.yaml 
apiVersion: v1
kind: Endpoints
metadata:
  name: external-service
subsets:
  - addresses:
    - ip: 192.168.100.31
    ports:
    - port: 30001
[root@k8s-01 chapter05]# cat external-endpoints-alias.yaml 
apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  type: ExternalName
  externalName: feitianshi.cc.cc
  ports:
  - port: 30001
 
 注意:此部分实验未成功,各位可以自己参考配置文件



[root@k8s-01 chapter05]# kubectl describe svc external-service
Name:              external-service
Namespace:         default
Labels:            <none>
Annotations:       Selector:  <none>
Type:              ClusterIP
IP:                10.105.6.128
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         192.168.100.31:30001
Session Affinity:  None
Events:            <none>



服务发布

发布服务的类型如下
ClusterIP 内部访问
NodePort 外部访问
LoadBalancer 外部访问
ExternalName 内部访问

案例
NodePort:
创建服务
kubectl create –f web-svc-nodeport.yaml

检查NodePort服务
kubectl get svc web-nodeport


[root@k8s-01 chapter05]# cat web-svc-nodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30123
  selector:
    app: nginx[root@k8s-01 chapter05]# kubectl create -f web-svc-nodeport.yaml 
service/web-nodeport created
[root@k8s-01 chapter05]# kubectl get svc web-nodeport
NAME           TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
web-nodeport   NodePort   10.105.18.188   <none>        80:30123/TCP   8s
[root@k8s-01 chapter05]# curl 10.105.18.188
<!DOCTYPE html>



[root@k8s-01 chapter05]# cat web-svc-loadbalancer.yaml 
apiVersion: v1
kind: Service
metadata:
  name: web-loadbalancer
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx


[root@k8s-01 chapter05]# cat service-external-ip.yaml 
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
  externalIPs:
    - 192.168.100.199

在这里插入图片描述

无头服务

无头服务:没有clusterIp字段的服务就是无头服务。
有些服务需要直接连接后端的pod 

案例:
- 创建无头服务
# kubectl create –f web-headless.yaml


[root@k8s-01 chapter05]# cat web-headless.yaml 
apiVersion: v1
kind: Service
metadata:
  name: web-headless
spec:
  clusterIP: None
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx


- 查看创建的服务
# kubectl get svc
# kubectl describe svc web-headless

通过dns发现pods
# kubectl run dnsutils --image=tutum/dnsutils --generator=run-pod/v1 --command -- sleep infinity
# kubectl exec dnsutils nslookup web-headless

[root@k8s-01 chapter05]# kubectl exec dnsutils nslookup web-headless
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   web-headless.default.svc.cluster.local
Address: 10.244.1.61
Name:   web-headless.default.svc.cluster.local
Address: 10.244.1.60
Name:   web-headless.default.svc.cluster.local
Address: 10.244.1.2
Name:   web-headless.default.svc.cluster.local
Address: 10.244.1.59

[root@k8s-01 chapter05]# kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP        40h
my-service     ClusterIP   10.104.130.24    <none>        80/TCP         2s
nginx          NodePort    10.104.210.165   <none>        80:30001/TCP   39h
web-headless   ClusterIP   None             <none>        80/TCP         8m50s
[root@k8s-01 chapter05]# kubectl exec dnsutils nslookup my-service
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   my-service.default.svc.cluster.local
Address: 10.104.130.24

无头服务比有头服务更快些,注意区分

服务,pod和dns的关系

什么东西可以获取DNS的名称?
集群中定义的每个服务都会被分配一个DNS名称。默认情况下,客户机pod的dns搜索列表包括Pod自己的名称空间和集群的默认域。

假设k8s集群bar的名称空间中有一个名为foo的服务,在该名称空间运行的pod可以直接对foo执行dns查询来查找此服务。在别的名称空间中执行foo.bar进行查询。

服务
A记录
普通服务分配一个DNS A记录作为表单的名称my-svc.my-namespace.svc.cluster-domain.example,这将解析到服务的集群IP。
无头服务也分配一个DNS记录,针对my-svg.my-namespace.svg.cluster-domain.example表单的名称。与普通服务不同,这将解析为服务选择的pod的ip集。

SRV记录
SRV记录是作为普通服务或无头服务一部分的指定端口创建的。每于每个指定端口,SRV记录都有相应的形式_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example。

对于无头服务,这解析为多个答案,每个答案对应一个支持的pod,并包含pod的端口号和域名。
Auto-generated-name.my-svcc.my-namespace.svc.cluster-domain.example

Pods
pods的主机名和子域名字段
比如在名称空间my-namespace中将主机名设置为“foo”,子域设置为“bar”的pod将具有完全限定的域为:foo.bar.my-namespace.svc.cluster-domain.example


Pods dns策略有以下4种:
Default
ClusterFirst
ClusterFirstWithHostNet
None

Pod dns配置
属性有以下三个:
Nameservers
Searchs
options

端口转发

对于排错比较方便
创建redis的部署和应用
创建deployment资源
# kubectl create –f redis-master-deployment.yaml

查看部署状态
# kubectl get pods

查看replicaset状态
# kubectl get rs

创建服务
# kubectl create –f redis-master-service.yaml

查看服务
# kubectl get svc | grep redis

校验运行在pod中的redis server是否侦听在6379端口
# kubectl get pods redis-master-7db7f6579f-zd27q –template=‘{
   
   {(index(index.spec.containers 0).ports 0).containerPort}}{
   
   {“\n”}}’

执行端口转发
# kubectl port-forward redis-master-7db7f6579f-zd27q 7000:6379

客户端进行测试
# redis-cli –p 7000


[root@k8s-01 chapter05]# cat redis-master-deployment.yaml 
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: redis-master
  labels:
    app: redis
spec:
  selector:
    matchLabels:
      app: redis
      role: master
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
        tier: backend
    spec:
      containers:
      - name: master
        image: redis  # or just image: redis
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379


[root@k8s-01 chapter05]# cat redis-master-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    app: redis
    role: master
    tier: backend
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
    role: master
    tier: backend

通过expose 暴露应用

创建资源
# kubectl create –f hello-application.yaml

查看关于部署的信息
# kubectl get deployment hello-world
# kubectl describe deployments hello-world
# kubectl get replicasets
# kubectl describe replicasets

暴露刚才的部署
# kubectl expose deployment hello-world --type=NodePort --name=example-service

显示关于服务的信息
# kubectl describe services example-service

列出在Hello World应用运行的Pods
# kubectl get pods –selector=“run=load-balancer-example” --output=wide

使用下面的方法进行测试
# curl http://<public-node-ip>:<node-port>



[root@k8s-01 chapter05]# cat hello-application.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      run: load-balancer-example
  replicas: 2
  template:
    metadata:
      labels:
        run: load-balancer-example
    spec:
      containers:
        - name: hello-world
          image: "mike0405/node-hello:1.0"
          ports:
            - containerPort: 8080
              protocol: TCP


[root@k8s-01 chapter05]# cat hello-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: hello
spec:
  selector:
    app: hello
    tier: backend
  ports:
  - protocol: TCP
    port: 80
    targetPort: http

服务案例


 创建后端的部署
# kubectl create –f hello.yaml

创建后端的服务
# kubectl create –f hello-service.yaml

创建前端的部署和服务
# kubectl create –f fronted.yaml

测试前端和后端的交互
# curl http://${EXTERNAL_IP}



[root@k8s-01 chapter05]# curl 192.168.100.31:32746
{"message":"Hello"}
[root@k8s-01 chapter05]# curl 192.168.100.31:32746
{"message":"Hello"}
[root@k8s-01 chapter05]# cat frontend.yaml 
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  selector:
    app: hello
    tier: frontend
  ports:
  - protocol: "TCP"
    port: 80
    targetPort: 80
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  selector:
    matchLabels:
      app: hello
      tier: frontend
      track: stable
  replicas: 1
  template:
    metadata:
      labels:
        app: hello
        tier: frontend
        track: stable
    spec:
      containers:
      - name: nginx
        image: "mike0405/hello-frontend:1.0"
        lifecycle:
          preStop:
            exec:
              command: ["/usr/sbin/nginx","-s","quit"][root@k8s-01 chapter05]# 
[root@k8s-01 chapter05]# cat hello.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
spec:
  selector:
    matchLabels:
      app: hello
      tier: backend
      track: stable
  replicas: 7
  template:
    metadata:
      labels:
        app: hello
        tier: backend
        track: stable
    spec:
      containers:
        - name: hello
          image: "mike0405/hello-go-gke:1.0"
          ports:
            - name: http
              containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: hello
spec:
  selector:
    app: hello
    tier: backend
  ports:
  - protocol: "TCP"
    port: 80
    targetPort: 80


[root@k8s-01 chapter05]# kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
dnsutils                        1/1     Running   0          129m
frontend-76c7d58dc5-l5kcz       1/1     Running   0          5m30s
hello-84ccf7cd9d-97htk          1/1     Running   0          7m2s
hello-84ccf7cd9d-9sl6v          1/1     Running   0          7m2s
hello-84ccf7cd9d-9tg8f          1/1     Running   0          7m2s
hello-84ccf7cd9d-bps5g          1/1     Running   0          7m2s
hello-84ccf7cd9d-lh446          1/1     Running   0          7m2s
hello-84ccf7cd9d-tl2gx          1/1     Running   0          7m2s
hello-84ccf7cd9d-w2hjz          1/1     Running   0          7m2s
hello-world-7457d6ddb5-g2fcf    1/1     Running   0          37m
hello-world-7457d6ddb5-mknkq    1/1     Running   0          37m
nginx-97499b967-jzxwg           1/1     Running   0          42h
redis-master-7d557b94bb-8wqjh   1/1     Running   0          60m
web-764vs                       1/1     Running   0          4h8m
web-kd8ml                       1/1     Running   0          4h8m
web-rqc7q                       1/1     Running   0          4h8m




INGRESS

为什么需要INGRESS ? 
一个重要原因,每个LoadBalancer服务都需要自己负载均衡器和自己的公共IP地址,而一个Ingress只需要一个,即使提供对数个服务的访问时也是如此。对象发送HTTP请求时请求中的主机和路径决定请求转发给哪个服务。

internet - ingress - service

ingress 可以理解成nginx配置文件

MetalLB使用

这个了解下,根据实际情况看

参考文档

https://edu.csdn.net/course/detail/27762?spm=1003.2449.3001.8295.2

猜你喜欢

转载自blog.csdn.net/startfefesfe/article/details/132431663