service
etcd-xx 保持整个服务的数据持久化,所有的信息存储到里面
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
ports:
- containerPort: 80
pod之间可以相互通信
clusterIP
kind: Service
apiVersion: v1
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: nginx
开启kube-proxy的ipvs模式:
在每个节点安装ipvsadm
lsmod 检查模块
刷新识别:
ipvs策略修改完成
控制端删除或创建pod各节点策略会发生变化
删除:
创建:
并不能自动发现
手动更新发现
各pod节点具备sevrice vip
通信原理
从图里看每个宿主机都有一个flannel1的设备,就是VXLAN所需的VTEP设备(就是flannel1“用于VXLAN报文的封装和解封装”),它既有IP地址也有MAC地址。现在我们是container1 访问 container2,当container1发出请求后,这个目的的地址是10.244.1.3的IP包,会先出现在cni0网桥,然后被路由到本机flanner1设备上处理,也就是说,来到了“隧道”的出口。既目的宿主机的VTEP设备(就是flannel1 设备)。
当所有主机启动后,我们可以在server4上可以看到多个flannel1 网卡的路由信息,是因为flanneld启动后创建的。
从上图看到server3的VTEP设备(flannel1)的IP地址,而这些VTEP设备之间通讯就需要想办法组成一个虚拟的二层网络,既:通过二层数据帧进行通信,而Node1上的VTEP设备收到原始报文后,就要想办法把原始报文加一个目的MAC地址,封装成二层数据帧,然后发送给目的VTEP设备。这里需要解决一个问题目的VTEP设备的MAC地址是什么?
根据路由表信息我们知道了目的VTEP设备的IP地址,而根据三层IP地址查询二层MAC地址正是ARP表的功能。而这里用ARP表的记录,也就是flanneld进程在Node2节点启动时,自动添加到Node1上的。
有了这个MAC地址linux内核就可以开始二层封装了,上面提到的MAC地址,对宿主机的二层网络没有任何意义,所以上述封装的数据帧不能在宿主机的二层网络里传输,为了方便概述,我们把上述数据帧称为内部数据帧。所以Linux内核还要把内部数据帧进一步封装成宿主机网络的一个普通数据帧,好让他载着内部数据帧,通过eth0网卡进行传输。这次封装我们称为外部数据帧,为了实现这个搭便车的机制,Linux内核在封装内部数据帧前面,加上特殊的VXLAN头,用来表示这个乘客实际上是VXLAN使用的数据帧。而这个VXLAN头里有一个重要的标志VNI,它是识别某个数据帧是不是应该归属自己处理的标志。而flannel中,VNI的值是1,这也是为什么宿主机的VTEP设备都叫做flannel1的原因。这个时候linux内核会把这数据帧封装一个UDP报文在转发出去。虽然server4的flannel1知道server3的flannel1的MAC地址,但是不知道server3MAC的地址,也就是UDP该发往那台主机,实际上flannel1还要扮演一个网桥的角色,在二层网络进行UDP转发,而在Linux内核里面,网桥设备进行转发的依据来自FDB的转发数据库。这个flannel网桥对应的FDB信息,就是flannel进程维护的,他的内容如下:
NodePort(从外部访问第一种方式)
外部访问:
也可以在清单直接设置:
kind: Service
apiVersion: v1
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: nginx
type: NodePort 类型
通过DNS解析来访问
ip可以经常变,但是DNS解析不会变
DNS的IP
无头服务
通过DNS解析实现
滚动更新依然可以解析
Ip地址变了
直接指定端口
LoadBalancer(从外部访问第二种方式)
由于没有处在共有云环境,虽然myservice有映射端口,但外部负载一直处于pending状态
ExternalName(第三种外部访问方式)
外部有效网站
直接指定IP
ingress服务1
可以实现7层负载
本次ingress=nginx
安装ingress服务:
https://github.com/kubernetes/ingress-nginx/releases
因为本人网络问题,所以先下载所需镜像上传到私有仓库
wget所需要的yaml文件
从私有仓库拉取镜像,所以需要修改yaml文件
[kubeadm@server2 manifest]$ vim mandatory.yaml
[kubeadm@server2 manifest]$ kubectl -n ingress-nginx logs nginx-ingress-controller-c5ff5ddcb-sm6g5
看日志
缺少service
继续下载:
1.单服务ingress
负载均衡
指定主机
在真机对server4做解析
访问域名+端口
两个域名分别访问,将所有命令写在一张清单上:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: mynginx
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: myapp
type: ClusterIP
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-example
spec:
rules:
- host: www2.westos.org
http:
paths:
- path: /
backend:
serviceName: mynginx
servicePort: 80
ip访问回有错误
真机做解析
实现负载均衡:还可以进行拉伸
同一个域名下的不同地址:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: www3.westos.org
http:
paths:
- path: /v1
backend:
serviceName: mynginx
servicePort: 80
- path: /v2
backend:
serviceName: myservice
servicePort: 80
域名解析:
实际上ingress pod就是一个nginx服务,进入到pod里面,可以查看nginx的配置,所有的数据清单里面的配置都会写道这个配置文件中。