示例:Service連接應用程序


整體思路:
1.創建pod
2.創建關聯上一步pod的service
3.使用不同的方式配置service從而能夠在集群內部訪問
4.使用ssl方式加密訪問service
5.配置service為nodePort方式在外部進行訪問

Kubernetes 的網絡模型

通常,Docker 使用一種 host-private 的聯網方式,在此情況下,只有兩個容器都在同一個節點(主機)上時,一個容器才可以通過網絡連接另一個容器。為了使 Docker 容器可以跨節點通信,必須在宿主節點(主機)的 IP 地址上分配端口,並將該端口接收到的網絡請求轉發(或代理)到容器中。這意味着,用戶必須非常小心地為容器分配宿主節點(主機)的端口號,或者端口號可以自動分配。可以通俗的理解成不同主機的docker容器如何進行跨主機通信,具體可以參考這篇文章

在一個集群中,多個開發者之間協調分配端口號是非常困難的。Kubernetes 認為集群中的兩個 Pod 應該能夠互相通信,無論他們各自在哪個節點上。每一個 Pod 都被分配自己的 “cluster-private-IP”,因此,您無需在 Pod 間建立連接,或者將容器的端口映射到宿主機的端口。因此:

  • Pod 中的任意容器可以使用 localhost 直連同 Pod 中另一個容器的端口
  • 集群中的任意 Pod 可以使用另一的 Pod 的 cluster-private-IP 直連對方的端口,(無需 NAT 映射)

本文檔的后續章節使用了一個 nginx server 的例子,詳細闡述了如何使用這種網絡模型發布 Service。

在集群中部署 Pod

部署 nginx 應用,並將關注點放在網絡連接方面(請留意該 Pod 指定了一個 containerPort)。

  • 創建文件 run-my-nginx.yaml,文件內容如下
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
  • 執行命令 kubectl get pods -l run=my-nginx -o yaml | grep podIP, 檢查 Pod 的 IP 地址,輸出結果如下:
  podIP: 10.244.3.4
  podIP: 10.244.2.5

在集群中的任意節點上,您可以執行 curl 10.244.3.4curl 10.244.2.5 獲得 nginx 的響應。此時:

  • 容器並沒有使用節點上的 80 端口
  • 沒有使用 NAT 規則對容器端口進行映射

這意味着,您可以

  • 在同一節點上使用 80 端口運行多個 nginx Pod
  • 在集群的任意節點/Pod 上使用 nginx Pod 的 clusterIP 訪問 nginx 的 80 端口

同 Docker 一樣,Kubernets 中,仍然可以將 Pod 的端口映射到宿主節點的網絡地址上(使用 nodePort),但是使用 Kubernetes 的網絡模型時,這類需求已經大大減少了。

為了區分兩個不同的pod,可以登陸pod里的容器中,修改nginx的首頁返回的信息,具體操作如下

[root@master ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
my-nginx-5dc4865748-b69hc   1/1     Running   0          158m
my-nginx-5dc4865748-jkq45   1/1     Running   0          158m

[root@master ~]# kubectl exec my-nginx-5dc4865748-b69hc -i -t -- bash -il         
root@my-nginx-5dc4865748-b69hc:/# cd /etc/nginx/conf.d/
root@my-nginx-5dc4865748-b69hc:/etc/nginx/conf.d# cat default.conf 
......

root@my-nginx-5dc4865748-b69hc:/etc/nginx/conf.d# echo "1111" > /usr/share/nginx/html/index.html 
root@my-nginx-5dc4865748-b69hc:/etc/nginx/conf.d# cat /usr/share/nginx/html/index.html 

另一個pod中的容器nginx可以修改成返回2222.

創建 Service

上面的步驟中,我們已經創建了 nginx Pod,運行在集群的 IP 地址空間。您可以直接通過 Pod 的地址訪問其端口,但是如果某一個 Pod 終止了該怎么辦?Pod 因為故障或其他原因終止后,Deployment Controller 將創建一個新的 Pod 以替代該 Pod,但是 IP 地址將發生變化。Kubernetes Service 解決了這樣的問題。

Kubernetes Service:

  • 定義了集群中一組 Pod 的邏輯集合,該集合中的 Pod 提供了相同的功能
  • 被創建后,獲得一個唯一的 IP 地址(ClusterIP),直到該 Service 被刪除,此地址不會發生改變
  • Pod 可以直接連接 Service IP 地址上的端口,且發送到該 IP 地址的網絡請求被自動負載均衡分發到 Service 所選取的 Pod 集合中

執行命令 kubectl expose deployment/my-nginx 可以為上面的兩個 nginx Pod 創建 Service,輸出結果如下所示:

service/my-nginx exposed

該命令等價於 kubectl apply -f nginx-svc.yaml,其中 nginx-svc.yaml 文件的內容如下所示:

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

該 yaml 文件將創建一個 Service:

  • 該 Service 通過 label selector 選取包含 run: my-nginx 標簽的 Pod 作為后端 Pod
  • 該 Service 暴露一個端口 80(spec.ports[*].port
  • 該 Service 將 80 端口上接收到的網絡請求轉發到后端 Pod 的 80 (spec.ports[*].targetPort)端口上,支持負載均衡

執行命令 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 實際上通過 Endpoints 來暴露。Kubernetes 會持續檢查 Service 的 label selector spec.selector,並將符合條件的 Pod 更新到與 Service 同名(my-nginx)的 Endpoints 對象。如果 Pod 終止了,該 Pod 將被自動從 Endpoints 中移除,新建的 Pod 將自動被添加到該 Endpoint。

執行命令 kubectl describe svc my-nginx,輸出結果如下,請注意 Endpoints 中的 IP 地址與上面獲得的 Pod 地址相同:

Name:                my-nginx
Namespace:           default
Labels:              run=my-nginx
Annotations:         <none>
Selector:            run=my-nginx
Type:                ClusterIP
IP:                  10.0.162.149
Port:                <unset> 80/TCP
Endpoints:           10.244.2.5:80,10.244.3.4:80
Session Affinity:    None
Events:              <none>

執行命令 kubectl get ep my-nginx,輸出結果如下:

NAME       ENDPOINTS                     AGE
my-nginx   10.244.2.5:80,10.244.3.4:80   1m

此時,您可以在集群的任意節點上執行 curl 10.0.162.149:80,通過 Service 的 ClusterIP:Port 訪問 nginx。

TIP Service 的 IP 地址是虛擬地址。請參考 虛擬 IP 的實現

訪問 Service

Kubernetes 支持兩種方式發現服務:

TIP
由於如下原因,您可能不想激活 Service 的環境變量發現機制:

  • 可能與應用程序的環境變量沖突
  • 太多的環境變量
  • 只想使用 DNS 等

您可以在 Pod 的定義中,將 enableServiceLinks 標記設置為 false

環境變量

針對每一個有效的 Service,kubelet 在創建 Pod 時,向 Pod 添加一組環境變量。這種做法引發了一個 Pod 和 Service 的順序問題。例如,

  • 執行命令 kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE (您的 Pod 名字可能不一樣),輸出結果如下:
KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443

請注意,此時環境變量中沒有任何與您的 Service 相關的內容。因為在本教程的前面部分,我們先創建了 Pod 的副本,后創建了 Service。如果我們刪除已有的兩個 Pod,Deployment 將重新創建 Pod 以替代被刪除的 Pod。此時,因為在創建 Pod 時,Service 已經存在,所以我們可以在新的 Pod 中查看到 Service 的環境變量被正確設置。

執行命令 kubectl delete pods -l run=my-nginx以刪除 Pod

執行命令 kubectl get pods -l run=my-nginx -o wide 查看新建Pod,輸出結果如下:

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

執行命令 kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE (Pod 重建后,名字將會發生變化。請使用您的 Pod 名),輸出結果如下,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 cluster addon,可自動為 Service 分配 DNS name。前提條件是已經安裝coredns

執行命令 kubectl get services kube-dns --namespace=kube-system 查看該 addon 在您的集群上是否可用,輸出結果如下所示:

NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   10.0.0.10    <none>        53/UDP,53/TCP   8m

本章節假設:

  • 您已經按照本文前面的章節創建了 Service(my-nginx)
  • 您已經安裝了 DNS Server(CoreDNS cluster addon)

此時,您可以從集群中任何 Pod 中按 Service 的名稱訪問該 Service。

  • 執行命令 kubectl run curl --image=radial/busyboxplus:curl -i --tty 獲得 busyboxplus 容器的命令行終端,該命令輸出結果如下所示:
Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false
Hit enter for command prompt

然后,單擊回車鍵,並執行命令 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
  • 執行命令 curl my-nginx:80,可獲得 Nginx 的響應。
  • 執行命令 exit 可推出該容器的命令行
  • 執行命令 kubectl delete deployment curl 可刪除剛才創建的 curl 測試容器

注意:使用上述命令刪除curl測試容器的話會報錯,具體如下:

# kubectl delete deployment curl
Error from server (NotFound): deployments.apps "curl" not found

通過查看可知這只是一個單獨的pod,並沒有采用deployment的方式部署,所以,刪除的話使用如下命令

[root@master ~]# kubectl delete deployments.apps curl-deployment 
deployment.apps "curl-deployment" deleted

[root@master ~]# kubectl delete pods curl-deployment-76c66b6b4b-bgcbs 
pod "curl-deployment-76c66b6b4b-bgcbs" deleted

保護 Service 的安全

到目前為止,我們只是從集群內部訪問了 nginx server。在將該 Service 公布到互聯網時,您可能需要確保該通信渠道是安全的。為此,您必須:

  • 准備 https 證書(購買,或者自簽名)
  • 將該 nginx 服務配置好,並使用該 https 證書
  • 配置 Secret,以使得其他 Pod 可以使用該證書

您可按照如下步驟配置 nginx 使用自簽名證書:

  • 創建密鑰對
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/nginx.key -out /tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx"

將密鑰對轉換為 base64 編碼

cat /tmp/nginx.crt | base64
cat /tmp/nginx.key | base64

創建一個如下格式的 nginxsecrets.yaml 文件,使用前面命令輸出的 base64 編碼替換其中的內容(base64編碼內容不能換行)(請使用前面兩行命令生成的結果替換 nginx.crt 和 nginx.key 的內容,)

apiVersion: "v1"
kind: "Secret"
metadata:
  name: "nginxsecret"
  namespace: "default"
data:
  nginx.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIekNDQWdlZ0F3SUJBZ0lKQUp5M3lQK0pzMlpJTUEwR0NTcUdTSWIzRFFFQkJRVUFNQ1l4RVRBUEJnTlYKQkFNVENHNW5hVzU0YzNaak1SRXdEd1lEVlFRS0V3aHVaMmx1ZUhOMll6QWVGdzB4TnpFd01qWXdOekEzTVRKYQpGdzB4T0RFd01qWXdOekEzTVRKYU1DWXhFVEFQQmdOVkJBTVRDRzVuYVc1NGMzWmpNUkV3RHdZRFZRUUtFd2h1CloybHVlSE4yWXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSjFxSU1SOVdWM0IKMlZIQlRMRmtobDRONXljMEJxYUhIQktMSnJMcy8vdzZhU3hRS29GbHlJSU94NGUrMlN5ajBFcndCLzlYTnBwbQppeW1CL3JkRldkOXg5UWhBQUxCZkVaTmNiV3NsTVFVcnhBZW50VWt1dk1vLzgvMHRpbGhjc3paenJEYVJ4NEo5Ci82UVRtVVI3a0ZTWUpOWTVQZkR3cGc3dlVvaDZmZ1Voam92VG42eHNVR0M2QURVODBpNXFlZWhNeVI1N2lmU2YKNHZpaXdIY3hnL3lZR1JBRS9mRTRqakxCdmdONjc2SU90S01rZXV3R0ljNDFhd05tNnNTSzRqYUNGeGpYSnZaZQp2by9kTlEybHhHWCtKT2l3SEhXbXNhdGp4WTRaNVk3R1ZoK0QrWnYvcW1mMFgvbVY0Rmo1NzV3ajFMWVBocWtsCmdhSXZYRyt4U1FVQ0F3RUFBYU5RTUU0d0hRWURWUjBPQkJZRUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjcKTUI4R0ExVWRJd1FZTUJhQUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjdNQXdHQTFVZEV3UUZNQU1CQWY4dwpEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRVhTMW9FU0lFaXdyMDhWcVA0K2NwTHI3TW5FMTducDBvMm14alFvCjRGb0RvRjdRZnZqeE04Tzd2TjB0clcxb2pGSW0vWDE4ZnZaL3k4ZzVaWG40Vm8zc3hKVmRBcStNZC9jTStzUGEKNmJjTkNUekZqeFpUV0UrKzE5NS9zb2dmOUZ3VDVDK3U2Q3B5N0M3MTZvUXRUakViV05VdEt4cXI0Nk1OZWNCMApwRFhWZmdWQTRadkR4NFo3S2RiZDY5eXM3OVFHYmg5ZW1PZ05NZFlsSUswSGt0ejF5WU4vbVpmK3FqTkJqbWZjCkNnMnlwbGQ0Wi8rUUNQZjl3SkoybFIrY2FnT0R4elBWcGxNSEcybzgvTHFDdnh6elZPUDUxeXdLZEtxaUMwSVEKQ0I5T2wwWW5scE9UNEh1b2hSUzBPOStlMm9KdFZsNUIyczRpbDlhZ3RTVXFxUlU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
  nginx.key: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2RhaURFZlZsZHdkbFIKd1V5eFpJWmVEZWNuTkFhbWh4d1NpeWF5N1AvOE9ta3NVQ3FCWmNpQ0RzZUh2dGtzbzlCSzhBZi9WemFhWm9zcApnZjYzUlZuZmNmVUlRQUN3WHhHVFhHMXJKVEVGSzhRSHA3VkpMcnpLUC9QOUxZcFlYTE0yYzZ3MmtjZUNmZitrCkU1bEVlNUJVbUNUV09UM3c4S1lPNzFLSWVuNEZJWTZMMDUrc2JGQmd1Z0ExUE5JdWFubm9UTWtlZTRuMG4rTDQKb3NCM01ZUDhtQmtRQlAzeE9JNHl3YjREZXUraURyU2pKSHJzQmlIT05Xc0RadXJFaXVJMmdoY1kxeWIyWHI2UAozVFVOcGNSbC9pVG9zQngxcHJHclk4V09HZVdPeGxZZmcvbWIvNnBuOUYvNWxlQlkrZStjSTlTMkQ0YXBKWUdpCkwxeHZzVWtGQWdNQkFBRUNnZ0VBZFhCK0xkbk8ySElOTGo5bWRsb25IUGlHWWVzZ294RGQwci9hQ1Zkank4dlEKTjIwL3FQWkUxek1yall6Ry9kVGhTMmMwc0QxaTBXSjdwR1lGb0xtdXlWTjltY0FXUTM5SjM0VHZaU2FFSWZWNgo5TE1jUHhNTmFsNjRLMFRVbUFQZytGam9QSFlhUUxLOERLOUtnNXNrSE5pOWNzMlY5ckd6VWlVZWtBL0RBUlBTClI3L2ZjUFBacDRuRWVBZmI3WTk1R1llb1p5V21SU3VKdlNyblBESGtUdW1vVlVWdkxMRHRzaG9reUxiTWVtN3oKMmJzVmpwSW1GTHJqbGtmQXlpNHg0WjJrV3YyMFRrdWtsZU1jaVlMbjk4QWxiRi9DSmRLM3QraTRoMTVlR2ZQegpoTnh3bk9QdlVTaDR2Q0o3c2Q5TmtEUGJvS2JneVVHOXBYamZhRGR2UVFLQmdRRFFLM01nUkhkQ1pKNVFqZWFKClFGdXF4cHdnNzhZTjQyL1NwenlUYmtGcVFoQWtyczJxWGx1MDZBRzhrZzIzQkswaHkzaE9zSGgxcXRVK3NHZVAKOWRERHBsUWV0ODZsY2FlR3hoc0V0L1R6cEdtNGFKSm5oNzVVaTVGZk9QTDhPTm1FZ3MxMVRhUldhNzZxelRyMgphRlpjQ2pWV1g0YnRSTHVwSkgrMjZnY0FhUUtCZ1FEQmxVSUUzTnNVOFBBZEYvL25sQVB5VWs1T3lDdWc3dmVyClUycXlrdXFzYnBkSi9hODViT1JhM05IVmpVM25uRGpHVHBWaE9JeXg5TEFrc2RwZEFjVmxvcG9HODhXYk9lMTAKMUdqbnkySmdDK3JVWUZiRGtpUGx1K09IYnRnOXFYcGJMSHBzUVpsMGhucDBYSFNYVm9CMUliQndnMGEyOFVadApCbFBtWmc2d1BRS0JnRHVIUVV2SDZHYTNDVUsxNFdmOFhIcFFnMU16M2VvWTBPQm5iSDRvZUZKZmcraEppSXlnCm9RN3hqWldVR3BIc3AyblRtcHErQWlSNzdyRVhsdlhtOElVU2FsbkNiRGlKY01Pc29RdFBZNS9NczJMRm5LQTQKaENmL0pWb2FtZm1nZEN0ZGtFMXNINE9MR2lJVHdEbTRpb0dWZGIwMllnbzFyb2htNUpLMUI3MkpBb0dBUW01UQpHNDhXOTVhL0w1eSt5dCsyZ3YvUHM2VnBvMjZlTzRNQ3lJazJVem9ZWE9IYnNkODJkaC8xT2sybGdHZlI2K3VuCnc1YytZUXRSTHlhQmd3MUtpbGhFZDBKTWU3cGpUSVpnQWJ0LzVPbnlDak9OVXN2aDJjS2lrQ1Z2dTZsZlBjNkQKckliT2ZIaHhxV0RZK2Q1TGN1YSt2NzJ0RkxhenJsSlBsRzlOZHhrQ2dZRUF5elIzT3UyMDNRVVV6bUlCRkwzZAp4Wm5XZ0JLSEo3TnNxcGFWb2RjL0d5aGVycjFDZzE2MmJaSjJDV2RsZkI0VEdtUjZZdmxTZEFOOFRwUWhFbUtKCnFBLzVzdHdxNWd0WGVLOVJmMWxXK29xNThRNTBxMmk1NVdUTThoSDZhTjlaMTltZ0FGdE5VdGNqQUx2dFYxdEYKWSs4WFJkSHJaRnBIWll2NWkwVW1VbGc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"

使用該文件創建 Secrets

# 創建 Secrets
kubectl apply -f nginxsecrets.yaml
# 查看 Secrets
kubectl get secrets

輸出結果為:

NAME                  TYPE                                  DATA      AGE
default-token-il9rc   kubernetes.io/service-account-token   1         1d
nginxsecret           Opaque                                2         1m

修改 nginx 部署,使 nginx 使用 Secrets 中的 https 證書,修改 Service,使其暴露 80 端口和 443端口。nginx-secure-app.yaml 文件如下所示:

apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  type: NodePort
  ports:
  - port: 80
    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
      containers:
      - name: nginxhttps
        image: bprashanth/nginxhttps:1.0
        ports:
        - containerPort: 443
        - containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx/ssl
          name: secret-volume

關於 nginx-secure-app.yaml

  • 該文件同時包含了 Deployment 和 Service 的定義
  • nginx server 監聽 HTTP 80 端口和 HTTPS 443 端口的請求, nginx Service 同時暴露了這兩個端口
  • nginx 容器可以通過 /etc/nginx/ssl 訪問到 https 證書,https 證書存放在 Secrets 中,且必須在 Pod 創建之前配置好。

執行命令使該文件生效:

kubectl delete deployments,svc my-nginx
kubectl create -f ./nginx-secure-app.yaml

此時,您可以從任何節點訪問該 nginx server

kubectl get pods -o yaml | grep -i podip
    podIP: 10.244.3.5

node $ curl -k https://10.244.3.5
...
<h1>Welcome to nginx!</h1>

curl -k

  • 在 curl 命令中指定 —k 參數,是因為我們在生成 https 證書時,並不知道 Pod 的 IP 地址,因此,在執行 curl 命令時必須忽略 CName 不匹配的錯誤。
  • 通過創建 Service,我們將 https 證書的 CName 和 Service 的實際 DNS Name 聯系起來,因此,我們可以嘗試在另一個 Pod 中使用 https 證書的公鑰訪問 nginx Service。此時,curl 指令不在需要 -k 參數

創建 curlpod.yaml 文件,內容如下:

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

執行命令,完成 curlpod 的部署

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

執行 curl,訪問 nginx 的 https 端口(請使用您自己的 Pod 名稱)

kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    12  100    12    0     0     99      0 --:--:-- --:--:-- --:--:--   203
...
<title>Welcome to nginx!</title>
...

暴露 Service

在您的應用程序中,可能有一部分功能需要通過 Service 發布到一個外部的 IP 地址上。Kubernetes 支持如下兩種方式:

在上一個章節 保護 Service 的安全 中創建的 Service 已經是 NodePort 類型的了,此時,如果您的節點有公網地址,則 nginx HTTPS 部署已經可以接受來自於互聯網的請求了。

假若上一步的"保護 Service 的安全"沒有進行操作,可以直接修改該servie中的yaml文件,修改ClusterIP為nodePort,從而繼續進行下面的步驟

執行命令 kubectl get svc my-nginx -o yaml | grep nodePort -C 5,輸出結果如下:

結果中的 nodePort 將被標記為紅色字體

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    

假設您的某一節點的公網 IP 地址為 23.251.152.56,則您可以使用任意一台可上網的機器執行命令 curl https://23.251.152.56:32453 -k。輸出結果為:

...
<h1>Welcome to nginx!</h1>

Ingress

  • 對於 HTTP、HTTPS 形式的訪問推薦使用 Ingress 替代這種用法,參考 Ingress通過互聯網訪問您的應用
  • 對於 TCP、UDP 等形式的訪問,您仍然應該使用 Service NodePort


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM