The "build once, run anywhere" approach has gained momentum alongside the growing use of containers. It has mainly targeted cloud-native development, but by using Podman, systemd, and OSBuild, it can now also apply to developing edge devices.
[ Getting started with containers? Check out Deploying containerized applications: A technical overview. ]
What does "build once, run anywhere" mean?
"Build once, run anywhere" was coined by Sun Microsystems long ago to describe the ability to write Java code once and run it anywhere. Recently, this phrase has expanded to include containers, meaning that developers can package their entire application and all its dependencies in a container and run it anywhere.
What does "running a container" really mean?
To run a container, you need the container image and its running instructions. Running instructions can take different forms. You can run commands in a terminal, a docker-compose file, or a Kubernetes YAML file. Even though you can reuse the same container in each scenario, the instruction's format changes. But what if you could use the same format everywhere?
By using podman kube play
, you can pass Kubernetes manifests to Podman, which exports the objects into Podman objects.
Using this mechanism, you can employ the "build once, run anywhere" principle not just for containers but also for the instructions about how to run these containers.
Using systemd to monitor containers
Although you can run Podman as a daemon, in most cases, it runs without one. As a result, the containers are not monitored, so failed containers remain down with no service to restart them.
In Linux systems, systemd monitors processes. When you use a daemon to monitor a container, systemd monitors the daemon as well. You can skip added complexity by allowing systemd to monitor the container directly.
[ Get the Systemd commands cheat sheet ]
You can use systemd to run and manage containerized applications. That means systemd starts a containerized application and manages its entire lifecycle. Podman simplifies this process with the podman generate systemd
command, which generates a systemd unit file for a specified container or pod. Alternatively, you can use the systemd template unit file for Kubernetes YAML files.
As of version 4.4, Podman includes built-in support for Quadlet, a service that allows users to manage containerized services using service-like .container
or .kube
files, but that's enough content for a separate article.
Containers on the edge
OSBuild is an open source build pipeline that allows you "to create images of your Linux operating system in a reliable fashion, isolating the image creation from your host operating system, and producing a reliable, well-defined image ready to be deployed." Using OSBuild, you can embed the containers, Kubernetes YAML files, and systemd unit files to create a device image that runs the workloads.
Bring it together with a demo
This demo uses a sample automotive application implemented in the sample automotive applications repository, along with a containerized version of vsomeip, which implements SOME/IP (Scalable service-Oriented MiddlewarE over IP), a communications protocol for automotive applications. Of note:
- A prebuilt version of these containers for AArch64 and x86-64 is available in the automotive container registry.
- All Kubernetes YAML files are located in the Git repository.
- Although the instructions get the files directly from GitLab, you may get the code by cloning the repo:
git clone https://gitlab.com/CentOS/automotive/sample-images.git
- This demo uses Kubernetes and the command
kubectl
, but you can achieve the same thing using OpenShift and theoc
command.
[ Download the Podman basics cheat sheet ]
1. Deploy on Kubernetes
a. Create the namespace:
kubectl create namespace build-once-run-anywhere
b. Deploy vsomeip:
kubectl apply -n build-once-run-anywhere -f https://gitlab.com/CentOS/automotive/sample-images/-/raw/main/osbuild-manifests/files/ocp/vsomeip.yml
c. Deploy the engine application:
kubectl apply -n build-once-run-anywhere -f https://gitlab.com/CentOS/automotive/sample-images/-/raw/main/osbuild-manifests/files/ocp/engine.yml
d. Deploy the radio application:
kubectl apply -n build-once-run-anywhere -f https://gitlab.com/CentOS/automotive/sample-images/-/raw/main/osbuild-manifests/files/ocp/radio.yml
e. After the deployments are running, you can monitor changes in the radio service's volume based on the notification from the engine service:
kubectl get pods -n build-once-run-anywhere -l app=radio -o jsonpath={.items[0].metadata.name} | xargs kubectl logs -n build-once-run-anywhere -f
RADIO: Started main thread
RADIO: Started playing
Engine Service is NOT available.
Engine Service is available.
RADIO: Playing song "R-Cali" by A$AP Rocky feat. Aston Matthews & Joey Fatts (on Radio Los Santos) 50% volume
RADIO: Lowering volume due to reverse
RADIO: Playing song "R-Cali" by A$AP Rocky feat. Aston Matthews & Joey Fatts (on Radio Los Santos) 30% volume
RADIO: Playing song "Swimming Pools, Drank" by Kendrick Lamar (on Radio Los Santos) 30% volume
RADIO: Restoring volume due to cancelled reverse
RADIO: Playing song "Swimming Pools, Drank" by Kendrick Lamar (on Radio Los Santos) 50% volume
2. Deploy locally using Podman
a. Deploy vsomeip:
podman kube play https://gitlab.com/CentOS/automotive/sample-images/-/raw/main/osbuild-manifests/files/ocp/vsomeip.yml
b. Deploy the engine application:
podman kube play https://gitlab.com/CentOS/automotive/sample-images/-/raw/main/osbuild-manifests/files/ocp/engine.yml
c. Deploy the radio application:
podman kube play https://gitlab.com/CentOS/automotive/sample-images/-/raw/main/osbuild-manifests/files/ocp/radio.yml
d. After the deployments are running, you can monitor changes in the radio service's volume based on the notification from the engine service:
podman logs -f radio-pod-0-radio
RADIO: Started main thread
RADIO: Started playing
RADIO: Playing song "How It Was" by DJ Esco feat. Future (on Radio Los Santos) 50% volume
Engine Service is NOT available.
Engine Service is available.
RADIO: Playing song "Swimming Pools, Drank" by Kendrick Lamar (on Radio Los Santos) 50% volume
RADIO: Lowering volume due to reverse
RADIO: Playing song "Swimming Pools, Drank" by Kendrick Lamar (on Radio Los Santos) 30% volume
RADIO: Playing song "Hood Gone Love It" by Jay Rock feat. Kendrick Lamar (on Radio Los Santos) 30% volume
RADIO: Restoring volume due to cancelled reverse
RADIO: Playing song "Hood Gone Love It" by Jay Rock feat. Kendrick Lamar (on Radio Los Santos) 50% volume
3. Embed inside an image
For more information about how to build an image, see Building images on the Automotive SIG documentation site. The image manifest of this demo is the ocp.mpp
file.
Contents of the manifest file
The manifest describes the different steps required to create the image.
Embed the container image
- type: org.osbuild.skopeo
inputs:
images:
type: org.osbuild.containers
origin: org.osbuild.source
mpp-resolve-images:
images:
- source: registry.gitlab.com/centos/automotive/sample-images/demo/auto-apps
tag: latest
- source: registry.gitlab.com/centos/automotive/sample-images/demo/vsomeip
tag: v0.1
options:
destination:
type: containers-storage
storage-path: /usr/share/containers/storage
Copy the unit and Kubernetes YAML files
- type: org.osbuild.copy
inputs:
ocp-vsomeip:
type: org.osbuild.files
origin: org.osbuild.source
mpp-embed:
id: vsomeip.yml
path: ../files/ocp/vsomeip.yml
unit-vsomeip:
type: org.osbuild.files
origin: org.osbuild.source
mpp-embed:
id: vsomeip.service
path: ../files/ocp/vsomeip.service
options:
paths:
- from:
mpp-format-string: input://ocp-vsomeip/{embedded['vsomeip.yml']}
to: tree:///demo/ocp/vsomeip.yml
- from:
mpp-format-string: input://unit-vsomeip/{embedded['vsomeip.service']}
to: tree:///usr/lib/systemd/system/vsomeip.service
Notice the similar copy operations for the engine and radio services.
Enable the radio service
- type: org.osbuild.systemd
options:
enabled_services:
- radio.service
Build the image
Now it's time to build the image.
For the demo
To run the demo image on an ARM machine on AWS, make the target with:
cd osbuild-manifests
make cs9-aws-ocp-regular.aarch64.img
Building other images
Alternatively, you can build the demo on x86 hardware and run it with QEMU:
cd osbuild-manifests
make cs9-aws-ocp-regular.x86_64.qcow2
c. You can find a convenient tool to simplify running the qcow2 image in the repository at osbuild-manifests/runvm. This can make it easier for you to run the image with QEMU virtualization.
[ Try the Getting started with Red Hat OpenShift Service on AWS (ROSA) learning path. ]
Convert the image into an AWS AMI
To convert the image you created into an Amazon Machine Image (AMI), follow the instructions below.
Prerequisites
- Create an S3 bucket to upload the image to.
- Access to the AWS command-line interface (CLI).
- AWS credentials:
- If you are running it on your own machine, configure the AWS CLI with your credentials.
- If you are running on an EC2 instance, attach an identity and access management (IAM) instance profile with the VMImporter policy to your instance.
Create the AMI
a. From the osbuild-manifests
directory, run the export-image-aws.sh
tool:
./tools/export-image-aws.sh cs9-aws-ocp-regular.aarch64.img <The name of the S3 Bucket> 8
b. Once completed, you can find the new AMI with the name cs9-aws-ocp-regular.aarch64
.
Use the newly created AMI
Once you've created the AMI, you can start using it.
Start an EC2 instance
- Locate the AMI you created in the previous step in your AWS console (its name is
cs9-aws-soafee-regular.aarch64
). - Click Launch instance from AMI.
- Complete the instance-launching flow:
- Give your instance a name.
- Choose the instance type. The recommended one is c6g.large.
- Set (or create) your key pair to Secure Shell (SSH) into the instance.
- Set (or create) the Security Group that allows SSH access to the machine from your IP.
- Click Launch instance.
Verify the service operation
SSH into your instance and check the logs coming from the radio service:
journalctl -u radio -f
RADIO: Started main thread
RADIO: Started playing
RADIO: Playing song "How It Was" by DJ Esco feat. Future (on Radio Los Santos) 50% volume
Engine Service is NOT available.
Engine Service is available.
RADIO: Playing song "R-Cali" by A$AP Rocky feat. Aston Matthews & Joey Fatts (on Radio Los Santos) 50% volume
RADIO: Playing song "Swimming Pools, Drank" by Kendrick Lamar (on Radio Los Santos) 50% volume
RADIO: Lowering volume due to reverse
RADIO: Playing song "Swimming Pools, Drank" by Kendrick Lamar (on Radio Los Santos) 30% volume
RADIO: Restoring volume due to cancelled reverse
RADIO: Playing song "Swimming Pools, Drank" by Kendrick Lamar (on Radio Los Santos) 50% volume
Build once, run anywhere
Container images are the manifestation of the "build once, run anywhere" approach. Using Kubernetes, Podman, and OSBuild (and, in the future, Quadlet), "anywhere" is now bigger than ever.
[ Boost security, flexibility, and scale at the edge with Red Hat Enterprise Linux. ]
저자 소개
Ygal Blum is a Principal Software Engineer who is also an experienced manager and tech lead. He writes code from C and Java to Python and Golang, targeting platforms from microcontrollers to multicore servers, and servicing verticals from testing equipment through mobile and automotive to cloud infrastructure.
유사한 검색 결과
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
오리지널 쇼
엔터프라이즈 기술 분야의 제작자와 리더가 전하는 흥미로운 스토리
제품
- Red Hat Enterprise Linux
- Red Hat OpenShift Enterprise
- Red Hat Ansible Automation Platform
- 클라우드 서비스
- 모든 제품 보기
툴
체험, 구매 & 영업
커뮤니케이션
Red Hat 소개
Red Hat은 Linux, 클라우드, 컨테이너, 쿠버네티스 등을 포함한 글로벌 엔터프라이즈 오픈소스 솔루션 공급업체입니다. Red Hat은 코어 데이터센터에서 네트워크 엣지에 이르기까지 다양한 플랫폼과 환경에서 기업의 업무 편의성을 높여 주는 강화된 기능의 솔루션을 제공합니다.