使用 k8s 部署你的第一個應用: Pod,Deployment 與 Service

千里之行,始於足下html

當咱們新學習一門編程語言時,老是從 hello, world 開始。nginx

當咱們學習如何在 k8s 上部署應用時,部署一個簡單的 nginx,可以訪問到它的配置頁面。因爲它五臟俱全,功能簡單,無狀態,能夠當作 k8s 部署應用的 hello, worldgit

本篇文章將學習如何使用 PodDeploymentService 開始部署第一個應用github

若是對你可以有所幫助,能夠幫我在 shfshanyue/op-note 上點個 star。web

Pod

podkubernetes 中最小的編排單位,一般由一個容器組成 (有時候會有多個容器組成)。docker

如下是一個 pod 資源配置文件的最小示例,關於詳細配置參考 kubernetes v1.16 Podshell

咱們使用 nginx:alpine 做爲鏡像部署了一個 Pod,而且暴露了 80 端口編程

apiVersion: v1
kind: Pod
metadata:
 name: nginx
  # 指定 label,便於檢索
 labels:
 app: nginx
spec:
 containers:
 - name: nginx
    # 指定鏡像
 image: nginx:alpine
    # 指定暴露端口
 ports:
 - containerPort: 80
複製代碼

使用 kubectly apply,部署 Pod後端

$ kubectl apply -f nginx.yaml
pod/nginx created
複製代碼

校驗部署狀態,此時 STATUS 爲 Running 代表部署成功api

# 獲取 Pod 部署的狀態,特別是 IP
# -o wide 列出IP/Node等更多信息
$ kubectl get pods nginx -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          14m   10.244.1.9   shuifeng   <none>           <none>
複製代碼

使用 -o wide 獲取到 pod 的 IP 地址,訪問該 IP 查看是否可以訪問到 nginx 經典的配置頁面

# 獲取更加詳細的信息
$ kubectl describe pod nginx

# 每一個 pod 都有一個IP地址,直接訪問IP地址獲取內容
$ curl 10.244.1.9
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
複製代碼

此時咱們可使用 kubectl exec 進入 Pod 的內部容器。若是 Pod 中有多個容器,使用 kubectl exec -c 指定容器

$ kubectl exec -it nginx sh
複製代碼

Pod 容器中執行命令,校驗其中的 socket 狀況以及 nginx 服務

# 在 POD 中執行命令

# 能夠看到 nginx 起的80端口
$ netstat -tan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN

# 訪問 nginx,正確返回配置頁面的內容
# -q: 不輸出 wget 自身信息
# -O -: 定向到標準輸出
$ wget -q -O - localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
複製代碼

Deployment

k8s 中編排應用能夠更好地作彈性擴容,負載均衡。既然要均衡,一個 Pod 確定不能均衡,天然要部署多個 Pod

docker-compose 能夠簡單地經過 docker-compose scale 來擴容,k8s 更不在話下了。

在k8s中管理 Pod 的稱做 Controller,咱們可使用 Deployment 這種 Controller 來爲 Pod 進行擴容,固然它還能夠滾動升級,回滾,金絲雀等等關於部署的事情

咱們編寫一個 Deployment 的資源配置文件

  • spec.template: 指定要部署的 Pod
  • spec.replicas: 指定要部署的個數
  • spec.selector: 定位須要管理的 Pod
apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
spec:
 selector:
 matchLabels:
 app: nginx
 replicas: 3
 template:
 metadata:
 labels:
 app: nginx
 spec:
 containers:
 - name: nginx
 image: nginx:alpine
 ports:
 - containerPort: 80
複製代碼

咱們使用 kubectl apply 部署生效後查看 Pod 以及 Deployment 狀態

$ kubectl apply -f nginx.yaml

# nginx-deployment 部署的三個 pod 所有成功
$ kubectl get pods -o wide -l 'app=nginx'
NAME                                READY   STATUS    RESTARTS   AGE     IP            NODE       NOMINATED NODE   READINESS GATES
nginx                               1/1     Running   1          4h29m   10.244.1.9    shuifeng   <none>           <none>
nginx-deployment-54f57cf6bf-57g8l   1/1     Running   0          23m     10.244.1.10   shuifeng   <none>           <none>
nginx-deployment-54f57cf6bf-ltdf7   1/1     Running   0          23m     10.244.1.11   shuifeng   <none>           <none>
nginx-deployment-54f57cf6bf-n8ppt   1/1     Running   0          23m     10.244.1.12   shuifeng   <none>           <none>

# READY 3/3 代表所有部署成功
$ kubectl get deploy nginx-deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           23m
複製代碼

Service

如今咱們已經部署了一個 Deployment,其中有三個 Pod,就有三個 IP,那咱們如何向這三個 Pod 請求服務呢,況且每當上線部署後,就會產生新的 Pod IP。即咱們如何作服務發現

咱們能夠經過 Service 解決這個問題,作指定 Deployment 或者特定集合 Pod 的網絡層抽象

配置文件以下

  1. spec.selector: 指定如何選擇 Pod
  2. spec.ports: 指定如何暴露端口
apiVersion: v1
kind: Service
metadata:
 name: nginx-service
spec:
 selector:
 app: nginx
 ports:
 - protocol: TCP
 port: 80
 targetPort: 80
複製代碼

咱們使用 kubectl apply 部署生效後查看 Service 狀態

$ kubectl get svc nginx-service -o wide
NAME            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
nginx-service   ClusterIP   10.108.9.49   <none>        80/TCP    11m   app=nginx
複製代碼

ClusterIP 表明服務只能在集羣內部訪問,此時咱們訪問 10.108.9.49 訪問服務

$ curl 10.108.9.49
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
複製代碼

服務發現,咱們只須要知道服務的名字便可以訪問服務,只能經過 IP 訪問也太 low 了。Service 固然不會這麼 low

在 k8s 中,全部的服務能夠經過 my-svc.my-namespace.svc.cluster.local 作服務發現,對於剛纔部署的 Service 就是 nginx-service.default.svc.cluster.local

在集羣中的任意一個 Pod 中經過域名訪問服務,訪問成功

$ curl nginx-service.default.svc.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
複製代碼

小結

經過配置 DeploymentService ,此時咱們能夠在集羣中經過服務發現訪問域名。完整的配置文件以下

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
spec:
 selector:
 matchLabels:
 app: nginx
 replicas: 3
 template:
 metadata:
 labels:
 app: nginx
 spec:
 containers:
 - name: nginx
 image: nginx:alpine
 ports:
 - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
 name: nginx-service
spec:
 selector:
 app: nginx
 ports:
 - protocol: TCP
 port: 80
 targetPort: 80
複製代碼

當咱們仍然須要把服務暴露給互聯網,那咱們如何在集羣外訪問域名呢?

關注公衆號

歡迎關注公衆號山月行,我會按期分享一些先後端以及運維的文章,而且會有技術與生活上的每日回顧與總結,歡迎關注交流

歡迎關注公衆號山月行,我會按期分享一些先後端以及運維的文章
相關文章
相關標籤/搜索