美文网首页微服务架构和实践Kubernetes
k8s使用kube-router网络组件并实现网络隔离

k8s使用kube-router网络组件并实现网络隔离

作者: 647f379ea944 | 来源:发表于2018-08-12 09:35 被阅读0次

    简介

    本文章主要介绍k8s如何使用kube-router实现pod通信,服务代理,网络策略隔离等功能

    kube-router是一个新的k8s的网络插件,使用lvs做服务的代理及负载均衡,使用iptables来做网络的隔离策略。部署简单,只需要在每个节点部署一个daemonset即可,高性能,易维护。支持pod间通信,以及服务的代理。

    环境说明

    本实验在已经安装配置好k8s集群基础之上进行实验,k8s安装参考博客其他文章。

    实验架构

    lab1: master 11.11.11.111
    lab2: node 11.11.11.112
    lab3: node 11.11.11.113
    

    安装

    # 本次实验重新创建了集群,使用之前测试其他网络插件的集群环境没有成功
    # 可能是由于环境干扰,实验时需要注意
    
    # 创建kube-router目录下载相关文件
    mkdir kube-router && cd kube-router
    rm -f generic-kuberouter-all-features.yaml
    wget https://raw.githubusercontent.com/cloudnativelabs/kube-router/master/daemonset/generic-kuberouter-all-features.yaml
    
    # 启用pod网络通信,网络隔离策略,服务代理所有功能
    # CLUSTERCIDR kube-controller-manager 启动参数 --cluster-cidr 的值
    # APISERVER kube-apiserver 启动参数 --advertise-address 值
    CLUSTERCIDR='10.244.0.0/16'
    APISERVER='https://11.11.11.111:6443'
    sed -i "s;%APISERVER%;$APISERVER;g" generic-kuberouter-all-features.yaml
    sed -i "s;%CLUSTERCIDR%;$CLUSTERCIDR;g" generic-kuberouter-all-features.yaml
    kubectl apply -f generic-kuberouter-all-features.yaml
    
    # 删除kube-proxy
    kubectl -n kube-system delete ds kube-proxy
    
    # 在每个节点上执行
    # 如果是二进制安装使用如下命令
    systemctl stop kube-proxy
    
    # 在每个节点上执行
    # 清理kube-proxy留下的规则
    docker run --privileged --net=host registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy-amd64:v1.10.2 kube-proxy --cleanup
    
    # 查看
    kubectl get pods -n kube-system
    kubectl get svc -n kube-system
    

    测试

    # 测试之前请先安装配置好kube-dns或者coredns
    
    # 启动用于测试的deployment
    kubectl run nginx --replicas=2 --image=nginx:alpine --port=80
    kubectl expose deployment nginx --type=NodePort --name=example-service-nodeport
    kubectl expose deployment nginx --name=example-service
    
    # 查看
    kubectl get pods -o wide
    kubectl get svc -o wide
    
    # dns及访问测试
    kubectl run curl --image=radial/busyboxplus:curl -i --tty
    nslookup kubernetes
    nslookup example-service
    curl example-service
    
    # 清理
    kubectl delete svc example-service example-service-nodeport
    kubectl delete deploy nginx curl
    

    网络隔离策略

    部署应用

    # 创建 production staging 命名空间
    kubectl create namespace production
    kubectl create namespace staging
    
    # 在每个命名空间各部署一套服务
    cd kube-router
    wget https://raw.githubusercontent.com/mgxian/istio-test/master/service/node/v1/node-v1.yml
    wget https://raw.githubusercontent.com/mgxian/istio-test/master/service/go/v1/go-v1.yml
    kubectl apply -f node-v1.yml -n production
    kubectl apply -f go-v1.yml -n production
    kubectl apply -f node-v1.yml -n staging
    kubectl apply -f go-v1.yml -n staging
    
    # 查看状态
    kubectl get pods --all-namespaces -o wide
    

    测试pod通信

    # 获取相关POD信息
    PRODUCTION_NODE_NAME=$(kubectl get pods -n production | grep Running | grep service-node | awk '{print $1}')
    STAGING_NODE_NAME=$(kubectl get pods -n staging | grep Running | grep service-node | awk '{print $1}')
    PRODUCTION_GO_IP=$(kubectl get pods -n production -o wide | grep Running | grep service-go | awk '{print $6}')
    STAGING_GO_IP=$(kubectl get pods -n staging -o wide | grep Running | grep service-go | awk '{print $6}')
    echo $PRODUCTION_NODE_NAME $PRODUCTION_GO_IP
    echo $STAGING_NODE_NAME $STAGING_GO_IP
    
    
    # 同namespace的pod通信
    kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $PRODUCTION_GO_IP 
    kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $STAGING_GO_IP 
    
    # 不同namespace的pod通信
    kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $STAGING_GO_IP
    kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $PRODUCTION_GO_IP
    
    # 结论:任何namespace的任何pod间都可以直接通信
    

    设置默认策略测试

    # 设置默认策略为拒绝所有流量
    cat >default-deny.yml<<EOF
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: default-deny
    spec:
      podSelector: {}
      policyTypes:
      - Ingress
    EOF
    kubectl apply -f default-deny.yml -n production
    kubectl apply -f default-deny.yml -n staging
    
    # 测试通信
    # 同namespace的pod通信
    kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $PRODUCTION_GO_IP 
    kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $STAGING_GO_IP 
    
    # 不同namespace的pod通信
    kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $STAGING_GO_IP
    kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $PRODUCTION_GO_IP
    
    # 结论:所有pod间都不能通信
    

    设置允许规则

    # 设置 service-go 允许从 service-node 访问
    cat >service-go-allow-service-node.yml<<EOF
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: service-go-allow-service-node
    spec:
      podSelector:
        matchLabels:
          app: service-go
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: service-node
    EOF
    kubectl apply -f service-go-allow-service-node.yml -n production
    kubectl apply -f service-go-allow-service-node.yml -n staging
    
    # 设置 service-node 允许 访问 tcp 80 端口
    cat >service-node-allow-tcp-80.yml<<EOF
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: service-node-allow-tcp-80
    spec:
      podSelector:
        matchLabels:
          app: service-node
      ingress:
      - from:
        ports:
        - protocol: TCP
          port: 80
    EOF
    kubectl apply -f service-node-allow-tcp-80.yml -n production
    kubectl apply -f service-node-allow-tcp-80.yml -n staging
    
    # 测试通信
    # 同namespace的pod通信
    kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $PRODUCTION_GO_IP 
    kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $STAGING_GO_IP 
    
    # 不同namespace的pod通信
    kubectl exec -it $PRODUCTION_NODE_NAME --namespace=production -- ping -c4 $STAGING_GO_IP
    kubectl exec -it $STAGING_NODE_NAME --namespace=staging -- ping -c4 $PRODUCTION_GO_IP
    
    # 通过service测试
    PRODUCTION_GO_SVC=$(kubectl get svc -n production | grep service-go | awk '{print $3}')
    STAGING_GO_SVC=$(kubectl get svc -n staging | grep service-go | awk '{print $3}')
    echo $PRODUCTION_GO_SVC $STAGING_GO_SVC
    curl $PRODUCTION_GO_SVC
    curl $STAGING_GO_SVC
    
    # 结论:同一namespace的pod间可以通信,不同namespace的pod间不可以通信,只允许配置了网络规则的pod间通信
    # 通过 service 也无法绕过网络隔离策略
    

    清理

    # 删除 namespace 自动删除相关资源
    kubectl delete ns production
    kubectl delete ns staging
    

    参考文档

    相关文章

      网友评论

        本文标题:k8s使用kube-router网络组件并实现网络隔离

        本文链接:https://www.haomeiwen.com/subject/igtsbftx.html