一.容器外部访问容器内部服务

HostNetwork

需要容器内部服务与宿主机同一网段

特点:当Pod调度到哪个节点就使用哪个节点的IP地址,客户端使用IP地址访问容器里面的服务。一个node只能启动一个pod端口,端口不能冲突。

[root@k8s01 yaml]# cat end-nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx1
  labels:
    app: web
spec:
 hostNetwork: true
 containers:
  - name: ng-web
    image: nginx:latest
    imagePullPolicy: Never
[root@k8s01 yaml]# kubectl apply -f end-nginx.yaml
[root@k8s01 yaml]# kubectl  get pods -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
nginx1                1/1     Running   0          72s   192.168.54.129   k8s02   <none>           <none>

可以直接访问 192.168.54.129

HostPort

将容器内端口暴露出来

特点:Pod调度到哪个节点就用哪个节点的IP址访问, 端口可以随机指定。生产环境pod必须与宿机绑定才可使用。

[root@k8s01 yaml]# cat end-nginx2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx2
  labels:
    app: web
spec:
 containers:
  - name: ng-web2
    image: nginx:latest
    imagePullPolicy: Never
    ports:
    - name: http
      containerPort: 80     --容器端口
      hostPort: 80     --暴露端口(节点的端口)
      protocol: TCP
[root@k8s01 yaml]# kubectl apply -f  end-nginx2.yaml
pod/nginx2 created
[root@k8s01 yaml]# kubectl  get pods  -o wide
NAME           READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
nginx2               1/1     Running   0          4m31s   10.244.1.67   k8s02   <none>           <none>
[root@k8s01 yaml]# curl -I http://192.168.54.129      --Pod在哪个宿主机就用哪个IP地址 

NodePort

特 点:使用node节点的IP加端口可以访问Pod服务,master节点IP不可以访问。端口范围30000-32767。

[root@k8s01 yaml]# cat end-nginx3.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx3
  labels:
    app: web
spec:
 containers:
  - name: ng-web3
    image: nginx:latest
    imagePullPolicy: Never
    ports:
      - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: ng-service
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      nodePort: 31000  #不指定nodePort则随机选择30000-32767
  selector:     #后端Pod标签
    app: web
[root@k8s01 yaml]# kubectl apply -f  end-nginx3.yaml
pod/nginx3 created
service/ng-service created
[root@k8s01 yaml]# kubectl  get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP       NODE    NOMINATED NODE   READINESS GATES
nginx3         1/1     Running   0          63s   10.244.1.77   k8s02   <none>           <none>
[root@k8s01 yaml]# kubectl  get svc -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
ng-service   NodePort    10.102.52.148   <none>        80:31000/TCP   66s   app=web

使用任意nodeIP+ 31000 访问

LoadBalancer

特点:必须使用云服务商提供一个VIP地址,只能node节点的IP地址可以访问,master地址不能访问。

[root@k8s01 yaml]# cat end-nginx4.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx4
  labels:
    app: web
spec:
 containers:
  - name: ng-web4
    image: nginx:latest
    imagePullPolicy: Never
    ports:
      - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: ng-lb
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
  selector:
    app: web
status:                           --如果有vip就要写,没有就不用写。
  loadBalancer:
    ingress:
    - ip: 192.168.54.131
[root@k8s01 yaml]# kubectl apply -f  end-nginx4.yaml
pod/nginx4 created
service/ng-lb created
[root@k8s01 yaml]# kubectl  get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE    IP        NODE    NOMINATED NODE   READINESS GATES
nginx4            1/1     Running   0          4m6s   10.244.1.80   k8s02   <none>           <none>
[root@k8s01 yaml]# kubectl  get svc -o wide
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE     SELECTOR
ng-lb        LoadBalancer   10.99.49.195    <pending>     80:30183/TCP   4m10s   app=web     --没有VIP地址

使用任意nodeIP+ 30183 访问

二.容器内部服务访问外部服务

HostNetwork

需要Pod与宿主机IP在同一网段

[root@k8s01 yaml]# cat mysql.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: nginx5
  labels:
    app: mysql
spec:
  hostNetwork: true
  containers:
  - name: db-mysql
    image: nginx:latest
    imagePullPolicy: Never

endpoints

[root@k8s01 yaml]# cat endpoint.yaml

apiVersion: v1
kind: Endpoints
metadata:
  name: mysql-test
  namespace: default
subsets:
  - addresses:
    - ip: 192.168.54.130    #指定宿机主mysql服务器
    ports:
      - port: 3306      #指定端口
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-test    #service后端指向endpoints地址
  labels:
    app: abc
spec:
  ports:
    - port: 3306
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx6       #启动一个容器,测试连接mysql
  labels:
    app: db
spec:
 containers:
  - name: mysql-test
    image: nginx:latest
    imagePullPolicy: Never
[root@k8s01 yaml]# kubectl  apply -f endpoint.yaml
endpoints/mysql-test created
service/mysql-test created
pod/nginx6 created
[root@k8s01 yaml]# kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP          NODE    NOMINATED NODE   READINESS GATES
nginx6                    1/1     Running   0          12s   10.244.1.85   k8s02   <none>           <none>
[root@k8s01 yaml]# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE   SELECTOR
mysql-test   ClusterIP   10.98.57.89     <none>        3306/TCP   16s   <none>
[root@k8s01 yaml]# kubectl get endpoints -o wide
NAME         ENDPOINTS                       AGE
mysql-test   192.168.54.130:3306             21s
[root@k8s01 yaml]# kubectl exec -it nginx6 /bin/bash
root@ nginx6:/# mysql -h mysql-test -u repl -p123456    --使用endpoints名字(映射到service,service映射到192.168.54.130)

service中的配置

apiVersion: v1
kind: Service
metadata:
 name: nginx-service
spec:
 type: NodePort         // 配置为NodePort,外部可以访问
 ports:
 - port: 30080          // 容器间,服务调用的端口
   targetPort: 80       // 容器暴露的端口,与Dockerfile暴露端口保持一致
   nodePort: 30001      // NodePort,外部访问的端口,如果不显示指定,k8s会随机分配一个端口
 selector:
  name: nginx-pod

NodePort
nodeport是外部流量访问K8s的一种方式,即nodeIP:nodePort,是提供给外部流量访问K8s集群资源的一种方式。总的来说,我们可以通过在service中配置nodeport,从而使得我们可以通过集群外的机器进行访问我们的服务。

Port
port是K8s集群内部服务访问service的入口。是service暴露在Cluster上的端口,ClusterIP:Port。如下面的yaml配置文件所示,K8s集群内部节点可以通过30080端口访问Nginx服务,然而外部网络还是不能够访问到服务,因为nodePort参数没有配置。

targetPort
targetPort是容器的端口,也是最终底层的服务所提供的端口,所以说targetPod也就是Pod的端口。从port或者是nodePort进入的流量,经过路由转发之后,最终都会都通过targetPort进入到Pod中。

targetPort要与Dockerfile中暴露的端口一致。

Kubernetes集群里有三种IP地址,分别如下:

  • Node IP:Node节点的IP地址,即物理网卡的IP地址。
  • Pod IP:Pod的IP地址,即docker容器的IP地址,此为虚拟IP地址。
  • Cluster IP:Service的IP地址,此为虚拟IP地址。外部网络无法ping通,只有kubernetes集群内部访问使用。
  • Node IP
    可以是物理机的IP(也可能是虚拟机IP)。每个Service都会在Node节点上开通一个端口,外部可以通过NodeIP:NodePort即可访问Service里的Pod,和我们访问服务器部署的项目一样,IP:端口/项目名。
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐