k8s 網絡基礎
pod
Field | Description |
---|---|
containerPort | integer Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. |
hostIP | string What host IP to bind the external port to. |
hostPort | integer Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. |
name | string If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. |
protocol | string Protocol for port. Must be UDP or TCP. Defaults to "TCP". |
重點關注containerPort,他與Pod IP組成了endpoint,Pod IP就是docker0網橋分配的IP,有pause容器擁有,Pod其他容器與pause容器公用一個network namespace。
關于containerPort有個問題,如果一個pod中有2個容器,2個容器暴露相同的port,為什么可以?兩個容器應該是公用pause容器的網絡協議棧,如果tcp來了,到底是訪問哪個容器的里面的進程?
如果簡單點想盡快從外部訪問pod,就可以直接指定hostPort,一般不推薦。
這個問題需要理解pause,待解決
serivce
Field | Description |
---|---|
name | string The name of this port within the service. This must be a DNS_LABEL. All ports within a ServiceSpec must have unique names. This maps to the 'Name' field in EndpointPort objects. Optional if only one ServicePort is defined on this service. |
nodePort | integer The port on each node on which this service is exposed when type=NodePort or LoadBalancer. Usually assigned by the system. If specified, it will be allocated to the service if unused or else creation of the service will fail. Default is to auto-allocate a port if the ServiceType of this Service requires one. More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport |
port | integer The port that will be exposed by this service. |
protocol | string The IP protocol for this port. Supports "TCP" and "UDP". Default is TCP. |
targetPort | Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map). This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service |
- targetPort,將外部流量映射到對應Pod的Container Port
- port就是service port,與cluster ip組合就是k8s內部服務互相通信的地址
- nodePort:暴露給外部程序使用,需要與node ip一起使用,配合type: NodePort
service的網絡信息早期采用ENV管理,后期通過DNS系統,直接使用service name訪問cluster ip。
cluster ip
為什么cluster ip不能ping?
Headless Service
設置clusterIP: None,自己做LB,而非k8s做LB,提供cluster IP,減少網絡損耗。直接返回對應ep。
endpoints
service通過label selector篩選合適的pod,然后post到同名的Endpoints對象,Endpoints對象保存Endpoint,即Pod IP + Container Port
[圖片上傳失敗...(image-83ad0d-1536978807340)]
endpoints用法:
- 使用外部非k8s服務,比如外部還沒有容器化的數據庫服務
- 把一個service指向其他的service
具體流程:
- 創建一個沒有label selector的service,因為沒有選擇器,所以就沒有對應的Endpoints對象
- 手動創建Endpoints對象,重點是想要代理的服務地址
比如這里有個場景,batch服務的task多副本,一個task對應一個service,一個pod;那么如何對這些task多副本做一個統一的入口呢?我們可以在這些services上面再加一個serivce,然后手動創建對應的Endpoints,這里注意endpoint必須是pod ip,而不能是cluster ip,至于為什么暫時不清楚。
詳見services