如果你看了《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 AGEkubernetes-nginx 1/1 1 1 43h
- 获取所有ReplicaSet可应用如下命令:
kubectl get rs
NAME DESIRED CURRENT READY AGEkubernetes-nginx-78bcc44665 1 1 1 43h
- 对利用进行扩容操作,扩容到4个实例,再查看所有:
kubectl scale deployments/kubernetes-nginx --replicas=4
[macro@linux-local root]$ kubectl get deploymentsNAME READY UP-TO-DATE AVAILABLE AGEkubernetes-nginx 4/4 4 4 43h
- 查看所有Pod,发现曾经有4个运行在不同的IP地址上了;
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESkubernetes-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 GATESkubernetes-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 podsNAME READY STATUS RESTARTS AGEkubernetes-nginx-78bcc44665-8fnnn 1/1 Running 2 44hkubernetes-nginx-78bcc44665-jpw2g 1/1 Running 0 5skubernetes-nginx-78bcc44665-w7xqd 1/1 Running 0 59mkubernetes-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 AGEkubernetes-nginx-66f67cd758-rbcz5 0/1 ContainerCreating 0 11skubernetes-nginx-66f67cd758-s9ck8 0/1 ContainerCreating 0 11skubernetes-nginx-78bcc44665-8fnnn 1/1 Running 2 45hkubernetes-nginx-78bcc44665-jpw2g 0/1 Terminating 0 15mkubernetes-nginx-78bcc44665-w7xqd 1/1 Running 0 75mkubernetes-nginx-78bcc44665-xx8s5 1/1 Running 0 15m# 1个实例已被进行2个新实例仍创立中NAME READY STATUS RESTARTS AGEkubernetes-nginx-66f67cd758-rbcz5 0/1 ContainerCreating 0 30skubernetes-nginx-66f67cd758-s9ck8 0/1 ContainerCreating 0 30skubernetes-nginx-78bcc44665-8fnnn 1/1 Running 2 45hkubernetes-nginx-78bcc44665-w7xqd 1/1 Running 0 75mkubernetes-nginx-78bcc44665-xx8s5 1/1 Running 0 15m# 4个新实例均已创立实现NAME READY STATUS RESTARTS AGEkubernetes-nginx-66f67cd758-jn926 1/1 Running 0 48skubernetes-nginx-66f67cd758-rbcz5 1/1 Running 0 3m12skubernetes-nginx-66f67cd758-s9ck8 1/1 Running 0 3m12skubernetes-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: v1kind: ConfigMapmetadata: name: nginx-config namespace: defaultdata: nginx-env: test
- 利用
nginx-config.yaml
文件创建ConfigMap:
kubectl create -f nginx-config.yaml
- 获取所有ConfigMap:
kubectl get configmap
NAME DATA AGEkube-root-ca.crt 1 2d22hnginx-config 1 13s
- 通过
yaml
格局查看ConfigMap中的内容:
kubectl get configmaps nginx-config -o yaml
apiVersion: v1data: nginx-env: testkind: ConfigMapmetadata: 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/v1kind: Deploymentmetadata: name: nginx-deployment labels: app: nginxspec: 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:/binHOSTNAME=nginx-deployment-66fcf997c-xxdsbNGINX_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/v1kind: Deploymentmetadata: name: nginx-volume-deployment labels: app: nginxspec: 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: v1kind: Servicemetadata: name: nginx-servicespec: 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 servicesNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d23hkubernetes-nginx NodePort 10.106.227.54 <none> 80:30158/TCP 5d22hnginx-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插件;
# 查找启动有问题的Podkubectl get pods -n kube-system# 查看启动失败起因kubectl describe ingress-nginx-controller-xxx -n kube-system# 连贯到Minikubeminikube 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 AGEingress-nginx-admission-create-krpgk 0/1 Completed 0 46hingress-nginx-admission-patch-wnxlk 0/1 Completed 3 46hingress-nginx-controller-558664778f-wwgws 1/1 Running 2 46h
- 增加配置文件
nginx-ingress.yaml
用于创立Ingress;
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: nginx-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1spec: 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 AGEnginx-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!