【Java】自从上了K8S,项目更新都不带停机的!

自从上了K8S,项目更新都不带停机的!

macrozheng发布于 今天 01:19

SpringBoot实战电商项目mall(40k+star)地址:https://github.com/macrozheng/mall

核心概念

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终结和基于名称的虚拟托管。

【Java】自从上了K8S,项目更新都不带停机的!

高级特性

扩缩应用

  • 获取所有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

[[email protected] 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>

滚动更新

  • 目前运行了4个Nginx1.10版本的实例:

[[email protected] 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命令来查看镜像版本号:

[[email protected] root]$ kubectl describe pods |grep Image

Image: nginx:1.10

Image ID: docker-pullable://[email protected]: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版本:

[[email protected] root]$ kubectl describe pods |grep Image

Image: nginx:1.19

Image ID: docker-pullable://[email protected]:4cf620a5c81390ee209398ecc18e5fb9dd0f5155cd82adcbae532fec94006fb9

  • 如果想回滚到原来的版本的话,直接使用kubectl rollout undo命令即可。

kubectl rollout undo deployments/kubernetes-nginx

配置管理

  • 添加配置文件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 [email protected]:/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服务访问端口;

[[email protected] 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

网关路由

  • Minikube默认没有启用Ingress插件,需要手动开启;

minikube addons enable ingress

  • 开启Ingress过程中遇到了一个坑,会在验证的时候卡主,其实是Minikube内部无法下载Ingress镜像导致的:

[[email protected] ~]$ 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...

javakubernetesspringboot

阅读 40发布于 今天 01:19

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议


mall学习教程

mall学习教程,架构、业务、技术要点全方位解析。mall项目(20k+star)是一套电商系统,使用现阶段主流...

avatar

macrozheng

公众号:macrozheng | Java后端技术 |Github开源项目mall(40k+star)

553 声望

25 粉丝

0 条评论

得票时间

avatar

macrozheng

公众号:macrozheng | Java后端技术 |Github开源项目mall(40k+star)

553 声望

25 粉丝

宣传栏

SpringBoot实战电商项目mall(40k+star)地址:https://github.com/macrozheng/mall

核心概念

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终结和基于名称的虚拟托管。

【Java】自从上了K8S,项目更新都不带停机的!

高级特性

扩缩应用

  • 获取所有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

[[email protected] 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>

滚动更新

  • 目前运行了4个Nginx1.10版本的实例:

[[email protected] 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命令来查看镜像版本号:

[[email protected] root]$ kubectl describe pods |grep Image

Image: nginx:1.10

Image ID: docker-pullable://[email protected]: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版本:

[[email protected] root]$ kubectl describe pods |grep Image

Image: nginx:1.19

Image ID: docker-pullable://[email protected]:4cf620a5c81390ee209398ecc18e5fb9dd0f5155cd82adcbae532fec94006fb9

  • 如果想回滚到原来的版本的话,直接使用kubectl rollout undo命令即可。

kubectl rollout undo deployments/kubernetes-nginx

配置管理

  • 添加配置文件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 [email protected]:/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服务访问端口;

[[email protected] 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

网关路由

  • Minikube默认没有启用Ingress插件,需要手动开启;

minikube addons enable ingress

  • 开启Ingress过程中遇到了一个坑,会在验证的时候卡主,其实是Minikube内部无法下载Ingress镜像导致的:

[[email protected] ~]$ 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...

以上是 【Java】自从上了K8S,项目更新都不带停机的! 的全部内容, 来源链接: utcz.com/a/109517.html

回到顶部