k8s-service-ingress

service

  service存在的意义

        1 防止pod失去联系(服务发现)

2 定义一组pod的访问策略(负载均衡)

通过label-selector相关联(标签关联)

通过service实现pod的负载均衡(tcp/UDP/只能支持4层)

service只支持4层负载均衡

4层: OSI中的传输层, TCP/UDP协议 只负责数据包的转发

7层: OSI中的应用层 http fTP  可以拿到这些协议头部信息 可以实现基于协议层面的处理

service的三种常用的类型

  ClusterIP 集群内部使用

      clusterIP 默认分配一个稳定的IP  即VIP 只能在集群内部访问 (同Namespace内的pod)

  NOdePort 对外部暴露应用

      NoPort访问流程

          [  USER > 域名 > node ip+port > iptables/ipvs > pod]


  LoadBalancer 对外暴露应用 适合公有云


  LoadBalancer访问流程

    [user > 域名 > 公有云的slb (自动配置端口) > node:ip:port > pod]

  userspace 自己用户实现的转发

  iptables  阻止ip通信 端口映射 跟踪包状态  数据包的修改

  ipvs      LVS 就是基于ipvs模块做的4层负载均衡器


kube-proxy 

    1:实现数据包的转发

    2:将service相关的规则落地现实

iptables规则:

Nodeport -> KUBE-SVC-RRHDV4CFXHW7RWV3 -> KUBE-SEP-XE5XFBDN7LLHNVMO -> -j DNAT --to-destination 10.244.2.2:80

clusterip -> KUBE-SVC-RRHDV4CFXHW7RWV3 -> KUBE-SEP-XE5XFBDN7LLHNVMO -> -j DNAT --to-destination 10.244.2.2:80

-A KUBE-SVC-RRHDV4CFXHW7RWV3 -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-BGV4R4Y32WAZO4AD

-A KUBE-SVC-RRHDV4CFXHW7RWV3 -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-XE5XFBDN7LLHNVMO

-A KUBE-SVC-RRHDV4CFXHW7RWV3 -j KUBE-SEP-CYUFO3BNAYR2R5O3

上面是转发到3个pod规则。

轮训

ip_vs启动

lsmod|grep ip_vs 查看ip_vs是否启动

modprobe ip_v  启动ipvs

启动模块 ip_vs 

    modprobe ip_vs

modprobe ip_vs_rr

modprobe ip_vs_wrr

modprobe ip_vs_sh

modprobe nf_conntrack_ipv4

在每一个机器上面执行一遍 把这些启动的模块加入到 [etc/rc.local]里面开机启动

通过 kubectl get cm -n kube-system 查看kube-porxy

通过 kubectl edit cm kube-porxy -n kube-system 修改启动ipvs  mode"ipvs"

lvs  虚拟服务器  真实服务器

  TCP  10.96.0.1:443 rr

  -> 192.168.195.110:6443        Masq    1      0          0       

TCP  10.96.0.10:53 rr

  -> 10.244.1.6:53                Masq    1      0          0       

  -> 10.244.1.7:53                Masq    1      0          0       

TCP  10.96.0.10:9153 rr

  -> 10.244.1.6:9153              Masq    1      0          0       

  -> 10.244.1.7:9153              Masq    1      0          0       

UDP  10.96.0.10:53 rr

  -> 10.244.1.6:53                Masq    1      0          0       

  -> 10.244.1.7:53                Masq    1      0       

ipvs 通过 虚拟的vip 流量首先会到ipvs的虚拟服务器 在通过虚拟服务器 转发给真实服务器

通过 yum install ipvsadm -y 安装ipvs的用户端看见当前状态和转发规则

iptables

灵活强大 规则遍历匹配和更新慢 呈线性时延

ipvs

    工作在内核 有更好的性能

调度算法丰富 rr wrr lc wlc ip hash

ipvs 在部署 pod多的时候 客园切换因为调度快规则匹配少

有ipvs以后iptables的规则不要清空因为 ipvs还是需要通过iptables转发流量到ipvs

service DNS

  程序比写死ip更好的方式

    1. dns解析

2. 绑定hosts

coreDNS pod ->  获取server (apiserver 获取) -> 更新到本地

kubelet 运行pod > pod 默认走> coreDNS pod > 

[1. 采用Nodeport 对外暴露应用 前面加一个LB实现统一访问入口]

[2. 优秀使用IPVS 代理模式]

[3. 集群内部采用dns名称访问]、

web.default.svc.cluster.local  名称.命名空间.svc.默认域

ingress

      [nodeporet存在的不足

      一个端口只能一个服务去使用 端口需要提前规划

  只支持4层负载均衡]


pod与ingress的关系

    [通过 service相联

    通过ingress Controll现实pod的负载均衡

支持tcp/udp4层和http7层]

ingress访问流程

    user >  域名 >

node: ip:80/443 > ingress controller > 域名分流 > pod

    ingress

  基于URL路由到多个服务类式nginx的反向代理

[apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

name: url-ingress

annotations:

nginx.ingress.kubernetes.io/rewrite-target: /

spec:

rules:

- host: foobar.ctnrs.com

http:

paths:

- path: /foo

backend:

serviceName: service1

servicePort: 80

- host: foobar.ctnrs.com

http:

paths:

- path: /bar

backend:

serviceName: service2

servicePort: 80]

ingress 基于虚拟机主机

配置两个域名 主机就可以了

  [apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  name: name-virtual-host-ingress

spec:

  rules:

  - host: foo.ctnrs.com

    http:

      paths:

      - backend:

          serviceName: service1

          servicePort: 80

  - host: bar.ctnrs.com

    http:

      paths:

      - backend:

          serviceName: service2

          servicePort: 80]

Annotations对Ingress个性化配置

  +超时时间

[apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  name: example-ingress

  annotations:

    kubernetes.io/ingress.class: "nginx“

    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"

    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"

    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"

    nginx.ingress.kubernetes.io/proxy-body-size: "10m"

spec:

  rules:

  - host: example.ctnrs.com

    http:

      paths:

      - path: /

        backend:

          serviceName: web

          servicePort: 80]

ingress controller pod -> 获取service(apiserver)-> 应用到本地nginx

1、控制器获取service关联的pod应用到nginx

2、nginx 提供七层负载均衡

ingress controller 高可用方案

  1. 使用  Daemonset+nodeselector

          固定ingress到两个nodes上

  访问逻辑

      user > 域名解析到 > vip (keepalived) ha功能 > pod

  2.

          固定ingress到N个nodes上 因并发定

        user > 域名 > LB (nginx  lvs haproxy) >  ingress controller > pod  

360 调度流程

      lvs(定制开发的lvs控制器 对接lvs的api)  >  pod


应用程序管理配置

    secret

    加密数据并存放在ETCD中 让pod容器以挂载volume的方式 去访问

应用场景 凭据

pod使用 secret的两种方式

      变量注入

  挂载


secret的应用场景

    1. ingress  https证书

2. secret 存放docker registry认证信息

3. 存放文件内容或者是字符串

configmap 主要是使用文件传入 和secret的使用场景不一样

[参数

  docker-registry 创建一个给 Docker registry 使用的 secret

  generic        从本地 file, directory 或者 literal value 创建一个 secret

  tls            创建一个 TLS secret

用法

  kubectl create secret [flags] [options]]

---

用户名 密码这些必须通过base64转过 因为这样子比较安全

echo -n 'admin' | base64

---

创建一个secret

apiVersion: v1

kind: Secret

metadata:

  name: mysecret

type: Opaque

data:

  username: YWRtaW4=

  password: MWYyZDFlMmU2N2Rm

----

引入secret变量

[apiVersion: v1

kind: Pod

metadata:

  name: mypod

spec:

  containers:

  - name: nginx

    image: nginx

    env:

      - name: secret_user

        valueFrom:

          secretKeyRef:

            name: mysecret

            key: username

      - name: secret_passwd

        valueFrom:

          secretKeyRef:

            name: mysecret

            key: password]

~                       

-------------------------------------

secret通过挂载的方式

apiVersion: v1

kind: Pod

metadata:

  name: mypod

spec:

  containers:

  - name: nginx

    image: nginx

    volumeMounts:

    - name: foo

      mountPath: "/etc/foo"

      readOnly: true

  volumes:

  - name: foo

    secret:

      secretName: mysecret

~             

----------------------------

应用程序如何动态更新配置

  1. 重新构建pod

  2. 应用程序本身实现监听本地配置文件 如果发生变化触发配置热更新

  3. 使用 sidecal容器是否触发更新 如果发生变化触发 socket http 通知应用程序热更新



  采用配置中心的 例如 nacos apollo

------------------------------

你可能感兴趣的:(k8s-service-ingress)