使用kubernetes运行Java Spring Boot 应用

Spring Wu 305 2022-10-10

安装

我的机器为centos7,使用的是单机方式的安装,安装之前需要注意本机没有安装docker 或 k8s相关的软件。否则安装会报错。

# 安装docker、etcd、k8s
yum install docker etcd kubernetes -y

如果出现以下报错

Transaction check error:
  file /usr/bin/kubectl from install of kubernetes-client-1.5.2-0.7.git269f928.el7.x86_64 conflicts with file from package kubectl-1.16.3-0.x86_64
  file /usr/bin/kubelet from install of kubernetes-node-1.5.2-0.7.git269f928.el7.x86_64 conflicts with file from package kubelet-1.16.3-0.x86_64
  file /usr/lib/systemd/system/kubelet.service from install of kubernetes-node-1.5.2-0.7.git269f928.el7.x86_64 conflicts with file from package kubelet-1.16.3-0.x86_64
  
Error Summary
-------------

说明之前机器上安装有k8s相关东西。需要删除干净。

# 删除kube*所有匹配到的软件, 生产机器慎用。
yum remove kube*

启动k8s的各项服务

systemctl start etcd
systemctl start docker
systemctl start kube-apiserver
systemctl start kube-controller-manager
systemctl start kube-scheduler
systemctl start kubelet
systemctl start kube-proxy

创建一个Spring Boot Demo运行到docker中

通过start.spring.io创建一个有demo,编写controller

/**
 * Hello kubernetes!
 * @author ShuaiPing.Wu
 */
@RequestMapping(value = "/hello")
@RestController
public class HelloController {
    @GetMapping
    public String hello(){
        return "hello kubernetes!";
    }
}

打开application.yaml设置应用端口

server:
  port: 9999

把项目打成jar包

maven clean package

将jar包移动到centos机器中,我是通过xftp来操作的。
之后在同一级目录中编写Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD k8s-sb-demo-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

在Dockerfile目录下,将jar包打成docker镜像

docker build -t wushuaiping.com/k8s-demo.0.0.1.latest .

查看镜像是否打包好

[root@wushuaiping-private demo]# docker images
REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE
wushuaiping.com/k8s-demo.0.0.1.latest                         latest              77ac7eaec116        4 seconds ago       122 MB

运行镜像

[root@wushuaiping-private demo]# docker run -d -p 9999:9999 wushuaiping.com/k8s-demo.0.0.1.latest
bdbe4f6ee3d5951b73dc387dc77eb3370567015a46928629f50bc01db45ca354

验证是否运行成功

image

在k8s中管理应用

在同一级目录下创建k8s的部署文件deployment.yaml并编写。

[root@wushuaiping-private demo]# ls
Dockerfile  k8s-sb-demo-0.0.1-SNAPSHOT.jar
[root@wushuaiping-private demo]# vim k8s-demo-deployment.yaml 

打开的文件如下:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: k8s-demo-deployment
  labels:
    app: k8s-demo
spec:
  # 副本数
  replicas: 3
  selector:
    matchLabels:
      app: k8s-demo
  template:
    metadata:
      labels:
        app: k8s-demo
    spec:
      containers:
        - name: k8s-demo
          image: wooo.io/k8s-demo.0.0.1.latest
          workingDir: /usr/src/demo/k8s-demo
          command: ["/bin/bash", "-c", "ln -s /usr/src/demo/k8s-demo/config/conf.properties /usr/src/demo/k8s-demo/conf.properties && java -jar app.jar"]
          ports:
            - containerPort: 9999
          volumeMounts:
            - mountPath: /usr/src/demo/k8s-demo/config
              name: config
      volumes:
        - name: config
          configMap:
            name: k8s-demo-config
            items:
              - key: c1.properties
                path: conf.properties

创建deployment

[root@wushuaiping-private demo]# kubectl create -f k8s-demo-deployment.yaml 
error: error validating "k8s-demo-deployment.yaml": error validating data: couldn't find type: v1beta1.Deployment; if you choose to ignore these errors, turn validation off with --validate=false

发现报错了,这个报错是由于版本问题导致的,我使用的是:

[root@wushuaiping-private demo]# kubectl --version
Kubernetes v1.5.2

然后在deployment.yaml文件中我编写的apiVersion: apps/v1beta1,该配置是在1.6版本以后才有的。1.5.x的版本应该使用apiVersion: extensions/v1beta1
问题链接:
When I use Deployment in Kubernetes, what’s the differences between apps/v1beta1 and extensions/v1beta1?
重新运行命令

[root@wushuaiping-private demo]# kubectl create -f k8s-demo-deployment.yaml 
deployment "k8s-demo-deployment" created
# 查看
[root@wushuaiping-private demo]# kubectl get deployments
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
k8s-demo-deployment   3         3         3            0           8m

新建service.yaml文件

[root@wushuaiping-private demo]# vim k8s-demo-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: k8s-demo-service
  labels:
    app: k8s-demo
spec:
  type: NodePort
  ports:
    - port: 9999
      protocol: TCP
      targetPort: 9999
  selector:
    app: k8s-demo

创建service

[root@wushuaiping-private demo]# kubectl create -f k8s-demo-service.yaml 
service "k8s-demo-service" created
# 查看
[root@wushuaiping-private demo]# kubectl get services
NAME               CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
k8s-demo-service   10.254.9.32   <nodes>       9999:31165/TCP   10s
kubernetes         10.254.0.1    <none>        443/TCP          1h

这里可以看到k8s对外暴露的端口为31165