| 知乎专栏 |
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<sonar.projectKey>netkiller.cn_java_AX0HsoVkT19KeT2iVgUT</sonar.projectKey>
<sonar.qualitygate.wait>true</sonar.qualitygate.wait>
<docker.registry>registry.netkiller.cn/netkiller.cn</docker.registry>
</properties>
<repositories>
<repository>
<id>gitlab-maven</id>
<url>${env.CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
<url>${CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
<url>${CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!-- <version>4.13.2</version> -->
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<imageName>${docker.registry}/${project.artifactId}</imageName>
<baseImage>openjdk:8-alpine</baseImage>
<maintainer>netkiller@msn.com</maintainer>
<volumes>/srv</volumes>
<workdir>/srv</workdir>
<env>
<JAVA_OPTS>-server -Xms512m -Xmx4096m -Djava.security.egd=file:/dev/./urandom</JAVA_OPTS>
</env>
<exposes>8080</exposes>
<entryPoint>["sh", "-c", "/srv/docker-entrypoint.sh"]</entryPoint>
<resources>
<resource>
<targetPath>/srv</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
<resource>
<targetPath>/srv</targetPath>
<directory>.</directory>
<include>docker-entrypoint.sh</include>
</resource>
</resources>
<registryUrl>http://${docker.registry}/v2/</registryUrl>
<imageTags>
<imageTag>${project.version}</imageTag>
<imageTag>latest</imageTag>
</imageTags>
</configuration>
</plugin>
</plugins>
</build>
</project>
在项目目录创建 docker-entrypoint.sh 文件
#!/bin/sh
if [ ! -z $1 ]; then
MODULE=$1
shift
fi
if [ -z $JAVA_OPTS ]; then
JAVA_OPTS='-Xms1024m -Xmx4096m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -Djava.security.egd=file:/dev/./urandom -Duser.timezone=GMT+8 -Dfile.encoding=utf-8'
fi
if [ -z $MODULE ]; then
echo "MODULE environment is not set"
exit 127
else
PACKAGE=/srv/$MODULE.jar
fi
DEBUG='-Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=5555'
SKYWALKING="-javaagent:/srv/skywalking/agent/skywalking-agent.jar -Dskywalking.collector.backend_service=oap.netkiller.cn:11800 -Dskywalking.agent.service_name=${MODULE}"
exec java ${JAVA_OPTS} -jar ${PACKAGE} $@
暂时 DEBUG,SKYWALKING 没有使用,放在一遍不碍事。脚本的用法
./docker-entrypoint.sh your_module --server.port=8080
运行 mvn 命令构建 docker 镜像
neo@Netkiller-iMac ~/w/java.netkiller.cn (master)> mvn package docker:build docker:push
不出预料,你会看到下面输出
[INFO] Building image registry.netkiller.cn/netkiller.cn/demo
Step 1/9 : FROM openjdk:8-alpine
---> a3562aa0b991
Step 2/9 : MAINTAINER netkiller@msn.com
---> Using cache
---> b4a79be602ae
Step 3/9 : ENV JAVA_OPTS -server -Xms512m -Xmx4096m -Djava.security.egd=file:/dev/./urandom
---> Using cache
---> 9d685ea4a0d3
Step 4/9 : WORKDIR /srv
---> Using cache
---> e2feea451bb1
Step 5/9 : ADD /srv/demo-0.0.1-SNAPSHOT.jar /srv/
---> 7ad53fb991b8
Step 6/9 : ADD /srv/docker-entrypoint.sh /srv/
---> 39def6507064
Step 7/9 : EXPOSE 8080
---> Running in 338a99e6ec36
Removing intermediate container 338a99e6ec36
---> f192b73ab3b9
Step 8/9 : ENTRYPOINT ["sh", "-c", "/srv/docker-entrypoint.sh"]
---> Running in 5bda82acd305
Removing intermediate container 5bda82acd305
---> 85c1b2615a97
Step 9/9 : VOLUME /srv
---> Running in 27d71c55bf7e
Removing intermediate container 27d71c55bf7e
---> 64e0d8992fdd
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 64e0d8992fdd
Successfully tagged registry.netkiller.cn/netkiller.cn/demo:latest
[INFO] Built registry.netkiller.cn/netkiller.cn/demo
[INFO] Tagging registry.netkiller.cn/netkiller.cn/demo with 0.0.1-SNAPSHOT
[INFO] Tagging registry.netkiller.cn/netkiller.cn/demo with latest
查看镜像
neo@Netkiller-iMac ~/w/java.netkiller.cn (master)> docker image ls | grep netkiller registry.netkiller.cn/netkiller.cn/demo 0.0.1-SNAPSHOT 64e0d8992fdd 3 minutes ago 122MB registry.netkiller.cn/netkiller.cn/demo latest 64e0d8992fdd 3 minutes ago 122MB
from netkiller.kubernetes import *
namespace = 'default'
compose = Compose('development')
module = 'demo'
# version = '0.0.1-SNAPSHOT'
version = 'latest'
deployment = Deployment()
deployment.apiVersion('apps/v1')
deployment.metadata().name(module).labels({'app': module}).namespace(namespace)
deployment.spec().replicas(1)
deployment.spec().selector({'matchLabels': {'app': module}})
deployment.spec().template().metadata().labels({'app': module})
deployment.spec().template().spec().containers().name(module).image(
'registry.netkiller.cn/netkiller.cn/cloud.netkiller.cn:%s' % version).ports([{
'containerPort': 8080
}]).env([
{'name': 'TZ', 'value': 'Asia/Shanghai'},
{'name': 'LANG', 'value': 'en_US.UTF-8'},
]).args([module,'--server.port=8080'])
# deployment.debug()
# deployment.json()
service = Service()
service.metadata().name(module)
service.metadata().namespace(namespace)
service.spec().selector({'app': module})
service.spec().type('NodePort')
service.spec().ports([{
'name': 'http',
'protocol': 'TCP',
'port': 8080,
'targetPort': 8080
}])
compose.add(deployment)
compose.add(service)
print("=" * 40, "Compose", "=" * 40)
compose.debug()
compose.delete()
compose.create()⏎
查看容器运行状态
neo@Netkiller-iMac ~/w/java.netkiller.cn (master)> kubectl get pods NAME READY STATUS RESTARTS AGE nginx-88c84c4d8-8pmzp 1/1 Running 1 3d20h demo-76b7598b76-5hstp 1/1 Running 0 5h43m busybox 0/1 CrashLoopBackOff 52 4h44m
容器中不方便修改配置文件,我们可以使用环境变量覆盖配置
JAVA_OPTS=-Dspring.cloud.nacos.username=nacos \ -Dspring.cloud.nacos.password=nacos \ -Dspring.cloud.nacos.config.server-addr=mse-032dbef0-nacos-ans.mse.aliyuncs.com:8848 \ -Dspring.cloud.nacos.discovery.server-addr=mse-032dbef0-nacos-ans.mse.aliyuncs.com:8848 \
相当于
java -Dspring.cloud.nacos.username=nacos \ -Dspring.cloud.nacos.password=nacos \ -Dspring.cloud.nacos.config.server-addr=mse-032dbef0-nacos-ans.mse.aliyuncs.com:8848 \ -Dspring.cloud.nacos.discovery.server-addr=mse-032dbef0-nacos-ans.mse.aliyuncs.com:8848 \ -jar netkiller.jar