k8s | 搞不明白爲何你們都在學習 k8s

Hi! 我是小小,今天是本週的第二篇,本篇主要內容是講解k8shtml

前言

都9102年了,你還不知道kubernetes就真的真的真的out啦。(販賣焦慮體) 什麼是k8s,k8s這個詞來自於希臘語,有主管,舵手,船長的意思,咱們從圖標中能看出來。在k8s的網站上,描述是這樣的node

生產級別的容器編排系統linux

從定義中能夠提煉出三個關鍵字,分別是nginx

  1. 生產級別
  2. 容器
  3. 編排系統

1. 生產級別

說k8s是生產級別的有以下的幾個緣由:web

  1. k8s 是谷歌的開源系統,基於谷歌的系統設計,而且已經在谷歌系統上平穩運行的好久。
  2. k8s 是CNCF的首個畢業項目。

2. 容器

容器有如下幾個特色面試

  1. 可移植性,容器能夠被任何類型的操做系統安裝使用。
  2. 包容性:支持多種類型的軟件,這些軟件均可以打包在容器內。
  3. 標準格式。
  4. 共存,多個容器能夠運行在同一個物理機上。
  5. 隔離,不一樣的容器的軟件彼此隔離。

最重要的一句話:沒有容器就沒有微服務。docker

容器和微服務化後,帶來了一些好處,好比:數據庫

  1. 模塊間更加獨立,能夠獨立的部署和發佈,加快了發佈和更新的速度
  2. 隔離的運行環境,能夠爲不一樣模塊定製不一樣的運行環境

3. 編排系統

容器的編排系統能夠有效的管理在宿主機上的容器。後端

  1. 管理網絡和訪問
  2. 跟蹤容器的狀態
  3. 增大或縮小服務的規模
  4. 實現負載平衡
  5. 宿主機無響應後實現容器的從新分配
  6. 服務發現
  7. 管理容器的存儲 等等…

主要功能

數據卷

pod中容器之間共享數據,可使用數據卷。api

應用程序健康檢查

容器內服務可能進程阻塞沒法處理請求,能夠設置監控檢查的策略,

複製應用程序實例

控制器維護者pod副本數量,保證一個pod或一組同類prod數量始終可用

彈性伸縮

根據設定的指標,自動縮放pod副本數

服務發現

使用環境變量或DNS插件保證容器中程序發現pod入口訪問地址。

負載均衡

一組pod副本分配一個私有的集羣ip地址,負載均衡轉發請求到後端容器,在集羣類其餘pod能夠經過clusterIP訪問應用。

滾動更新

更新服務不中斷,一次更新一個pod,而不是同時刪除整個服務。

服務編排

經過文件描述部署服務,使得應用程序部署變得高效。

資源監控

Node節點組件集成cAdvisor資源收集工具,經過Heapster彙總,並保存到influxDB時序數據庫,最後由Grafana展現。

提供認證受權

支持RBAC認證受權機制。

設計架構

功能組件

k8s 集羣中有管理節點,Master與工做節點,Node兩種類型。

  1. 管理節點Master主要負責k8s集羣管理,集羣中各個節點之間信息交互,任務調度,還負責容器,pod, namespaces , pv 等生命週期的管理。
  2. 工做節點node主要爲容器和pod提供計算資源,pod及其容器所有運行在工做節點上,工做節點經過kubelet服務與管理節點通訊以管理容器的生命週期,並與集羣其餘節點進行通訊。

master組件

kube-apiserver

kubernetes api 資源操做的惟一入口,各類組件的協調者,以HTTP API 提供接口服務,並提供相關的認證,受權等機制,

kube-controller-manager

處理集羣中常規的後臺任務,一個資源對應一個控制器,而ControllerManager負責管理這些控制器,並維護集羣的狀態。

kube-scheduler

負責資源的調度,按照預約的策略把pod調度到對應的Node節點上。

Node組件

kubelet

kubelet是Master在Node節點上的agent,管理本機運行容器的生命週期,同時也負責Volume和網絡的管理。例如建立容器,掛載數據卷,下載secret,獲取容器和節點的狀態等工做。

kube-proxy

在Node節點上實現Pod/serviced網絡代理,提供cluster內部的服務發現和四層負載均衡。

docker

真正運行容器的地方

etcd集羣

分佈式鍵值對儲存系統,用於保存集羣狀態,好比pod,service等對象信息。

分層架構

核心層:最核心的功能,對外提供api 應用層,部署無狀態應用,等,和路由。管理層:系統度量,自動化,以及RBAC等 接口層:kubectl命令行工具,以及客戶端sdk 生態系統:分爲外部的日誌,監控等,內部的鏡像倉庫等。

安裝

建立集羣

首先,查看所使用的 minikube 版本:

$ minikube version
minikube version: v0.25.0

啓動 minikube:

$ minikube start
Starting local Kubernetes v1.9.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

minikube 啓動以後,會建立一個單節點 Kubernetes 集羣。

查看集羣版本:

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.0", GitCommit:"925c127ec6b946659ad0fd596fa959be43f0cc05", GitTreeState:"clean", BuildDate:"2017-12-15T21:07:38Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"", Minor:"", GitVersion:"v1.9.0", GitCommit:"925c127ec6b946659ad0fd596fa959be43f0cc05", GitTreeState:"clean", BuildDate:"2018-01-26T19:04:38Z", GoVersion:"go1.9.1", Compiler:"gc", Platform:"linux/amd64"}

這裏有兩個版本,client version 指的是 kubectl 命令行工具的版本,而 server version 纔是 Kubernetes 的版本。

查看更詳細的版本信息:

$ kubectl cluster-info
Kubernetes master is running at https://172.17.0.77:8443

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

集羣所在主機的 ip 爲 172.17.0.77。

注意:這裏的 master 指的是 Kubernetes 集羣的 master 節點(在 Kubernetes 集羣中,節點分爲兩類,一類是 master 節點,一類是 node 節點)。那怎麼看到 node 節點呢?

$ kubectl get node
NAME STATUS ROLES AGE VERSION
host01 Ready <none> 20m v1.9.0

host01 就是 node 節點,在當前環境中,實際上只有一臺主機。這臺主機既做爲 master 節點,也做爲 node 節點。

部署應用

下面以部署一個 nginx 爲例來演示部署應用的過程:

$ kubectl run first-app --image=nginx --port=80
deployment "first-app" created

經過 run 命令建立一個名爲 first-app 的 deployment,使用的是 docker hub 上最新的 nginx 鏡像,並指定了應用端口爲 80。deployment 是幹嗎的呢?別急,往下看:

查看當前的 deployment:

$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
first-app 1 1 1 1 1m

查看當前的 pod:

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
first-app-6db44b474-dbbtp 1/1 Running 0 4m

查看更詳細的 pod 內容:

$ kubectl describe pod first-app-6db44b474-dbbtp
Name: first-app-6db44b474-dbbtp
Namespace: default
Node: host01/172.17.0.77
Start Time: Fri, 02 Mar 2018 06:48:02 +0000
Labels: pod-template-hash=286006030
run=first-app
Annotations: <none>
Status: Running
IP: 172.18.0.4
Controlled By: ReplicaSet/first-app-6db44b474
Containers:
first-app:
Container ID: docker://54eacc7ff536d7181fa366883f7ed4cf632492ad6ed391207fea436d22d219a9
Image: nginx
Image ID: docker-pullable://nginx@sha256:4771d09578c7c6a65299e110b3ee1c0a2592f5ea2618d23e4ffe7a4cab1ce5de
Port: 80/TCP
State: Running
Started: Fri, 02 Mar 2018 06:48:14 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-zkqw6 (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-zkqw6:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-zkqw6
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 7m default-scheduler Successfully assigned first-app-6db44b474-dbbtp to host01
Normal SuccessfulMountVolume 7m kubelet, host01 MountVolume.SetUp succeeded for volume "default-token-zkqw6"
Normal Pulling 7m kubelet, host01 pulling image "nginx"
Normal Pulled 7m kubelet, host01 Successfully pulled image "nginx"
Normal Created 7m kubelet, host01 Created container
Normal Started 7m kubelet, host01 Started container

對外發布服務

已經部署好了一個 nginx 應用,那麼要怎麼去訪問呢?這時候就須要用到 service。建立一個 service:

$ kubectl expose deployment/first-app --type="NodePort" --port=80
service "first-app" exposed

查看建立好的名爲 first-app 的 service :

$ kubectl get svc first-app
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
first-app NodePort 10.102.0.12 <none> 80:30491/TCP 1m

在 PORT(S) 一欄中,除了 80 端口,後面還有一個 30491 端口。這是使用了「NodePort」類型建立 service 分配的端口,經過主機 ip 和這個端口,就能夠訪問到這個 service 了。可使用 curl 工具進行訪問:

$ curl 172.17.0.77:30491
<!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>

擴縮應用

剛剛已經成功訪問到 nginx 應用,但有些時候,可能須要多個 nginx 來橫向擴展,那麼在 Kubernetes 中怎麼實現呢?

$ kubectl scale deployment/first-app --replicas=3
deployment "first-app" scaled

再查看當前的 pod,能夠看到當前已經有了 3 個 first-app 了。

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
first-app-6db44b474-6vlrj 1/1 Running 0 39s
first-app-6db44b474-dbbtp 1/1 Running 0 19m
first-app-6db44b474-gjzgg 1/1 Running 0 39s

若是以爲 3 個太浪費資源了,想減小 pod 的數量,那麼可使用一樣的命令,把 replicas 參數的值改成須要的值就能夠了。

更新應用

最經常使用的就是更新鏡像。以前使用的是 docker hub 上最新的 nginx,如今用 1.10.3 這個比較老的版原本替代最新版本。先查看當前使用的 nginx 版本。這裏有一個很簡單的方法,訪問一個不存在的頁面,以下:

$ curl 172.17.0.77:30491/abc
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.13.9</center>
</body>
</html>

當前使用的 nginx 版本是 1.13.9,接下來進行更新操做:

$ kubectl set image deployment/first-app first-app=nginx:1.10
deployment "first-app" image updated

再查看當前 nginx 的版本:

$ curl 172.17.0.77:30491/abc
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>

nginx 版本已經成功更新爲 1.10.3。

刪除應用

最後來說講刪除應用,以前是經過 deployment 來建立應用,因此只須要刪除 deployment 就能夠刪除對應的應用了。

$ kubectl delete deployment/first-app
deployment "first-app" deleted

再查看一下當前的 pod:

$ kubectl get pod
No resources found.

全部的 pod 都已經刪除了。

關於做者

一個生於二線,活在一線城市的程序猿,我是小小,咱們下期再見。



小明菜市場


往期推薦

對戰 | RabbitMq 大戰 kafka

執行流程 | 你真的瞭解Spring AOP的執行順序嗎?

吊打面試官 | Java究竟是值傳遞仍是引用傳遞

容器 | Docker 如此之好,你爲何還要用k8s

分佈式ID | 這六種分佈式ID生成方法,總有一款適合你



本文分享自微信公衆號 - 小明菜市場(fileGeek)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索