1、容器技术介绍
传统问题
- 应用程序和依赖需要一起安装在物理主机或虚拟机上的操作系统
- 应用程序版本比当前操作系统安装的版本更低或更新
- 两个应用程序可能需要某一软件的不同版本,彼此版本之间不兼容
解决方式
- 将应用程序打包并部署为容器
- 容器是与系统的其他部分隔离的一个或多个进程的集合
- 容器内容和其他容器内容是隔离的,不会相互影响
- 容器是打包应用程序以简化和管理的方式
2、容器和虚拟化的对比
虚拟化
- 可以在单一硬件设备上运行多个操作系统
- 通过虚拟化软件将硬件拆分成多个虚拟硬件,允许多个操作系统同时运行
- 需要完整的操作系统来支持应用允许
容器
- 容器可以在操作系统上直接运行,容器之间共享硬件和操作系统资源
- 容器中应用现对于虚拟化环境更轻量,运行速度更快速
- 容器共享操作系统的内核,将容器化的应用程序进程与系统的其余部分隔离开,可以使用与该内核兼容的任何软件
- 现对于虚拟化使用的硬件资源更少,可以快速启动和关闭,减少存储要求
- 可以保存容器的多个版本,根据需求快速访问特定版本
- 容器是临时的,可以将容器运行时产生的数据永久保存在持久存储中
3、Rootless和Rootful容器
在容器主机上,可以使用root用户或普通用户运行容器。其中由特权用户运行的容器称为Rootful容器,普通用户运行的容器称为Rootless容器。Rootless容器不允许使用给特权用户所保留的系统资源(访问受限目录、在受端口(1024以下)发布网络服务)。
容器管理工具与开放容器协议(OCI)兼容,意味着我们可以管理所有兼容OCI协议的Linux容器,如Docker
容器管理工具
- podman:直接管理容器和容器镜像
- skopep:检查、复制、删除和签名镜像
- buildah:创建新的容器镜像
4、容器镜像和注册表
运行容器必须使用容器镜像。容器镜像是包含编码步骤的静态文件,充当创建容器的蓝图。容器镜像会打包应用及其所有的依赖项,如系统库、编程语言运行时和库,以及其他配置设置。
镜像容器根据规范构建,遵循开放容器项目OCI镜像格式规范。这些规范定义容器镜像的格式,以及镜像支持的容器主机操作系统和硬件架构的元数据。
容器注册表是用于存储和检索容器镜像的存储库,通过将容器镜像推送或上传到容器注册表中,可以通过注册表中将这些容器镜像拉取或下载到本地系统,用于运行容器。有点类似于dnf。
可以使用第三方镜像的公共注册表,也可以使用私有注册表。需要注意容器镜像的来源,和dnf中的软件包一样,需要清楚容器镜像中的代码是否合规、安全。红帽通过两个主容器注册表来分发认证容器镜像,可以通过RedHat登录凭据来访问这个两个注册表。
红帽官方提供的注册表
- registry.redhat.io:适用于基于RedHat官方产品的容器
- registry.connect.redhat.com:适用于基础第三方产品的容器
- https://access.redhat.com/containers:基于Web的界面
5、红帽Quay镜像仓库
访问红帽中国官网
bash
https://www.redhat.com/zh
在菜单栏中找到【产品】,随后单击【查看所有产品】
点击左侧【产品A-Z】,然后选择【Quay】
红帽Quay需要收费
在红帽提供的学员练习环境中,有一个utility虚拟机,内置Quay,提供了部分的容器镜像。
bash
https://utility/
账号密码
账号 | 密码 |
---|---|
admin | redhat321 |
只提供了几个容器镜像
6、容器安装与登陆
安装podman容器(建议使用普通用户身份)
bash
sudo dnf -y install container-tools
登陆podman
建议使用交互式登陆,避免遗留密码
bash
# 登陆方式1:交互式
podman login registry.lab.example.com
> admin # 输入账号
> redhat321 # 输入密码
# 登陆方式1:非交互式
podman login registry.lab.example.com -u admin -p redhat321
查看登陆
bash
podman login --get-login
登出podman
bash
podman logout registry.lab.example.com
搜索镜像仓库
bash
podman serach registry.lab.example.com/ # 地址末尾需要加上/,代表访问仓库根目录
7、规模化容器管理
新应用越来越多的使用容器来实现功能组件,越来越多的容器难于管理。
在实际环境中部署容器需要一个强大的环境
- 平台必须确保必须服务容器的可靠性
- 通过增加或减少运行中的容器实例,对流量进行负载均衡,应对应用使用高峰
- 检测容器或主机的故障,并快速作出反应
Kubernetes(K8s,为什么叫K8s,是因为开头字母为K,结尾字母为s,中间8个字符)是一项编排服务,可以在容器集群中部署、管理和扩展基于容器的应用。通过负载均衡器将流量重定向到容器,以便扩展提供容器的数量。同时支持用户定义的健康性检查,以便监控容器,并在容器出现错误时将其自动重启。
RedHat提供了一个名为OpenShift的Kubernets发行版,是基于Kubernetes基础架构构建的一组模块化组件和服务。提供额外功能包括基于Web的远程管理、多租户、监控和审计、高级安全功能、应用生命周期管理和自助服务实例等。
8、部署容器
podman来自于container-tools元数据包的全功能容器引擎,用于管理开放容器计划(OCI)容器和镜像。podman的运行不使用守护进程,不需要使用root用户来启动或停止容器。
podman常用命令
参数 | 作用 |
---|---|
podman login | 登录 |
podman logout | 登出 |
podman search | 搜索镜像仓库内文件 |
podman login --get-login | 查看登录 |
--tls-verify | 不使用https验证 |
podman images | 查看当前系统中存在的镜像 |
podman ps | 查看系统中存在的容器 |
podman --version | 查看容器版本 |
podman build | 使用容器文件构建容器镜像 |
podman run | 在新容器中运行命令 |
podman images | 列出本地存储中的镜像 |
podman ps | 打印出有关容器的信息 |
podman inspect | 显示容器、镜像、卷、网络或容器基的配置 |
podman pull | 从注册表下载镜像 |
podman cp | 在容器和主机之间复制 |
podman exec | 在运行中的容器内执行命令 |
podman rm | 删除一个或多个容器 |
podman rmi | 删除1个或多个本地存储镜像 |
使用registries.conf文件中指定的注册表列表搜索匹配的名称镜像
bash
podman search registry.lab.example.com/
拉取/下载指定镜像
bash
podman pull registry.lab.example.com/ubi8/python-38
查看本地镜像
bash
podman images
podman image ls
9、使用容器文件构建容器镜像
容器文件是一种文本文件,包含用于构建容器镜像的指令。容器文件通常具有定义其文件和目录所在路径的URL上下文。生成的容器镜像由只读层组成,每一层代表容器文件中的一条指令。
podman build构建容器镜像
bash
podman build -t NAME:TAG DIR
- podman build:构建容器镜像
- -t NAME:指定生成镜像的名称
- TAG:新镜像的标签,默认值为latest
- DIR:工作目录路径
容器文件必须位于工作目录中,如果工作目录是当前目录,可以使用.
来指定。可以通过-f
指定与当前目录不同的目录。
Containerfile文件是构建镜像的命令参数脚本文件,构建容器镜像的步骤
- 编写一个Containerfile文件
- 使用podman build命令构建镜像
编写Containerfile文件,用于构建一个RedHat9并配置了YUM源,同时安装了Python3的镜像
dockerfile
vim Containerfile
# 写入下列内容
FROM registry.lab.example.com/ubi9-beta/ubi:latest
RUN echo -e '[BaseOS]\nname=BaseOS\nbaseurl=http://content.example.com/rhel9.0/x86_64/dvd/BaseOS\nenable=1\ngpgcheck=0\n[AppStream]\nname=AppStream\nbaseurl=http://content.example.com/rhel9.0/x86_64/dvd/AppStream\nenable=1\ngpgcheck=0' > /etc/yum.repos.d/dvd.repo
RUN dnf install python3 -y
CMD ["/bin/bash","-c","sleep infinity"]
- FROM:代表所使用的镜像
- RUN:在构建镜像时执行的命令,该命令会依次执行(这里是创建一个YUM仓库文件)
- CMD:构建完镜像后指定的命令,注意CMD指令的语法是使用JSON数组格式(如果使用数组,则值需要使用双引号)
- sleep infinity:让容器在启动后保持运行状态
简单查看一下RUN命令的执行效果
bash
echo -e '[BaseOS]\nname=BaseOS\nbaseurl=http://content.example.com/rhel9.0/x86_64/dvd/BaseOS\nenable=1\ngpgcheck=0\n[AppStream]\nname=AppStream\nbaseurl=http://content.example.com/rhel9.0/x86_64/dvd/AppStream\nenable=1\ngpgcheck=0'
需要先确保已经登陆podman
bash
podman login --get-login
开始构建容器
bash
podman build -t python3:1.0 .
- podman build:构建容器镜像
- -t python3:1.0:-t指定容器镜像的名称(镜像名称不允许大写),1.0为镜像标签(这里用1.0代表版本号)
- .:指定Containerfile文件的路径,
.
代表在当前路径下
验证本地镜像存储库,可以看到我们刚刚创建的镜像
bash
podman images
查看镜像的相关信息
bash
podman inspect localhost/python3:1.0 # 用于搜寻本地镜像的信息
skopeo inspect docker://xxxx # 在网上搜寻镜像信息
移除本地镜像
bash
podman rmi registry.lab.example.com/ubi8/python-38
10、创建、运行、删除容器
容器的状态
状态 | 说明 |
---|---|
Created | 已创建好但未启动的容器 |
Runing | 与其进程一起运行的容器 |
Stop | 其进程停止的容器 |
Paused | 其进程已停止的容器,不支持Rootless容器 |
Deleted | 其进程已被杀死的容器 |
列出系统上正在运行的容器
bash
podman ps # 查看当前正在运行的容器
podman ps -a # 查看计算机上的所有容器(已创建、停止、状态或在运行的)
创建容器
bash
podman create --name python3-1 localhost/python3:1.0
- podman create:创建容器
- --name python3-1:指定容器的名称(容器名称需保持唯一)
- localhost/python3:1.0:创建容器所使用的容器镜像
- d4b569c51c440cd091cff994c649734ef6651e22212413e5bed0d900505150c2:返回容器的长ID值
bash
podman create --name python3-2 7c85859a8381 # 可以使用容器镜像的IMAGE ID
运行容器
bash
podman start python3-1 # 可以使用名称(可以自动补全)
podman start d4b569c51c44 # 也可以使用CONTAINER ID
删除容器
bash
podman rm -f d4b569c51c44 # 删除指定容器
podman rm -rf python3-1 # 删除指定容器
podman rm -f -a # 删除所有容器
创建容器并在后台运行容器
bash
podman run -d --name python3-1 localhost/python3:1.0 sleep infinity
podman run -di --name python3-1 localhost/python3:1.0 # 等同于上面
- podman run:创建容器并运行容器
- -d:在后台运行容器,容器的输出不会直接显示在终端上
- --name python3-1:指定容器的名称
- localhost/python3:1.0:使用的容器镜像
- sleep infinity:容器启动后执行的命令:保持容器运行
11、创建容器并与容器进行交互
创建一个RedHat7容器,并在终端与容器交互,在退出交互窗口后,容器状态会更改为退出
bash
podman search registry.lab.example.com/ # 搜寻镜像
podman pull registry.lab.example.com/ubi7/ubi # 拉取镜像
podman images # 查看本地存储库中的镜像
podman run -ti --name redhat7 registry.lab.example.com/ubi7/ubi:latest # 保持容器的运行状态,并在终端交互
- podman run:创建容器并运行容器
- -t:分配一个伪终端,用于与容器交互
- -i:等同于sleep infinity,让容器保持运行
- --name python3-2:指定容器的名称
- localhost/python3:1.0:使用的容器镜像
新开一个终端然后查看运行状态
bash
ssh student@servera
podman ps
退出与容器的交互
bash
exit
然后继续查看容器的状态,可以看到容器状态变为退出
bash
podman ps
12、创建容器并让容器持续运行
继续使用刚刚拉取的redhat7镜像创建容器
bash
podman run -di --name redhat7-2 registry.lab.example.com/ubi7/ubi:latest
- -d:在后台运行
- -i:持续运行
查看容器的状态
bash
podman ps -a
与容器进行交互,其实就是让容器执行/bin/bash命令,而/bin/bash会启动一个新的Bash shell会话
bash
podman exec -ti redhat7-2 /bin/bash
退出会话,然后查看容器的状态
bash
exit
podman ps -a
封装要在容器中执行的命令,可以避免特殊字符被转义
bash
podman exec redhat7-2 sh -c 'echo HELLO > hello.txt;cat hello.txt'
- sh -c 'xxx':封装要在容器中执行的命令
13、容器中的环境隔离
容器隔离应用环境,每一个容器都有自己的文件系统、网络和进程。
在运行状态的容器中执行命令,可以看到我们容器的版本是Redhat7,而运行容器的系统版本是Redhat9,由此可以看出容器会隔离应用环境。
bash
podman exec redhat7-2 cat /etc/redhat-release
14、容器中的文件系统隔离
首先在主机上创建一个脚本文件
bash
echo "echo Hello!" > demo.sh
将脚本文件复制到容器中
bash
podman cp demo.sh redhat7-2:/
运行容器中的脚本
bash
podman exec redhat7-2 sh -c "chmod o+x demo.sh;./demo.sh"
15、删除容器和镜像
在删除容器镜像之前,必须先从该镜像移除任何现有运行的中的容器。
查看当前存在的容器
bash
podman ps -a
当前存在容器,尝试删除镜像
bash
podman rmi localhost/python3:1.0
先删除容器
bash
podman rm -f python3-1
podman rm -f python3-2
再删除镜像
bash
podman rmi localhost/python3