K8S的containerPort、hostPort和service的port、targetPort、nodePort

K8S的containerPort、hostPort和service的port、targetPort、nodePort

  • k8s集群的端口映射
    • 1.1 containerPort(容器内部端口)
    • 1.2 hostPort(将pod的端口直接映射到真机上,不使用service绑定)
    • 1.3 service的port、targetPort、nodePort
      • 1.3.1 service的port端口和镜像的端口一致
      • 1.3.2 service的port和targetPort配合使用
      • 1.3.2 nodePort(节点开放端口,pod对外端口)

k8s集群的端口映射

1.1 containerPort(容器内部端口)

搭建K8S文档:yum安装K8S
ansible搭建K8S集群:ansible搭建K8S
准备至少3个机器搭建好K8S集群

节点名称 IP
k8s-master 192.168.116.134
k8s-node1 192.168.116.135
k8s-node2 192.168.116.136

官网port和service文档:K8S-service-port
containerPort:正常情况下,pod的镜像只要有启用服务和端口,就可以在pod和pod之间访问了,流量已经可以在pod出去了。而containerPort这个字段主要是为了指明端口(让机器知道开放了什么端口)以及和集群的service或者真机进行绑定,让流量知道怎么进入pod。

查看集群节点开放端口

ss -tnl    查看k8s-node1,k8s-node2没有创建pod的时候的开放的端口

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第1张图片
K8S的containerPort、hostPort和service的port、targetPort、nodePort_第2张图片
创建一个pod

vi nginx-container.yml   创建pod

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-con
  name: nginx-con-deployment
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-con
  template:
    metadata:
      labels:
        app: nginx-con
    spec:
      containers:
      - name: nginx-con
        image: docker.io/library/nginx:1.18.0-alpine
        ports:
        - containerPort: 80   #让集群知道pod开放的端口


kubectl apply -f nginx-container.yml   创建pod
kubectl get pod -o wide                查看pod的创建节点

进入容器
kubectl exec -it nginx-con-deployment-7cff68b8f8-f5lbm /bin/sh

vi /etc/apk/repositories   修改源为国内源

https://mirrors.aliyun.com/alpine/v3.6/main
https://mirrors.aliyun.com/alpine/v3.6/community

apk add net-tools    安装网络工具
netstat -tnl         可以看到pod的80端口是开放的
ip a                查看ip为10.100.2.144

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第3张图片

在创建上面pod的k8s-node2节点上查看没有新增的开放端口
证明这个pod没有对外开放端口

ss -tnl

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第4张图片
在master创建一个测试容器,测试pod和pod之间的访问

kubectl run net-test1 --image=alpine --replicas=1 sleep 360000 创建测试pod
kubectl get pod  查看pod名字
kubectl exec -it net-test1-5fcc69db59-mztj2 /bin/sh 连接pod

vi /etc/apk/repositories   修改源为国内源

https://mirrors.aliyun.com/alpine/v3.6/main
https://mirrors.aliyun.com/alpine/v3.6/community

apk add curl    安装网络工具

可以看到网页内容
证明2个pod之间是可以相互访问的,上面的那个老的pod的80端口只是对pod和pod之间开放
curl http://10.100.2.144

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第5张图片

1.2 hostPort(将pod的端口直接映射到真机上,不使用service绑定)

hostport:将pod开放的端口映射到真机节点上,只要有外来的访问到真机的这个端口,那么真机会通过路由和套接字的方式将访问转发到pod。

注意:

  1. pod的yml必须要有containerPort字段指明端口
  2. 创建pod的节点不会开放端口,只会转发流量,如果节点也开放了这个端口,访问请求优先转发到pod
  3. 这种操作适合一次性测试使用,正式环境最好不要使用
  4. 因为pod有重建机制,所以当pod重建到其他节点时,访问的IP也会发生变化

在master创建pod

vi nginx-hostport.yml 

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-host
  name: nginx-host-deployment
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-host
  template:
    metadata:
      labels:
        app: nginx-host
    spec:
      containers:
      - name: nginx-host
        image: docker.io/library/nginx:1.18.0-alpine
        ports:
        - containerPort: 80
          hostPort: 80
          
kubectl apply -f nginx-hostport.yml   创建pod
kubectl get pod -o wide               可以看到pod在k8s-node2创建

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第6张图片
在k8s-node2可以看到没有开放80端口

ss -tnl

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第7张图片
用master直接访问k8s-node2的真机IP的80端口,可以访问到网页

curl http://192.168.116.136

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第8张图片

1.3 service的port、targetPort、nodePort

port:在k8s集群中,service的port可任意取值的抽象端口,其他 Pod 通过该端口访问 Service,正常情况下,service的port和pod镜像开放的端口一致。

比如nginx的镜像是开放80端口,service的port指定的是80端口,那么pod和pod直接就可以进行访问,不用指定targetPort端口。

1.3.1 service的port端口和镜像的端口一致

在master查看service

kubectl get svc -A    可以看到集群2个默认的service

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第9张图片
在master创建pod和service绑定

vi nginx-service-port.yml   创建pod

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-service-port
  name: nginx-service-port-deployment
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-service-port
  template:
    metadata:
      labels:
        app: nginx-service-port
    spec:
      containers:
      - name: nginx-service-port
        image: docker.io/library/nginx:1.18.0-alpine
        ports:
        - containerPort: 80
--- #2个api之间必须要有这个间隔
apiVersion: v1
kind: Service
metadata:
  labels:
    svc: nginx-svc-port     #设置service的标签
  name: nginx-svc-port      #设置service的显示名字
spec:
  ports:
  - port: 80               #让集群知道service绑定的端口
  selector:
    app: nginx-service-port  #指定pod的标签

kubectl apply -f nginx-service-port.yml    创建pod
kubectl get pod -o wide                    查看pod的IP
kubectl get svc -A                         查看service是否创建
kubectl describe svc nginx-svc-port        指定service查看详细信息

Endpoints:         10.100.2.159:80       这个就是代表service绑定的pod的IP

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第10张图片
在master重建pod,查看service的Endpoints的ip会不会随着pod重建而发生改变

上面service的Endpoints的ip对应pod的ip10.100.2.159

kubectl get pod -o wide  查看老的pod的名字

指定pod名字删除,不指定名称空间只会重建pod
kubectl delete pod nginx-service-port-deployment-848bcb6657-5jcxf -n default
kubectl get svc -A   查看service名字
kubectl describe svc nginx-svc-port  再次查看service的详细信息

Endpoints:  10.100.2.160:80  可以看到service会随着绑定的pod的IP变化而变化

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第11张图片
port 注意:
当pod和service绑定后:

  • 不是创建pod的真机node节点不能直接访问service的IP
  • 创建pod的真机node节点能直接访问service的IP
  • pod和pod之间可以直接访问pod的IP和service的IP
  • 有配置dns容器情况下,pod和pod之间可以直接用service的名字访问

在master节点查看

kubectl get pod -o wide             查看pod创建在k8s-node2,IP为10.100.2.160
kubectl get svc                     查看service
curl -I http://10.100.2.160         访问pod的IP
curl -I http://10.200.197.189       访问service的IP,可以看到不能直接访问

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第12张图片
在pod之间访问

kubectl get pod -o wide           查看pod
kubectl exec -it net-test1-5fcc69db59-mztj2 /bin/sh   连接另外的pod
curl -I http://10.100.2.160         访问pod的IP
curl -I http://10.200.197.189       访问service的IP
curl -I http://nginx-svc-port       访问service的名字

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第13张图片

在k8s-node2节点查看

在创建pod的节点上,直接访问pod的IP和service的IP可以直接访问
curl -I http://10.100.2.160         访问pod的IP
curl -I http://10.200.197.189       访问service的IP

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第14张图片

1.3.2 service的port和targetPort配合使用

targetPort:指定从集群内部或外部流入pod的流量端口,通常配合port、nodePort使用。一般port、nodePort和镜像的3个端口一致。
当service的port为其他端口,targetPort指定pod镜像端口时:
比如nginx的镜像是开放80端口,但是service的port指定的是33端口,这种情况下其他pod访问时,就需要访问nginx的service的33端口。

在master创建pod和service

vi nginx-service-port2.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-service-port2
  name: nginx-service-port2-deployment
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-service-port2
  template:
    metadata:
      labels:
        app: nginx-service-port2
    spec:
      containers:
      - name: nginx-service-port2
        image: docker.io/library/nginx:1.18.0-alpine
        ports:
        - containerPort: 80  #指定流量进入pod的端口
---
apiVersion: v1
kind: Service
metadata:
  labels:
    svc: nginx-svc-port2
  name: nginx-svc-port2
spec:
  ports:
  - port: 33              #设置service的端口
    targetPort: 80        #设置pod的端口
  selector:
    app: nginx-service-port2  #指定pod的标签
    
kubectl apply -f nginx-service-port2.yml   创建pod
kubectl get pod -o wide                    查看pod的IP
kubectl get svc                            查看service
kubectl describe svc nginx-svc-port2       查看service的详细信息

Port:              <unset>  33/TCP   可以看到service的端口是33

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第15张图片
在测试容器上安装工具,测试pod和pod之间的访问

kubectl get pod 
kubectl exec -it net-test1-5fcc69db59-7tbsz /bin/sh  进入容器
apk add busybox-extras curl
busybox-extras telnet 10.100.2.167 80     连接nginx的pod的80端口可以连接
curl -I http://10.100.2.167               访问网站可以访问

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第16张图片
在测试容器上,测试pod和service之间的访问

kubectl exec -it net-test1-5fcc69db59-7tbsz /bin/sh   进入容器
busybox-extras telnet 10.200.79.16 80               连接service的80端口
busybox-extras telnet 10.200.79.16 33               连接service的33端口

可以看到service的80端口实际是没有在工作的
所以当其他pod需要指定service的端口时,必须指定33端口
curl -I http://10.200.79.16:33              访问service的33端口
curl -I http://10.200.79.16:80              访问service的80端口

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第17张图片

1.3.2 nodePort(节点开放端口,pod对外端口)

nodePort:在k8s集群中,将pod的内部端口映射到创建pod的节点的指定端口,让外部的流量可以到达pod。

默认yum安装的K8S集群node的开放的端口为30000-32767
如果不是设置这个范围,会提示下面这个报错
The Service “nginx-svc-port” is invalid: spec.ports[0].nodePort: Invalid value: 80: provided port is not in the valid range. The range of valid ports is 30000-32767

如果想要修改K8S集群的端口,按照下面操作
全部master节点修改这个文件,yum按照k8s是这个路径

vi /etc/kubernetes/manifests/kube-apiserver.yaml
在spec.containers.- command字段中添加指定的端口
spec:
  containers:
  - command:
    - --service-node-port-range=10000-12767  #添加指定端口范围

查看k8s-master的api容器名字
kubectl get pods --selector=component=kube-apiserver -n kube-system --output=jsonpath={.items..metadata.name}

指定pod名字,让集群自动重建容器
kubectl delete pod kube-apiserver-k8s-master -n kube-system
kubectl get pod -n kube-system  查看pod的运行时间是否改变

查看pod的信息是否变化
kubectl describe pod kube-apiserver-k8s-master -n kube-system |grep service

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第18张图片
master创建pod

vi nginx-service-nodeport.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-service-nodeport  #设置pod标签
  name: nginx-service-nodeport-deployment
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-service-nodeport
  template:
    metadata:
      labels:
        app: nginx-service-nodeport
    spec:
      containers:
      - name: nginx-service-nodeport
        image: docker.io/library/nginx:1.18.0-alpine
        ports:
        - containerPort: 80  #指定pod端口
---
apiVersion: v1
kind: Service
metadata:
  labels:
    svc: nginx-svc-nodeport
  name: nginx-svc-nodeport
spec:
  type: NodePort     #默认是clusterIP,如果是nodePort,要设置这个
  ports:
  - port: 80         #指定service端口
    targetPort: 80   #指定pod端口
    nodePort: 10080  #指定node的端口
  selector:
    app: nginx-service-nodeport  #指定pod的标签

kubectl apply -f nginx-service-nodeport.yml  创建pod
kubectl get pod -o wide                      查看pod创建的节点
kubectl get svc                              查看service
kubectl describe svc nginx-svc-nodeport      查看service的详细信息

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第19张图片
在创建pod的k8s-node2查看端口是否打开

ss -tnl     可以看到端口10080已经打开

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第20张图片
在master测试访问,可以看到节点端口能被访问

kubectl get pod -o wide            查看pod的IP
kubectl get svc -o wide            查看service
kubectl describe svc nginx-svc-nodeport  查看service的信息
curl -I http://10.100.2.172              访问pod
curl -I http://192.168.116.136:10080     访问节点开放的端口

K8S的containerPort、hostPort和service的port、targetPort、nodePort_第21张图片

你可能感兴趣的:(系统服务,kubernetes,docker,容器,运维,centos)