SpringBoot Dockerfile
https://spring.io/guides/topicals/spring-boot-docker/
run.sh for The Entry Point
FROM openjdk:8-jdk-alpine VOLUME /tmp COPY run.sh . COPY target/*.jar app.jar ENTRYPOINT ["run.sh"]
Smaller Images
OPENJDK:8-JDK-ALPINE
alpine이미지는 표준보다 작습니다.
목표가 반드시 항상 가능한 가장 작은 이미지를 빌드하는 것은 아닙니다.
일반적으로 작은 이미지는 업로드 및 다운로드에 시간이 덜 걸리지 만 이미지에 이미 캐시 된 레이어가없는 경우에만 적합합니다.
요즘 이미지 레지스트리는 매우 정교하며 이미지 구성을 영리하게 시도하면 이러한 기능의 이점을 쉽게 잃을 수 있습니다.
공통 기본 레이어를 사용하는 경우 이미지의 전체 크기는 문제가되지 않으며 레지스트리와 플랫폼이 발전함에 따라 더 작아 질 것입니다.
그럼에도 불구하고 애플리케이션 이미지의 레이어를 최적화하는 것이 여전히 중요하고 유용하지만 목표는 항상 가장 빠르게 변화하는 항목을 가장 높은 레이어에 배치하는 것이어야합니다.
A Better Dockerfile
## Jar로 압축되지 않은, 압축이 풀린 상태로 서비스를 제공하는 것이 좋습니다.
## 또한 Image Layer를 세분할 수 있습니다.
## 따라서, 첫 번째 레이어 ( BOOT-INF/lib)가 변경되지 않으므로 빌드가 더 빨라지고 기본 레이어가 이미 캐시 된 한 런타임에 컨테이너가 시작됩니다.
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]
Multi-Stage Build
FROM openjdk:8-jdk-alpine as build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]
Security Aspects
Ubuntu
FROM openjdk:8-jdk-alpine RUN groupadd appgroup && useradd -G appgroup appuser USER appuser
Kubernetes Deployment
https://v1-18.docs.kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/
apiVersion: v1
kind: Pod
metadata:
name: hello-world
spec:
containers:
# specification of the pod’s containers
# ...
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
Pod Security-Context
https://v1-18.docs.kubernetes.io/docs/tasks/configure-pod-container/security-context/
포드에 대한 보안 컨텍스트 설정
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
volumes:
- name: sec-ctx-vol
emptyDir: {}
containers:
- name: sec-ctx-demo
image: busybox
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: sec-ctx-vol
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: false
포드에 대한 볼륨 권한 및 소유권 변경 정책 구성
securityContext: runAsUser: 1000 runAsGroup: 3000 fsGroup: 2000 fsGroupChangePolicy: "OnRootMismatch"
컨테이너에 대한 보안 컨텍스트 설정
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-2
spec:
securityContext:
runAsUser: 1000
containers:
- name: sec-ctx-demo-2
image: gcr.io/google-samples/node-hello:1.0
securityContext:
runAsUser: 2000
allowPrivilegeEscalation: false
컨테이너에 대한 기능 설정
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-4
spec:
containers:
- name: sec-ctx-4
image: gcr.io/google-samples/node-hello:1.0
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
컨테이너에 SELinux 레이블 할당
...
securityContext:
seLinuxOptions:
level: "s0:c123,c456"