访问k8s中的Pod的几种方式

2,191 阅读4分钟

HostNetwork

如果在Pod中使用hostNetwork:true配置的话,在这种pod中运行的应用程序可以直接看到pod启动的主机的网络接口。在主机的所有网络接口上都可以访问到该应用程序。以下是使用主机网络的pod的示例定义:

apiVersion: v1
kind: Pod
metadata:
   name: nginx
   labels:
      app: nginx-web
spec:
   hostNetwork: true
   containers:
   - name: nginx
     image: nginx:1.14.2
     ports:
       - containerPort: 80
     imagePullPolicy: IfNotPresent

注意每次启动这个Pod的时候都可能被调度到不同的节点上,所有外部访问Pod的IP也是变化的,而且调度Pod的时候还需要考虑是否与宿主机上的端口冲突,因此一般情况下除非您知道需要某个特定应用占用特定宿主机上的特定端口时才使用hostNetwork: true的方式。

HostPort

这是一种直接定义Pod网络的方式,hostPort是直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过宿主机的IP加上来访问Pod了,如:

apiVersion: v1
kind: Pod
metadata:
   name: nginx
   labels:
      app: nginx-web
spec:
   containers:
   - name: nginx
     image: nginx:1.14.2
     ports:
       - containerPort: 80
         hostPort: 8088
     imagePullPolicy: IfNotPresent

这样做有个缺点,因为Pod重新调度的时候该Pod被调度到的宿主机可能会变动,这样就变化了,用户必须自己维护一个Pod与所在宿主机的对应关系;这种网络方式可以用来做 nginx Ingress controller。外部流量都需要通过kubenretes node节点的80和443端口。

NodePort

NodePort在kubenretes里是一个广泛应用的服务暴露方式。Kubernetes中的service默认情况下都是使用的ClusterIP这种类型,这样的service会产生一个ClusterIP,这个IP只能在集群内部访问,要想让外部能够直接访问service,需要将service type修改为 nodePort:

apiVersion: v1
kind: Pod
metadata:
   name: my-nginx
   labels:
      app: my-nginx
spec:
   containers:
   - name: my-nginx
     image: nginx:1.14.2
     ports:
       - containerPort: 80

同时还可以给service指定一个nodePort值,范围是30000-32767,这个值在API server的配置文件中,用--service-node-port-range定义:

kind: Service
apiVersion: v1
metadata:
  name: nginx-service
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 31000
  selector:
    app: my-nginx

集群外就可以使用kubernetes任意一个节点的IP加上31000端口访问该服务了。kube-proxy会自动将流量以round-robin的方式转发给该service的每一个pod;这种服务暴露方式,无法让你指定自己想要的应用常用端口,不过可以在集群上再部署一个反向代理作为流量入口。

LoadBalancer

这玩意是要收费的,这边就不写例子了;LoadBalancer 只能在service上定义。这是公有云提供的负载均衡器,如AWS、Azure、CloudStack、GCE等。

Ingress

需先安装ingress-controller,之前安装的时候饶了很多弯路,安装的ingress-chart包要么是低于1.18版本的要么是高于1.18版本以至于不能install成功的,这边找了个1.18版本能用的chart包: 下载地址
安装命令:

             helm应用名称   上面的压缩包的包名         设置额外参数:你的k8s集群有多少个节点就要配多少个
helm install nginx-ingress nginx-ingress --set "controller.service.externalIPs[0]=172.17.68.39,controller.service.externalIPs[1]=172.17.68.40"

显示如下输出时就说明安装成功了,当然还需要看下ingress-controller 那个pod是否正常启动: 1.png 这边安装的时候遇到了个问题就是nginx-ingress-ingress-nginx-controller这个pod 镜像一直拉不下来,看了下原来是谷歌的镜像:k8s.gcr.io/ingress-nginx/controller:v0.48.1@sha256:e9fb216ace49dfa4a5983b183067e97496e7a8b307d2093f4278cd550c303899

然后我就docker search 了一下别人封装的镜像,然后就找到了人家同步过来的: 2.png 于是我就拉了下来,然后重新tag了一下:

docker tag willdockerhub/ingress-nginx-controller:v0.48.1 k8s.gcr.io/ingress-nginx/controller:v0.48.1

然后再去改了ingress-nginx chart包里面的image地址,把digest给去了,然后我的pod就起来了,至此ingress-controller就安装好了。

配置 Ingress 映射域名:

与已知知识关联有助于我们更好地学习新知识,以下是关于 nginx 与 ingress 部署一个博客应用的简单配置文件

  1. 外网通过域名 nginx.xiange.tech 来访问应用
  2. 代理服务 nginx 来做负载均衡
  3. nginx 暴露出 80 端口
server {
  listen 80
  server_name nginx.xiange.tech

  location / {
    proxy_pass: http://nginx:80
  }
}

然后就编写我们的ingres资源对象,并在里面绑定service就可以啦: 注意:这里的host要配置域名

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-service-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: dong.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: nginx-service
          servicePort: 80
      - path: /bar
        backend:
          serviceName: spring-boot-k8s-service
          servicePort: 8080

Forward

kubectl port-forward 允许使用资源名称 (例如 pod 名称)来选择匹配的 pod 来进行端口转发:

kubectl port-forward pod名称 28015:27017
输出:
Forwarding from 127.0.0.1:28015 -> 27017
Forwarding from [::1]:28015 -> 27017

这个命令的功能是把宿主的端口请求转发到pod中的端口,左边为宿主机的端口,右边为pod的端口。