ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] # 从外部访问集群中的Pod 从外部访问集群的方式有以下几种: * hostNetwork * hostPort * NodePort * LoadBalancer * Ingress ### hostNetwork ~~~ apiVersion: v1 kind: Pod metadata: name: http-pod spec: containers: - name: http image: registry.cn-shenzhen.aliyuncs.com/zwh-kubea/http:v1 hostNetwork: true # 直接通过pod所在的宿主机IP访问 # 补充说明: # metadata中的name,是通过kubectl get pod 查看到的pod的名称 # 而spec中,containers的name,则是关联到k8s集群 DNS 服务发现的名字 # 具体内容,可以网上查看关于DNS的知识 ~~~ #### 小结 通常Pod是时常消亡、不断的重建的,通常不会固定到某一个特定节点,如果切换节点,访问的IP也会变更。 这种Pod的网络模式有一个用处就是可以将网络插件包装在Pod中然后部署在每个宿主机上,这样该Pod就可以控制该宿主机上的所有网络。 ### hostPort ~~~ apiVersion: v1 kind: Pod metadata: name: http-pod spec: containers: - name: http image: registry.cn-shenzhen.aliyuncs.com/zwh-kubea/http:v1 ports: - containerPort: 80 hostPort: 80 # 将容器的80映射到主机的80 ~~~ ![](https://img.kancloud.cn/b4/02/b402cae86d6ede79abca61fd6d9ddcbe_700x58.png) ![](https://img.kancloud.cn/a6/51/a6513941a35eac51d55c073c184ec040_699x226.png) ### NodePort NodePort的方式,需要配合service来访问,这是一种比较常见的方式 ~~~ --- apiVersion: v1 kind: Pod metadata: name: http-pod labels: #这个标签是用于service链接到pod的 name: labels-http-pod spec: containers: - name: http image: registry.cn-shenzhen.aliyuncs.com/zwh-kubea/http:v1 ports: - containerPort: 80 --- kind: Service apiVersion: v1 metadata: name: http-service spec: type: NodePort #使用nodeport类型网络,不指定默认cluster IP ports: - port: 80 nodePort: 30000 # 这个端口范围被k8s限定在了30000-32767之间 selector: name: labels-http-pod # 通过pod的labels标签去链接 ~~~ * 查看 ![](https://img.kancloud.cn/0d/6a/0d6adeda067b487179eee951cb13f9a5_626x82.png) 在集群外面,使用任意节点上的IP加30000端口,就能访问pod。 #### 小结 通过这种方式,访问任意节点上的端口,都会被kube-proxy自动指向后端Pod,但是这种方式端口往往是高位端口,不能设置为常用端口,比如80、3306等 不过可以在集群上部署一个nginx,将流量代理到正确的高位端口上。 * 设想(没有用于实际生产): 在每个节点上部署一个nginx,使用hostport方式打开常用80、3306等端口,然后再反向代理到正确的高位端口上去 ### LoadBalancer 这个只能通过service,在公有云的负载均衡上运行 (悲惨~我没有公有云,做不了测试,详细api实例官网有) ### Ingress 有多种软件实现 Ingress 方式访问,我部署的集群选择Ingres-NGINX,这个k8s官方参与的项目,算是k8s的亲儿子。[Ingress-Nginx官网](https://kubernetes.github.io/ingress-nginx/) #### 概念 一开始我不是很明白ingress提供的访问方式,总是用虚拟机的思维方式去理解ingress,其实我错了。 其实很简单: * ingress-nginx使用NodePort方式,监听物理机上的某个端口,映射到ingress-nginx-controller的80和443端口上 * 然后找一个一级域名:`example.com`,把解析映射到ingress-nginx所绑定的物理机NodePort端口上 * 接着在ingress类型yaml中,在字段`rules`中,分别定义两个host:`one.example.com`和`two.example.com`,最后分别对应不同的后端pod:`pod-1`和`pod-2` ~~~ one.example.com| |one.example.com --> pod-1:80 | 178.91.123.132| two.example.com| |two.example.com --> pod-2:80 ~~~ #### 安装 * 第一步:首先执行一句话,创建ingress所需条件 ~~~ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml ~~~ 这个步骤创建集群角色、服务、命名空间等需要的东西 ![](https://img.kancloud.cn/e9/14/e9149123d13c09465030edb6aab9b8c2_744x204.png) * 第二步:根据k8s所在环境的不同,分别执行特定的步骤。 因为现有环境中为物理机,所以选择裸金属部署方式(还有其他环境的部署方式,可以参考官网)。 裸金属提供ingress服务的方式有metaiLB、NodePort、HostPort、外部haproxy方式。 根据官方推荐,使用NodePort方式进行部署,这一步是在创建ingress-nginx的服务 ~~~ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml ~~~ ![](https://img.kancloud.cn/ee/f1/eef15b3096e95d1931c8fc2cc6d4c1e6_956x121.png) 可以看到NodePort监听主机的30806,31488端口 #### 检查安装 ~~~ kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx --watch ~~~ ![](https://img.kancloud.cn/54/d1/54d100640080b8f60eec8c43a6a4801b_859x73.png) #### 应用测试 先在集群中部署两个带有http并打开80端口的pod ![](https://img.kancloud.cn/14/a0/14a032cbd9fdf4a5a2d6bdf758a1777a_910x233.png) ##### Ingress.yaml ~~~ apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: one.example.com http: paths: - backend: serviceName: http-pod-1 servicePort: 80 - host: two.example.com http: paths: - backend: serviceName: http-pod-2 servicePort: 80 ~~~ ##### 在DNS中添加域解析 因为我的环境中没有部署DNS服务器,所以直接修改window的hots文件 添加以下内容: ~~~ 192.168.241.100 one.example.com 192.168.241.100 two.example.com ~~~ ##### 验证访问 因为我们Ingress用的是NodePort方式,所以访问的时候,还是需要添加端口的 ![](https://img.kancloud.cn/70/1c/701c2ed99893bdee57b130c34c7f5cd6_463x270.png) ##### 后续 完成测试之后,有另外一个设想,但是没有实践,所以先写在这里记录一下。 ~~~ 1、在定义Ingress资源的时候,可以在`host`字段中使用多个一级域名 2、原理和使用多个多级域名一样,都是在nginx中定义不同的访问header 3、根据不同的header将流量指向不同的pod 4、再将不同的域名解析到同一个IP地址上(其实原理和二级域名一样) ~~~