將應用程式與服務連接
用於連接容器的 Kubernetes 模型
現在您已擁有持續執行、複寫的應用程式,您可以將其公開在網路上。
Kubernetes 假設 Pod 可以與其他 Pod 通訊,無論它們落在哪個主機上。Kubernetes 為每個 Pod 提供自己的叢集私有 IP 位址,因此您不需要明確地在 Pod 之間建立連結或將容器連接埠對應至主機連接埠。這表示 Pod 內的容器都可以在 localhost 上互相存取連接埠,並且叢集中的所有 Pod 都可以互相看到,而無需 NAT。本文檔的其餘部分詳細說明如何在這樣的網路模型上執行可靠的服務。
本教學課程使用簡單的 nginx Web 伺服器來示範此概念。
將 Pod 公開至叢集
我們在先前的範例中已執行此操作,但讓我們再次執行它,並專注於網路角度。建立 nginx Pod,並注意它具有容器連接埠規格
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
這使其可從叢集中的任何節點存取。檢查 Pod 正在執行的節點
kubectl apply -f ./run-my-nginx.yaml
kubectl get pods -l run=my-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m
my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd
檢查您的 Pod IP
kubectl get pods -l run=my-nginx -o custom-columns=POD_IP:.status.podIPs
POD_IP
[map[ip:10.244.3.4]]
[map[ip:10.244.2.5]]
您應該能夠 ssh 連線到叢集中的任何節點,並使用像是 curl
這類的工具,對兩個 IP 進行查詢。請注意,這些容器並未使用節點上的 80 埠,也沒有任何特殊的 NAT 規則將流量路由到 Pod。這表示您可以在同一個節點上執行多個 nginx Pod,全部都使用相同的 containerPort
,並從叢集中的任何其他 Pod 或節點,使用指派給 Pod 的 IP 位址來存取它們。如果您想要安排將主機節點上的特定埠轉發到後端的 Pod,您可以做到 - 但網路模型應該表示您不需要這樣做。
如果您感到好奇,可以閱讀更多關於 Kubernetes 網路模型 的資訊。
建立服務(Service)
因此,我們在一個扁平的、叢集範圍的位址空間中執行 nginx Pod。理論上,您可以直接與這些 Pod 通訊,但是當節點故障時會發生什麼事?Pod 會隨著節點一起停止運作,而 Deployment 內的 ReplicaSet 將會建立新的 Pod,並具有不同的 IP。這就是 Service 要解決的問題。
Kubernetes Service 是一種抽象概念,它定義了在叢集中某處運行的、提供相同功能的一組邏輯 Pod。當建立時,每個 Service 都會被指派一個唯一的 IP 位址(也稱為 clusterIP)。此位址與 Service 的生命週期相關聯,並且在 Service 存活期間不會變更。Pod 可以設定為與 Service 通訊,並且知道與 Service 的通訊將會自動負載平衡到作為 Service 成員的某個 Pod。
您可以使用 kubectl expose
為您的 2 個 nginx 副本建立一個 Service
kubectl expose deployment/my-nginx
service/my-nginx exposed
這等同於在以下 yaml 中使用 kubectl apply -f
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
此規範將建立一個 Service,目標是標籤為 run: my-nginx
的任何 Pod 上的 TCP 80 埠,並在抽象化的 Service 埠上公開它 (targetPort
:是容器接受流量的埠,port
:是抽象化的 Service 埠,可以是任何其他 Pod 用於存取 Service 的埠)。檢視 Service API 物件,以查看 Service 定義中支援的欄位列表。檢查您的 Service
kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.0.162.149 <none> 80/TCP 21s
如先前所述,Service 由一組 Pod 支援。這些 Pod 通過 EndpointSlices 公開。Service 的選擇器將會持續評估,並且結果將會 POST 到使用 標籤 連接到 Service 的 EndpointSlice。當 Pod 停止運作時,它會自動從包含它作為端點的 EndpointSlices 中移除。符合 Service 選擇器的新 Pod 將會自動新增到該 Service 的 EndpointSlice。檢查端點,並注意這些 IP 與第一步中建立的 Pod 的 IP 相同
kubectl describe svc my-nginx
Name: my-nginx
Namespace: default
Labels: run=my-nginx
Annotations: <none>
Selector: run=my-nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.0.162.149
IPs: 10.0.162.149
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.5:80,10.244.3.4:80
Session Affinity: None
Events: <none>
kubectl get endpointslices -l kubernetes.io/service-name=my-nginx
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
my-nginx-7vzhx IPv4 80 10.244.2.5,10.244.3.4 21s
現在您應該能夠從叢集中的任何節點,使用 curl 對 <叢集-IP>:<埠號>
上的 nginx Service 進行操作。請注意,Service IP 完全是虛擬的,它永遠不會實際傳輸。如果您對這如何運作感到好奇,可以閱讀更多關於 service proxy 的資訊。
存取 Service
Kubernetes 支援兩種主要的 Service 尋找模式 - 環境變數和 DNS。前者開箱即用,而後者則需要 CoreDNS 叢集附加元件。
注意
如果不需要 Service 環境變數(因為可能與預期的程式變數衝突、變數太多而無法處理、僅使用 DNS 等),您可以透過在 pod spec 上將enableServiceLinks
標誌設定為 false
來停用此模式。環境變數
當 Pod 在節點上執行時,kubelet 會為每個作用中的 Service 新增一組環境變數。這會引入排序問題。為了了解原因,請檢查您正在執行的 nginx Pod 的環境(您的 Pod 名稱會有所不同)
kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
請注意,沒有提到您的 Service。這是因為您在 Service 之前建立了副本。這樣做的另一個缺點是,排程器可能會將兩個 Pod 放在同一部機器上,如果該機器故障,將會使您的整個 Service 停止運作。我們可以透過終止 2 個 Pod 並等待 Deployment 重新建立它們來以正確的方式執行此操作。這次 Service 在副本之前就已存在。這將為您提供 Pod 的排程器層級 Service 分散(假設您的所有節點都具有相等的容量),以及正確的環境變數
kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2;
kubectl get pods -l run=my-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-e9ihh 1/1 Running 0 5s 10.244.2.7 kubernetes-minion-ljyd
my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8 kubernetes-minion-905m
您可能會注意到 Pod 有不同的名稱,因為它們被終止並重新建立。
kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE
KUBERNETES_SERVICE_PORT=443
MY_NGINX_SERVICE_HOST=10.0.162.149
KUBERNETES_SERVICE_HOST=10.0.0.1
MY_NGINX_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT_HTTPS=443
DNS
Kubernetes 提供了一個 DNS 叢集附加元件 Service,可以自動為其他 Service 指派 DNS 名稱。您可以檢查它是否在您的叢集上執行
kubectl get services kube-dns --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 8m
本節的其餘部分將假設您有一個具有長期 IP (my-nginx) 的 Service,以及一個已為該 IP 指派名稱的 DNS 伺服器。在這裡,我們使用 CoreDNS 叢集附加元件(應用程式名稱 kube-dns
),因此您可以使用標準方法(例如 gethostbyname()
)從叢集中的任何 Pod 與 Service 通訊。如果 CoreDNS 沒有執行,您可以參考 CoreDNS README 或 安裝 CoreDNS 來啟用它。讓我們執行另一個 curl 應用程式來測試這個
kubectl run curl --image=radial/busyboxplus:curl -i --tty --rm
Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false
Hit enter for command prompt
然後,按下 Enter 鍵並執行 nslookup my-nginx
[ root@curl-131556218-9fnch:/ ]$ nslookup my-nginx
Server: 10.0.0.10
Address 1: 10.0.0.10
Name: my-nginx
Address 1: 10.0.162.149
保護 Service 的安全
到目前為止,我們僅從叢集內部存取了 nginx 伺服器。在將 Service 公開到網際網路之前,您需要確保通訊通道是安全的。為此,您將需要
- 用於 https 的自我簽署憑證(除非您已經有身分憑證)
- 設定為使用憑證的 nginx 伺服器
- 一個 secret,使憑證可以被 Pod 存取
您可以從 nginx https 範例 中取得所有這些。這需要安裝 go 和 make 工具。如果您不想安裝這些工具,請按照稍後的步驟手動操作。簡而言之
make keys KEY=/tmp/nginx.key CERT=/tmp/nginx.crt
kubectl create secret tls nginxsecret --key /tmp/nginx.key --cert /tmp/nginx.crt
secret/nginxsecret created
kubectl get secrets
NAME TYPE DATA AGE
nginxsecret kubernetes.io/tls 2 1m
以及 configmap
kubectl create configmap nginxconfigmap --from-file=default.conf
您可以在 Kubernetes examples 專案儲存庫 中找到 default.conf
的範例。
configmap/nginxconfigmap created
kubectl get configmaps
NAME DATA AGE
nginxconfigmap 1 114s
您可以使用以下命令檢視 nginxconfigmap
ConfigMap 的詳細資訊
kubectl describe configmap nginxconfigmap
輸出類似於
Name: nginxconfigmap
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
default.conf:
----
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
listen 443 ssl;
root /usr/share/nginx/html;
index index.html;
server_name localhost;
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/tls.key;
location / {
try_files $uri $uri/ =404;
}
}
BinaryData
====
Events: <none>
以下是在您執行 make 時遇到問題(例如在 Windows 上)時要遵循的手動步驟
# Create a public private key pair
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /d/tmp/nginx.key -out /d/tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx"
# Convert the keys to base64 encoding
cat /d/tmp/nginx.crt | base64
cat /d/tmp/nginx.key | base64
使用先前命令的輸出,建立一個 yaml 檔案,如下所示。base64 編碼值應全部在一行上。
apiVersion: "v1"
kind: "Secret"
metadata:
name: "nginxsecret"
namespace: "default"
type: kubernetes.io/tls
data:
tls.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIekNDQWdlZ0F3SUJBZ0lKQUp5M3lQK0pzMlpJTUEwR0NTcUdTSWIzRFFFQkJRVUFNQ1l4RVRBUEJnTlYKQkFNVENHNW5hVzU0YzNaak1SRXdEd1lEVlFRS0V3aHVaMmx1ZUhOMll6QWVGdzB4TnpFd01qWXdOekEzTVRKYQpGdzB4T0RFd01qWXdOekEzTVRKYU1DWXhFVEFQQmdOVkJBTVRDRzVuYVc1NGMzWmpNUkV3RHdZRFZRUUtFd2h1CloybHVlSE4yWXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSjFxSU1SOVdWM0IKMlZIQlRMRmtobDRONXljMEJxYUhIQktMSnJMcy8vdzZhU3hRS29GbHlJSU94NGUrMlN5ajBFcndCLzlYTnBwbQppeW1CL3JkRldkOXg5UWhBQUxCZkVaTmNiV3NsTVFVcnhBZW50VWt1dk1vLzgvMHRpbGhjc3paenJEYVJ4NEo5Ci82UVRtVVI3a0ZTWUpOWTVQZkR3cGc3dlVvaDZmZ1Voam92VG42eHNVR0M2QURVODBpNXFlZWhNeVI1N2lmU2YKNHZpaXdIY3hnL3lZR1JBRS9mRTRqakxCdmdONjc2SU90S01rZXV3R0ljNDFhd05tNnNTSzRqYUNGeGpYSnZaZQp2by9kTlEybHhHWCtKT2l3SEhXbXNhdGp4WTRaNVk3R1ZoK0QrWnYvcW1mMFgvbVY0Rmo1NzV3ajFMWVBocWtsCmdhSXZYRyt4U1FVQ0F3RUFBYU5RTUU0d0hRWURWUjBPQkJZRUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjcKTUI4R0ExVWRJd1FZTUJhQUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjdNQXdHQTFVZEV3UUZNQU1CQWY4dwpEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRVhTMW9FU0lFaXdyMDhWcVA0K2NwTHI3TW5FMTducDBvMm14alFvCjRGb0RvRjdRZnZqeE04Tzd2TjB0clcxb2pGSW0vWDE4ZnZaL3k4ZzVaWG40Vm8zc3hKVmRBcStNZC9jTStzUGEKNmJjTkNUekZqeFpUV0UrKzE5NS9zb2dmOUZ3VDVDK3U2Q3B5N0M3MTZvUXRUakViV05VdEt4cXI0Nk1OZWNCMApwRFhWZmdWQTRadkR4NFo3S2RiZDY5eXM3OVFHYmg5ZW1PZ05NZFlsSUswSGt0ejF5WU4vbVpmK3FqTkJqbWZjCkNnMnlwbGQ0Wi8rUUNQZjl3SkoybFIrY2FnT0R4elBWcGxNSEcybzgvTHFDdnh6elZPUDUxeXdLZEtxaUMwSVEKQ0I5T2wwWW5scE9UNEh1b2hSUzBPOStlMm9KdFZsNUIyczRpbDlhZ3RTVXFxUlU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
tls.key: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2RhaURFZlZsZHdkbFIKd1V5eFpJWmVEZWNuTkFhbWh4d1NpeWF5N1AvOE9ta3NVQ3FCWmNpQ0RzZUh2dGtzbzlCSzhBZi9WemFhWm9zcApnZjYzUlZuZmNmVUlRQUN3WHhHVFhHMXJKVEVGSzhRSHA3VkpMcnpLUC9QOUxZcFlYTE0yYzZ3MmtjZUNmZitrCkU1bEVlNUJVbUNUV09UM3c4S1lPNzFLSWVuNEZJWTZMMDUrc2JGQmd1Z0ExUE5JdWFubm9UTWtlZTRuMG4rTDQKb3NCM01ZUDhtQmtRQlAzeE9JNHl3YjREZXUraURyU2pKSHJzQmlIT05Xc0RadXJFaXVJMmdoY1kxeWIyWHI2UAozVFVOcGNSbC9pVG9zQngxcHJHclk4V09HZVdPeGxZZmcvbWIvNnBuOUYvNWxlQlkrZStjSTlTMkQ0YXBKWUdpCkwxeHZzVWtGQWdNQkFBRUNnZ0VBZFhCK0xkbk8ySElOTGo5bWRsb25IUGlHWWVzZ294RGQwci9hQ1Zkank4dlEKTjIwL3FQWkUxek1yall6Ry9kVGhTMmMwc0QxaTBXSjdwR1lGb0xtdXlWTjltY0FXUTM5SjM0VHZaU2FFSWZWNgo5TE1jUHhNTmFsNjRLMFRVbUFQZytGam9QSFlhUUxLOERLOUtnNXNrSE5pOWNzMlY5ckd6VWlVZWtBL0RBUlBTClI3L2ZjUFBacDRuRWVBZmI3WTk1R1llb1p5V21SU3VKdlNyblBESGtUdW1vVlVWdkxMRHRzaG9reUxiTWVtN3oKMmJzVmpwSW1GTHJqbGtmQXlpNHg0WjJrV3YyMFRrdWtsZU1jaVlMbjk4QWxiRi9DSmRLM3QraTRoMTVlR2ZQegpoTnh3bk9QdlVTaDR2Q0o3c2Q5TmtEUGJvS2JneVVHOXBYamZhRGR2UVFLQmdRRFFLM01nUkhkQ1pKNVFqZWFKClFGdXF4cHdnNzhZTjQyL1NwenlUYmtGcVFoQWtyczJxWGx1MDZBRzhrZzIzQkswaHkzaE9zSGgxcXRVK3NHZVAKOWRERHBsUWV0ODZsY2FlR3hoc0V0L1R6cEdtNGFKSm5oNzVVaTVGZk9QTDhPTm1FZ3MxMVRhUldhNzZxelRyMgphRlpjQ2pWV1g0YnRSTHVwSkgrMjZnY0FhUUtCZ1FEQmxVSUUzTnNVOFBBZEYvL25sQVB5VWs1T3lDdWc3dmVyClUycXlrdXFzYnBkSi9hODViT1JhM05IVmpVM25uRGpHVHBWaE9JeXg5TEFrc2RwZEFjVmxvcG9HODhXYk9lMTAKMUdqbnkySmdDK3JVWUZiRGtpUGx1K09IYnRnOXFYcGJMSHBzUVpsMGhucDBYSFNYVm9CMUliQndnMGEyOFVadApCbFBtWmc2d1BRS0JnRHVIUVV2SDZHYTNDVUsxNFdmOFhIcFFnMU16M2VvWTBPQm5iSDRvZUZKZmcraEppSXlnCm9RN3hqWldVR3BIc3AyblRtcHErQWlSNzdyRVhsdlhtOElVU2FsbkNiRGlKY01Pc29RdFBZNS9NczJMRm5LQTQKaENmL0pWb2FtZm1nZEN0ZGtFMXNINE9MR2lJVHdEbTRpb0dWZGIwMllnbzFyb2htNUpLMUI3MkpBb0dBUW01UQpHNDhXOTVhL0w1eSt5dCsyZ3YvUHM2VnBvMjZlTzRNQ3lJazJVem9ZWE9IYnNkODJkaC8xT2sybGdHZlI2K3VuCnc1YytZUXRSTHlhQmd3MUtpbGhFZDBKTWU3cGpUSVpnQWJ0LzVPbnlDak9OVXN2aDJjS2lrQ1Z2dTZsZlBjNkQKckliT2ZIaHhxV0RZK2Q1TGN1YSt2NzJ0RkxhenJsSlBsRzlOZHhrQ2dZRUF5elIzT3UyMDNRVVV6bUlCRkwzZAp4Wm5XZ0JLSEo3TnNxcGFWb2RjL0d5aGVycjFDZzE2MmJaSjJDV2RsZkI0VEdtUjZZdmxTZEFOOFRwUWhFbUtKCnFBLzVzdHdxNWd0WGVLOVJmMWxXK29xNThRNTBxMmk1NVdUTThoSDZhTjlaMTltZ0FGdE5VdGNqQUx2dFYxdEYKWSs4WFJkSHJaRnBIWll2NWkwVW1VbGc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"
現在使用該檔案建立 secret
kubectl apply -f nginxsecrets.yaml
kubectl get secrets
NAME TYPE DATA AGE
nginxsecret kubernetes.io/tls 2 1m
現在修改您的 nginx 副本,以使用 secret 中的憑證啟動 https 伺服器,並修改 Service 以公開兩個埠(80 和 443)
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
protocol: TCP
name: http
- port: 443
protocol: TCP
name: https
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
- name: configmap-volume
configMap:
name: nginxconfigmap
containers:
- name: nginxhttps
image: bprashanth/nginxhttps:1.0
ports:
- containerPort: 443
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
- mountPath: /etc/nginx/conf.d
name: configmap-volume
關於 nginx-secure-app 宣告檔案的重點
- 它在同一個檔案中包含 Deployment 和 Service 規範。
- nginx 伺服器 在 80 埠上提供 HTTP 流量,在 443 埠上提供 HTTPS 流量,而 nginx Service 公開這兩個埠。
- 每個容器都可以透過掛載在
/etc/nginx/ssl
的卷存取金鑰。這是在 nginx 伺服器啟動之前設定的。
kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml
此時,您可以從任何節點連線到 nginx 伺服器。
kubectl get pods -l run=my-nginx -o custom-columns=POD_IP:.status.podIPs
POD_IP
[map[ip:10.244.3.5]]
node $ curl -k https://10.244.3.5
...
<h1>Welcome to nginx!</h1>
請注意,我們在最後一步中如何提供 -k
參數給 curl,這是因為我們在憑證產生時對執行 nginx 的 Pod 一無所知,因此我們必須告訴 curl 忽略 CName 不符的情況。透過建立 Service,我們將憑證中使用的 CName 與 Pod 在 Service 查找期間使用的實際 DNS 名稱連結起來。讓我們從 Pod 測試這個(為了簡單起見,重複使用相同的 secret,Pod 只需要 nginx.crt 即可存取 Service)
apiVersion: apps/v1
kind: Deployment
metadata:
name: curl-deployment
spec:
selector:
matchLabels:
app: curlpod
replicas: 1
template:
metadata:
labels:
app: curlpod
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
containers:
- name: curlpod
command:
- sh
- -c
- while true; do sleep 1; done
image: radial/busyboxplus:curl
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
kubectl apply -f ./curlpod.yaml
kubectl get pods -l app=curlpod
NAME READY STATUS RESTARTS AGE
curl-deployment-1515033274-1410r 1/1 Running 0 1m
kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/tls.crt
...
<title>Welcome to nginx!</title>
...
公開 Service
對於應用程式的某些部分,您可能想要將 Service 公開到外部 IP 位址。Kubernetes 支援兩種方式來做到這一點:NodePorts 和 LoadBalancers。在上一個章節中建立的 Service 已經使用了 NodePort
,因此如果您的節點具有公用 IP,您的 nginx HTTPS 副本已準備好在網際網路上提供流量。
kubectl get svc my-nginx -o yaml | grep nodePort -C 5
uid: 07191fb3-f61a-11e5-8ae5-42010af00002
spec:
clusterIP: 10.0.162.149
ports:
- name: http
nodePort: 31704
port: 8080
protocol: TCP
targetPort: 80
- name: https
nodePort: 32453
port: 443
protocol: TCP
targetPort: 443
selector:
run: my-nginx
kubectl get nodes -o yaml | grep ExternalIP -C 1
- address: 104.197.41.11
type: ExternalIP
allocatable:
--
- address: 23.251.152.56
type: ExternalIP
allocatable:
...
$ curl https://<EXTERNAL-IP>:<NODE-PORT> -k
...
<h1>Welcome to nginx!</h1>
現在讓我們重新建立 Service 以使用雲端負載平衡器。將 my-nginx
Service 的 Type
從 NodePort
變更為 LoadBalancer
kubectl edit svc my-nginx
kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx LoadBalancer 10.0.162.149 xx.xxx.xxx.xxx 8080:30163/TCP 21s
curl https://<EXTERNAL-IP> -k
...
<title>Welcome to nginx!</title>
EXTERNAL-IP
欄位中的 IP 位址是在公用網際網路上可用的位址。CLUSTER-IP
僅在您的叢集/私有雲網路內部可用。
請注意,在 AWS 上,類型為 LoadBalancer
會建立 ELB,它使用(較長的)主機名稱,而不是 IP。它太長而無法放入標準的 kubectl get svc
輸出中,事實上,因此您需要執行 kubectl describe service my-nginx
才能看到它。您會看到類似這樣的內容
kubectl describe service my-nginx
...
LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.elb.amazonaws.com
...
下一步
- 深入了解 使用 Service 存取叢集中的應用程式
- 深入了解 使用 Service 連接前端到後端
- 深入了解 建立外部負載平衡器