本篇将一步步介绍如何将sck-demo整个项目部署到本地kubernetes,包括镜像升级、让服务可通过浏览器访问、回滚版本,以及调整minikube虚拟机的内存大小。
项目地址:https://github.com/wujiuye/share-projects/tree/master/sck-demo
修改minikube的cpu核心数量和内存大小
先来说说如何调整minikube虚拟机的内存大小。默认的minikube虚拟机分配的内存很小,如果不调整大小,你会发现,pod一起动起来,要么一会挂掉,要么就是其它服务的pod挂掉。不过对sck-demo来说默认的内存大小是足够的。
- 1、如果已经启动过
minikube,则需要先删除
minikube delete
- 2、启动时指定虚拟机的
cpu和内存大小
minikube start --image-mirror-country='cn' \
--image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' \
--cpus 2 --memory 4g \
--vm-driver=virtualbox
或者先修改配置,再执行minikube delete,再重新启动
minikube config set memory 4096
建议:如果本地机器内存少于8g,不建议在本地搞minikube,不然电脑会很卡。
为容器配置预估的应用需要消费的cpu资源和内存大小(resources项):
将jar包构建为镜像
将项目打包,然后构建镜像,构建镜像时应该打上tag,标志着每个镜像的版本号,启动一个服务也应该明确地指定镜像的版本,而不是使用默认latest。
- 1、项目打包
mvn clean package -DskipTests
- 2、确保
minikube已经启动,确保使用minikube docker守护进程
为使镜像自动存在,而不需要将镜像推送至远程仓库再拉取,可以使用与minikube vm相同的docker主机构建镜像。
eval $(minikube docker-env)
如果不再使用minikube主机时,可以通过运行eval $(minikube docker-env -u)来撤消此更改:
eval $(minikube docker-env -u)
- 3、使用
minikube的docker守护进程构建镜像
以sck-demo项目的其中一个模块为例:
docker build -t wujiuye/sck-demo-provider:v1.0.0 ./sck-demo-provider
命令参数说明:
-t: 构建镜像并打标签;wujiuye/sck-demo-provider:v1.0.0:镜像标签;./sck-demo-provider:Dockerfile文件所在目录
同样步骤,将sck-demo-consumer构建为镜像。
编写各描述文件,将镜像部署到minikube
- 1、为服务提供者和服务消费者都编写
Deployment与Service描述文件,这两个配置写在同一个yaml文件。
以sck-demo-provider为例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: sck-demo-provider
namespace: default
spec:
# 副本数
replicas: 1
selector:
matchLabels:
app: sck-demo-provider
template:
metadata:
labels:
app: sck-demo-provider
env: dev
spec:
# 容器配置
containers:
- name: sck-demo-provider
image: wujiuye/sck-demo-provider:v1.0.0
# 镜像拉去策略:Always(总是拉取)、IfNotPresent(默认值,本地有则使用本地镜像,不拉取)、Never(只使用本地镜像,从不拉取)
imagePullPolicy: Never
ports:
- name: http-port
containerPort: 8080
# 环境变量,引用ConfigMap资源,sck-demo-common-config为通用环境变量配置
envFrom:
- configMapRef:
name: sck-demo-common-config
# 指定ServiceAccount,稍后创建
serviceAccountName: pod-configmap-sa
# 使用---分割配置
---
apiVersion: v1
kind: Service
metadata:
name: sck-demo-provider
namespace: default
spec:
selector:
app: sck-demo-provider
env: dev
ports:
- protocol: TCP
port: 80
targetPort: 8080
其中sck-demo-common-config的配置如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: sck-demo-common-config
namespace: default
data:
SPRING_PROFILES_ACTIVE: dev
SERVER_PORT: "8080"
sck-demo-common-config为通用环境变量配置,也是ConfigMap资源。
使用kubectl创建名为sck-demo-common-config的ConfigMap资源:
kubectl apply -f k8s/dev/config/sck-demo-common-config.yaml
使用kubectl创建sck-demo-provider服务的Deployment与Service:
kubectl apply -f k8s/dev/service/sck-demo-provider.yaml
- 2、由于
sck-demo项目使用到动态配置,因此还需要为每个服务(使用到动态配置的服务)编写ConfigMap资源配置文件。
以sck-demo-provider为例:
apiVersion: v1
kind: ConfigMap
metadata:
name: sck-demo-provider-config
namespace: default
data:
## 动态配置内容
application-dev.yml: |-
sck-demo:
message: for dev config map
使用kubectl创建ConfigMap:
kubectl apply -f k8s/dev/config/sck-demo-provider-config.yaml
- 3、添加一个用户,并为用户授权,应用程序读取
ConfigMap资源配置时需要用到。
创建一个ServiceAccount:
# 创建ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-configmap-sa
namespace: default
创建角色pod-configmap-read-role:
# 创建角色(pod级别)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-configmap-read-role
namespace: default
# 注册中心需要services的访问权限
rules:
- apiGroups: [""]
# 该角色可以访问的资源
resources: ["pods","configmaps","endpoints","services"]
# 限定能做哪些操作
verbs: ["get", "watch", "list"]
将ServiceAccount与角色绑定:
# 为指定ServiceAccount绑定角色
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-configmap-read-role-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-configmap-read-role
subjects:
- kind: ServiceAccount
name: pod-configmap-sa
namespace: default
将这三个文件放在同一个目录account,最后使用kubectl创建用户、角色、以及将用户与角色绑定:
kubectl apply -f k8s/dev/account
测试服务间调用,测试动态配置
如果我们只是想测试sck-demo-consumer调用sck-demo-provider能否成功,我们可以选择只暴露sck-demo-consumer。由于动态配置是写在sck-demo-provider的,并且提供了api来验证动态配置是否生效,因此也需要将sck-demo-provider暴露到外部可访问。
修改sck-demo-provider与sck-demo-consumer的Service配置,将集群IP类型改为NodePort。
sck-demo-consumer.yaml
apiVersion: v1
kind: Service
metadata:
name: sck-demo-consumer
namespace: default
spec:
selector:
app: sck-demo-consumer
env: dev
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: NodePort
sck-demo-provider.yaml
apiVersion: v1
kind: Service
metadata:
name: sck-demo-provider
namespace: default
spec:
selector:
app: sck-demo-provider
env: dev
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: NodePort
更新Service:
kubectl apply -f k8s/dev/service
其中k8s/dev/service目录存放sck-demo项目的dev环境下所有服务的Deployment与Service配置的配置文件。
使用minikube service命令暴露服务,让本地可访问。
暴露sck-demo-consumer服务:
minikube service sck-demo-consumer
暴露sck-demo-provider服务:
minikube service sck-demo-provider
在浏览器访问http://192.168.99.103:30462/demo,验证服务是否调用成功,如果如下:
修改sck-demo-provider-config.yaml文件,或者直接在kubernetes dashboard修改,验证动态配置是否生效。
如图,我们将sck-demo.message修改为for dev config map yyyyy,修改完成后点击update,接着浏览器访问:http://192.168.99.103:31424/v1/config:
接收动态配置的bean:
@Component
@ConfigurationProperties(prefix = "sck-demo")
@RefreshScope(proxyMode = ScopedProxyMode.TARGET_CLASS)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class DemoProps {
private String message;
}
注意:在测试时,不要将DemoProps写到响应体,否则会报序列化异常,因为这是一个动态代理对象,我们在分析动态配置实现源码后再回过头来看就不难理解了。
在上一篇文章中,我们添加了监听动态配置刷新事件并打印日记的代码,因此,现在我们还可以使用kubectl logs查看Pod输出的日记:
kubectl logs pod的name
镜像版本升级
- 1、构建镜像时带上新版本号,假设新的版本号为
v1.0.1:
docker build -t wujiuye/sck-demo-provider:v1.0.1 ./sck-demo-provider
对Deployment做一次升级
kubectl set image deployment deployment名称 容器名称=镜像版本
如
kubectl set image deployment sck-demo-provider sck-demo-provider=wujiuye/sck-demo-provider:v1.0.1
命令执行成功后,会启动新的Pod,当新的Pod启动成功后,旧的Pod会被移除。新Pod的描述文件容器配置部分将会更新为如下:
spec:
containers:
- name: sck-demo-provider
image: 'wujiuye/sck-demo-provider:v1.0.1'
版本回退
以sck-demo-provider为例:
在更新Deployment时加上--record,记录本次执行的命令,以便后续查看历史记录时,能够看出每个版本都做了什么,能够判断需要回滚到哪个版本。
kubectl set image Deployment sck-demo-provider sck-demo-provider=wujiuye/sck-demo-provider:v1.0.3 --record
查看历史版本:
kubectl rollout history deployment sck-demo-provider --namespace=default
回滚到某个版本:
kubectl rollout undo deployment sck-demo-provider --to-revision=10 --namespace=default
--to-revision:指定回滚到哪个版本--namespace:名称空间sck-demo-provider:需要回滚的deployment的名称
如上图所示,回滚成功后,版本10就更新成新的版本号了。
通过-o wide查看deployment状态信息:
kubectl get deployment sck-demo-provider -o wide
查看replicaset每个版本的状态信息:
kubectl get replicaset
可使用revisionHistoryLimit控制ReplicaSet的历史版本保留数量,默认为10。