1、Network
接下来就要说到跟Kubernetes网络通信相关的内容,我们都知道K8S最小的操作单位是Pod,而我们在前面章节说过同一个Pod中多个容器通信是默认就已经支持了的。但是怎么支持的没去解释,下面就开始说明各种情况下的容器是如何通信的。
1.1 集群内部通信
1.1.1 同一个 Pod 中的容器通信
因为一个 Pod 是存在一台机器中的,不可能说 Pod 里的容器会存到不同机器的,而同一台机器中的Container想要通信肯定是很方便的。
在前面章节演示中,我们知道每一个Pod中都一定会有一个 Pause Container,这个Container就是同一个Pod中其他Container通信的桥梁,其他Container在创建完成之后都会与Pause Container建立连接,于是它们就有了共同的网段,从而实现了通信!
-
理解 Pause Container
- 在Kubernetes Pod中,首先创建一个基础结构或 “Pause” 容器来托管容器端点
- 属于同一 Pod 的容器(包括基础结构容器和工作容器)共享一个公共的网络名称空间和终结点(相同的IP和端口空间)
- 它会在每个 Pod 里,额外起一个 Infra container 小容器来共享整个 Pod 的 Network Namespace。
- 其他所有容器都会通过 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。
- 所以说一个 Pod 里面的所有容器,它们看到的网络视图是完全一样的。
- 需要 Pause 容器来容纳工作容器崩溃或重新启动而不会丢失任何网络配置
-
案例测试
-
准备 yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
-
创建资源
[root@master-kubeadm-k8s deployment]# kubectl apply -f nginx_deployment.yaml deployment.apps/nginx-deployment created # Pod 分布在 worker01 和 worker02 中,我们选择一个node去看一下 [root@master-kubeadm-k8s deployment]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-6dd86d77d-2sm56 1/1 Running 0 8m44s 192.168.14.17 worker01-kubeadm-k8s
nginx-deployment-6dd86d77d-dh5hj 1/1 Running 0 8m44s 192.168.14.16 worker01-kubeadm-k8s nginx-deployment-6dd86d77d-zk8ms 1/1 Running 0 8m44s 192.168.221.76 worker02-kubeadm-k8s -
worker01 节点查看容器
[root@worker01-kubeadm-k8s ~]# docker ps | grep nginx b918c5aa0352 84581e99d807 "nginx -g 'daemon of…" About a minute ago Up About a minute k8s_nginx_nginx-deployment-6dd86d77d-2sm56_default_fde4c80d-70ea-11ea-937b-5254008afee6_0 54de85908726 84581e99d807 "nginx -g 'daemon of…" About a minute ago Up About a minute k8s_nginx_nginx-deployment-6dd86d77d-dh5hj_default_fe03776c-70ea-11ea-937b-5254008afee6_0 889f8517be18 k8s.gcr.io/pause:3.1 "/pause" About a minute ago Up About a minute k8s_POD_nginx-deployment-6dd86d77d-dh5hj_default_fe03776c-70ea-11ea-937b-5254008afee6_0 fbe190cf8c77 k8s.gcr.io/pause:3.1 "/pause" About a minute ago Up About a minute k8s_POD_nginx-deployment-6dd86d77d-2sm56_default_fde4c80d-70ea-11ea-937b-5254008afee6_0
因为 worker01 节点被分配了两个 Pod,所以这里也就有2个容器存在,以及2个 Pause 容器分别属于2个Pod。
-
1.1.2 集群内 Pod 之间的通信
接下来就聊聊K8S最小的操作单元,Pod之间的通信,我们知道Pod会有独立的IP地址,这个IP地址是被Pod中所有的Container共享的,那多个Pod之间的通信能通过这个IP地址吗?
这里可能会想到需要分两个维度去验证:
- 集群中同一台机器中的Pod
- 集群中不同机器中的Pod
但是我们无需分成两个维度去验证,因为在 K8S网络模型
中,集群内所有 Pod 默认都是可以直接通信的。因为有网络插件的存在,我们的案例中使用的插件是 Calico ,它已经帮我们完成了所有的准备。
-
官方对K8S网络模型的介绍
每个人
Pod
都有自己的IP地址。这意味着无需显式地在它们之间创建链接,Pods
并且几乎不需要处理将容器端口映射到主机端口的问题。这将创建一个干净的,向后兼容的模型,
Pods
从端口分配,命名,服务发现,负载平衡,应用程序配置和迁移的角度来看,该模型可以像VM或物理主机一样对待。
-
Kubernetes对任何网络实施都施加以下基本要求(除非有任何故意的网络分段策略):
节点上的Pod可以与所有节点上的所有Pod通信,而无需NAT
节点上的代理(例如系统守护程序,kubelet)可以与该节点上的所有pod通信
节点主机网络中的Pod可以与所有节点上的所有Pod通信,而无需NAT
-
案例验证
-
编写 nginx_network.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
-
创建资源
[root@master-kubeadm-k8s test_network1]# kubectl apply -f nginx_network.yaml deployment.apps/nginx-deployment created # 查看 Pod 分配的节点以及所分配的ip [root@master-kubeadm-k8s test_network1]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-6dd86d77d-rfgnq 1/1 Running 0 16s 192.168.14.19 worker01-kubeadm-k8s
nginx-deployment-6dd86d77d-xf2j6 1/1 Running 0 16s 192.168.221.78 worker02-kubeadm-k8s nginx-deployment-6dd86d77d-zx897 1/1 Running 0 16s 192.168.221.79 worker02-kubeadm-k8s -
进入容器测试通信
# 进入worker01节点的容器 [root@worker01-kubeadm-k8s ~]# docker exec -it f8693040e28d bash # 查看当前容器的IP root@nginx-deployment-6dd86d77d-rfgnq:/# ip a # ...省略其他组件... 4: eth0@if11:
mtu 1440 qdisc noqueue state UP link/ether 02:35:73:f0:76:83 brd ff:ff:ff:ff:ff:ff inet 192.168.14.19/32 scope global eth0 valid_lft forever preferred_lft forever # ping worker02节点中Pod的 IP,是可以正常ping通的 root@nginx-deployment-6dd86d77d-rfgnq:/# ping 192.168.221.78 PING 192.168.221.78 (192.168.221.78): 48 data bytes 56 bytes from 192.168.221.78: icmp_seq=0 ttl=62 time=4.273 ms 56 bytes from 192.168.221.78: icmp_seq=1 ttl=62 time=1.438 ms ^C--- 192.168.221.78 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 1.438/2.855/4.273/1.418 ms
-
1.1.3 集群内 Service-Cluster IP
对于上述的Pod虽然实现了集群内部互相通信,但是Pod是不稳定的,比如通过Deployment管理Pod,随时可能对Pod进行扩缩容,这时候Pod的IP地址是变化的。
能够有一个固定的IP,使得集群内能够访问。也就是之前在架构描述的时候所提到的,能够把相同或者具有关联的Pod,打上Label,组成 Service。而Service有固定的IP,不管Pod怎么创建和销毁,都可以通过Service的IP进行访问。
-
理解 Service
- Service 是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法
- Service 定义了这样一种抽象:逻辑上的一组
Pod
,一种可以访问它们的策略,通常称为微服务。 - 这一组 Pod 能够被 Service 访问到,通常是通过 selector 实现的。
-
使用 Service
-
编写 whoami-deployment.yaml
whoami 这个应用是用来查看当前访问的是哪台机器的
apiVersion: apps/v1 kind: Deployment metadata: name: whoami-deployment labels: app: whoami spec: replicas: 3 selector: matchLabels: app: whoami template: metadata: labels: app: whoami spec: containers: - name: whoami image: jwilder/whoami ports: - containerPort: 8000
-
创建资源
[root@master-kubeadm-k8s whoami]# kubectl apply -f whoami-deployment.yaml deployment.apps/whoami-deployment created
-
查看 Pod 与 Service
[root@master-kubeadm-k8s whoami]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES whoami-deployment-678b64444d-7nr87 1/1 Running 0 2m24s 192.168.221.80 worker02-kubeadm-k8s
whoami-deployment-678b64444d-hpnm5 1/1 Running 0 2m24s 192.168.14.20 worker01-kubeadm-k8s whoami-deployment-678b64444d-mfhz4 1/1 Running 0 2m24s 192.168.14.21 worker01-kubeadm-k8s # 发现并没有 whoami 的service [root@master-kubeadm-k8s whoami]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 4d -
验证通信
# 直接访问是没问题的 [root@master-kubeadm-k8s whoami]# curl 192.168.221.80:8000 I'm whoami-deployment-678b64444d-7nr87 [root@master-kubeadm-k8s whoami]# curl 192.168.14.20:8000 I'm whoami-deployment-678b64444d-hpnm5 [root@master-kubeadm-k8s whoami]# curl 192.168.14.21:8000 I'm whoami-deployment-678b64444d-mfhz4
-
创建 whoami 的 Service
-
YAML文件方式
apiVersion: v1 kind: Service # 定义资源类型为 Service metadata: name: whoami-service spec: selector: app: whoami # 选取具有label为 app: whoami 的Pod ports: - protocol: TCP # 协议为 TCP port: 80 # 映射端口为80 targetPort: 8000 # 目标端口为8000
-
命令方式
# 注意:使用命令来创建 Service,名称要与资源名称一致 whoami-deployment,否则会创建失败 [root@master-kubeadm-k8s whoami]# kubectl expose deployment whoami-deployment --port=80 --target-port=8000 service/whoami-deployment exposed # 失败案例 [root@master-kubeadm-k8s whoami]# kubectl expose deployment whoami-service --port=80 --target-port=8000 Error from server (NotFound): deployments.extensions "whoami-service" not found
-
-
再次查看 Service
# 新创建的service已经存在了,ClusterIP为 10.103.138.245, 映射端口为 80, selector选取的label为 app=whoami [root@master-kubeadm-k8s whoami]# kubectl get svc -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.96.0.1
443/TCP 4d whoami-service ClusterIP 10.103.138.245 80/TCP 2m14s app=whoami -
通过 Service-Cluster IP 访问 whoami
# 直接访问 Service-Cluster IP 可以自动帮我们负载均衡到每一个 Pod 上 [root@master-kubeadm-k8s whoami]# curl 10.103.138.245 I'm whoami-deployment-678b64444d-7nr87 [root@master-kubeadm-k8s whoami]# curl 10.103.138.245 I'm whoami-deployment-678b64444d-mfhz4 [root@master-kubeadm-k8s whoami]# curl 10.103.138.245 I'm whoami-deployment-678b64444d-7nr87 [root@master-kubeadm-k8s whoami]# curl 10.103.138.245 I'm whoami-deployment-678b64444d-hpnm5
-
查看 whoami-service的详情信息
[root@master-kubeadm-k8s whoami]# kubectl describe svc whoami-service Name: whoami-service Namespace: default Labels: app=whoami Annotations:
Selector: app=whoami Type: ClusterIP IP: 10.100.125.194 Port: 80/TCP TargetPort: 8000/TCP # 发现有一个Endpoints连接了具体3个Pod Endpoints: 192.168.14.20:8000,192.168.14.21:8000,192.168.221.80:8000 Session Affinity: None Events: -
测试扩缩容
# 将 whoami 扩容为 5 个 [root@master-kubeadm-k8s whoami]# kubectl scale deployment whoami-deployment --replicas=5 deployment.extensions/whoami-deployment scaled # 再次查看 whoami-service 详情 [root@master-kubeadm-k8s whoami]# kubectl describe svc whoami-service Name: whoami-service Namespace: default Labels: app=whoami Annotations:
Selector: app=whoami Type: ClusterIP IP: 10.100.125.194 Port: 80/TCP TargetPort: 8000/TCP # 发现这里多了 +2 more... 表示又多了2个新的 Pod Endpoints: 192.168.14.20:8000,192.168.14.21:8000,192.168.14.22:8000 + 2 more... Session Affinity: None Events: -
再次测试功能
# 可以负载均衡到 5 个 容器了 [root@master-kubeadm-k8s whoami]# curl 10.104.9.131 I'm whoami-deployment-678b64444d-nzqkp [root@master-kubeadm-k8s whoami]# curl 10.104.9.131 I'm whoami-deployment-678b64444d-7nr87 [root@master-kubeadm-k8s whoami]# curl 10.104.9.131 I'm whoami-deployment-678b64444d-hlpfp [root@master-kubeadm-k8s whoami]# curl 10.104.9.131 I'm whoami-deployment-678b64444d-nzqkp [root@master-kubeadm-k8s whoami]# curl 10.104.9.131 I'm whoami-deployment-678b64444d-mfhz4 [root@master-kubeadm-k8s whoami]# curl 10.104.9.131 I'm whoami-deployment-678b64444d-hpnm5
-
其实Service存在的意义就是为了Pod的不稳定性,而上述探讨的就是关于Service的一种类型Cluster IP,只能供集群内访问。
以Pod为中心,已经讨论了关于集群内的通信方式,接下来就是探讨集群中的Pod访问外部服务,以及外部服务访问集群中的Pod。
1.2 集群外与集群内通信
1.2.1 Pod访问外部服务
这个其实没啥可说的,因为外部的网络只要是可以与互联网联通的IP,Pod就可以直接访问了。
# 进入容器
[root@worker01-kubeadm-k8s ~]# docker exec -it 4895fc61ec69 bash
# 访问外部 ip
root@nginx-deployment-6dd86d77d-dxx67:/# ping www.baidu.com
PING www.baidu.com (180.101.49.12): 48 data bytes
56 bytes from 180.101.49.12: icmp_seq=0 ttl=50 time=15.508 ms
56 bytes from 180.101.49.12: icmp_seq=1 ttl=50 time=10.436 ms
^C--- www.baidu.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 10.436/12.972/15.508/2.536 ms
1.2.2 外部服务访问集群中的Pod
1.2.2.1 Service-NodePort
NodePort 也是Service的一种类型,可以通过NodePort的方式访问。因为外部能够访问到集群的物理机器IP,所以就是在集群中 每台物理机器
上暴露一个相同的IP,比如32008。
-
编写 whoami-nodePort.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: whoami-deployment labels: app: whoami spec: replicas: 3 selector: matchLabels: app: whoami template: metadata: labels: app: whoami spec: containers: - name: whoami image: jwilder/whoami ports: - containerPort: 8000
-
创建资源
[root@master-kubeadm-k8s nodePort]# kubectl apply -f whoami-nodePort.yaml deployment.apps/whoami-deployment created
-
创建 nodePort 类型的 Service
-
YAML文件方式
apiVersion: v1 kind: Service # 定义资源类型为 Service metadata: name: whoami-service spec: selector: app: whoami # 选取具有label为 app: whoami 的Pod ports: - protocol: TCP # 协议为 TCP port: 80 # 映射端口为80 targetPort: 8000 # 目标端口为8000 type: NodePort # 指定Service类型为 NodePort
-
命令方式
# 指定Service的类型为 NodePort [root@master-kubeadm-k8s nodePort]# kubectl expose deployment whoami-deployment --type=NodePort service/whoami-deployment exposed
-
-
查看 Service
# 新创建的 Service已经出来了,并且映射到宿主机的端口为 30184 [root@master-kubeadm-k8s nodePort]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1
443/TCP 4d1h whoami-deployment NodePort 10.101.187.169 8000:30184/TCP 6s -
测试功能
# 访问宿主机的 ip + 映射端口, 成功访问到 Pod [root@master-kubeadm-k8s nodePort]# curl 192.168.50.111:30184 I'm whoami-deployment-678b64444d-nhcpl [root@master-kubeadm-k8s nodePort]# curl 192.168.50.111:30184 I'm whoami-deployment-678b64444d-wvwg2 [root@master-kubeadm-k8s nodePort]# curl 192.168.50.111:30184 I'm whoami-deployment-678b64444d-nhcpl [root@master-kubeadm-k8s nodePort]# curl 192.168.50.111:30184 I'm whoami-deployment-678b64444d-djsx9
> NodePort虽然能够实现外部访问Pod的需求,但是真的好吗?
>
> 其实不好,因为占用了各个物理主机上的端口。
1.2.2.1 Service-LoadBalance
通常需要第三方云提供商支持,有约束性。
-
Ingress
- Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。
- Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。
- Ingress 公开了从集群外部到集群内 services 的HTTP和HTTPS路由。 流量路由由 Ingress 资源上定义的规则控制。
- 可以将 Ingress 配置为提供服务外部可访问的 URL、负载均衡流量、终止 SSL / TLS 并提供基于名称的虚拟主机。
- Ingress 控制器 通常负责通过负载均衡器来实现 Ingress
- 简单来说,Ingress就是帮助我们访问集群内的服务的。
-
环境准备
要使用 Ingress 必须具有 ingress 控制器才能满足 Ingress 的要求。仅创建 Ingress 资源是无效的。
-
Ingress 控制器有很多,我们选择自己熟悉的即可
- 可选的控制器
- Nginx、HAProxy、Istio、KONG等等。。。
- 我们这里使用:Ingress-nginx
- 可选的控制器
-
首先要加载 Ingress-nginx 资源
Ingress-nginx 官网也有这样的步骤,如果网络好的话可以直接创建资源
# 直接创建资源 kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml # 下载 yaml 文件 [root@master-kubeadm-k8s ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml --2020-03-29 06:30:17-- https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.108.133 Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.108.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 6635 (6.5K) [text/plain] Saving to: ‘mandatory.yaml’ 100%[====================================================================================================================================================================>] 6,635 2.65KB/s in 2.4s 2020-03-29 06:30:21 (2.65 KB/s) - ‘mandatory.yaml’ saved [6635/6635] # 看下这个 yaml 文件需要哪些镜像 [root@master-kubeadm-k8s ~]# cat mandatory.yaml | grep image image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 # 单独拉取,会有些慢,但我们可以看到进度,如果直接用官方的方式,我们就不知道进行到哪了 root@master-kubeadm-k8s ~]# docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 0.30.0: Pulling from kubernetes-ingress-controller/nginx-ingress-controller c9b1b535fdd9: Pull complete 45ba4c948320: Downloading [==============> ] 14.68MB/51.78MB 70c24c20a569: Download complete 58acda238271: Downloading [=======================================> ] 14.54MB/18.51MB 7873cb07ba91: Download complete 3572b831a7ad: Waiting 2e4b94d88c7a: Waiting 73d054fe6162: Waiting 72107c0475b3: Waiting 0920fa00bdaf: Waiting bbc4231b0eed: Waiting 1a0d8e7b84e8: Waiting
-
设置Pod在指定节点创建
# 先查看节点的名称 [root@master-kubeadm-k8s ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION master-kubeadm-k8s Ready master 4d16h v1.14.0 worker01-kubeadm-k8s Ready
4d16h v1.14.0 worker02-kubeadm-k8s Ready 4d16h v1.14.0 # 在 master 节点给 worker01 节点打一个标签 name=ingress [root@master-kubeadm-k8s ~]# kubectl label node worker01-kubeadm-k8s name=ingress node/worker01-kubeadm-k8s labeled # 查看节点的labels, [root@master-kubeadm-k8s ~]# kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS master-kubeadm-k8s Ready master 4d16h v1.14.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master-kubeadm-k8s,kubernetes.io/os=linux,node-role.kubernetes.io/master= # worker01 节点多了个name=ingress的label worker01-kubeadm-k8s Ready 4d16h v1.14.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker01-kubeadm-k8s,kubernetes.io/os=linux,name=ingress worker02-kubeadm-k8s Ready 4d16h v1.14.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker02-kubeadm-k8s,kubernetes.io/os=linux -
修改 YAML 文件,增加自定义的配置
在 mandatory.yaml 文件中找到这一段
# ...省略... 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 # 表示使用HostPort方式运行,需要增加配置 # =========================== nodeSelector: # ==========原来的文件中是没有这个配置的================= name: ingress # 表示选择 label为 name: ingress 的节点 # =========================== kubernetes.io/os: linux containers: - name: nginx-ingress-controller image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: allowPrivilegeEscalation: true capabilities: drop: - ALL add: - NET_BIND_SERVICE # www-data -> 101 runAsUser: 101 # ...省略...
-
创建 mandatory 资源
[root@master-kubeadm-k8s ~]# kubectl apply -f mandatory.yaml namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.apps/nginx-ingress-controller created limitrange/ingress-nginx created
-
-
创建 tomcat的 Pod 和Service
-
编写 tomcat-hostPort.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 --- # 同一个yaml文件中配置多个资源 apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: tomcat # 选择label为 app: tomcat 的Pod
-
创建资源
[root@master-kubeadm-k8s hostPort]# kubectl apply -f tomcat-hostPort.yaml deployment.apps/tomcat-deployment created service/tomcat-service created
-
查看资源
# 查看 pods [root@master-kubeadm-k8s hostPort]# kubectl get pods NAME READY STATUS RESTARTS AGE tomcat-deployment-6b9d6f8547-6ltxl 1/1 Running 0 95s # 查看 Service [root@master-kubeadm-k8s hostPort]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1
443/TCP 4d17h tomcat-service ClusterIP 10.101.241.112 80/TCP 7s
-
-
创建 Ingress 以及定义转发规则
-
编写 nginx-ingress.yaml
#ingress apiVersion: networking.k8s.io/v1beta1 # 版本 kind: Ingress # 定义资源类型为 Ingress metadata: name: nginx-ingress spec: rules: # 定义规则 - host: tomcat.sunny.com # 匹配的 域名为 tomcat.sunny.com http: paths: # 匹配的路径, 可配置多个规则 - path: / # 表示访问根目录就会被匹配 backend: serviceName: tomcat-service # 要访问的 Service servicePort: 80 # 服务的端口(Service映射)
-
创建资源
[root@master-kubeadm-k8s hostPort]# kubectl apply -f nginx-ingress.yaml ingress.extensions/nginx-ingress created
-
查看ingress
# 可以看到这个ingress对外暴露的域名和端口 [root@master-kubeadm-k8s hostPort]# kubectl get ingress NAME HOSTS ADDRESS PORTS AGE nginx-ingress tomcat.sunny.com 80 122m
-
修改 Windows 的Hosts文件
192.168.50.112 tomcat.sunny.com # 测试能否通信 C:\WINDOWS\system32>ping tomcat.sunny.com 正在 Ping tomcat.sunny.com [192.168.50.112] 具有 32 字节的数据: 来自 192.168.50.112 的回复: 字节=32 时间<1ms TTL=64 来自 192.168.50.112 的回复: 字节=32 时间<1ms TTL=64 192.168.50.112 的 Ping 统计信息: 数据包: 已发送 = 2,已接收 = 2,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 0ms,平均 = 0ms Control-C
-
-
测试
这里已经访问到 Tomcat了, 只是现在最新的 Tomcat 镜像里都是空的,没有应用,所以访问不到内容!
总结
:如果以后想要使用Ingress网络,其实只要定义ingress,service 和 pod 即可,前提是要保证nginx ingress controller已经配置好了。
1.2.2.3 NodePort 与 HostPort 区别
- NodePort会在每个集群节点上都开放端口,占用端口资源
- HostPort只会在指定的某个节点开放端口,不会有端口资源浪费