Dockerfile
不了解
Dockerfile
的基本文法,可以參考下面幾篇部落格:
- Docker:Dockerfile之FROM、ARG、LABEL、MAINTAINER、RUN、CMD指令詳解
- Docker:Dockerfile之ADD、COPY、WORKDIR、USER、EXPOSE指令詳解
- Docker:Dockerfile之ENV、ENTRYPOINT、VOLUME、ONBUILD、STOPSIGNAL指令詳解
安裝
Docker
:
- CentOS:安裝Docker
項目代碼
項目結構圖:
pom.xml
:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
</parent>
<packaging>jar</packaging>
<groupId>com.kaven</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot</name>
<description>springboot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>hello-world</finalName>
</build>
</project>
打包成
JAR
:
<packaging>jar</packaging>
application.properties
:
server.port=8080
Spring Boot
應用的預設啟動端口也是
8080
,這裡隻是為了示範。
HelloWorldController
:
package com.kaven.springboot.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloWorldController {
@GetMapping("/hello-world")
public String helloWorld() {
return "Hello World";
}
}
啟動類:
package com.kaven.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
使用
Maven
打包
Spring Boot
項目,直接使用
IDEA
的快捷鍵。
輕按兩下即可打包
Spring Boot
項目,如下圖所示,生成了
hello-world.jar
檔案。
該檔案的名稱由
pom.xml
的如下配置指定:
<build>
<finalName>hello-world</finalName>
</build>
建構鏡像
Dockerfile
:
FROM openjdk:8-jdk-alpine
ENV PORT=8080
EXPOSE ${PORT}
RUN mkdir /usr/local/work
WORKDIR /usr/local/work
COPY hello-world.jar ./app.jar
ENTRYPOINT java -jar ./app.jar --server.port=${PORT}
上傳檔案到虛拟機。
[root@192 ~]# ls
anaconda-ks.cfg Dockerfile hello-world.jar
[root@192 ~]# docker build -t kaven/app:v1 .
Sending build context to Docker daemon 17.57MB
Step 1/7 : FROM openjdk:8-jdk-alpine
8-jdk-alpine: Pulling from library/openjdk
e7c96db7181b: Pull complete
f910a506b6cb: Pull complete
c2274a1a0e27: Pull complete
Digest: sha256:94792824df2df33402f201713f932b58cb9de94a0cd524164a0f2283343547b3
Status: Downloaded newer image for openjdk:8-jdk-alpine
---> a3562aa0b991
Step 2/7 : ENV PORT=8080
---> Running in 416d1fad537b
Removing intermediate container 416d1fad537b
---> 63661c95ad05
Step 3/7 : EXPOSE ${PORT}
---> Running in e5904ad809c2
Removing intermediate container e5904ad809c2
---> 6375175d08fd
Step 4/7 : RUN mkdir /usr/local/work
---> Running in 8e63e0f8c201
Removing intermediate container 8e63e0f8c201
---> 141bc0602eb5
Step 5/7 : WORKDIR /usr/local/work
---> Running in bc3cb4d134c9
Removing intermediate container bc3cb4d134c9
---> 5d35babe551c
Step 6/7 : COPY hello-world.jar ./app.jar
---> 725b98b42c0d
Step 7/7 : ENTRYPOINT java -jar ./app.jar --server.port=${PORT}
---> Running in c7dc784db206
Removing intermediate container c7dc784db206
---> 36f926b2a1f5
Successfully built 36f926b2a1f5
Successfully tagged kaven/app:v1
- Docker:Docker Image及Image指令詳解
檢視
Docker
已有鏡像資訊。
[root@192 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
kaven/app v1 36f926b2a1f5 48 seconds ago 122MB
openjdk 8-jdk-alpine a3562aa0b991 2 years ago 105MB
運作鏡像,即建立并啟動容器。
[root@192 ~]# docker run -d --name app -e PORT="8888" -p 8888:8888 kaven/app:v1
e5f189df0d1077fb571fc4892c47462efc529f5f21f9f11d106ed35650acb566
- Docker:Docker Container及Container指令詳解
檢視容器是否啟動成功,很顯然啟動成功了(
Up 16 seconds
)。
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e5f189df0d10 kaven/app:v1 "/bin/sh -c 'java -j…" 17 seconds ago Up 16 seconds 8080/tcp, 0.0.0.0:8888->8888/tcp, :::8888->8888/tcp app
主控端請求接口。
[root@192 ~]# wget http://localhost:8888/hello-world
--2022-01-27 14:17:40-- http://localhost:8888/hello-world
正在解析主機 localhost (localhost)... ::1, 127.0.0.1
正在連接配接 localhost (localhost)|::1|:8888... 已連接配接。
已發出 HTTP 請求,正在等待回應... 200
長度:11 [text/plain]
正在儲存至: “hello-world”
100%[=======================================================================================================================================================================>] 11 --.-K/s 用時 0s
2022-01-27 14:17:40 (2.24 MB/s) - 已儲存 “hello-world” [11/11])
[root@192 ~]# ls
anaconda-ks.cfg Dockerfile hello-world hello-world.jar
[root@192 ~]# cat hello-world
Hello World
關閉防火牆,讓區域網路内的主機可以請求接口。
[root@192 ~]# systemctl stop firewalld
[root@192 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:04:21:5b brd ff:ff:ff:ff:ff:ff
inet 192.168.1.4/24 brd 192.168.1.255 scope global noprefixroute dynamic enp0s3
valid_lft 77546sec preferred_lft 77546sec
inet6 240e:381:4465:a200:d831:219:83:2618/64 scope global noprefixroute dynamic
valid_lft 213562sec preferred_lft 127162sec
inet6 fe80::78c7:a5b1:1ea9:9800/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:67:b8:89:e7 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:67ff:feb8:89e7/64 scope link
valid_lft forever preferred_lft forever
73: veth01ba79d@if72: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 6a:20:9d:ea:5b:be brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::6820:9dff:feea:5bbe/64 scope link
valid_lft forever preferred_lft forever
本地請求接口成功。
将應用建構成鏡像的好處,就是可以使用雲原生技術,比如使用容器編排工具對應用進行管理,這些以後再進行介紹。
[root@192 ~]# systemctl start firewalld
[root@192 ~]# docker run -d --name app2 -e PORT="9999" -p 9000:9999 kaven/app:v1
1f011919d65354a3861e420dc1c366efe34fe9b10501ad9896a2b443764d4dcf
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f011919d653 kaven/app:v1 "/bin/sh -c 'java -j…" 19 seconds ago Up 19 seconds 8080/tcp, 0.0.0.0:9000->9999/tcp, :::9000->9999/tcp app2
e5f189df0d10 kaven/app:v1 "/bin/sh -c 'java -j…" 12 minutes ago Up 11 minutes 8080/tcp, 0.0.0.0:8888->8888/tcp, :::8888->8888/tcp app
[root@192 ~]# wget http://localhost:9000/hello-world
--2022-01-27 14:28:53-- http://localhost:9000/hello-world
正在解析主機 localhost (localhost)... ::1, 127.0.0.1
正在連接配接 localhost (localhost)|::1|:9000... 已連接配接。
已發出 HTTP 請求,正在等待回應... 200
長度:11 [text/plain]
正在儲存至: “hello-world.1”
100%[=======================================================================================================================================================================>] 11 --.-K/s 用時 0s
2022-01-27 14:28:53 (2.36 MB/s) - 已儲存 “hello-world.1” [11/11])
[root@192 ~]# cat hello-world.1
Hello World