# Kubernetes核心技術-Controller
## 內容
- 什么是Controller
- Pod和Controller的關系
- Deployment控制器應用場景
- yaml文件字段說明
- Deployment控制器部署應用
- 升級回滾
- 彈性伸縮
## 什么是Controller
Controller是在集群上管理和運行容器的對象,Controller是實際存在的,Pod是虛擬機的
## Pod和Controller的關系
Pod是通過Controller實現應用的運維,比如彈性伸縮,滾動升級等
Pod 和 Controller之間是通過label標簽來建立關系,同時Controller又被稱為控制器工作負載

## Deployment控制器應用
- Deployment控制器可以部署無狀態應用
- 管理Pod和ReplicaSet
- 部署,滾動升級等功能
- 應用場景:web服務,微服務
Deployment表示用戶對K8S集群的一次更新操作。Deployment是一個比RS( Replica Set, RS) 應用模型更廣的 API 對象,可以是創建一個新的服務,更新一個新的服務,也可以是滾動升級一個服務。滾動升級一個服務,實際是創建一個新的RS,然后逐漸將新 RS 中副本數增加到理想狀態,將舊RS中的副本數減少到0的復合操作。
這樣一個復合操作用一個RS是不好描述的,所以用一個更通用的Deployment來描述。以K8S的發展方向,未來對所有長期伺服型的業務的管理,都會通過Deployment來管理。
## Deployment部署應用
之前我們也使用Deployment部署過應用,如下代碼所示
```bash
kubectrl create deployment web --image=nginx
```
但是上述代碼不是很好的進行復用,因為每次我們都需要重新輸入代碼,所以我們都是通過YAML進行配置
但是我們可以嘗試使用上面的代碼創建一個鏡像【只是嘗試,不會創建】
```bash
kubectl create deployment web --image=nginx --dry-run -o yaml > nginx.yaml
```
然后輸出一個yaml配置文件 `nginx.yml` ,配置文件如下所示
```bash
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
```
我們看到的 selector 和 label 就是我們Pod 和 Controller之間建立關系的橋梁

### 使用YAML創建Pod
通過剛剛的代碼,我們已經生成了YAML文件,下面我們就可以使用該配置文件快速創建Pod鏡像了
```bash
kubectl apply -f nginx.yaml
```

但是因為這個方式創建的,我們只能在集群內部進行訪問,所以我們還需要對外暴露端口
```bash
kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web1
```
關于上述命令,有幾個參數
- --port:就是我們內部的端口號
- --target-port:就是暴露外面訪問的端口號
- --name:名稱
- --type:類型
同理,我們一樣可以導出對應的配置文件
```bash
kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web1 -o yaml > web1.yaml
```
得到的web1.yaml如下所示
```bash
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2020-11-16T02:26:53Z"
labels:
app: web
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:labels:
.: {}
f:app: {}
f:spec:
f:externalTrafficPolicy: {}
f:ports:
.: {}
k:{"port":80,"protocol":"TCP"}:
.: {}
f:port: {}
f:protocol: {}
f:targetPort: {}
f:selector:
.: {}
f:app: {}
f:sessionAffinity: {}
f:type: {}
manager: kubectl
operation: Update
time: "2020-11-16T02:26:53Z"
name: web2
namespace: default
resourceVersion: "113693"
selfLink: /api/v1/namespaces/default/services/web2
uid: d570437d-a6b4-4456-8dfb-950f09534516
spec:
clusterIP: 10.104.174.145
externalTrafficPolicy: Cluster
ports:
- nodePort: 32639
port: 80
protocol: TCP
targetPort: 80
selector:
app: web
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
```
然后我們可以通過下面的命令來查看對外暴露的服務
```bash
kubectl get pods,svc
```

然后我們訪問對應的url,即可看到 nginx了 `http://192.168.177.130:32639/`

## 升級回滾和彈性伸縮
- 升級: 假設從版本為1.14 升級到 1.15 ,這就叫應用的升級【升級可以保證服務不中斷】
- 回滾:從版本1.15 變成 1.14,這就叫應用的回滾
- 彈性伸縮:我們根據不同的業務場景,來改變Pod的數量對外提供服務,這就是彈性伸縮
### 應用升級和回滾
首先我們先創建一個 1.14版本的Pod
```bash
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx:1.14
name: nginx
resources: {}
status: {}
```
我們先指定版本為1.14,然后開始創建我們的Pod
```bash
kubectl apply -f nginx.yaml
```
同時,我們使用docker images命令,就能看到我們成功拉取到了一個 1.14版本的鏡像

我們使用下面的命令,可以將nginx從 1.14 升級到 1.15
```bash
kubectl set image deployment web nginx=nginx:1.15
```
在我們執行完命令后,能看到升級的過程

- 首先是開始的nginx 1.14版本的Pod在運行,然后 1.15版本的在創建
- 然后在1.15版本創建完成后,就會暫停1.14版本
- 最后把1.14版本的Pod移除,完成我們的升級
我們在下載 1.15版本,容器就處于ContainerCreating狀態,然后下載完成后,就用 1.15版本去替換1.14版本了,這么做的好處就是:升級可以保證服務不中斷

我們到我們的node2節點上,查看我們的 docker images;

能夠看到,我們已經成功拉取到了 1.15版本的nginx了
#### 查看升級狀態
下面可以,查看升級狀態
```bash
kubectl rollout status deployment web
```

#### 查看歷史版本
我們還可以查看歷史版本
```bash
kubectl rollout history deployment web
```
#### 應用回滾
我們可以使用下面命令,完成回滾操作,也就是回滾到上一個版本
```bash
kubectl rollout undo deployment web
```
然后我們就可以查看狀態
```bash
kubectl rollout status deployment web
```

同時我們還可以回滾到指定版本
```bash
kubectl rollout undo deployment web --to-revision=2
```
### 彈性伸縮
彈性伸縮,也就是我們通過命令一下創建多個副本
```bash
kubectl scale deployment web --replicas=10
```
能夠清晰看到,我們一下創建了10個副本

- Kubernetes簡介
- 搭建K8S集群前置知識
- 使用kubeadm方式搭建K8S集群
- 使用二進制方式搭建K8S集群
- Kubeadm和二進制方式對比
- Kubernetes集群管理工具kubectl
- Kubernetes集群YAML文件詳解
- Kubernetes核心技術Pod
- Kubernetes核心技術Controller
- Kubernetes核心技術Service
- Kubernetes控制器Controller詳解
- Kubernetes配置管理
- Kubernetes集群安全機制
- Kubernetes核心技術Ingress
- Kubernetes核心技術Helm
- Kubernetes持久化存儲
- Kubernetes集群資源監控
- Kubernetes搭建高可用集群
- Kubernetes容器交付介紹
- 使用kubeadm-ha腳本一鍵安裝K8S
- Kubernetes可視化界面kubesphere
- Kubernetes配置默認存儲類
- 使用Rancher搭建Kubernetes集群
- Kubernetes中的CRI