一.MetalLB
通过MetalLB来实现适用于公有云上的 Kubernetes 服务LoadBalancer,MetalLB是用于裸机的负载均衡器实现 Kubernetes 群集,使用标准路由协议,注意网络插件兼容性,本次使用的是Flannel
# 1.准备环境
kubectl edit configmap -n kube-system kube-proxy #在IPVS模式下使用kube-proxy,编辑kube-proxy配置,启用ARP模式
kubectl get pod -n kube-system |grep kube-proxy| awk '{system("kubectl delete pod "$1" -n kube-system")}' #重载pod
# 2.通过清单安装MetalLB
mkdir /root/metallb
cd /root/metallb
wget https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/namespace.yaml
wget https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/metallb.yaml #根据yml内定义的镜像,下载并上传到本地仓库
# 将MetalLB部署到metallb-system 名称空间下的群集,其中metallb-system/controller处理IP地址分配的群集范围的控制器,metallb-system/speakerdaemonset选择的协议以使服务可访问的组件
kubectl apply -f namespace.yaml
kubectl apply -f metallb.yaml
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)" #加密信息
kubectl get ns #命名空间查看
kubectl -n metallb-system get secrets #加密信息查看
kubectl -n metallb-system get all
# 3.第2层配置,不需要任何特定于协议的配置,只需IP地址.第2层模式不需要将IP绑定到工作节点的网络接口.它的工作原理是直接响应本地网络上的ARP请求,从而将计算机的MAC地址提供给客户端
cd /root/metallb
vim config.yml #地址池
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 172.25.2.100-172.25.2.200
kubectl apply -f config.yml
kubectl -n metallb-system edit configmaps #查看config
vim demo.yml #后端服务,可以部署多个service
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
#externalIPs:
#- 172.25.2.100
#clusterIP: None
#type: NodePort
type: LoadBalancer #指定一个 LoadBalancer 类型的 Service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
kubectl apply -f demo.yml
多个后端服务
二.metallb+ingress
# ingress 在上一篇详解中,只需在ingress服务的基础上,将网络类型改成LoadBalancer,并不使用HostNetwork,且不固定节点.很好的解决了ingress的缺点,降低了节点的暴露,且更好的发挥ingress.还可以使用ingress的加密认证,地址重写等
kubectl apply -f deploy.yaml
user -> vip(metallb) -> ingress-nginx -> svc -> pod
1.metallb
2.ingress
3.default
4.外网访问
(1)编好本地解析 172.25.2.100 www1.westos.org
(2)也可以做成加密访问
三.calico网络插件
官网参考 (一)calico简介
1.flannel实现的是网络通信,calico的特性是在pod之间的隔离。
2.通过BGP路由,但大规模端点的拓扑计算和收敛往往需要一定的时间和计算资源。
3.纯三层的转发,中间没有任何的NAT和overlay,转发效率最好。
4.Calico 仅依赖三层路由可达。Calico 较少的依赖性使它能适配所有 VM、Container、白盒或者混合环境场景
(二)环境
最新版镜像在拉取过程中,下载速度极慢,反而低一些的版本拉取速度快,因此,选了v3.16.1版本,为了实验效果,yaml文件也是对应版本的
IPIP工作模式:适用于互相访问的pod不在同一个网段中,跨网段访问的场景
BGP工作模式:适用于互相访问的pod在同一个网段,适用于大型网络
此处将IPIP模式关闭
之前安装的flannel插件,需保持一致;如果没有安装过flannel,则不需要管
kubectl delete -f kube-flannel.yml
(三)安装calico
cd /etc/cni/net.d/
mv 10-flannel.conflist /mnt #所有节点的flannel,将flannel配置文件移走
# 清理干净之前
wget https://docs.projectcalico.org/manifests/calico.yaml #最新的calico yaml文件,由于最新版镜像拉取太慢,所以用v3.16.1,同时也要有对应的yaml文件
kubectl apply -f calico.yaml
(四)网络策略
k8s参考 NetworkPolicy策略模型:控制某个namespace下的pod的网络出入站规则
1.限制访问指定服务
这块只是更改了网络插件,其他的pod,svc,ns和上面一样
# 后端服务
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
# 限制策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-nginx
spec:
podSelector:
matchLabels:
app: myapp
kubectl apply -f deny-nginx.yml
kubectl get networkpolicies.networking.k8s.io
# 含有标签app=myapp的pod都不能被访问
2.允许指定pod访问服务
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: access-nginx
spec:
podSelector:
matchLabels:
app: myapp
ingress:
- from:
- podSelector:
matchLabels:
run: demo
3.禁止 namespace 中所有 Pod 之间的相互访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: demo
spec:
podSelector: {}
kubectl create namespace demo
kubectl run demo1 --image=busyboxplus -it -n demo
kubectl -n demo get pod -o wide
kubectl attach demo1 -n demo -it
4.禁止其他 namespace 访问服务
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: deny-namespace
spec:
podSelector:
matchLabels:
ingress:
- from:
- podSelector: {}
kubectl create namespace test
kubectl run demo3 --image=busyboxplus -it -n test
5.只允许指定namespace访问服务
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: access-namespace
spec:
podSelector:
matchLabels:
run: nginx
ingress:
- from:
- namespaceSelector:
matchLabels:
role: prod
kubectl get ns --show-labels
kubectl get pod -o wide
kubectl get pod -o wide -n demo
kubectl get pod -o wide -n test
kubectl attach demo3 -n test -it
6.允许外网访问服务
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-external
spec:
podSelector:
matchLabels:
app: myapp
ingress:
- ports:
- port: 80
from: []
借用前面做好的MetalLB+ingress,还没有和1.限制访问指定服务拒绝标签myapp冲突