Linux学习笔记(31)容器
【1】容器的介绍
红帽9重启网络 systemctl restart NetworkManager
(1.1)基本概念
容器:针对应用(服务)所需的运行环境,比如依赖、目录、网络、用户等整体封装的技术。(简单理解为一个独立的虚拟机,里面只运行某个镜像软件服务)
封装好的应用(服务)环境叫做镜像,可以理解成迷你版虚拟机或者豪华软件包。
当前大多数镜像, 是软件厂商自己封装好的,我们直接下载使用即可。如:nginx。
核心三个组件如下:
仓库服务器(注册表服务器)----》镜像(静止的)-------》容器(运行中的)
reglstry.access.redhat.com image container
【2】podman
(2.1)安装
DNF(全称为Dandified yum)是新一代的rpm软件包管理器,他首先出现在 Fedora 18 这个发行版中。而最近,它取代了yum,正式成为 Fedora 22 的包管理器。使用DNF需要管理员权限,本章所有命令需要在管理员权限下执行。
redhat 9.0
yum -y install podman
dnf -y groupinstall "Container Management" -- 或者 dnf -y install podman
(2.2)配置pod仓库服务器(rht9)
vi /etc/containers/registries.conf
找到 [registries.search]
然后如果没有外网,要些自定义的仓库地址,修改次数即可。
如 registries=['registry.lab.example.com:5000']
验证使用
podman search nginx
如果有错误,说不安全无法使用,配置改成如下:
unqualified-search-registries = [ "registry.lab.example.com:5000" ] [[registry]] location = "registry.lab.example.com:5000" insecure=true
修改前,修改后:
(rht8)配置
(2.3)镜像与容器命令
// 镜像
podman imgages # 查看当前已有镜像 podman search imagename # 搜索镜像包 podman pull image_url # 获取镜像包 podman images # 查看当前已有镜像 podman build -t imagename . # 从Containerfile 文件中获取镜像 podman rmi nginx # 删除nginx 镜像
// 容器 podman run -d imageid # 运行的镜像,就是容器 -d 是放在后台运行,可以用镜像id 或 镜像名称
podman run --name new_name imageid # 给对应镜像的容器,在容器中起个名字并运行 podman ps -a # 查看当前正在运行的所有容器 podman stop containerid # 根据容器id ,停止容器里正在运行的镜像。
podman start containerid # 根据容器id,重启启动容器。
podman rm containerid # 根据容器id,删除已经停止的容器,如果想要强行删除正常运行的可以加 -f
// 导入导出,tag修改 podman save registry.lab.example.com:5000/library/nginx >/opt/nginx # 备份、导出 podman load -i /opt/nginx #装载、恢复 podman tag imageid或者名称 nginx:001 # 根据 imageid 或者名称 修改该进行的 tag
// 容器内与容器外的:端口映射、目录映射
# 外界的 /home/tammy/a 映射成容器中的/a,然后无论存哪个目录都是相通共享的,只是在root登录服务器和容器访问目录时不一样。再加个:Z在后面避免selinux问题。
podman run -d -v /home/tammy/a:/a:Z
podman exec -it 容器id bash # -i 为交互式 -t 为新开一个终端。释义:进到对应的容器里以bash命令的方式开一个交互式的终端。
podman run -d -p 8080:80 containerid #服务器的8080端口映射容器内的80端口
获取镜像
1、查看镜像
2、搜索镜像,查看镜像完整路径
3、根据镜像完整路径,从仓库获取镜像,
查看镜像 podman images
如上图,搜索有该镜像,就可以 podman pull registry.lab.example.com:5000/library/nginx 拉取服务下载
(rhel9:需要用文件来拉)
REPOSITORY是名称,TAG只是标签别名的意思。
再次查看就有了。
(登录容器仓库,输入账户密码)
podman login registry.lab.example.com
rhel9:定义容器文件(Containerfile)来拉取镜像
mkdir nginx; cd nginx/
vi Containerfile(考试不需要自己写,也不要修改文件内容) FROM registry.lab.example.com:5000/library/nginx:latest
# FROM abcd.com/nginx:abc #注意,这个:后面的 abc就是一个标签别名,无固定要求,用于相同名称镜像区别。 RUN echo 'aaa' > /aa.txt #每次下载的时候执行的命令 CMD ["/bin/bash","-c","sleep infinity"] # 每次容器装载镜像服务时,会执行的命令
podman build -t nginx . // 读取当前目录下的 Containerfile 文件,制作一个新镜像(适用于 RHEL9)
(2.4)容器
podman ps -a # 查看当前正在运行的所有容器
podman stop containerid # 根据容器id ,停止容器里正在运行的镜像实例。
如下图:也可以根据 names 停止容器里正在运行的某个镜像实例
(2.5)容器的端口、目录映射
什么叫容器的目录映射?就是说我新建一个a目录,把它关联到容器id,a目录就是容器的某个目录,外面传数据到a目录容器可以看得到,容器里存储数据到a目录外面也看得到。
-- 目录映射
# 外界的 /home/tammy/a 映射成容器中的/a,然后无论存哪个目录都是相通共享的,只是在root登录服务器和容器访问目录时不一样。 podman run -d -v /home/tammy/a:/a
# -i 为交互式 -t 为新开一个终端。释义:进到对应的容器里以bash命令的方式开一个交互式的终端。
podman exec -it 容器id bash
podman run --name logserver -d -v /home/tammy/container_logserver:/var/log/journal:Z -v /tmp/test/:/opt/nihao:Z nginx
//运行容器,--name是定义容器名称,-d是将容器以进程方式放后台运行,-v是目录映射,前面是linux的目录,冒号后面是容器里面的目录,最后的nginx是镜像名称
再加个:Z在后面避免selinux问题。
podman run -d -v /home/tammy/a:/a:Z
-- 端口映射
podman run -d -p 8080:80 containerid
目录映射:即linux的目录映射到容器内的目录
-- 目录映射 [root@red ~]# podman run -d -v /home/tammy/a/:/a 4c220f97e79a 1a6037f8bf3d6a30d3b37ebd0208ab5b94732c396ed3f4c796ae1662ae3823bd [root@red ~]# [root@red ~]# podman exec -it 1a6037f8bf3d bash root@1a6037f8bf3d:/# root@1a6037f8bf3d:/# ls a bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var aa.txt boot docker-entrypoint.d etc lib media opt root sbin sys usr root@1a6037f8bf3d:/# # 我们可以看到 aa.txt 就是我们2.3中RUN echo 'aaa' > /aa.txt 生成的 # 然后 a 目录,就是我们映射的目录,也就是对应容器外服务器的 /home/tammy/a
#核验,修改一遍另外一遍同步
root@402c69642458:/# ls a abc.txt root@402c69642458:/# ls / a bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var aa.txt boot docker-entrypoint.d etc lib media opt root sbin sys usr root@402c69642458:/# echo '1'>/a/1.txt root@402c69642458:/# #然后我们切回Linux环境,就发现 1.txt 就有了 [root@red a]# pwd /home/tammy/a [root@red a]# ls 1.txt abc.txt [root@red a]#
端口映射:即容器内部端口对应容器外服务器端口。
podman run -d -p 8080:80 containerid
[root@red ~]# podman run -d -p 8080:80 4c220f97e79a 22e7b899f9aedf1bd75ec59776897dea360e05d7435e06cc60da702e989d5e56 [root@red ~]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 22e7b899f9ae registry.lab.example.com:5000/library/nginx:latest nginx -g daemon o... 14 seconds ago Up 14 seconds ago 0.0.0.0:8080->80/tcp gallant_mahavira [root@red ~]# [root@red ~]# curl localhost:8080 # 验证成功 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> </head> <body> <h1>Welcome to nginx!</h1> </body> </html> [root@red ~]#
(2.6)将容器服务配置以 systemd 服务的形式运行(实践)
利用 nginx 镜像,创建一个名为 logserver的容器
需求1:将其配置为以 systemd 服务的形式运行,仅面向用户 tammy
需求2:该服务应命名为 container-logserver,并设置开机自启。
也就是想以 systemctl start logserver
systemctl --user start logserver 以当前登录用户的权限来启动服务
步骤1:
#1 拉取镜像,运行容器并取名叫 logserver
su -l tammy
podman search nginx
podman pull registry.lab.example.com:5000/library/nginx
podman run -d --name logserver 4bb46517cac3
#2 构建 container-logserver.service 文件 mkdir -p .config/systemd/user cd .config/systemd/user podman generate systemd --name logserver --files #自动会在该目录下生成一个文件叫 container-logserver
[tammy@red user]$ podman generate systemd --name logserver --files /home/tammy/.config/systemd/user/container-logserver.service [tammy@red user]$ ls container-logserver.service [tammy@red user]$
#3 重新系统进程文件
systemctl --user daemon-reload
#如果出现报错,Failed to connect to bus: No medium found,那么久切回root,再 ssh tammy@localhost 再尝试
#4 关闭容器,用系统 systemd 运行容器
podman stop logserver
systemctl --user start container-logserver.service
#5 设计开机自启
systemctl --user enable container-logserver.service
# 验证:切换root 用户,重启该服务器,查看验证
# 出现这样才算成功:Created symlink /home/tammy/.config/systemd/user/default.target.wants/
# container-logserver.service → /home/tammy/.config/systemd/user/container-logserver.service.
#6 为了保证绝对能开机自启,
方法1:即使用户不登录系统,也为其保持服务及资源
loginctl enable linger tammy
方法2:如果linger无效的话,可以作为弥补措施。修改 crontab
crontab -e -u tammy
@reboot systemctl --user start container-logserver.service