kubernetes网络 – metallb讲解

metallb用来实现在私有化搭建的裸机环境中实现负载均衡器的功能,在没有云环境的情况下通过metallb将service暴露到网络环境中,供其他系统访问。 https://metallb.universe.tf/ 部署metallb kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml 创建配置 metallb监视名为config或metallb-config(helm部署)的configmap资源,我们创建这个资源之后它就开始工作了。 下面是layer 2模式下的配置示例,其中的addresses配置为预留的ip地址段,可配置多个。 [root@master3 ~]# cat metallb-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: namespace: metallb-system name: config data: config: | address-pools: - name: default protocol: layer2 addresses: # 可配置为下列形式或者192.168.1.0/24形式,根据预留的网段具体决定 # 可配置多个 - 10.77.1.220-10.77.1.240 kubectl apply -f metallb-configmap.yaml 测试 [root@master3 ~]# kubectl run nginx --image=nginx --port=80 [root@master3 ~]# kubectl expose pod nginx --port=80 --target-port=80 --type=LoadBalancer [root@master3 ~]# kubectl get svc…

kubernetes网络 – 云控制器

https://kubernetes.io/zh/docs/concepts/architecture/cloud-controller/ 使用云基础设施技术,你可以在公有云、私有云或者混合云环境中运行 Kubernetes。 Kubernetes 的信条是基于自动化的、API 驱动的基础设施,同时避免组件间紧密耦合。 组件 cloud-controller-manager 是指云控制器管理器, 云控制器管理器是指嵌入特定云的控制逻辑的 控制平面组件。 云控制器管理器使得你可以将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。 通过分离 Kubernetes 和底层云基础设置之间的互操作性逻辑, 云控制器管理器组件使云提供商能够以不同于 Kubernetes 主项目的 步调发布新特征。 cloud-controller-manager 组件是基于一种插件机制来构造的, 这种机制使得不同的云厂商都能将其平台与 Kubernetes 集成。 设计 云控制器管理器以一组多副本的进程集合的形式运行在控制面中,通常表现为 Pod 中的容器。每个 cloud-controller-manager 在同一进程中实现多个 控制器。 说明: 你也可以用 Kubernetes 插件 的形式而不是控制面中的一部分来运行云控制器管理器。 云控制器管理器的功能 云控制器管理器中的控制器包括: 节点控制器 节点控制器负责在云基础设施中创建了新服务器时为之 创建 节点(Node)对象。 节点控制器从云提供商获取当前租户中主机的信息。节点控制器执行以下功能: 针对控制器通过云平台驱动的 API 所发现的每个服务器初始化一个 Node 对象; 利用特定云平台的信息为 Node 对象添加注解和标签,例如节点所在的 区域(Region)和所具有的资源(CPU、内存等等); 获取节点的网络地址和主机名;否则是由kubelet获取设置这些信息。 检查节点的健康状况。如果节点无响应,控制器通过云平台 API 查看该节点是否 已从云中禁用、删除或终止。如果节点已从云中删除,则控制器从 Kubernetes 集群 中删除 Node 对象。 某些云驱动实现中,这些任务被划分到一个节点控制器和一个节点生命周期控制器中。 路由控制器 Route 控制器负责适当地配置云平台中的路由,以便 Kubernetes…

kubernetes网络 – 网络插件 – calico

calico支持host-gateway,vxlan,ipip和bgp网络模式。calico网络插件支持下列功能 基于vxlan,ipip的overlay集群网络方案。 基于bgp的路由网络方案,以及将podIP,服务的clusterIP,externalIP和LoadBalancerIP路由到集群外的能力。 kubernetes cni插件,calico和calico-ipam kubernetes原生网络策略和扩展网络策略 基于eBPF的数据面,实现网络策略和kubernetes服务功能 和其他系统(如openstack)的集成 istio网络策略扩展 架构与组件 https://docs.projectcalico.org/reference/architecture/overview Calico组件 Felix BIRD confd Dikastes CNI plugin Datastore plugin IPAM plugin kube-controllers Typha calicoctl Felix 管理主机上的路由规则,数据面访问控制等,提供访问该主机上服务的能力。比如: 接口管理管理网络接口设备,比如vxlan,ipip隧道接口设备,arp表信息,配置ip地址转发等。 配置路由配置子网和端点的路由信息。 配置访问控制如网络策略。 状态报告节点上的网络健康数据,错误信息等。 BIRD 获取路由信息,并分发到BGP peers,基于开源的bird软件。 路由分发当Felix修改系统路由后(FIB),bird感知到将其分发到其他节点。 路由反射传统bgp网络各个节点之间组成mesh,节点数量很多时,会有大量连接,有性能影响。通过使用reflector,将其作为中心节点,所有peer都和他建链接,它想每个peer分发整个集群的路由信息。 confd 检测calico的datastore数据变化以便及时修改bgp配置,如AS编号,日志级别等。它通过修改bird的配置文件并重新加载bird实现这些功能。 Dikastes 执行istio服务网格的网络策略,作为sidecar运行在集群中。 CNI plugin kubernetes的cni插件的实现,在每个节点上都要部署。 Datastore plugin 存储插件,减轻各个节点对存储引擎的影响。支持kubernetes和etcd。 IPAM plugin 结合calico cni插件使用,使用calico的ippool下分配ip地址。 kube-controllers 检测kubernetes集群资源变化,执行相关动作,包含下列控制器: 策略控制器 命名空间控制器 服务账户控制器 工作负载控制器 节点控制器 Typha 减轻各个节点对存储中心的影响。目的是争取和存储中心保持一个链接。像Felix和confd都是连接Typha。 calicoctl 客户端工具,可以用来对calico的各种资源执行增删改查等操作。 安装部署 calico的网路配置,网络策略都是通过datastore组件进行存储的。datastore后端存储支持kubernetes和etcd。如果是单独针对kubernetes使用,推荐使用默认的kuberentes后端,如果要和openstack这样的系统进行集成,那么推荐使用etcd后端。我们使用kubernetes后端存储。 快速部署: curl https://docs.projectcalico.org/manifests/calico.yaml -O # 修改CALICO_IPV4POOL_CIDR为集群的pod网段,并安装 kubectl…

kubernetes网络 – 网络插件 – flannel

flannel支持host-gw,vxlan,ipip,ipsec模式和VPC路由模式。 部署 使用下面命令对部署flannel到集群中,会在集群中创建flannel的daemonset和一个flannel的配置文件。 kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml 其中默认配置文件内容如下,主要包含了cni配置和网络配置。其中cni配置为采用flannel cni,指定网桥名称为cbr0,打开网桥接口的haripin模式,并将网桥设置为默认的网关。这些参数的含义可参考后面cni部分。 默认也指定了集群的网络模式为vxlan,使用flannel cni,并配置了整个网络的网段。 kind: ConfigMap apiVersion: v1 metadata: name: kube-flannel-cfg namespace: kube-system labels: tier: node app: flannel data: cni-conf.json: | { "name": "cbr0", "cniVersion": "0.3.1", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } net-conf.json: | { "Network": "10.248.0.0/13", "Backend": { "Type": "vxlan" } } cni插件 cni要解决的问题是本机如何访问pod以及外部主机进来的数据包怎么进入pod。使用flannel作为网络插件的话,可选两种cni插件,其一是flannel…

kubernetes网络 – ingress资源

ingress主要用来将集群内的http服务暴露到集群外。ingress提供负载均衡,ssl/tls终结和基于名称的虚拟服务器功能。 下图是ingress架构图: ingress用来暴露http和https服务,如果是其他的服务协议,无法通过ingress进行暴露,需要使用nodeport或者loadbalancer类型的服务。 ingress控制器 要使用配置ingress,需要集群内存在ingress控制器,ingress控制器负责将ingress的定义配置到具体的控制器服务上。kubernetes支持的ingress控制器参考: https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/ 此处我们使用nginx-ingress进行配置和演示,参考下面文档进行安装配置: https://github.com/kubernetes/ingress-nginx/tree/main/charts/ingress-nginx kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.3/deploy/static/provider/baremetal/deploy.yaml kubectl annotate ingressclasses nginx ingressclass.kubernetes.io/is-default-class=true # 改成LoadBalancer类型 kubectl edit svc -n ingress-nginx ingress-nginx-controller # 修改deployment # - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller # - --enable-ssl-passthrough kubectl edit deployments.apps -n ingress-nginx ingress-nginx-controller # 创建测试应用 kubectl apply -f https://github.com/istio/istio/blob/1.11.3/samples/helloworld/helloworld.yaml ingress 创建ingress资源进行测试。 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: minimal-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: /hello pathType: Prefix backend: service: name:…

kubernetes网路 – 服务与DNS

kubernetes会为每个service对象创建dns记录,这个操作是由dns插件完成的,基本上所有集群都会使用coredns作为dns插件。 kubernetes中的服务是区分命名空间的,nginx这个域名在默认情况下是使用本pod所在namespace解析的,如pod所在的namespace为default,则默认解析为nginx.default。下列是一个示例pod的resolv文件配置 [root@master1 ~]# kubectl exec -it nginx-deployment-66b6c48dd5-95c7f -- cat /etc/resolv.confnameserver 172.17.0.10search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5 服务对象分为普通服务和无头服务,无头服务是指spec.clusterIP=None的,其他服务则为普通服务。 如果service是一个普通服务对象,则会为其创建一个dns A记录(ipv6则为AAAA记录),该记录的ip地址是在kube-controller-manager的--service-cluster-ip-range参数指定的网段内,该网段和pod网段以及节点网段都不在一个网段内。 如果service是一个无头服务,则会创建一些列dns A记录,记录的ip地址是pod的ip。 k8s还会为服务对象的每个命名端口创建srv记录。如_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example。对于普通服务,解析到my-svc.my-namespace.svc.cluster-domain.exampl加端口号。对于无头服务会为每个pod创建一个类似的记录。auto-generated-name.my-svc.my-namespace.svc.cluster-domain.example加端口号。 通常情况下,会为所有pod创建如下类型的dns解析: pod-ip-address.my-namespace.pod.cluster-domain.example -> pod-ip kubectl run aaaa --image=nginx [root@master1 ~]# nslookup 10-248-5-2.default.pod.cluster.local 172.17.0.10 Server: 172.17.0.10 Address: 172.17.0.10#53 ​ Name: 10-248-5-2.default.pod.cluster.local Address: 10.248.5.2 通常情况下,会为deployment和daemonset的pod,且通过service进行暴露的话,则会创建下列dns解析: pod-ip-address.deployment.my-namespace.svc.cluster.local -> pod-ip 针对deployment进行测试 kubectl create deployment nginx --image=nginx kubectl expose deployment nginx --port 80 [root@master3 ~]# nslookup nginx.default.svc.cluster.local 172.17.0.10 Server: 172.17.0.10 Address: 172.17.0.10#53 ​…

kubernetes网络 – 服务概念

kubernetes中服务主要用来进行服务发现和负载均衡。 在集群中我们的工作负载是不稳定的,ip地址可能随着pod重启,升级和扩容等不断发生变化,为了能够让其他工作负载可以稳定访问到这个工作负载,我们需要为其创建一个服务对象。 服务对象也是一个api资源对象,和其他api对象定义方法相同,下面是一个服务对象的定义: apiVersion: v1 kind: Service metadata: name: nginx spec: selector: # 根据标签选择pod app: nginx # type: ClusterIP # clusterIP: 192.168.3.251 ports: # TCP, UDP, SCTP - protocol: TCP appProtocol: http name: nginx-http port: 80 targetPort: 80 # 支持多个端口配置 - name: https protocol: TCP port: 443 targetPort: 9377 externalTrafficPolicy: Cluster 这个服务对象会创建一个service资源,服务控制器会根据我们的selector选择对应的pod,创建endpoint后endpointslice资源关联到这个服务。服务控制器还会为我们的服务自动创建一个虚拟ip地址,其他工作负载使用这个虚拟ip地址访问这个服务。endpoint资源代表后端真正的服务实例,它关联到pod,访问到虚拟ip的流量会转到对应的后端pod对应的端口上。 通过selector可以让kunbernetes根据标签自动选择pod并创建endpoint关联到service。有些场景我们也可以不使用selector,例如: 引用已有服务的ip列表 apiVersion: v1 kind: Service metadata: name: my-service spec: ports: - protocol: TCP port: 443 targetPort: 6443…