Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

68.2. Kubernetes 部署微服务

68.2.1. pom.xml 中加入 docker 插件

			
<?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>			
			
			

68.2.2. 容器启动脚本

在项目目录创建 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
			
			

68.2.3. 构建 docker 镜像

运行 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			
			
			

68.2.4. 编排 kubernetes 容器

			
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			
			
			

68.2.5. 启动指定 nacos

容器中不方便修改配置文件,我们可以使用环境变量覆盖配置

			 
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