一.MetalLB
   
    
    
    
    
    通过MetalLB来实现适用于公有云上的 Kubernetes 服务LoadBalancer,MetalLB是用于裸机的负载均衡器实现 Kubernetes 群集,使用标准路由协议,注意网络插件兼容性,本次使用的是Flannel
    
    
     MetalLB
    
   
# 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冲突
    
     
   
 
