podman
is meant to be the replacement of the docker
command: so it makes sense to get familiar with it, although they are quite interchangeable considering that they use the same syntax.FROM docker.io/httpd:2.4
RUN echo "Hello, World!" > /usr/local/apache2/htdocs/index.html
:~$ podman build -t simpleapp .
STEP 1/2: FROM httpd:2.4
STEP 2/2: RUN echo "Hello, World!" > /usr/local/apache2/htdocs/index.html
COMMIT simpleapp
--> ef4b14a72d0
Successfully tagged localhost/simpleapp:latest
ef4b14a72d02ae0577eb0632d084c057777725c279e12ccf5b0c6e4ff5fd598b
:~$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/simpleapp latest ef4b14a72d02 8 seconds ago 148 MB
docker.io/library/httpd 2.4 98f93cd0ec3b 7 days ago 148 MB
:~$ podman image tree localhost/simpleapp:latest
Image ID: ef4b14a72d02
Tags: [localhost/simpleapp:latest]
Size: 147.8MB
Image Layers
├── ID: ad6562704f37 Size: 83.9MB
├── ID: c234616e1912 Size: 3.072kB
├── ID: c23a797b2d04 Size: 2.721MB
├── ID: ede2e092faf0 Size: 61.11MB
├── ID: 971c2cdf3872 Size: 3.584kB Top Layer of: [docker.io/library/httpd:2.4]
└── ID: 61644e82ef1f Size: 6.144kB Top Layer of: [localhost/simpleapp:latest]
:~$ podman run -d --name test -p 8080:80 localhost/simpleapp
2f3d7d613ea6ba19703811d30704d4025123c7302ff6fa295affc9bd30e532f8
:~$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f3d7d613ea6 localhost/simpleapp:latest httpd-foreground 5 seconds ago Up 6 seconds ago 0.0.0.0:8080->80/tcp test
:~$ podman logs test
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message
[Sat Jun 04 16:15:38.071377 2022] [mpm_event:notice] [pid 1:tid 139756978220352] AH00489: Apache/2.4.53 (Unix) configured -- resuming normal operations
[Sat Jun 04 16:15:38.073570 2022] [core:notice] [pid 1:tid 139756978220352] AH00094: Command line: 'httpd -D FOREGROUND'
:~$ curl 0.0.0.0:8080
Hello, World!
:~$ podman exec -it test cat /usr/local/apache2/htdocs/index.html
Hello, World!
Note: Some small distributions of Kubernetes (such as microk8s) have a built-in registry you can use for this exercise. If this is not your case, you’ll have to setup it on your own.
:~$ podman tag localhost/simpleapp $registry_ip:5000/simpleapp
:~$ podman push $registry_ip:5000/simpleapp
Verify that the registry contains the pushed image and that you can pull it
:~$ curl http://$registry_ip:5000/v2/_catalog
{"repositories":["simpleapp"]}
# remove the image already present
:~$ podman rmi $registry_ip:5000/simpleapp
:~$ podman pull $registry_ip:5000/simpleapp
Trying to pull 10.152.183.13:5000/simpleapp:latest...
Getting image source signatures
Copying blob 643ea8c2c185 skipped: already exists
Copying blob 972107ece720 skipped: already exists
Copying blob 9857eeea6120 skipped: already exists
Copying blob 93859aa62dbd skipped: already exists
Copying blob 8e47efbf2b7e skipped: already exists
Copying blob 42e0f5a91e40 skipped: already exists
Copying config ef4b14a72d done
Writing manifest to image destination
Storing signatures
ef4b14a72d02ae0577eb0632d084c057777725c279e12ccf5b0c6e4ff5fd598b
:~$ kubectl run simpleapp --image=$registry_ip:5000/simpleapp --port=80
:~$ curl ${kubectl get pods simpleapp -o jsonpath='{.status.podIP}'}
Hello, World!
Note: The two most used container registry servers with a free plan are DockerHub and Quay.io.
:~$ podman login --username $YOUR_USER --password $YOUR_PWD docker.io
:~$ cat ${XDG_RUNTIME_DIR}/containers/auth.json
{
"auths": {
"docker.io": {
"auth": "Z2l1bGl0JLSGtvbkxCcX1xb617251xh0x3zaUd4QW45Q3JuV3RDOTc="
}
}
}
:~$ kubectl create secret generic mysecret --from-file=.dockerconfigjson=${XDG_RUNTIME_DIR}/containers/auth.json --type=kubernetes.io/dockeconfigjson
secret/mysecret created
:~$ kubectl create secret docker-registry mysecret2 --docker-server=https://index.docker.io/v1/ --docker-username=$YOUR_USR --docker-password=$YOUR_PWD
secret/mysecret2 created
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: $YOUR_PRIVATE_IMAGE
imagePullSecrets:
- name: mysecret
:~$ podman rm --all --force
:~$ podman rmi --all
:~$ kubectl delete pod simpleapp