简介
容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序几乎可以在任何地方以相同的方式运行。
容器构成
1、应用程序本身
2、依赖:比如应用程序需要的库或其他软件
Podman
简介
Podman是一个开源的容器运行时项目,可在大多数LInux平台上使用。Podman提供与Docker非常相似的功能。Podman无需运行守护进程,并且可以在没有root权限的情况下运行。Podman可以
管理和运行任何符合OCI(Open Container Initiative)规范的容器和镜像。Podman提供了一个与Docker兼容的命令行前端来管理Docker镜像。
Podman和Docker的主要区别
-
dockers在实现CRI的时候,它需要一个守护进程,其次需要以root运行,因此这也带来了安全隐患。
-
podman不需要守护程序,也不需要root用户运行,从逻辑架构上,比docker更加合理。
-
在docker的运行体系中,需要多个daemon才能调用到OCI的实现RunC。
-
在容器管理的链路中,Docker Engine的实现就是dockerd
-
daemon,它在linux中需要以root运行,dockerd调用containerd,containerd调用containerd-shim,然后才能调用runC。顾名思义shim起的作用也就是“垫片”,避免父进程退出影响容器的运行
-
podman直接调用OCI,runtime(runC),通过common作为容器进程的管理工具,但不需要dockerd这种以root身份运行的守护进程。
-
在podman体系中,有个称之为common的守护进程,其运行路径通常是/usr/libexec/podman/conmon,它是各个容器进程的父进程,每个容器各有一个,common的父则通常是1号进程。podman中的common其实相当于docker体系中的containerd-shim。
图中所体现的事情是,podman不需要守护进程,而dorker需要守护进程。在这个图的示意中,dorcker的containerd-shim与podman的common被归在Container一层。
环境
centos7.6 阿里云yum源
安装
yum -y install podman
查看安装版本
[root@wzy ~]#podman version
Version: 1.6.4
RemoteAPI Version: 1
Go Version: go1.12.12
OS/Arch: linux/amd64
配置文件
配置文件:/etc/containers/registries.conf
#备份原始配置文件
cp /etc/containers/registries.conf /etc/containers/registries.conf.back
#修改配置文件
vim /etc/containers/registries.conf
#配置镜像仓库
[registries.search]
registries = [‘docker.io’]
#配置加速器
#centos7
location=”txi5z2at.mirror.aliyuncs.com”
#centos8
unqualified-search-registries = [“docker.io”]
[[registry]]
prefix = “docker.io”
location = “txi5z2at.mirror.aliyuncs.com”
#测试
podman run hello-world
镜像管理
podman images 列出本地主机上的镜像
镜像的仓库源 标签(版本) 镜像ID 镜像创建时间 镜像大小
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/hello-world latest feb5d9fea6a5 16 months ago 19.9 kB
同一个仓库源可以有多个TAG,代表不同的版本。
podman search httpd 搜索httpd镜像
podman pull httpd 下载httpd镜像
podman tag docker.io/library/httpd myhttpd:v1 添加镜像标签
podman rmi docker.io/library/httpd 删除镜像
podman image prune -a 清理没有正在使用的镜像
podman image save docker.io/library/httpd > test-httpd.tar.gz 导出镜像
podman image load -i test-httpd.tar.gz 导入镜像
podman history docker.io/library/httpd 查看镜像构建的历史信息
镜像结构
以centos7镜像中包含了以下内容
FROM scratch
ADD centos-7-docker.tar.xz /
CMD [“/bin/bash”]
第一行:FROM scratch 表示镜像是从0开始构建的。
第二行:ADD表示添加到镜像的tar包就是Centos7的rootfs文件,在制作镜像时,这个tar包会自动解压至/目录下,生成/dev、/proc、/bin等目录,相当于提供了一个基本的操作系统环境,用户可以根据需要安装和配置软件,这种镜像成为Base镜像。
Base镜像有两钟
1:不依赖其他镜像,从scratch构建
2:以此为镜像基础,进行拓展
rootfs
容器只能使用podman host的kernel,并且不能修改。所有容器共用podman host的kernel,无法对kernel升级。如果容器对kernel版本有要求,则不建议只用容器,虚拟机更合适。
分层结构
Podman镜像是Podman容器运行的基础,没有podman镜像,就不可能有podman容器。
镜像是静态文件,只读,容器是动态文件,可读可写。
所有对容器的改动(文件的增加、修改、删除)都只会发生在容器层,只有容器层是可写的,容器层下面的所有镜像层都是只读的。
镜像层数量可能会很多,所有的镜像层会联合在一起组成一个统一的文件系统。如果不同层中一个相同路径的文件,比如/dir,则上层的/dir会覆盖下层的/dir,用户只能访问到上层中的/dir;在容器层中,用户看到的是一个叠加后的文件系统。
- 添加文件:在容器中创建文件时,新文件被添加到容器层中。
- 读取文件:在容器中读取某个文件时,podman会从上往下依次在各个镜像层中查找此文件,一旦找到,打开读入内存。
- 修改文件:在容器中修改已存在的文件时,podman会从上往下依次在各个镜像层中查找此文件,一旦找到,立即将其复制到容器层,然后修改。
- 删除文件:在容器中删除文件时,podman会从上往下依次在各个镜像层中查找此文件,找到后,会在容器层记录下此删除操作,并不是真正的删除。
只有当需要修改时才复制一份数据,这种特性被称作Copy-on-Write。可见,容器保存的是镜像变化的部分,不会对镜像本身进行任何修改。所有镜像都是只读,不会被容器修改,所以镜像可以被多个容器共享。
容器管理
创建容器
podman create -itd docker.io/library/centos:7
-i:让容器的标准输入保持打开
-t:分配一个伪终端并绑定到容器的标准输入上
-d:丢到后台运行
使用podman create 新建的容器处于停止状态,可以用podman start命令启动。
启动容器
podman start docker.io/library/centos:7
创建并运行容器
podman run -itd --name mycentos7 docker.io/library/centos:7
--name:给新建的容器命名
查看所有容器
podman ps -a
进入容器
podman attach 不建议使用这种,因为退出容器终端会导致容器停止。
podman exec -it mycentos7 /bin/bash 建议用这种,因为退出容器不会导致容器停止。
暂停容器
podman pause mycentos7
解除暂停
podman unpause mycentos7
停止容器
podman stop mycentos7
删除停止的容器
podman container prune
删除容器
podman rm mycentos7
-f:可以强制删除
导出容器(无论容器此时什么状态)
podman export -o test_centos7.tar mycentos7
导入容器
podman import test_centos7 mycentos7_02
容器端口映射
当我们启动一个web容器时,可以将容器的端口映射到宿主机上,便于从外部访问该web服务.
-P参数将容器内部使用的80端口映射到宿主机的随机端口上
podman run -itd —name httpd -P docker:io/library/httpd:latest
-p参数将容器内部使用的80端口映射到宿主机的指定端口上
podman run -itd —name httpd -p 80:80 docker:io/library/httpd:latest
持久化存储
以Nginx为例,使用podman容器部署web服务
1、查找Docker Hub 上的Nginx镜像
podman search nginx
2、获取镜像
podman pull nginx
3、使用默认配置启动一个Nginx容器实例
podman run -itd --name nginx-test -p 80:80 docker.io/library/nginx:latest
4、nginx部署
在宿主机创建目录,用于存放映射数据。其中www目录将映射为Nginx容器配置的虚拟目录;logs目录将映射为Nginx容器的日志目录;conf目录里的配置将映射为Nginx容器的配置文件。
mkdir -p ~/nginx/www
mkdir -p ~/nginx/logs
mkdir -p ~/nginx/conf
5、拷贝容器内Nginx默认配置文件到本地当前目录下的conf目录
podman cp 容器ID:/etc/nginx/nginx.conf ~/nginx/conf/
6、部署容器(此处一步搞定,可以先把第三步的容器实例nginx-test删除)
将宿主机目录挂载到容器目录
-v 宿主机目录:容器目录:Z
podman run -itd --name mynginx -p 2000:80 -v ~/nginx/www:/usr/share/nginx/html:Z -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:Z -v ~/nginx/logs:/var/log/nginx:Z
docker.io/library/nginx:latest
7、创建自己的网页并访问。
cd ~/nginx/www/
echo test > index.html
开机自启
一、root用户下podman容器服务开机自启
1、切换到/usr/lib/systemd/system目录
cd /usr/lib/systemd/system
2、下载httpd镜像,生成并运行web容器
podman pull httpd
podman run -itd --name web docker.io/library/httpd:latest
3、生成web容器的systemd单元文件(文件固定格式 container-xxx.service)
命令 podman generate systemd --name web --files
结果 /usr/lib/systemd/system/container-web.service
4、查看container-web服务状态
systemctl status container-web.service
5、更改container-web.service文件内容
cd /usr/lib/systemd/system
vim container-web.service
[Install]
WantedBy=default.target
systemctl daemon-reload
6、重启container-web服务,设置下次启动生效
systemctl restart container-web.service;systemctl enable container-web.service
一、普通用户下podman容器服务开机自启
1、新建普通用户testuser,并设置密码为redhat
useradd testuser
echo ‘redhat’ | passwd --stdin testuser
2、使用ssh切换到普通用户testuser下,下载nginx镜像,创建并运行名字为myhttpd的容器
podman pull nginx;podman run --itd --name myhttpd docker.io/library/httpd:latest
3、在用户家目录下创建递归目录 ~/.config/systemd/user 目录。只能是此目录名,因为普通用户启动服务时一定只能是此目录
mkdir -p ~/.config/systemd/user
4、切换至 ~/.config/systemd/user 目录下,生成systemd管理的服务单元文件
cd ~/.config/systemd/user/
podman generate systemd --name myhttpd --files
5、编辑单元文件 container-myhttpd.service
vim container-myhttpd.service
[Install]
WantedBy=default.target
systemctl --user daemon-reload
6、将container-httpd.service设置为开启自启。
systemctl --user enable container-myhttpd.service
7、启用逗留
loginctl enable-linger testuser
8、停止myhttpd 容器,然后启动container-myhttpd.service服务
podman stop myhttpd
systemctl --user start container-myhttpd.service