美文网首页
K8s 的端口port映射问题

K8s 的端口port映射问题

作者: eleven_a1dc | 来源:发表于2019-12-18 14:46 被阅读0次

背景

对于port 可能有以下大概三种需求

  1. 同一个pod 里不同container 可以访问
  2. 在一个cluster 里, 不同pod 里可以访问
  3. 暴露到集群外面。即 可以在集群外通过ip 端口访问

先来了解下 k8s cluster networking

k8s cluster networking

每个pod 都有自己的 IP 地址 。这意味着你不需要 处理容器port 对 主机 port 的映射。pods 就像VM 或者 物理机哪样

k8s 的IP 地址 存在于 pod scope - 在一个Pod 的 容器们 共享 networknamespaces, 包括IP 地址。这意味着在一个pod 里的容器们 能够通过localhost 访问彼此的 端口。这也意味着 在一个pod 里的容器们需要协调 端口的使用。这就叫做 "IP-per-pod" model

来看一个例子

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80

将上面代码保存为nginx.yaml

kubectl apply -f nginx.yaml
# 查看pod
kubectl get pods -l run=my-nginx -o wide
# 查看pod ip
kubectl get pods -l run=my-nginx -o yaml | grep podIP

你可以ssh 连接到集群里的任意一个node 并curl IPs。 Note: 这个容器没有用node 的80 端口。也没有用NAT 规则到这个pod 上。这意味着可以在同一个node 上使用相同的 containerPort 并且在 你的集群里用ip 从node或者其他 pod 上去访问 它们。类似 Docker, ports 仍然可以被 published 到 host node 的接口上。但在这个网络模型下这个需求大大减少了。

Service

为什么需要 service ?

我们可以直接与pod 交流。但是当 一个node die 的时候会发生什么呢?
pod 也会die, 然后Deployment 会创建新的pods(IP不同)。这是 Service 要解决的问题。
来看一个service yaml

apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 80
  selector:
    run: my-nginx

kubectl get svc my-nginx

➜  k8s_demo kubectl get svc my-nginx
NAME       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
my-nginx   ClusterIP   10.68.82.69   <none>        8080/TCP   26s

你可以从集群里的任意node 上 curl nginx Service on <CLUSTER-IP>:<PORT>。 Note: service IP 是完全虚拟的。

访问 Service

两种方式

  • 环境变量
  • DNS

环境变量

kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
这事你并没有发现 my-nginx servervice.因为 pods 先启动的。还带来的一个缺点是 2个pods 都在一个机器上,当机器挂掉, service 也会挂掉。我们先杀死两个pod 然后 等待deployment 重新创建。会正确调度并且带有正确的环境变量。

DNS

k8s 提供了DNS 集群附加服务会自动授予其他services dns name。你可以检查它是不是在你的集群运行.
你可以在一个pod里 curl <service-name>:<port> 来访问service

kubectl get services kube-dns --namespace=kube-system

NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.68.0.2    <none>        53/UDP,53/TCP,9153/TCP   338d

expose internet

使用Nodeport 或者loadbalance

其他

当删除一个service, 再apply, cluster IP 也会变化
下面这张图 是说明了 deployment 的port 参数。这表示这个参数是不必要的,即使没有也会暴露出来


image.png

参考

相关文章

网友评论

      本文标题:K8s 的端口port映射问题

      本文链接:https://www.haomeiwen.com/subject/xinynctx.html