Chapter 5. Packaging OCI Images
플러그인은 Cloud Native Buildpacks(CNB)를 사용하여 jar 또는 war 파일에서 OCI 이미지를 생성할 수 있다. bootBuildImage
태스크를 사용하여 이미지를 빌드할 수 있다.
보안상의 이유로 이미지는 루트가 아닌 사용자로 빌드 및 실행된다. 자세한 내용은 CNB 사양을 참조해보자.
태스크는 java
또는 war
플러그인이 적용될 때 자동으로 생성되며 BootBuildImage
의 인스턴스이다.
5.1. Docker Daemon
bootBuildImage
태스크에는 도커 데몬에 대한 액세스 권한이 필요하다. 기본적으로, 로컬 연결을 통해 도커 데몬과 통신한다. 이는 구성 없이 지원되는 모든 플랫폼에서 도커 엔진과 함께 작동한다.
환경 변수를 설정하여 bootBuildImage
태스크를 대체 로컬(alternative local) 또는 원격 연결을 사용하도록 구성할 수 있다. 다음 표는 환경 변수와 해당 값을 보여준다:
Environment variable | Description |
---|---|
DOCKER_HOST | 도커 데몬의 호스트 및 포트를 포함하는 URL - 예를들어 tcp://192.168.99.100:2376 |
DOCKER_TLS_VERIFY | 1 로 설정된 경우 보안 HTTPS 프로토콜 활성화(선택 사항) |
DOCKER_CERT_PATH | HTTPS용 인증서 및 키 파일의 경로(DOCKER_TLS_VERIFY=1 인 경우 필수, 그렇지 않은 경우 무시됨) |
플러그인 구성에서 docker
프로퍼티를 사용하여 도커 데몬 연결 정보를 제공할 수도 있다. 다음 표에는 사용 가능한 프로퍼티가 요약되어 있다:
Property | Description |
---|---|
host | 도커 데몬의 호스트 및 포트를 포함하는 URL - 예를들어 tcp://192.168.99.100:2376 |
tlsVerify | true 로 설정된 경우 보안 HTTPS 프로토콜 활성화(선택 사항) |
certPath | HTTPS용 인증서 및 키 파일의 경로(tlsVerify 가 true 인 경우 필요, 그렇지 않은 경우 무시됨) |
bindHostToBuilder | When true, the value of the host property will be provided to the container that is created for the CNB builder (optional) |
자세한 내용은 예제를 참조해보자.
5.2. Docker Registry
builder
또는 runImage
프로퍼티에 지정된 도커 이미지가 인증이 필요한 프라이빗(private) 도커 이미지 레지스트리에 저장되는 경우, docker.builderRegistry
프로퍼티를 사용하여 인증 크리덴셜(credentials)를 제공할 수 있다.
프로퍼티는 사용자 인증 또는 ID 토큰 인증을 위해 제공된다. 지원되는 인증 메소드에 대한 자세한 내용은 이미지를 저장하는 데 사용되는 도커 레지스트리에 대한 설명서를 참조하자.
다음 표는 docker.builderRegistry
및 docker.publishRegistry
에 사용 가능한 프로퍼티가 요약되어 있다.
Property | Description |
---|---|
username | 도커 이미지 레지스트리 사용자의 이름. 사용자 인증에 필수. |
password | 도커 이미지 레지스트리 사용자의 비밀번호. 사용자 인증에 필수. |
url | 도커 이미지 레지스트리의 주소. 사용자 인증을 위한 선택 사항. |
email | 도커 이미지 레지스트리 사용자의 이메일 주소. 사용자 인증을 위한 선택 사항. |
token | 도커 이미지 레지스트리 사용자의 ID 토큰. 토큰 인증에 필수. |
자세한 내용은 예제를 참조해보자.
5.3. Image Customizations
플러그인은 빌더를 호출하여 이미지 생성을 조율(orchestrate)한다. 빌더에는 애플리케이션을 검사하여, 생성된 이미지에 영향을 줄 수 있는 여러 빌드팩(Buildpack)이 포함되어 있다. 기본적으로, 플러그인은 빌더 이미지를 선택한다. 생성된 이미지 이름은 프로젝트 프로퍼티에서 유추된다.
태스크 프로퍼티를 사용하여 빌더가 프로젝트에서 작동하는 방식을 구성할 수 있다. 다음 표에는 사용 가능한 프로퍼티와 기본값이 요약되어 있다:
Property | Command-line option | Description | Default value |
---|---|---|---|
builder | --builder | 사용할 빌더 이미지 이름. | paketobuildpacks/builder:base |
runImage | --runImage | 사용할 실행 이미지 이름. | 빌더 메타데이터에 지정된 실행 이미지 기본값 없음. |
imageName | --imageName | 생성된 이미지 이름. | docker.io/library/${project.name}:${project.version} |
pullPolicy | --pullPolicy | 빌더를 끌어오고 레지스트리에서 이미지를 실행할 시기를 결정하는 데 사용되는 정책이다. 허용값은 ALWAYS , NEVER , IF_NOT_PRESENT 이다. | ALWAYS |
environment | 빌더에 전달해야 하는 환경 변수이다. | ||
buildpacks | 빌더가 이미지를 빌드할 때 사용해야 하는 빌드팩이다. 빌더에 포함된 기본 빌드팩을 오버라이드(overriding)하여 지정된 빌드팩만 사용된다. 빌드팩 레퍼런스는 다음 형식 중 하나여야 한다.: • 빌더의 빌드팩 - [urn:cnb:builder:]<buildpackID>[@<version>] • 파일 시스템의 디렉토리에 있는 빌드팩 - [file://]<path> • 파일 시스템의 gzip으로 압축된 tar(.tgz) 파일의 빌드팩 - [file://]<path>/<file name> • OCI 이미지의 빌드팩 - [docker://]<host>/<repo>[:<tag>][@<digest>] | 기본값 없음, 빌더가 빌더에 포함된 빌드팩을 사용해야 함을 나타낸다. | |
bindings | 이미지 빌드할 때 빌더 컨테이너에 마운트해야 하는 볼륨 바인드 마운트. 바인딩은 빌더 컨테이너를 생성할 때 구문 분석 및 검증되지 않은 상태로 도커에 전달된다. 바인딩은 다음 형식 중 하나여야 한다: • <host source path>:<container destination path>[:<options>] • <host volume name>:<container destination path>[:<options>] <options>에는 다음과 같은 내용이 포함될 수 있다.: • 컨테이너에서 볼륨을 읽기-전용으로 마운트하기 위해 ro 옵션을 사용한다.• 컨테이너에서 볼륨을 읽기 및 쓰기가 가능하도록 마운트하기 위해 rw 옵션을 사용한다.• 옵션 이름과 해당 값을 포함하는 키-값 쌍을 지정하기 위해 volume-opt=key=value 형식을 사용한다. | ||
network | --network | 빌더 컨테이너가 구성될 때 사용할 네트워크 드라이버이다. 제공된 값은 빌더 컨테이너를 생성할 때 도커에게 유효성을 검증받지 않고 전달된다. | |
cleanCache | --cleanCache | 빌드하기 전에 캐시를 정리할지 여부이다. | false |
verboseLogging | 빌더 작업에 대한 자세한 로깅을 활성화한다. | false | |
publish | --publishImage | 생성된 이미지를 도커 레지스트리에 게시할지 여부이다. | false |
tags | 생성된 이미지에 적용할 하나 이상의 추가 태그 목록입니다. 태그 옵션에 제공하는 값은 [image name]:[tag] or [repository]/[image name]:[tag] 형식의 완전한 이미지 레퍼런스여야 한다. | ||
buildCache | 빌드팩에서 생성되고 이미지 빌드 프로세스에서 사용되는 레이어가 포함된 캐시. | 이미지 이름에서 파생된 이름을 가진, 도커 데몬의 명명된 볼륨이다. | |
launchCache | 빌드팩에서 생성되고 이미지 시작 프로세스에서 사용되는 레이어가 포함된 캐시. | 이미지 이름에서 파생된 이름을 가진, 도커 데몬의 명명된 볼륨이다. |
플러그인은 JavaPlugin의
targetCompatibility
프로퍼티을 사용하여 프로젝트의 대상 자바 호환성(compatibility)을 감지한다. 기본 Paketo 빌더 및 빌드팩을 사용하는 경우, 플러그인은 동일한 자바 버전을 설치하도록 빌드팩에 지시한다. 빌더 구성 예제에 표시된 대로 이 동작작을 오버라이드할 수 있다.
5.4. Examples
5.4.1. Custom Image Builder and Run Image
이미지를 생성하는 데 사용되는 빌더(builder) 또는 빌드된 이미지를 시작하는 데 사용되는 실행 이미지(run image)를 사용자 지정해야 하는 경우, 다음 예와 같이 작업을 구성한다:
Groovy
tasks.named("bootBuildImage") {
builder = "mine/java-cnb-builder"
runImage = "mine/java-cnb-run"
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
builder = "mine/java-cnb-builder"
runImage = "mine/java-cnb-run"
}
위 구성은 이름이 mine/java-cnb-builder
이고 태그가 latest
인 빌더 이미지와 이름이 mine/java-cnb-run
이고 태그가 latest
인 실행 이미지를 사용한다. 빌더 및 실행 이미지는, 이 예제와 같이 명령줄에서도 지정할 수 있다:
$ gradle bootBuildImage --builder=mine/java-cnb-builder --runImage=mine/java-cnb-run
5.4.2. Builder Configuration
만약 빌더가 구성 옵션을 노출시킨다면, environment
프로퍼티를 사용하여 설정할 수 있다. 다음은 빌드 시 Paketo 자바 빌드팩에서 사용하는 JVM 버전 구성 예시이다:
Groovy
tasks.named("bootBuildImage") {
environment = ["BP_JVM_VERSION" : "8.*"]
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
environment = mapOf("BP_JVM_VERSION" to "8.*")
}
빌더가 실행되는 도커 데몬과 빌드팩이 아티팩트(artifacts)를 다운로드하는 네트워크 위치 사이에 네트워크 프록시가 있는 경우, 프록시를 사용하도록 빌더를 구성해야 한다. Paketo 빌더를 사용하는 경우 다음 예제와 같이 HTTPS_PROXY
및/또는 HTTP_PROXY
환경 변수를 설정하여 이를 수행할 수 있다.
Groovy
tasks.named("bootBuildImage") {
environment = [
"HTTP_PROXY" : "http://proxy.example.com",
"HTTPS_PROXY": "https://proxy.example.com"
]
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
environment = mapOf(
"HTTP_PROXY" to "http://proxy.example.com",
"HTTPS_PROXY" to "https://proxy.example.com"
)
}
5.4.3. Runtime JVM Configuration
Paketo 자바 빌드팩은 JAVA_TOOL_OPTIONS
환경 변수를 설정하여 JVM 런타임 환경을 구성한다. 제공된-빌드팩 JAVA_TOOL_OPTIONS
값을 수정하여 애플리케이션 이미지가 컨테이너에서 실행될 때 JVM 런타임 동작을 사용자 정의할 수 있다. 이미지에 저장되며 모든 배포에 적용해야 하는 환경 변수 수정 사항은 Paketo 문서에 설명된 대로 설정할 수 있으며 다음 예제에 표시된다:
Groovy
tasks.named("bootBuildImage") {
environment = [
"BPE_DELIM_JAVA_TOOL_OPTIONS" : " ",
"BPE_APPEND_JAVA_TOOL_OPTIONS" : "-XX:+HeapDumpOnOutOfMemoryError"
]
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
environment = mapOf(
"BPE_DELIM_JAVA_TOOL_OPTIONS" to " ",
"BPE_APPEND_JAVA_TOOL_OPTIONS" to "-XX:+HeapDumpOnOutOfMemoryError"
)
}
5.4.4. Custom Image Name
기본적으로, 이미지 이름은 docker.io/library/${project.name}:${project.version}
과 같이, 프로젝트 name
및 version
에서 유추된다. 다음 예제와 같이, 태스크 프로퍼티을 설정하여 이름을 제어할 수 있다:
Groovy
tasks.named("bootBuildImage") {
imageName = "example.com/library/${project.name}"
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
imageName = "example.com/library/${project.name}"
}
위 구성은 명시적으로 태그를 제공하지 않으므로 latest
가 사용된다. ${project.version}
을 사용하여, 빌드에서 사용 가능한 프로퍼티 또는 하드코딩으로 태그를 지정할 수도 있다.
아래 예제처럼, 이미지 이름은 명령줄에서도 지정할 수 있다:
$ gradle bootBuildImage --imageName=example.com/library/my-app:v1
5.4.5. Buildpacks
기본적으로, 빌더는 빌더 이미지에 포함된 빌드팩을 사용하고 미리 정의된 순서대로 적용한다. 빌더에 포함되지 않은 빌드팩을 적용하거나 포함된 빌드팩의 순서를 변경하기 위해 대체 빌드팩 세트를 제공할 수 있다. 하나 이상의 빌드팩이 제공되면, 지정된 빌드팩만 적용된다.
다음 예제에서는 빌더가 .tgz
파일에 패키징된 사용자 정의 빌드팩을 사용하고, 빌더에 포함된 빌드팩을 사용하도록 지시한다.
Groovy
tasks.named("bootBuildImage") {
buildpacks = ["file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java"]
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
buildpacks = listOf("file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java")
}
빌드팩은 아래 표시된 양식 중 하나로 지정할 수 있다.
CNB 빌더에 있는 빌드팩 (빌더에 buildpack-id
와 일치하는 빌드팩이 하나만 있는 경우 버전을 생략할 수 있다.):
urn:cnb:builder:buildpack-id
urn:cnb:builder:buildpack-id@0.0.1
buildpack-id
buildpack-id@0.0.1
빌드팩 콘텐츠가 포함된 디렉토리 경로 (윈도우는 지원하지 않음):
file:///path/to/buildpack/
/path/to/buildpack/
빌드팩 콘텐츠가 포함된 gzip으로 압축된 tar 파일의 경로:
file:///path/to/buildpack.tgz
/path/to/buildpack.tgz
패키지 빌드팩을 포함하는 OCI 이미지:
docker://example/buildpack
docker:///example/buildpack:latest
docker:///example/buildpack@sha256:45b23dee08...
example/buildpack
example/buildpack:latest
example/buildpack@sha256:45b23dee08...
5.4.6. Image Publishing
생성된 이미지는 publish
옵션을 활성화하여 도커 레지스트리에 게시할 수 있다.
도커 레지스트리에 인증이 필요한 경우, docker.publishRegistry
프로퍼티을 사용하여 크리덴셜(credentials)을 구성할 수 있다. 도커 레지스트리에 인증이 필요하지 않은 경우, docker.publishRegistry
구성을 생략할 수 있다.
이미지가 게시될 레지스트리는 이미지 이름(아래 예제에서는
docker.example.com
)의 레지스트리 파트(part)에 의해 결정된다.docker.publishRegistry
크리덴셜을 구성하고url
프로퍼티를 포함하는 경우, 이 값은 레지스트리로 전달되지만 게시되는 레지스트리 위치를 결정하는 데 사용되지 않는다.
Groovy
tasks.named("bootBuildImage") {
imageName = "docker.example.com/library/${project.name}"
publish = true
docker {
publishRegistry {
username = "user"
password = "secret"
}
}
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
imageName = "docker.example.com/library/${project.name}"
isPublish = true
docker {
publishRegistry {
username = "user"
password = "secret"
}
}
}
publish 옵션은 아래 예제와 같이, 명령줄에서도 지정할 수 있다.
$ gradle bootBuildImage --imageName=docker.example.com/library/my-app:v1 --publishImage
5.4.7. Builder Cache Configuration
CNB 빌더는 이미지를 빌드하고 시작할 때 사용되는 레이어를 캐시(cache)한다. 기본적으로, 이러한 캐시는 도커 데몬의 명명된 볼륨으로 저장되며 이 볼륨의 명칭은 대상 이미지의 전체 이름에서 파생된다. 이미지 이름이 자주 변경되는 경우(예: 프로젝트 버전이 이미지 이름의 태그로 사용되는 경우) 캐시가 자주 무효화될 수 있다.
다음 예와 같이 대체 이름을 사용하여 캐시 생명 주기를 더 많이 제어할 수 있도록 캐시 볼륨을 구성할 수 있다:
Groovy
tasks.named("bootBuildImage") {
buildCache {
volume {
name = "cache-${rootProject.name}.build"
}
}
launchCache {
volume {
name = "cache-${rootProject.name}.launch"
}
}
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
buildCache {
volume {
name = "cache-${rootProject.name}.build"
}
}
launchCache {
volume {
name = "cache-${rootProject.name}.launch"
}
}
}
5.4.8. Docker Configuration Docker Configuration for minikube
플러그인은 기본 로컬 연결 대신 미니큐브(minikube)에서 제공하는 도커 데몬과 통신할 수 있다.
리눅스 및 맥OS에서는, 미니큐브가 시작된 후 eval $(minikube docker-env)
명령을 사용하여 환경 변수를 설정할 수 있다.
다음 예제에 표시된 것처럼 연결의 세부 정보를 제공하여 미니큐브 데몬을 사용하도록 플러그인을 구성할 수도 있다:
Groovy
tasks.named("bootBuildImage") {
docker {
host = "tcp://192.168.99.100:2376"
tlsVerify = true
certPath = "/home/user/.minikube/certs"
}
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
host = "tcp://192.168.99.100:2376"
isTlsVerify = true
certPath = "/home/user/.minikube/certs"
}
}
Docker Configuration for podman
플러그인은 파드맨(podman) 컨테이너 엔진과 통신할 수 있다.
다음 예에 표시된 것처럼 연결의 세부 정보를 제공하여 파드맨 로컬 연결을 사용하도록 플러그인을 구성할 수 있다:
Groovy
tasks.named("bootBuildImage") {
docker {
host = "unix:///run/user/1000/podman/podman.sock"
bindHostToBuilder = true
}
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
host = "unix:///run/user/1000/podman/podman.sock"
isBindHostToBuilder = true
}
}
파드맨
CLI가 설치된 상태에서podman info --format=''
명령을 사용하여 위 예제에 표시된docker.host
구성 프로퍼티의 값을 가져올 수 있다.
Docker Configuration for Authentication
빌더 또는 실행 이미지가 사용자 인증을 지원하는 프라이빗(private) 도커 레지스트리에 저장되어 있는 경우, 다음 예제와 같이 docker.builderRegistry
프로퍼티를 사용하여 인증 세부 정보를 제공할 수 있다:
Groovy
tasks.named("bootBuildImage") {
docker {
builderRegistry {
username = "user"
password = "secret"
url = "https://docker.example.com/v1/"
email = "user@example.com"
}
}
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
builderRegistry {
username = "user"
password = "secret"
url = "https://docker.example.com/v1/"
email = "user@example.com"
}
}
}
빌더 또는 실행 이미지가 토큰 인증을 지원하는 프라이빗 도커 레지스트리에 저장되어 있는 경우 다음 예제와 같이 docker.builderRegistry
를 사용하여 토큰 값을 제공할 수 있다:
Groovy
tasks.named("bootBuildImage") {
docker {
builderRegistry {
token = "9cbaf023786cd7..."
}
}
}
Kotlin
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
builderRegistry {
token = "9cbaf023786cd7..."
}
}
}