Minikube中springboot读取configmap配置

510 阅读6分钟

前言

首先介绍一下原理:原理很简单,即将configmap配置成卷,文件名为application.properties,挂载至容器中springboot可读取的路径上,springboot应用在启动时读取application.properties的内容 。

之前本机环境一直在使用Rancher Desktop提供的k3s集群环境。k3s是k8s的瘦身版,其完全实现了 Kubernetes API,但剔除了很多不必要的驱动程序,转而使用附加组件对其进行替换,这样使得k3s只需要极少的资源就可以运行,所以k3s通常更适用于一些边缘计算和物联网场景,或其它一些非核心集群的场景,如开发测试等。

由于Rancher Desktop了解的人不多,大多数人还是偏向使用minikube来部署开发测试环境,所以我也安装一套minikube环境。MiniKube可以部署成VM,container或bare-metal,不同OS提供的不同类型driver支持。具体可以查看官方说明:minikube.sigs.k8s.io/docs/driver… 如果基于docker部署成container的话,需要每次都开启Rancher Desktop,或者重新安装一个docker,这样会和rancher desktop的docker冲突,故选择基于Windows Hyper-V虚拟机安装minikube。

本文源代码:github.com/tzjavadmg/j…

基于Windows Hyper-V安装minikube

官方参考文档

minikube.sigs.k8s.io/docs/driver…

管理员身份打开 powershell

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

启动minikube,首次启动时间会比较长,因为要下载相关镜像文件。中途如果停顿时间过长,可以终止进程后运行minikube stop命令,再重新开始。

minikube start --vm-driver=hyperv --image-mirror-country=cn

当看到以下输出时,表示minikube启动成功

  • Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

查看上下文环境信息,现在我有两个context了,一个是minikube,一个是之前使用的rancher-desktop. 默认环境是minikube,此时使用kubectl命令操作的都是minikube集群。

PS C:\WINDOWS\system32> kubectl config get-contexts
CURRENT   NAME              CLUSTER           AUTHINFO          NAMESPACE
*         minikube          minikube          minikube          default
          rancher-desktop   rancher-desktop   rancher-desktop

如果希望管理rancher-desktop集群,将应用部署至rancher-desktop,则可以使用如下命令切换context

PS C:\WINDOWS\system32> kubectl config use-context  rancher-desktop
Switched to context "rancher-desktop".
PS C:\WINDOWS\system32> kubectl config get-contexts
I1102 20:03:35.321147   16964 versioner.go:56] Remote kubernetes server unreachable
CURRENT   NAME              CLUSTER           AUTHINFO          NAMESPACE
          minikube          minikube          minikube          default
*         rancher-desktop   rancher-desktop   rancher-desktop

创建Spring boot工程

下面创建一个spring boot 工程custom-resource,工程如下图所示:

image.png

工程使用自定义的Dockerfile和yaml资源描述文件。在CustomResourceController中将演示从configmap读取配置项数据。代码如下:

@RestController
public class CustomResourceController {

    @Value("${welcome:no config}")
    private String welcome;

    @Value("${name:no config}")
    private String name;

    @RequestMapping("/")
    public String index() {
        return name + " " + welcome;
    }
}

配置Maven连接minikube docker

由于minikube部署的k8s集群中的docker容器位于Hyper-V虚拟机中,避免构建镜像还需要上传仓库的麻烦,直接配置Maven使用minikube的docker环境构建应用程序的镜像。

首先用minikube docker-env命令查看minikube的docker环境。

PS C:\WINDOWS\system32> minikube docker-env
$Env:DOCKER_TLS_VERIFY = "1"
$Env:DOCKER_HOST = "tcp://172.19.27.78:2376"
$Env:DOCKER_CERT_PATH = "C:\Users\Lenovo\.minikube\certs"
$Env:MINIKUBE_ACTIVE_DOCKERD = "minikube"
# To point your shell to minikube's docker-daemon, run:
# & minikube -p minikube docker-env --shell powershell | Invoke-Expression

根据输出的环境信息,修改maven配置如下:

    <properties>
        <jkube.docker.host>tcp://172.19.27.78:2376</jkube.docker.host>
        <jkube.docker.certPath>C:\Users\Lenovo.minikube\certs</jkube.docker.certPath>
    </properties>

这样就可以直接使用maven命令来构建docker镜像至minikube环境。

构建Docker镜像

编写Dockerfile文件,存放于工程根目录下(也可以放于src/main/docker目录,或者在pom里配置成其它目录)。

FROM maven:3.8.3-openjdk-17
EXPOSE 8080/tcp
COPY maven/target/*.jar /opt/app.jar
WORKDIR /opt
ENTRYPOINT [ "java", "-jar", "/opt/app.jar" ]

执行maven命令构建docker镜像

mvn package k8s:build

[INFO] --- kubernetes-maven-plugin:1.9.1:build (default-cli) @ docker-file ---
[INFO] k8s: Building Docker image in Kubernetes mode
[INFO] k8s: Using Dockerfile: D:\i-workspace\jkube-examples\docker-file\Dockerfile
[INFO] k8s: Using Docker Context Directory: D:\i-workspace\jkube-examples\docker-file
[INFO] k8s: [jkube-examples/docker-file:latest]: Created docker-build.tar in 1 second 
[INFO] k8s: [jkube-examples/docker-file:latest]: Built image sha256:49570
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

使用minikube image list命令查看镜像

PS C:\WINDOWS\system32> minikube image list --format table
|-----------------------------------------------------------------------------|------------------|---------------|--------|
|                                    Image                                    |       Tag        |   Image ID    |  Size  |
|-----------------------------------------------------------------------------|------------------|---------------|--------|
| registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler          | v1.25.2          | ca0ea1ee3cfd3 | 50.6MB |
| registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy              | v1.25.2          | 1c7d8c51823b5 | 61.7MB |
| registry.cn-hangzhou.aliyuncs.com/google_containers/pause                   | 3.8              | 4873874c08efc | 711kB  |
| registry.cn-hangzhou.aliyuncs.com/google_containers/etcd                    | 3.5.4-0          | a8a176a5d5d69 | 300MB  |
| registry.cn-hangzhou.aliyuncs.com/google_containers/coredns                 | v1.9.3           | 5185b96f0becf | 48.8MB |
| registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner     | v5               | 6e38f40d628db | 31.5MB |
| docker.io/jkube-examples/docker-file                                        | latest           | 495705464559c | 805MB  |
| docker.io/jkube-examples/custom-resource                                    | latest           | 0649d5f3d8b1d | 805MB  |
| registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver          | v1.25.2          | 97801f8394908 | 128MB  |
| registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager | v1.25.2          | dbfceb93c69b6 | 117MB  |
| docker.io/library/maven                                                     | 3.8.3-openjdk-17 | 0b9ddcb8259ea | 785MB  |
| k8s.gcr.io/pause                                                            | 3.6              | 6270bb605e12e | 683kB  |
|-----------------------------------------------------------------------------|------------------|---------------|--------|

如上所示,docker.io/jkube-examples/custom-resource 即为刚才构建的docker 镜像

部署spring boot应用至minikube k8s集群

编写k8s配置文件

service.yml

metadata:
  annotations:
    api.service.kubernetes.io/path: /
spec:
  type: NodePort
  ports:
    - name: http
      port: 8080
      nodePort: 30000

使用NodePort Type直接暴露30000端口访问服务。

configmap.yml

metadata:
  name: ${project.artifactId}
data:
  application.properties: |
    # spring application properties file
    welcome = Hello from Kubernetes ConfigMap!!!
    name = codyzeng

deplyment.yml

spec:
  replicas: 1
  template:
    spec:
      volumes:
        - name: config
          configMap:
            name: ${project.artifactId}
            items:
              - key: application.properties
                path: application.properties
      containers:
        - volumeMounts:
            - name: config
              mountPath: /opt/config
          env:
            - name: MY_POD_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
      serviceAccount: codyzeng

配置一个名为config的卷,引用configMap,然后将其挂载至容器的/opt/config目录下。 为什么挂载至此目录下?看Dockerfile,应用程序启动的工作目录是/opt,springboot应用读取的配置文件可以存放在工作目录根目录,也可以存放在工作目录的config目录下。config目录比根目录优先级更高。

这里注意工作目录是指运行java命令的当前目录,并不是指应用程序Jar包存放的目录。

运行mvn clean k8s:resource k8s:apply 目录部署应用至k8s

PS D:\i-workspace\jkube-examples\custom-resource> mvn clean k8s:resource k8s:apply    
[INFO] Scanning for projects...
[INFO] 
[INFO] --------------------< com.codyzeng:custom-resource >--------------------
[INFO] Building custom-resource 1.0-SNAPSHOT                                   
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.2.0:clean (default-clean) @ custom-resource ---
[INFO] Deleting D:\i-workspace\jkube-examples\custom-resource\target
[INFO] 
[INFO] --- kubernetes-maven-plugin:1.9.1:resource (default-cli) @ custom-resource ---
[INFO] k8s: Using Dockerfile: D:\i-workspace\jkube-examples\custom-resource\Dockerfile
[INFO] k8s: Using Docker Context Directory: D:\i-workspace\jkube-examples\custom-resource
[INFO] k8s: Using resource templates from D:\i-workspace\jkube-examples\custom-resource\src\main\jkube
[INFO] k8s: jkube-healthcheck-spring-boot: Adding readiness probe on port 8080, path='/actuator/health', scheme='HTTP', with initial delay 10 seconds
[INFO] k8s: jkube-healthcheck-spring-boot: Adding liveness probe on port 8080, path='/actuator/health', scheme='HTTP', with initial delay 180 seconds
[INFO] k8s: jkube-service-discovery: Using first mentioned service port '8080' 
[INFO] k8s: jkube-revision-history: Adding revision history limit to 2
[INFO] k8s: Updated ConfigMap: custom-resource\target\jkube\applyJson\default\configmap-custom-resource.json
[INFO] k8s: Updating Deployment from kubernetes.yml
[INFO] k8s: Updated Deployment: custom-resource\target\jkube\applyJson\default\deployment-custom-resource.json
[INFO] k8s: HINT: Use the command `kubectl get pods -w` to watch your pods start up
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

使用minikube dashboard查看集群和部署信息

运行minikube dashboard命令,会自动打开dashboard界面。

PS C:\WINDOWS\system32> minikube dashboard
* 正在开启 dashboard ...
  - Using image docker.io/kubernetesui/dashboard:v2.7.0
  - Using image docker.io/kubernetesui/metrics-scraper:v1.0.8
* 正在验证 dashboard 运行情况 ...
* Launching proxy ...
* 正在验证 proxy 运行状况 ...
* Opening http://127.0.0.1:3984/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...

面板首页即可看到刚才部署的Deployments:custom-resource

image.png

从【配置和存储】-【Config Maps】菜单下可以查看config map配置,如下图:

image.png 点进去查看详细信息:

image.png

从【工作负载】-【Pods】菜单可以查看Pod卷挂载配置,如下图

image.png

也可以进入容器使用命令行查看文件是否已经正确挂载

image.png

image.png

浏览器展示最终效果

通过虚拟主机IP:30000端口访问结果如下:

image.png