Docker和K8S的网络
docker的安装与下载
访问dacker的官网 https://www.docker.com/get-started/
根据自己的系统选择相应的下载包
并根据指引安装(不过没有老版本的下载地址,我还无奈的升级了自己电脑的系统。)
docker单机网络
docker其实是利用到了linux的namespace和cgroups技术来实现资源和网络的隔离。
1、docker拉起的容器之间都是互通的,可以尝试在容器A里ping容器B的ip,是能够ping通的;且宿主机和容器互通;
原因:单机的docker 会在宿主机上创建一个docker0的网卡,每创建一个容器就会创建一个veth-pair,这个veth-pair是一对网卡,这对网卡拥有同网段ip,互通,这对网卡一个给了容器,一个给了宿主机;实现了容器与宿主机的通信;容器和容器通信则是有宿主机起到桥接作用实现通信的。 这也就是桥接模式的网络。
2、容器之间如何实现按照容器名称来通信呢?
首先,默认使用docker0的两个容器虽然能够使用ip相互ping通,但是使用容器名称是无法ping通的;
但是,如果自己创建一个network,然后两个容器都使用这个network,那么他们可以使用容器名称相互ping通,这是因为同一个network默认支持这种,类似于dns的作用
3、不同的network之间互通吗?
答案:不通,network的创建就是为了联通某些容器,和隔离某些容器;同一个network里的容器互通,不同的network的容器则不通。
docker多机网络
处在不同的宿主机的docker容器之间通过overlay来进行通信。
K8S
【service的负载均衡】:
K8S维护的最小单元是pod,pod部署在node上,node就是集群里面的一台机器;
K8S集群里面需要安装网络插件实现网络通信,例如calic
网络插件会给pod分配ip;
但是pod是很不稳定的,挂掉了就会新拉起,扩缩容也会导致pod变化,因此podId是不能使用的,因此使用service,给service一个ip,这个ip是稳定的,service包含endpoints,这个endpoints里面是一组podIp列表,可以实现负载均衡(kubectl describe svc XXX-service 命令即可看到)
【service的两个类型】:
- ClusterIp:默认的类型,这个类型是集群内的通信(pod到node、node到pod;node内部pod到pod;跨node的pod之间等)。原理:网络插件=>实现集群内部访问
- NodePort:端口映射,将pod的service端口映射到宿主机的端口=>外部与k8s集群内部的通信(外部通过K8S宿主机ip+宿主机被映射的port访问K8S集群)(受到端口数量限制),生产环境一般不使用
- hostPort:只会在一台主机打开端口(nodeport是打开集群所有主机的端口)
servicedemo.yaml
apiversion: v1
kind: service
metadata:
name: test-service
spec:
ports:
- port: 80 #映射到宿主机的端口
protocol: TCP
targetPort: 8080 #容器端口
selector:
app: tomcat
type: NodePort #这里配置的是NodePort,如果不配置,默认的就是hostPort
【ingress】
主要用于外界通过HTTP/HTTPS访问K8S集群内部
有负载均衡、网关等作用
实现的是域名与node的hostPort的映射
ingressController:没有实现具体的通信,只是配置,真实实现的事nginx-ingress-controller(就能配置规则,怎样的url路由到哪一个service)等其他实现
如下demo,将域名url规则匹配到具体的端口的service
apiversion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- host: XXX域名
http:
paths:
- path: /
backend:
serviceName: xxxservice
servicePort: 80
在集群内部可以使用clusterIp:映射的宿主机端口访问
ps
nodeSelector可以让yaml部署在标签匹配的node上
hostNetwork: true 则可以使用hostNetwork