其实 K8S 中还有一些高级特性也很值得学习,比如弹性扩缩应用、滚动更新、配置管理、存储卷、网关路由等。今天我们就来了解下这些高级特性,希望对大家有所帮助!
核心概念
首先我们先来了解一些核心概念,了解这些核心概念对使用 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 中的副本数量来实现的。
点击并拖拽以移动
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-nginx 1/1 1 1 43h
复制代码
点击并拖拽以移动
点击并拖拽以移动
NAME DESIRED CURRENT READY AGE
kubernetes-nginx-78bcc44665 1 1 1 43h
复制代码
点击并拖拽以移动
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
复制代码
点击并拖拽以移动
点击并拖拽以移动
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>
复制代码
点击并拖拽以移动
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 不仅可以实现滚动更新,还可以支持回滚操作。
[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
复制代码
点击并拖拽以移动
[macro@linux-local root]$ kubectl describe pods |grep Image
Image: nginx:1.10
Image ID: docker-pullable://nginx@sha256:6202beb06ea61f44179e02ca965e8e13b961d12640101fca213efbfd145d7575
复制代码
点击并拖拽以移动
# 命令格式 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
复制代码
点击并拖拽以移动
[macro@linux-local root]$ kubectl describe pods |grep Image
Image: nginx:1.19
Image ID: docker-pullable://nginx@sha256:4cf620a5c81390ee209398ecc18e5fb9dd0f5155cd82adcbae532fec94006fb9
复制代码
点击并拖拽以移动
kubectl rollout undo deployments/kubernetes-nginx
复制代码
配置管理
ConfigMap 允许你将配置文件与镜像文件分离,以使容器化的应用程序具有可移植性。接下来我们演示下如何将 ConfigMap 的的属性注入到 Pod 的环境变量中去。
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: default
data:
nginx-env: test
复制代码
点击并拖拽以移动
kubectl create -f nginx-config.yaml
复制代码
点击并拖拽以移动
点击并拖拽以移动
NAME DATA AGE
kube-root-ca.crt 1 2d22h
nginx-config 1 13s
复制代码
点击并拖拽以移动
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
复制代码
点击并拖拽以移动
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 # 需要取值的键
复制代码
点击并拖拽以移动
kubectl apply -f nginx-deployment.yaml
复制代码
点击并拖拽以移动
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 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
复制代码
点击并拖拽以移动
点击并拖拽以移动
点击并拖拽以移动
midir /home/docker/mydata
复制代码
点击并拖拽以移动
scp -r /home/macro/mydata/nginx docker@192.168.49.2:/home/docker/mydata/nginx
复制代码
点击并拖拽以移动
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
复制代码
点击并拖拽以移动
kubectl apply -f nginx-volume-deployment.yaml
复制代码
点击并拖拽以移动
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
复制代码
点击并拖拽以移动
kubectl apply -f nginx-service.yaml
复制代码
点击并拖拽以移动
[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 $(minikube ip):30080
复制代码
点击并拖拽以移动
网关路由
Ingress 可以作为 K8S 的网关来使用,能提供服务路由和负载均衡等功能。
minikube addons enable ingress
复制代码
点击并拖拽以移动
[macro@linux-local ~]$ minikube addons enable ingress
* Verifying ingress addon...
复制代码
点击并拖拽以移动
# 查找启动有问题的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
复制代码
点击并拖拽以移动
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
复制代码
点击并拖拽以移动
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
复制代码
点击并拖拽以移动
kubectl apply -f nginx-ingress.yaml
复制代码
点击并拖拽以移动
点击并拖拽以移动
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress <none> nginx-volume.com 192.168.49.2 80 6s
复制代码
点击并拖拽以移动
# 切换到root用户
su -
# 修改host文件
vi /etc/hosts
# 添加如下记录
192.168.49.2 nginx-volume.com
复制代码
点击并拖拽以移动
点击并拖拽以移动
总结
通过 K8S 扩展和管理容器化应用确实十分方便,通过几个命令我们就可以实现零停机更新,出了故障也不怕,一个命令实现回滚。但是大量的命令行操作总显得枯燥无味,要是有个可视化工具可以直接管理 K8S 就更好了。
推荐阅读
程序员年薪百万的飞马计划你听说过吗?
为什么阿里巴巴的程序员成长速度这么快,看完他们的内部资料我懂了
从事开发一年的程序员能拿到多少钱?
字节跳动总结的设计模式 PDF 火了,完整版开放下载
刷Github时发现了一本阿里大神的算法笔记!标星70.5K
程序员50W年薪的知识体系与成长路线。
关于【暴力递归算法】你所不知道的思路
开辟鸿蒙,谁做系统,聊聊华为微内核
看完三件事❤️
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
关注公众号 『 Java 斗帝 』,不定期分享原创知识。
同时可以期待后续文章 ing🚀
评论