6-kubernetes网络
1、service存在的意义
- 防止破的失联(服务发现)
- 定义一组pod的访问策略(提供负载均衡)
2、pod与service的关系
- 通过label-selector相关联
- 通过service实现pod的负载均衡(TCP/UDP 4层)
负载均衡器类型
- 四层 传输层,基于IP和端口
- 七层 应用层,基于应用协议转发,例如http协议
3、service三种常用类型
- Cluster:集群内部使用
- Nodeport:对外暴露应用
- Loadbalancer:对外暴露应用,适合公有云(腾讯云、阿里云、亚马逊等)
clusterIP:
默认分配一个稳定的IP地址,即VIP只能在集群内部访问(amespace内部pod)
nodeport:
在每个节点上启用一个端口来暴露服务,可以在集群外部访问,也会分配一个稳定内部集群IP地址。访问地址<nodeIP:nodeport
cluster端口 镜像中使用的端口
生成service的yaml
kubectl expose deploy web --port=80 --target-port=8080 --type=NodePort -o yaml --dry-run=client >service.yaml
cat service.yaml
apiVersion: v1 kind: Service metadata: labels: app: web name: web spec: ports: - port: 80 #clusterIP对应端口 protocol: TCP targetPort: 8080 #容器里面应用的端口 nodePort: 30012 #nodeport使用的节点端口 (配置的固定端口) selector: app: web type: NodePort
loadBalancer(只适合用云平台)
与nodeport类似,在每个节点上启用一个端口来暴露服务,除此之外,kubernetes会请求低层云平台删固定负载均衡器,将每个node(nodeIP):[nodePort]作为后端添加上
用户 -->域名 -->负载均衡器(公网IP) -->nodePoer(所有节点) -->pod
每个部署一个应用,都需要手工在负载衡器上配置,比较麻烦
4、service代理模式
service使用iptables或者ipvs进行转发的
kubeadm 方式修改ipvs模式
kubectl edit configmap kube-proxy -n kube-system ... 43 mode: "ipvs" ... kubectl delete pod kube-proxy-btz4p -n kube-system # 删除pod,会自动拉起 kubectl logs kube-proxy-wwqbh -n kube-system # 查看是否启用ipvs
注:
1、 kube-proxy配置文件以configmap方式存储
2、 如果让所有节点生效,需要重建所有节点kube-proxy pod
二进制修改ipvs模式:
vi kube-proxy-config.yml mode: ipvs scheduler: "rr" systemctl restart kube-proxy 注:参考不同资料,文件名可能不同
安装ipvsadm工具进行查看ipvs
yum install -y ipvsadm
lsmod |grep ip_vs #检测是否加载 modprobe ip_vs 或者更新一下内核 yum update -y
查看规则
[root@node-1 ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.17.0.1:32487 rr -> 10.244.84.176:80 Masq 1 0 0 TCP 192.168.10.111:30001 rr -> 10.244.247.3:8443 Masq 1 0 0 。。。
流程包流程:客户端-->clusterIP(iptables/ipvs负载均衡规则) -->分布在各个节点pod
查看负载均衡规则:
iptables 模式
iptables-save |grep <service-name>
ipvs模式
ipvsadm -L -n
iptables vs ipvs
iptables
灵活。功能强大 规则遍历匹配和更新,呈线性时延时
ipvs
工作在内核态,有更好的性能 调度算法丰富,rr、wrr、lc、wlc、ip hash
5、service DNS名称
DNS服务监视kubernetes API,为每一个service创建DNS记录用于域名解析
clusterIP A记录格式:<service-name>.<namespace-name>.svc,cluster.local
示例:my-svc.my-namespace.svc.cluster.local
小结:
1、 采用NodePort对外暴露应用,前面加一个LB实现统一访问入口 2、 优先使用IPVS代理模式 3、 集群内应用采用DNS名称访问
6、Ingress为弥补NodePort不足而生
NodePort存在的不足:
1、一个端口只能一个服务使用,端口需要提前规划
2、只支持4层负载均衡
7、Pod与ingress的关系
1、通过service相关联
2、通过ingress Controller实现pod的负载均衡
-支持TCP/UDP 4层和HTTP7层
8、Ingress Controller部署
1、 部署Ingress Controller
2、 创建ingress规则
ingress controller有很多方式实现,这里采用官方维护的nginx控制器
github代码托管地址:https://github.com/kunernetes/ingress-nginx
部署:kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
注意事项:
1、镜像地址改成国内的:lizhenliang/nginx-ingress-controller:0.30.0
2、建议直接宿主机网络暴露: hostNetwork: true
修改yaml文件
vim mandatory.yaml
216 nodeSelector: 217 kubernetes.io/os: linux 218 hostNetwork: true #将pod使用宿主机网络命名空间 219 containers: 220 - name: nginx-ingress-controller 221 image: lizhenliang/nginx-ingress-controller:0.30.0 #更改为国内下载地址
其他主流控制器
1、Traefik:HTTP反向代理、负载均衡工具
2、lstio:服务治理、控制入口流量
生效配置文件
kubectl apply -f mandatroy.yaml kubectl get pods -n ingress-nginx -o wide
创建服务发现
kubectl create deploy java-demo --image=lizhenliang/java-demo #创建pod kubectl expose deploy java-demo --port=80 --target-port=8080 #创建service [root@k8s-master ~]# kubectl get pods | grep java-demo java-demo-6bf9445595-z5f2s 1/1 Running 0 2m3s [root@k8s-master ~]# kubectl get ep | grep java-demo java-demo 10.244.84.182:8080 115s [root@k8s-master ~]# kubectl scale deploy java-demo --replicas=2 # 扩容副本 [root@k8s-master ~]# kubectl get pods -o wide|grep java java-demo-6bf9445595-6nmch 1/1 Running 0 103s 10.244.247.25 node-2 <none> <none> java-demo-6bf9445595-z5f2s 1/1 Running 0 61m 10.244.84.182 node-1 <none> <none> [root@k8s-master ~]#
kubectl get ep #查询是否被关联到一个负载均衡器里面
创建ingress规则(基于http的方式)
cat ingress.yaml
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: name-virtual-host-ingress spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: java-demo servicePort: 80
生效配置文件
[root@k8s-master ~]# kubectl apply -f ingress.yaml [root@k8s-master ~]# kubectl get ing NAME CLASS HOSTS ADDRESS PORTS AGE name-virtual-host-ingress <none> foo.bar.com 80 10s [root@k8s-master ~]#
ingress规则相当于在nginx里创建了一个基于域名虚拟主机。
upstream web { server pod1; server pod2; server pod3; } server { listen 80; server_name foo.bar.com; location / { cert key proxy_pass http://web; } }
用户--> 域名-->负载均衡器(公网IP) --> ingress controller(nginx实现负载均衡)-->pod
创建ingress规则(基于https的方式)
https方式通过证书方式进行实现,证书分自签证书和CA证书机构
这里使用自签证书方式进行实现https加密传输
部署生成证书的工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64 mv cfssl_linux-amd64 /usr/local/bin/cfssl mv cfssljson_linux-amd64 /usr/local/bin/cfssljson mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
脚本方式进行生成和办法证书
[root@k8s-master ~]# unzip ingress-https.zip [root@k8s-master ~]# cd ingress/ [root@k8s-master ingress]# ls certs.sh cfssl.sh ingress-controller.yaml ingress.yaml [root@k8s-master ingress]#
修改ceats.sh里面的域名,改成要使用的域名,然后生成证书
cd ingress/ && bash certs.sh #执行过程会将证书保存到secret中调用
#查看保存的证书
kubectl get secret
配置https证书访问
cat ingress-https.yaml
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: tls-example-ingress spec: tls: - hosts: - foo.bar.com # 以上四行就是加https证书位置 secretName: foo.bar.com #对应保存证书的名称 rules: - host: foo.bar.com http: paths: - path: / backend: serviceName: java-demo servicePort: 80
# 删除http规则,不删除可能会对https有影响
kubectl delete -f ingress.yaml
# 生效https规则
kubectl apply -f ingress-https.yaml kubectl get ing
如果需要每个节点需要使用,可以使用daemonset方式部署,有污点也需要的部署就要容忍污点进行部署