四、Kubernetes|四、Kubernetes 网络模型

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 NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES nginx-deployment-6dd86d77d-2sm561/1Running08m44s192.168.14.17worker01-kubeadm-k8s nginx-deployment-6dd86d77d-dh5hj1/1Running08m44s192.168.14.16worker01-kubeadm-k8s nginx-deployment-6dd86d77d-zk8ms1/1Running08m44s192.168.221.76worker02-kubeadm-k8s

    • worker01 节点查看容器
      [root@worker01-kubeadm-k8s ~]# docker ps | grep nginx b918c5aa035284581e99d807"nginx -g 'daemon of…"About a minute agoUp About a minutek8s_nginx_nginx-deployment-6dd86d77d-2sm56_default_fde4c80d-70ea-11ea-937b-5254008afee6_0 54de8590872684581e99d807"nginx -g 'daemon of…"About a minute agoUp About a minutek8s_nginx_nginx-deployment-6dd86d77d-dh5hj_default_fe03776c-70ea-11ea-937b-5254008afee6_0 889f8517be18k8s.gcr.io/pause:3.1"/pause"About a minute agoUp About a minutek8s_POD_nginx-deployment-6dd86d77d-dh5hj_default_fe03776c-70ea-11ea-937b-5254008afee6_0 fbe190cf8c77k8s.gcr.io/pause:3.1"/pause"About a minute agoUp About a minutek8s_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 NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES nginx-deployment-6dd86d77d-rfgnq1/1Running016s192.168.14.19worker01-kubeadm-k8s nginx-deployment-6dd86d77d-xf2j61/1Running016s192.168.221.78worker02-kubeadm-k8s nginx-deployment-6dd86d77d-zx8971/1Running016s192.168.221.79worker02-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 NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES whoami-deployment-678b64444d-7nr871/1Running02m24s192.168.221.80worker02-kubeadm-k8s whoami-deployment-678b64444d-hpnm51/1Running02m24s192.168.14.20worker01-kubeadm-k8s whoami-deployment-678b64444d-mfhz41/1Running02m24s192.168.14.21worker01-kubeadm-k8s# 发现并没有 whoami 的service [root@master-kubeadm-k8s whoami]# kubectl get svc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE kubernetesClusterIP10.96.0.1443/TCP4d

    • 验证通信
      # 直接访问是没问题的 [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 NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGESELECTOR kubernetesClusterIP10.96.0.1443/TCP4d whoami-serviceClusterIP10.103.138.24580/TCP2m14sapp=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

    四、Kubernetes|四、Kubernetes 网络模型
    文章图片
    Service.png
其实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 NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE kubernetesClusterIP10.96.0.1443/TCP4d1h whoami-deploymentNodePort10.101.187.1698000:30184/TCP6s

  • 测试功能
    # 访问宿主机的 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

四、Kubernetes|四、Kubernetes 网络模型
文章图片
NodePort.png
> 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,6352.65KB/sin 2.4s2020-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 NAMESTATUSROLESAGEVERSION master-kubeadm-k8sReadymaster4d16hv1.14.0 worker01-kubeadm-k8sReady4d16hv1.14.0 worker02-kubeadm-k8sReady4d16hv1.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 NAMESTATUSROLESAGEVERSIONLABELS master-kubeadm-k8sReadymaster4d16hv1.14.0beta.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-k8sReady4d16hv1.14.0beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker01-kubeadm-k8s,kubernetes.io/os=linux,name=ingressworker02-kubeadm-k8sReady4d16hv1.14.0beta.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 NAMEREADYSTATUSRESTARTSAGE tomcat-deployment-6b9d6f8547-6ltxl1/1Running095s# 查看 Service [root@master-kubeadm-k8s hostPort]# kubectl get svc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE kubernetesClusterIP10.96.0.1443/TCP4d17h tomcat-serviceClusterIP10.101.241.11280/TCP7s

  • 创建 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 NAMEHOSTSADDRESSPORTSAGE nginx-ingresstomcat.sunny.com80122m

    • 修改 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=64192.168.50.112 的 Ping 统计信息: 数据包: 已发送 = 2,已接收 = 2,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 0ms,平均 = 0ms Control-C

  • 测试
    这里已经访问到 Tomcat了, 只是现在最新的 Tomcat 镜像里都是空的,没有应用,所以访问不到内容!
四、Kubernetes|四、Kubernetes 网络模型
文章图片
Test.png 四、Kubernetes|四、Kubernetes 网络模型
文章图片
HostPort.png
【四、Kubernetes|四、Kubernetes 网络模型】总结:如果以后想要使用Ingress网络,其实只要定义ingress,service 和 pod 即可,前提是要保证nginx ingress controller已经配置好了。
1.2.2.3 NodePort 与 HostPort 区别
  • NodePort会在每个集群节点上都开放端口,占用端口资源
  • HostPort只会在指定的某个节点开放端口,不会有端口资源浪费

    推荐阅读