ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

service暴露端口的方式和代理方式

2021-12-27 13:04:59  阅读:121  来源: 互联网

标签:service 方式 端口 nginx master deployment apache root


service暴露端口的方式和代理方式

service 概念

SVC 通过 Label Selector 标签选择的方式,匹配一组 Pod,对外访问服务。每一个 SVC可以理解成为一个微服务。

service 能够提供负载均衡的能力,但是在使用上有以下限制:

只提供4层负载均衡能力(只有 RR 轮询算法),而没有7层功能,如果需要更多的匹配规则来转发请求,4层上的负载均衡是不支持的。

service 类型

Clusterip:默认类型,自动分配一个仅 Cluster 内部可以访问的 虚拟IP,一般用作集群内部负载均衡。

NodePort(service向外暴露):在ClusterIP 基础上为 Service 在每台机器上绑定一个映射端口,外网客户端可以通过 NodeIP,Nodeport访问。

LoadBalancer(service向外暴露):在 NodePort 基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到 NodeIP 和 NodePort

ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,只有1.7之后版本的 kube-dns支持。

SVC 访问流程组件

首先 apiserver 监听 kube-proxy 去进行服务和端口的发现。

通过kube-proxy监控,kube-proxy监控所有 Pod 节点信息,标签、IP、port 等,并负责把它们写入到 iptables 规则当中。

client 访问 SVC,其实访问的是 iptables规则。再由 iptables 导向后端 Pod 节点。

ipvs,图片上没有,现在的ClusterIP,NodePort 都是采取 ipvs 调度算法对后端 Pod 节点进行调度访问。

ipvs 代理模式

ipvs (IP Virtual Server) 实现了传输层负载均衡,也就是我们常说的4层LAN交换,作为 Linux 内核的一部分。ipvs运行在主机上,在真实服务器集群前充当负载均衡器。ipvs可以将基于TCP和UDP的服务请求转发到真实服务器上,并使真实服务器的服务在单个 IP 地址上显示为虚拟服务。

ipvs 对比 iptables 我们知道kube-proxy支持 iptables 和 ipvs 两种模式, 在kubernetes v1.8 中引入了 ipvs 模式,在 v1.9 中处于 beta 阶段,在 v1.11 中已经正式可用了。iptables 模式在 v1.1 中就添加支持了,从 v1.2 版本开始 iptables 就是 kube-proxy 默认的操作模式,ipvs 和 iptables 都是基于netfilter的,那么 ipvs 模式和 iptables 模式之间有哪些差异呢?

  • ipvs 为大型集群提供了更好的可扩展性和性能
  • ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权等等)
  • ipvs 支持服务器健康检查和连接重试等功能

ipvs为负载均衡提供算法:

  • rr:轮询带哦都
  • lc:最小连接数
  • dh:目标地址哈希
  • sh:源地址哈希
  • sed:最短期望延迟
  • nq:不排队调度

client Pod 访问 Server Pod

  • 首先,service IP 的 iptables代理变成了 ipvs 模块,实现负载均衡和流量导向。
  • client 访问到 IPvs 服务,将流量分发到不同的 Pod 上运行。

kubernetes暴露端口的方式

集群内部实现访问:Clusterip

Clusterip是集群内部的私有ip,在集群内部访问服务非常方便,也是kuberentes集群默认的方式,直接通过service的Clusterip访问,也可以直接通过ServiceName访问。集群外部则是无法访问的。

默认类型,自动分配一个仅Cluster内部能够访问的虚拟IP

[root@master ~]# cat cluster.yml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apache
  template: 
    metadata:
      labels:
        app: apache 
    spec:
      containers:
      - image: bravealove1/apache:v1.0 
        imagePullPolicy: IfNotPresent
        name: apache

---
apiVersion: v1
kind: Service
metadata:
  name: apache
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: apache
  type: ClusterIP  #指定网络模式

[root@master ~]# kubectl  apply -f cluster.yml 
deployment.apps/apache created
service/apache created


[root@master ~]# kubectl  get pods,svc
NAME                          READY   STATUS    RESTARTS   AGE
pod/apache-599bc546b8-xp5rg   1/1     Running   0          12s

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/apache       ClusterIP   10.98.249.13   <none>        80/TCP    12s
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   4d12h


[root@master ~]# curl 10.98.249.13
hello,this is a test page 1 

集群外部方式访问:NodePort

NodePort在kubenretes里是一个早期广泛应用的服务暴露方式。Kubernetes中的service默认情况下都是使用的ClusterIP这种类型,这样的service会产生一个ClusterIP,这个IP只能在集群内部访问,要想让外部能够直接访问service,需要将service type修改为 nodePort。将service监听端口映射到node节点。

nodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由 kube-proxy进一步到给对应的pod

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apache
  template: 
    metadata:
      labels:
        app: apache 
    spec:
      containers:
      - image: aimmi/apache:v1.0 
        imagePullPolicy: IfNotPresent
        name: apache

---
apiVersion: v1
kind: Service
metadata:
  name: apache
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30000   指定对外端口
  selector:
    app: apache
  type: NodePort   #指定网络模式


[root@master ~]# kubectl  apply -f nodeport.yml 
deployment.apps/apache created
service/apache created
[root@master ~]# kubectl get pods,svc
NAME                          READY   STATUS    RESTARTS   AGE
pod/apache-599bc546b8-w6xnd   1/1     Running   0          10s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/apache       NodePort    10.96.90.92   <none>        80:30000/TCP   10s
service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        4d12h
[root@master ~]# curl 192.168.145.188:30000
hello,this is a test page 1 

DNS解析

Service

  • 创建普通service 会以my-svc.my-namespace.svc.cluster.local 的形式指派一个 DNS A 记录,并解析到该service的Cluster IP。
  • 创建“Headless” Service(没有Cluster IP)也会以 my-svc.my-namespace.svc.cluster.local 的形式被指派一个 DNS A 记录,但是并不会解析到的Cluster IP,而是解析到一组被选中的- - pod 的IP,如果没有backend则不做处理。

Pod

  • 创建Pod 会以 pod-ip-address.my-namespace.pod.cluster.local 这种形式被指派一个 DNS A 记录。

案例

[root@master ~]# cat deploy.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
   matchLabels:
     app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80


参数--record可以记录当前版本的Deployment都执行过哪些命令
[root@master ~]# kubectl create -f deploy.yml  --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx-deployment created


创建完成后立即执行get命令查看这个Deployment
[root@master ~]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           2m14s
[root@master ~]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-74d589986c-kxcvx   1/1     Running   0          2m11s
nginx-deployment-74d589986c-s277p   1/1     Running   0          2m11s
nginx-deployment-74d589986c-zlf8v   1/1     Running   0          2m11s

使用 nginx:1.9.1 的镜像来代替原来的 nginx的镜像
[root@master ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment.apps/nginx-deployment image updated

查看更新进度
[root@master ~]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out

查看镜像信息
[root@master ~]# kubectl describe deployment/nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Fri, 24 Dec 2021 22:24:10 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 4
                        kubernetes.io/change-cause: kubectl create --filename=deploy.yml --record=true
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 4 total | 3 available | 1 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx:1.9.1
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>


使用rollout history命令查看Deployment的版本(revision)
[root@master ~]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment 
REVISION  CHANGE-CAUSE
1         kubectl create --filename=deploy.yml --record=true
2         kubectl create --filename=deploy.yml --record=true

使用rollout undo命令回滚到前一个revision
[root@master ~]# kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back


查看镜像信息
[root@master ~]# kubectl describe deployment/nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Fri, 24 Dec 2021 22:24:10 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 3
                        kubernetes.io/change-cause: kubectl create --filename=deploy.yml --record=true
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>

给一个应用扩容副本数为3
[root@master ~]# kubectl  apply -f cluster.yml 
deployment.apps/apache created

[root@master ~]# kubectl  get pods
NAME                          READY   STATUS    RESTARTS   AGE
pod/apache-599bc546b8-6tctl   1/1     Running   0          28s


[root@master ~]# kubectl scale  deployment apache --replicas 4
deployment.apps/apache scaled
[root@master ~]# kubectl  get pods
NAME                          READY   STATUS              RESTARTS   AGE
pod/apache-599bc546b8-6gx4p   0/1     ContainerCreating   0          2s
pod/apache-599bc546b8-6tctl   1/1     Running             0          2m3s
pod/apache-599bc546b8-8qzr4   0/1     ContainerCreating   0          2s
pod/apache-599bc546b8-j48v5   0/1     ContainerCreating   0          2s

创建一个pod,其中运行着nginx、redis、memcached 3个容器
[root@master ~]# vim pod.yml 
---
apiVersion: v1
kind: Pod
metadata:
  name: hellok8s
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: mynginx
    image: nginx 
    ports:
    - containerPort: 80
  - name: myredis
    image: redis
    ports:
    - containerPort: 6379
  - name: memcached
    image: memcached 

[root@master ~]# kubectl apply -f pod.yml 
pod/hellok8s created


[root@master ~]# kubectl  get pods
NAME       READY   STATUS    RESTARTS   AGE
hellok8s   3/3     Running   0          2m49s

给一个pod创建service,并可以通过ClusterlP/NodePort访问
[root@master ~]# vi nodeport.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apache
  template: 
    metadata:
      labels:
        app: apache 
    spec:
      containers:
      - image: bravealove1/apache:v1.0 
        imagePullPolicy: IfNotPresent
        name: apache

---
apiVersion: v1
kind: Service
metadata:
  name: apache
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30000   指定对外端口
  selector:
    app: apache
  type: NodePort   指定网络模式


[root@master ~]# kubectl  apply -f nodeport.yml 
deployment.apps/apache created
service/apache created
[root@master ~]# kubectl get pods,svc
NAME                          READY   STATUS    RESTARTS   AGE
pod/apache-599bc546b8-w6xnd   1/1     Running   0          10s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/apache       NodePort    10.96.90.92   <none>        80:30000/TCP   10s
service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        4d12h
[root@master ~]# curl 192.168.145.188:30000
hello,this is a test page 1 

创建deployment和service,使用busybox容器nslookup解析service
[root@master ~]# cat host.yml 
---
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: myapp-deploy 
  namespace: default 
spec: 
  replicas: 1
  selector: 
    matchLabels: 
      app: myapp 
  template:
    metadata: 
      labels: 
        app: myapp 
    spec: 
      containers: 
      - name: myapp
        image: httpd
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata: 
  name: myapp-externalname
  namespace: default
spec: 
  type: ExternalName 
  externalName: web.test.example.com


部署
[root@master ~]# kubectl apply -f host.yml 
deployment.apps/myapp-deploy created
service/apache created
[root@master ~]# kubectl  get pods
NAME                           READY   STATUS    RESTARTS   AGE
myapp-deploy-55bd85c8b-9jgf2   1/1     Running   0          107s

查看pods,service状态
[root@master ~]# kubectl  get pods,svc
NAME                               READY   STATUS    RESTARTS   AGE
pod/myapp-deploy-55bd85c8b-9jgf2   1/1     Running   0          18m

NAME                         TYPE           CLUSTER-IP   EXTERNAL-IP            PORT(S)   AGE
service/kubernetes           ClusterIP      10.96.0.1    <none>                 443/TCP   4d14h
service/myapp-externalname   ExternalName   <none>       web.test.example.com   <none>    3m35s


[root@master ~]# vibusybox.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: busybox-pod
  name: test-busybox
spec:
  containers:
  - command:
    - sleep
    - "3600"
    image: busybox
    imagePullPolicy: Always
    name: test-busybox

部署
[root@master ~]# kubectl apply -f busybox.yaml 
pod/test-busybox created

查看pod状态
[root@master ~]# kubectl  get pods,svc
NAME                               READY   STATUS    RESTARTS   AGE
pod/myapp-deploy-55bd85c8b-9jgf2   1/1     Running   0          19m
pod/test-busybox                   1/1     Running   0          8m15s

NAME                         TYPE           CLUSTER-IP   EXTERNAL-IP            PORT(S)   AGE
service/kubernetes           ClusterIP      10.96.0.1    <none>                 443/TCP   4d14h
service/myapp-externalname   ExternalName   <none>       web.test.example.com   <none>    4m49s

使用exec -it 与busybox进行交互
[root@master ~]# kubectl exec -it test-busybox /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup myapp-externalname.default.svc.cluster.local
Server:         10.96.0.10
Address:        10.96.0.10:53

myapp-externalname.default.svc.cluster.local    canonical name = web.test.example.com

标签:service,方式,端口,nginx,master,deployment,apache,root
来源: https://www.cnblogs.com/Aimmi/p/15735828.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有