记录一下将springboot项目编译打包并制作镜像到最后部署的过程

本文采用的是idea插件对springboot项目进行编译打包,再通过sh脚本制作和推送镜像;当然你也可以在sh脚本中将打包的部分也一起添加进去。
事实上,我所知道的一种常用方式是将整个java项目git到服务器上,再使用sh脚本一键完成打包,镜像和部署的过程(但是我还没学)。

1 申请腾讯云容器镜像服务

腾讯云提供了免费的个人容器镜像仓库,类似自己搭建harbor
需要注意的是,个人免费版的命名空间似乎是共用的,可以在控制台手动创建一个,确保该命名空间可用。

直接搜索容器镜像服务,点击授权即可。
在这里插入图片描述
点击登录实例可以快速生成登录命令

docker login xxx --username=xxx

在这里插入图片描述

2 生成jar

这一步很简单,可以自行解决
只要java -jar能够运行即可

3 制作dockerfile

具体的dockerfile命令可以自行百度。需要注意的是copy的路径等,只要确保能够按照路径找到jar包即可。

FROM java:8

#COPY target/dockerk8sdome-0.0.1-SNAPSHOT.jar dockerk8sdome.jar
COPY dockerk8sdome-0.0.1-SNAPSHOT.jar dockerk8sdome.jar
#开启端口
CMD ["--server.port=8080"]
##执行bash命令
#RUN bash -c "touch /dockerk8sdome.jar"
# 开放端口
EXPOSE 8080

ENTRYPOINT ["java","-jar","dockerk8sdome.jar"]

4 制作sh脚本

注意docker build后面的 . ,代表的是dockerfile的路径,按照自己的需要配置
经典用法

docker build  -t ImageName:TagName dir
## 构建镜像
harbor=腾讯云容器镜像访问域名
namespace=cttnamespace
image=springboot_images
version=1.0.0

docker build -t $harbor/$namespace/$image:$version .
# echo "build complete..."

# 按需是否登陆harbor,是否推送镜像
harbor_password=腾讯云容器镜像密码
# 控制台登陆实例生成的代码 --password $harbor_password
docker login harbor --username=xxx --password $harbor_password
# echo "login successful..."
docker push $harbor/$namespace/$image:$version
# echo "push successful..."

5 k8s部署(以deployment为例)

在此之前需要确保k8s集群正常(包括网络配置)
在虚拟机上使用fannel出现了failed to set up sandbox containe ,后来改用calico解决。

编写yml配置文件(常用的nginx例子),主要配置一下命名空间、副本数以及镜像

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-demo1
  namespace: ctt
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx:1.14
          imagePullPolicy: IfNotPresent
          name: nginx
          ports:
            - containerPort: 80
              protocol: TCP

按照上面的例子,把镜像、命名空间换成自己的就行

6 将jar包,sh文件放在服务器上(确保docker和sh脚本中的路径能够找到)

6.1 运行sh脚本

报错

-bash: ./image_push.sh: 权限不够
chmod +777 image_push.sh

再次执行

到这可以看到腾讯云的容器镜像控制台更新

6.2 k8s部署

默认命名空间是default,使用自己的命名空间需要先创建

kubectl create namespace xxx

创建deployment

kubectl apply -f xxx.yml

在这里插入图片描述

6.3 镜像拉取失败(ErrImageNeverPull)

如果使用nginx的yml可以直接运行
但是直接拉取个人仓库却失败
手动使用docker拉取却能够成功
在这里插入图片描述

6.4 添加secret

服务的部署文件里边没有配置拉取镜像用的secret,在服务配置文件中的名字是 imagePullSecrets 如下:

创建secret 需要指定namespace
kubectl create secret docker-registry <secret名称(docker-image-secret)> --namespace=<命名空间名称> --docker-username=<镜像仓库用户名> --docker-password=<镜像仓库密码> --docker-server=<镜像仓库地址> 
查看secret
kubectl get secrets -n ctt

在这里插入图片描述

最后在yml文件中添加 imagePullSecrets
spec:
      imagePullSecrets:
        - name: ctt-secret
      containers:
        - image: xxx:1.0.0
          imagePullPolicy: IfNotPresent
          name: springboot-deployment-demo1
          ports:
            - containerPort: 8080
              protocol: TCP
再次部署(apply -f)

在这里插入图片描述

7 编写service yml文件

每个pod都有自己的ip地址,当controller用新的pod代替发生故障的pod时,新的pod会分配到新的ip地址,因此如果一组pod对外提供服务,他们的ip可能发生变化,那么客户端如何找到并访问这个服务呢?
kubernetes给出的解决方案是service

7.1 创建yml文件
ClusterIP类型

在原来的deployment.yml文件后面继续写service的配置内容
以下是service的部分

---
apiVersion: v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Service # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
  name: springboot-service-demo1 # 资源的名字,在同一个namespace中必须唯一
  namespace: ctt # 部署在哪个namespace中
spec: # 资源规范字段
  type: ClusterIP # ClusterIP 类型
  ports:
    - port: 30088
      protocol: TCP
      targetPort: 8080
      nodePort: 30068
  selector: # 选择器
    app: springboot-deployment-demo1

该service的类型为ClusterIP,service通过cluster内部的ip对外提供服务,只有cluster内的结点和pod可以访问,这是默认的service类型
在这里插入图片描述在这里插入图片描述
可以看到只能通过10.110.152.59进行访问,外网是无法访问的。

hello docker again 2是springboot项目controller返回的内容。

NodeIP类型

需要额外配置nodeport的端口号,即暴露给外网的端口号

---
apiVersion: v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Service # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
  name: springboot-service-demo1 # 资源的名字,在同一个namespace中必须唯一
  namespace: ctt # 部署在哪个namespace中
spec: # 资源规范字段
  type: NodePort # ClusterIP 类型
  ports:
    - port: 30088
      protocol: TCP
      targetPort: 8080
      nodePort: 30068
  selector: # 选择器
    app: springboot-deployment-demo1

在这里插入图片描述
而其中的port则是暴露给内部的端口。
在这里插入图片描述

总的来说,port和nodePort都是service的端口,前者暴露给k8s集群内部服务访问,后者暴露给k8s集群外部流量访问。从上两个端口过来的数据都需要经过反向代理kube-proxy,流入后端pod的targetPort上,最后到达pod内的容器。

参考链接

https://blog.csdn.net/qq_33235529/article/details/106526553?ops_request_misc=&request_id=&biz_id=102&utm_term=imagePullSecrets&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-5-106526553.nonecase&spm=1018.2226.3001.4187

https://blog.csdn.net/zongshan_csdn/article/details/113251737?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166909882616782414963702%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166909882616782414963702&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-113251737-null-null.142v66pc_rank_34_queryrelevant25,201v3control_1,213v2t3_esquery_v3&utm_term=nodePort&spm=1018.2226.3001.4187

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐