{{tag>projects cloud club computing virtualization machines VMs AWS Azure GCP}} [[cloud_club|About the Club]] ==== Cloud Club Topics - Containers & Kubernetes ( k8s ) ==== ==== Questions ==== - What are containers? - How are they different from VMs? - What benefits do you get with containers? ==== Understanding Containers ==== - Terminology - Container image - binary file containing the application and it's dependencies - Container - running process in isolation from other processes - Runtime tools - LXC ( LinuX Containers ) - Portiable container - Light-weight, but full OS installation focus - 1 or more application(s) - Multi-process - Created before Docker and Kubernetes - Docker - Portable container - Light-weight - Single application-specific focus - Single process - Requires docker daemon ( service ) to run as root ( security risk ) - Created before Kubernetes was developed - No concept of pods - Self-healing - Single box only - no cluster - Podman - Portable container - Light-weight - Single process - Does not require any daemon ( less security risk ) - Self-healing - Single box only - no cluster - Created after Kubernetes to resolve the daemon security issue and to add pod functionality - Kubernetes ( K8s ) - Originally developed on top of Docker - Created with a plug-in model - Can swap each plug-in with another product - Developed the concept of pods ( "box" around the container(s) ) - Pods hold the IP for the container(s) instead of the container(s) - Enhances the scaling process, especially if the pod has an "init" and/or side-car containers with it - Self-healing - High availability ( H/A ) - Clustering - Repositories ( local ) - Location & application on local disk that hosts container images - Registries ( Remote ) - Remote location where container images are available to downlaod - Examples: - [[https://hub.docker.com/|Docker Hub ( public )]] - Ironbank ( Government ) - [[https://goharbor.io/|Harbor ( Host your own )]] - [[https://www.docker.com/blog/how-to-use-your-own-registry-2/| Docker Registry ( Host your own )]] - Others? ==== Running Containers ==== - Hands-on running containers - Install podman sudo dnf install -y podman - Verify the installation podman --version podman version 5.2.2 - List the container iamges we currently have podman images - Find the image you need - We don't have access to the internet, so look in the **BLAH** directory for container images in the .tar file format - Load the iamges podman load < filebrowser.v2.32.0-s6.tar Getting image source signatures Copying blob 9fb3fcee28a5 done | Copying blob 251ddab6d742 done | Copying blob 826ed011a96f done | Copying blob a2961ae79149 done | Copying blob c652740d6602 done | Copying blob 9044ca33e914 done | Copying blob 3f54fb0f79a5 done | Copying blob 04a0ae551679 done | Copying blob d15b2f89029d done | Copying blob ea7ed489f623 done | Copying blob a0b0a42e7090 done | Copying blob 5d420005b59f done | Copying config 4567130c34 done | Writing manifest to image destination Loaded image: docker.io/filebrowser/filebrowser:v2.32.0-s6 - Look for the version tag podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/filebrowser/filebrowser v2.32.0-s6 4567130c34df 2 months ago 48.6 MB - Load all of the images for IMG in $(ls *.tar); do podman load < $IMG; done - List the images again podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/nginx 1.28.0 244abd08b283 3 days ago 197 MB docker.io/library/nginx stable-alpine3.21 936a1208f403 3 days ago 49.6 MB docker.io/filebrowser/filebrowser v2.32.0-s6 4567130c34df 2 months ago 48.6 MB - At this point, we've only loaded the images into our local __repository__. We still need to create our containers ( running applications ) - Let's start wtih **nginx** since you've been able to create a web server and have content already - Create a pod to host our container podman pod create --name mike-web -p 8081:80 - Next, create the container in the pod, specifying which image to use - Create a directory for the container config and data mkdir web-mike cd web-mike - We use the documentation on [[https://hub.docker.com|Docker Hub]], but since we don't have access, we'll use the txt files I created from there. - Create the content directory as listed in the documentation mkdir content - Use the **rsync** or **scp** commands to copy your web pages to the new content directory - Create/run the container podman run --name mike-web --pod mike-web -v $PWD/content:/usr/share/nginx/html:ro -d docker.io/library/nginx:1.28.0 - Check if your app is running podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8562cd91ac4b localhost/podman-pause:5.2.2-1731414899 About a minute ago Up 27 seconds 0.0.0.0:34337->8080/tcp 3cd26dd9558f-infra bd615795eaa1 docker.io/library/nginx:1.28.0 nginx -g daemon o... 27 seconds ago Up 27 seconds 0.0.0.0:34337->8080/tcp mike-web - View the container logs ( -f keep displaying new lines as they are added to the logs ) podman logs -f mike-web /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh /docker-entrypoint.sh: Configuration complete; ready for start up 2025/04/27 03:48:45 [notice] 1#1: using the "epoll" event method 2025/04/27 03:48:45 [notice] 1#1: nginx/1.28.0 2025/04/27 03:48:45 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 2025/04/27 03:48:45 [notice] 1#1: OS: Linux 5.14.0-503.14.1.el9_5.x86_64 2025/04/27 03:48:45 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 524288:524288 2025/04/27 03:48:45 [notice] 1#1: start worker processes 2025/04/27 03:48:45 [notice] 1#1: start worker process 24 2025/04/27 03:48:45 [notice] 1#1: start worker process 25 - Press CTRL+C to exit the logs - Open the same port on the firewall to allow access sudo firewall-cmd --add-port=8081/tcp --permanent sudo firewall-cmd --reload - Flip back to the logs and see the entries that show we accessed the site/page 192.168.1.121 - - [27/Apr/2025:04:03:32 +0000] "GET / HTTP/1.1" 200 7620 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" "-" 192.168.1.121 - - [27/Apr/2025:04:03:32 +0000] "GET /icons/poweredby.png HTTP/1.1" 404 555 "http://192.168.1.11:8081/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" "-" 2025/04/27 04:03:32 [error] 25#25: *1 open() "/usr/share/nginx/html/icons/poweredby.png" failed (2: No such file or directory), client: 192.168.1.121, server: localhost, request: "GET /icons/poweredby.png HTTP/1.1", host: "192.168.1.11:8081", referrer: "http://192.168.1.11:8081/" 192.168.1.121 - - [27/Apr/2025:04:03:32 +0000] "GET /poweredby.png HTTP/1.1" 404 555 "http://192.168.1.11:8081/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" "-" 2025/04/27 04:03:32 [error] 25#25: *1 open() "/usr/share/nginx/html/poweredby.png" failed (2: No such file or directory), client: 192.168.1.121, server: localhost, request: "GET /poweredby.png HTTP/1.1", host: "192.168.1.11:8081", referrer: "http://192.168.1.11:8081/" 192.168.1.121 - - [27/Apr/2025:04:03:32 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://192.168.1.11:8081/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" "-" 2025/04/27 04:03:32 [error] 25#25: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.1.121, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.1.11:8081", referrer: "http://192.168.1.11:8081/" 192.168.1.121 - - [27/Apr/2025:04:03:42 +0000] "GET /pg2.html HTTP/1.1" 200 186 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" "-" 2025/04/27 04:08:27 [error] 24#24: *2 open() "/usr/share/nginx/html/no/page/here" failed (2: No such file or directory), client: 192.168.1.121, server: localhost, request: "GET /no/page/here HTTP/1.1", host: "192.168.1.11:8081" - Try to access a page that doesn't exist http:///no/page/here - Flip back to the logs again and see the new entry 192.168.1.121 - - [27/Apr/2025:04:08:27 +0000] "GET /no/page/here HTTP/1.1" 404 555 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" "-" - Now let's upgrade our container to a newer image - Stop the pod and delete it podman pod stop mike-web podman pod rm mike-web - Verify it's not running - you should see the column headers, but no entries podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - Create a new pod with the same command as before - Start the container with a new image tag as follows podman run --name mike-web --pod mike-web -v $PWD/content:/usr/share/nginx/html:ro -d docker.io/library/nginx:stable-alpine3.21 - View the logs like before - Access the website again - see the page still works - Flip back to the logs and see the new entry showing you accessed the page or the error if you didn't get to the page - Lastly, let's run a web-based file browser app to download our backups - Create a new directory in your homedirectory for the new app config and data - Create a directory inside there to host your files mkdir files - Create empty files the app needs touch filebrowser.db - Create a new files ( **settings.json** ) with the following content { "port": 8082, "baseURL": "", "address": "", "log": "stdout", "database": "/database/filebrowser.db", "root": "/srv" } - Create a pod with a different name and port number podman pod create --name mike-fb -p 8082:8082 - Run the container with the paremeters from the documentation podman run \ --name mike-fb \ --pod mike-fb \ -v $PWD/files:/srv:rw \ -v $PWD/filebrowser.db:/database/filebrowser.db:rw \ -v $PWD/settings.json:/config/settings.json:rw \ -d docker.io/filebrowser/filebrowser:v2.32.0-s6 - Verify your container & pod are running podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2a50be552bf6 localhost/podman-pause:5.2.2-1731414899 16 minutes ago Up 15 minutes 0.0.0.0:8081->80/tcp 2a8668698c07-infra 6f7b1f6d9928 docker.io/library/nginx:stable-alpine3.21 nginx -g daemon o... 15 minutes ago Up 15 minutes 0.0.0.0:8081->80/tcp mike-web ed8fb91c30e4 localhost/podman-pause:5.2.2-1731414899 6 minutes ago Up 5 seconds 0.0.0.0:8082->80/tcp 0f100802cff6-infra 97be288c6480 docker.io/filebrowser/filebrowser:v2.32.0-s6 5 seconds ago Up 4 seconds (starting) 0.0.0.0:8082->80/tcp mike-fb - Access your new application http://:8082 ==== Kubernetes ==== - Terminology ( [[https://kubernetes.io/docs/reference/glossary/?fundamental=true|Glossary]] ) - Container Runtime Interface ( CRI ) - Container ( application ) - Pod - Namespace - Kubernetes ( k8s ) - Manifest - Deployment - Helm chart - K8s Components - Control plane - Worker nodes ( nodes ) - kubelet - Cluster - DaemonSet - ReplicaSet - Container Storage Interface ( CSI ) - Options of components: [[https://landscape.cncf.io/|Kubernetes Lanscape]] - Cluster management tools - kubectl ( CLI ) - Lens ( Desktop app ) - k9s ( Terminal User Interface or TUI )