背景
对于port 可能有以下大概三种需求
- 同一个pod 里不同container 可以访问
- 在一个cluster 里, 不同pod 里可以访问
- 暴露到集群外面。即 可以在集群外通过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 参数。这表示这个参数是不必要的,即使没有也会暴露出来