共计 9308 个字符,预计需要花费 24 分钟才能阅读完成。
如果你看了《Kubernetes 太火了!花 10 分钟玩转它不香么?》一文的话,基本上曾经能够玩转 K8S 了。其实 K8S 中还有一些高级个性也很值得学习,比方弹性扩缩利用、滚动更新、配置管理、存储卷、网关路由等。明天咱们就来理解下这些高级个性,心愿对大家有所帮忙!
SpringBoot 实战电商我的项目 mall(40k+star)地址:https://github.com/macrozheng/mall
外围概念
首先咱们先来理解一些外围概念,理解这些外围概念对应用 K8S 的高级个性很有帮忙。
ReplicaSet
ReplicaSet 确保任何工夫都有指定数量的 Pod 正本在运行。通常用来保障给定数量的、完全相同的 Pod 的可用性。倡议应用 Deployment 来治理 ReplicaSet,而不是间接应用 ReplicaSet。
ConfigMap
ConfigMap 是一种 API 对象,用来将非机密性的数据保留到键值对中。应用时,Pod 能够将其用作环境变量、命令行参数或者存储卷中的配置文件。应用 ConfigMap 能够将你的配置数据和利用程序代码离开。
Volume
Volume 指的是存储卷,蕴含可被 Pod 中容器拜访的数据目录。容器中的文件在磁盘上是长期寄存的,当容器解体时文件会失落,同时无奈在多个 Pod 中共享文件,通过应用存储卷能够解决这两个问题。
罕用的存储卷有如下几种:
- configMap:configMap 卷提供了向 Pod 注入配置数据的办法。ConfigMap 对象中存储的数据能够被 configMap 类型的卷援用,而后被 Pod 中运行的容器化利用应用。
- emptyDir:emptyDir 卷可用于存储缓存数据。当 Pod 分派到某个 Node 上时,emptyDir 卷会被创立,并且 Pod 在该节点上运行期间,卷始终存在。当 Pod 被从节点上删除时 emptyDir 卷中的数据也会被永恒删除。
- hostPath:hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。在 Minikube 中的主机指的是 Minikube 所在虚拟机。
- local:local 卷所代表的是某个被挂载的本地存储设备,例如磁盘、分区或者目录。local 卷只能用作动态创立的长久卷,尚不反对动静配置。
- nfs:nfs 卷能将 NFS(网络文件系统)挂载到你的 Pod 中。
- persistentVolumeClaim:persistentVolumeClaim 卷用来将长久卷(PersistentVolume)挂载到 Pod 中。长久卷(PV)是集群中的一块存储,能够由管理员当时供给,或者应用存储类(Storage Class)来动静供给,长久卷是集群资源相似于节点。
Ingress
Ingress 相似于 K8S 中的网关服务,是对集群中服务的内部拜访进行治理的 API 对象,典型的拜访形式是 HTTP。Ingress 能够提供负载平衡、SSL 终结和基于名称的虚构托管。
高级个性
扩缩利用
当流量减少时,咱们须要扩容应用程序满足用户需要。当流量缩小时,须要缩放利用以缩小服务器开销。在 K8S 中扩缩是通过扭转 Deployment 中的正本数量来实现的。
- 获取所有 Deployment 可应用如下命令:
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-nginx 1/1 1 1 43h
- 获取所有 ReplicaSet 可应用如下命令:
kubectl get rs
NAME DESIRED CURRENT READY AGE
kubernetes-nginx-78bcc44665 1 1 1 43h
- 对利用进行扩容操作,扩容到 4 个实例,再查看所有:
kubectl scale deployments/kubernetes-nginx --replicas=4
[macro@linux-local root]$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-nginx 4/4 4 4 43h
- 查看所有 Pod,发现曾经有 4 个运行在不同的 IP 地址上了;
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kubernetes-nginx-78bcc44665-8fnnn 1/1 Running 2 43h 172.17.0.3 minikube <none> <none>
kubernetes-nginx-78bcc44665-dvq4t 1/1 Running 0 84s 172.17.0.8 minikube <none> <none>
kubernetes-nginx-78bcc44665-thzg9 1/1 Running 0 84s 172.17.0.7 minikube <none> <none>
kubernetes-nginx-78bcc44665-w7xqd 1/1 Running 0 84s 172.17.0.6 minikube <none> <none>
- 对利用进行缩放操作,缩放到 2 个实例;
kubectl scale deployments/kubernetes-nginx --replicas=2
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kubernetes-nginx-78bcc44665-8fnnn 1/1 Running 2 44h 172.17.0.3 minikube <none> <none>
kubernetes-nginx-78bcc44665-w7xqd 1/1 Running 0 11m 172.17.0.6 minikube <none> <none>
滚动更新
滚动更新容许通过应用新的实例逐渐更新 Pod 实例,零停机进行 Deployment 更新。K8S 不仅能够实现滚动更新,还能够反对回滚操作。
- 目前运行了 4 个 Nginx
1.10
版本的实例:
[macro@linux-local root]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-nginx-78bcc44665-8fnnn 1/1 Running 2 44h
kubernetes-nginx-78bcc44665-jpw2g 1/1 Running 0 5s
kubernetes-nginx-78bcc44665-w7xqd 1/1 Running 0 59m
kubernetes-nginx-78bcc44665-xx8s5 1/1 Running 0 5s
- 能够通过
kubectl describe
命令来查看镜像版本号:
[macro@linux-local root]$ kubectl describe pods |grep Image
Image: nginx:1.10
Image ID: docker-pullable://nginx@sha256:6202beb06ea61f44179e02ca965e8e13b961d12640101fca213efbfd145d7575
- 通过
kubectl set image
命令来更新 Nginx 镜像的版本号为1.19
,此时 K8S 会执行滚动更新,逐渐进行1.10
版本的实例并启动1.19
版本的实例;
# 命令格局 kubectl set image Deployment 的名称 容器名称 = 容器镜像: 镜像版本号
kubectl set image deployments/kubernetes-nginx nginx=nginx:1.19
# 进行 1 个旧实例并创立 2 个新实例
NAME READY STATUS RESTARTS AGE
kubernetes-nginx-66f67cd758-rbcz5 0/1 ContainerCreating 0 11s
kubernetes-nginx-66f67cd758-s9ck8 0/1 ContainerCreating 0 11s
kubernetes-nginx-78bcc44665-8fnnn 1/1 Running 2 45h
kubernetes-nginx-78bcc44665-jpw2g 0/1 Terminating 0 15m
kubernetes-nginx-78bcc44665-w7xqd 1/1 Running 0 75m
kubernetes-nginx-78bcc44665-xx8s5 1/1 Running 0 15m
# 1 个实例已被进行 2 个新实例仍创立中
NAME READY STATUS RESTARTS AGE
kubernetes-nginx-66f67cd758-rbcz5 0/1 ContainerCreating 0 30s
kubernetes-nginx-66f67cd758-s9ck8 0/1 ContainerCreating 0 30s
kubernetes-nginx-78bcc44665-8fnnn 1/1 Running 2 45h
kubernetes-nginx-78bcc44665-w7xqd 1/1 Running 0 75m
kubernetes-nginx-78bcc44665-xx8s5 1/1 Running 0 15m
# 4 个新实例均已创立实现
NAME READY STATUS RESTARTS AGE
kubernetes-nginx-66f67cd758-jn926 1/1 Running 0 48s
kubernetes-nginx-66f67cd758-rbcz5 1/1 Running 0 3m12s
kubernetes-nginx-66f67cd758-s9ck8 1/1 Running 0 3m12s
kubernetes-nginx-66f67cd758-smr7n 1/1 Running 0 44s
- 此时再应用
kubectl describe
命令来查看镜像版本号,发现 Nginx 曾经更新至1.19
版本:
[macro@linux-local root]$ kubectl describe pods |grep Image
Image: nginx:1.19
Image ID: docker-pullable://nginx@sha256:4cf620a5c81390ee209398ecc18e5fb9dd0f5155cd82adcbae532fec94006fb9
- 如果想回滚到原来的版本的话,间接应用
kubectl rollout undo
命令即可。
kubectl rollout undo deployments/kubernetes-nginx
配置管理
ConfigMap 容许你将配置文件与镜像文件拆散,以使容器化的应用程序具备可移植性。接下来咱们演示下如何将 ConfigMap 的的属性注入到 Pod 的环境变量中去。
- 增加配置文件
nginx-config.yaml
用于创立 ConfigMap,ConfigMap 名称为nginx-config
,配置信息寄存在data
节点下:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: default
data:
nginx-env: test
- 利用
nginx-config.yaml
文件创建 ConfigMap:
kubectl create -f nginx-config.yaml
- 获取所有 ConfigMap:
kubectl get configmap
NAME DATA AGE
kube-root-ca.crt 1 2d22h
nginx-config 1 13s
- 通过
yaml
格局查看 ConfigMap 中的内容:
kubectl get configmaps nginx-config -o yaml
apiVersion: v1
data:
nginx-env: test
kind: ConfigMap
metadata:
creationTimestamp: "2021-01-08T01:49:44Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:nginx-env: {}
manager: kubectl-create
operation: Update
time: "2021-01-08T01:49:44Z"
name: nginx-config
namespace: default
resourceVersion: "61322"
uid: a477567f-2aff-4a04-9a49-f19220baf0d3
- 增加配置文件
nginx-deployment.yaml
用于创立 Deployment,部署一个 Nginx 服务,在 Nginx 的环境变量中援用 ConfigMap 中的属性:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.10
ports:
- containerPort: 80
env:
- name: NGINX_ENV # 在 Nginx 中设置环境变量
valueFrom:
configMapKeyRef:
name: nginx-config # 设置 ConfigMap 的名称
key: nginx-env # 须要取值的键
- 利用配置文件文件创建 Deployment:
kubectl apply -f nginx-deployment.yaml
- 创立胜利后查看 Pod 中的环境变量,发现
NGINX_ENV
变量曾经被注入了;
kubectl exec deployments/nginx-deployment -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-deployment-66fcf997c-xxdsb
NGINX_ENV=test
存储卷应用
通过存储卷,咱们能够把内部数据挂载到容器中去,供容器中的利用拜访,这样就算容器解体了,数据仍然能够存在。
- 记得之前咱们应用 Docker 部署 Nginx 的时候,将 Nginx 的
html、logs、conf
目录从内部挂载到了容器中;
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
- Minikube 能够认为是一台虚拟机,咱们能够用 Minikube 的
ssh
命令来拜访它;
minikube ssh
- Minikube 中默认有一个
docker
用户,咱们先重置下它的明码;
sudo passwd docker
- 在 Minikube 中创立
mydata
目录;
midir /home/docker/mydata
- 咱们须要把 Nginx 的数据目录复制到 Minikube 中去,能力实现目录的挂载,留神 docker 用户只能批改
/home/docker
目录中的文件,咱们通过scp
命令来复制文件;
scp -r /home/macro/mydata/nginx docker@192.168.49.2:/home/docker/mydata/nginx
- 增加配置文件
nginx-volume-deployment.yaml
用于创立 Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-volume-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.10
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: html-volume
- mountPath: /var/log/nginx
name: logs-volume
- mountPath: /etc/nginx
name: conf-volume
volumes:
- name: html-volume
hostPath:
path: /home/docker/mydata/nginx/html
type: Directory
- name: logs-volume
hostPath:
path: /home/docker/mydata/nginx/logs
type: Directory
- name: conf-volume
hostPath:
path: /home/docker/mydata/nginx/conf
type: Directory
- 利用配置文件创立 Deployment;
kubectl apply -f nginx-volume-deployment.yaml
- 增加配置文件
nginx-service.yaml
用于创立 Service;
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
- 利用配置文件创立 Service;
kubectl apply -f nginx-service.yaml
- 查看下 Service 服务拜访端口;
[macro@linux-local nginx]$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d23h
kubernetes-nginx NodePort 10.106.227.54 <none> 80:30158/TCP 5d22h
nginx-service NodePort 10.103.72.111 <none> 80:30080/TCP 7s
- 通过 CURL 命令能够拜访 Nginx 首页信息。
curl $(minikube ip):30080
网关路由
Ingress 能够作为 K8S 的网关来应用,能提供服务路由和负载平衡等性能。
- Minikube 默认没有启用 Ingress 插件,须要手动开启;
minikube addons enable ingress
- 开启 Ingress 过程中遇到了一个坑,会在验证的时候卡主,其实是 Minikube 外部无奈下载 Ingress 镜像导致的:
[macro@linux-local ~]$ minikube addons enable ingress
* Verifying ingress addon...
- 解决该问题须要手动下载第三方镜像,并标记为须要的镜像,并从新启用 Ingress 插件;
# 查找启动有问题的 Pod
kubectl get pods -n kube-system
# 查看启动失败起因
kubectl describe ingress-nginx-controller-xxx -n kube-system
# 连贯到 Minikube
minikube ssh
# 原来须要下载的镜像(曾经无奈下载)docker pull us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.40.2
# 下载第三方代替镜像(间接去 DockerHub 官网搜寻即可)docker pull pollyduan/ingress-nginx-controller:v0.40.2
# 批改镜像名称
docker tag pollyduan/ingress-nginx-controller:v0.40.2 us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.40.2
- 重启插件后查看下 Ingress 是否在运行;
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-krpgk 0/1 Completed 0 46h
ingress-nginx-admission-patch-wnxlk 0/1 Completed 3 46h
ingress-nginx-controller-558664778f-wwgws 1/1 Running 2 46h
- 增加配置文件
nginx-ingress.yaml
用于创立 Ingress;
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: nginx-volume.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
- 利用配置文件创立 Ingress;
kubectl apply -f nginx-ingress.yaml
- 查看所有 Ingress,此时咱们曾经能够通过
nginx-volume.com
来拜访 Pod 中运行的 Nginx 服务了;
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress <none> nginx-volume.com 192.168.49.2 80 6s
- 须要批改下
host
文件,留神切换到root
账号后批改:
# 切换到 root 用户
su -
# 批改 host 文件
vi /etc/hosts
# 增加如下记录
192.168.49.2 nginx-volume.com
- 最初通过 CURL 命令能够拜访 Nginx 首页信息。
curl nginx-volume.com
总结
通过 K8S 扩大和治理容器化利用的确非常不便,通过几个命令咱们就能够实现零停机更新,出了故障也不怕,一个命令实现回滚。然而大量的命令行操作总显得枯燥无味,要是有个可视化工具能够间接治理 K8S 就更好了。
参考资料
官网文档:https://kubernetes.io/zh/docs…
本文 GitHub https://github.com/macrozheng/mall-learning 曾经收录,欢送大家 Star!