乐趣区

关于java:自从上了K8S项目更新都不带停机的

如果你看了《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 个 Nginx1.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!

退出移动版