kubernetes实践(五)pod的网络通信
一.pods的通信
1.
同一Pod内的容器通信在同一个Pod内的容器共享同一个网络命名空间,共享同一个Linux协议栈。所以对于网络的各类操作,就和它们在同一台机器上一样,它们可以用localhost地址直接访问彼此的端口。其实这和传统的一组普通程序运行的环境是完全一样的,传统的程序不需要针对网络做特别的修改就可以移植了。这样做的结果是简单、安全和高效,也能减少将已经存在的程序从物理机或者虚拟机移植到容器下运行的难度。
2.
pod之间的通信(1)两个pod在同一台主机
Pod1与Pod2在同一台主机。Pod1和Pod2在同一台主机的话,由Docker0网桥直接转发请求到Pod2,不需要经过Flannel。
(2)两个pod不在同一台主机
Pod的地址是与docker0在同一个网段的,但docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行。将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问。
二.
1.
(1)创建service
a.创建nginx_service.yaml文件
apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: nginx
b.根据nginx_service.yaml文件创建service
kubectl apply -f nginx_deployment.yaml
#查询所有命名空间service资源 kubectl get svc --all-namespaces -o wide #查询默认命名空间service资源 kubectl get svc -o wide #查询指定命名空间service资源 kubectl get svc -o wide -n namespace
(3)查询
详细信息#查询默认命名空间namespace详细信息 kubectl describe nginx- #查询指定命名空间 详细信息 kubectl describe nginx- -n
(4)删除
kubectl delete -f nginx_.yaml kubectl delete nginx-
2.
(1)
对于上述的Pod虽然实现了集群内部互相通信,但是Pod是不稳定的,比如通过Deployment管理Pod,随时可能对Pod进行扩缩容,这时候Pod的IP地址是变化的。能够有一个固定的IP,使得集群内能够访问。也就是之前在架构描述的时候所提到的,能够把相同或者具有关联的Pod,打上Label,组成Service。而Service有固定的IP,不管Pod怎么创建和销毁,都可以通过Service的IP进行访问
ClusterIP 给你一个集群内的服务,集群内的其它应用都可以访问该服务。集群外部无法访问它。
ClusterIP 服务的 YAML 文件类似如下:
apiVersion: v1 kind: Service metadata: name: my-internal-service selector: app: my-app spec: type: ClusterIP ports: - name: http port: 80 targetPort: 80 protocol: TCP
(2)
NodePortNodePort 服务是引导外部流量到你的服务的最原始方式。NodePort,正如这个名字所示,在所有节点(虚拟机)上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。
NodePort 服务的 YAML 文件类似如下:
apiVersion: v1 kind: Service metadata: name: my-nodeport-service selector: app: my-app spec: type: NodePort ports: - name: http port: 80 targetPort: 80 nodePort: 30036 protocol: TCP
NodePort 服务主要有两点区别于普通的“ClusterIP”服务。第一,它的类型是“NodePort”。有一个额外的端口,称为 nodePort,它指定节点上开放的端口值 。如果你不指定这个端口,系统将选择一个随机端口。
NodePort虽然能够实现外部访问Pod的需求,但是真的好吗?其实不好,占用了各个物理主机上的端口, 而且用户自己来选择可用端口代价太大。
何时使用这种方式?
这种方法有许多缺点:
a.每个端口只能是一种服务 b.端口范围只能是 30000-32767 c.如果节点/VM 的 IP 地址发生变化,你需要能处理这种情况。
基于以上原因,我不建议在生产环境上用这种方式暴露服务。如果你运行的服务不要求一直可用,或者对成本比较敏感,你可以使用这种方法。这样的应用的最佳例子是 demo 应用,或者某些临时应用。
(3)
LoadBalancer 服务是暴露服务到 internet 的标准方式。在 GKE 上,这种方式会启动一个 Network Load Balancer,它将给你一个单独的 IP 地址,转发所有流量到你的服务。
通常需要第三方云提供商支持,有约束性
何时使用这种方式?
如果你想要直接暴露服务,这就是默认方式。所有通往你指定的端口的流量都会被转发到对应的服务。它没有过滤条件,没有路由等。这意味着你几乎可以发送任何种类的流量到该服务,像 HTTP,TCP,UDP,Websocket,gRPC 或其它任意种类。
这个方式的最大缺点是每一个用 LoadBalancer 暴露的服务都会有它自己的 IP 地址,每个用到的 LoadBalancer 都需要付费,这将是非常昂贵的
(4)Ingress
有别于以上所有例子,Ingress 事实上不是一种服务类型。相反,它处于多个服务的前端,扮演着“智能路由”或者集群入口的角色。
你可以用 Ingress 来做许多不同的事情,各种不同类型的 Ingress 控制器也有不同的能力。
GKE 上的默认 ingress 控制器是启动一个 HTTP(S) Load Balancer。它允许你基于路径或者子域名来路由流量到后端服务。例如,你可以将任何发往域名 foo.yourdomain.com 的流量转到 foo 服务,将路径 yourdomain.com/bar/path 的流量转到 bar 服务。
这里我们选用Ingress Nginx Controller举例
:
a.安装nginx-controller
#下载mandatory.yaml文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.29.0/deploy/static/mandatory.yaml
hostNetwork: true
kubectl label node w1 name=ingress
nodeSelector: name: ingress
... apiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: # wait up to five minutes for the drain of connections terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount hostNetwork: true nodeSelector: name: ingress kubernetes.io/os: linux ...
kubectl apply -f mandatory.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: tomcat-deployment labels: app: tomcat spec: replicas: 1 selector: matchLabels: app: tomcat template: metadata: labels: app: tomcat spec: containers: - name: tomcat image: tomcat ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: tomcat --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx-ingress spec: rules: - host: tomcat.example.com http: paths: - path: / backend: serviceName: tomcat-service servicePort: 80
#执行安装
kubectl apply -f tomcat.yaml
#查询
#查询
#修改win的hosts文件,添加dns解析
192.168.50.15 tomcat.example.com