Docker、Podman 容器“扫盲“ 学习笔记【与云原生的故事】

网友投稿 985 2022-05-29

写在前面

笔记内容:由理论和具体docker常用操作构成。

这篇博文笔记的定位是:温习,查阅,不适合新手学习。

你拥有青春的时候,就要感受它,不要虚掷你的黄金时代,不要去倾听枯燥乏味的东西,不要设法挽留无望的失败,不要把你的生命献给无知,平庸和低俗。 ------王尔德

一、docker 原理

关于docker,容器这些,举一个很简单的例子,启动盘,有时候我们

Docker 是完整的一套容器管理系统,所以想要搞懂 Docker 的概念,我们必须先从容器开始说

起。什么是容器?

容器是用来装东西的,Linux 里面的容器是用来装应用的;

容器就是将软件打包成标准化单元,以用于开发、交付和部署;

容器技术已经成为应用程序封装和交付的核心技术;

容器技术的核心,由以下几个内核技术组成:

Cgroups (Control Groups) — 资源管理

SELinux — 安全 (是针对于文件系统,文件的管理措施)

NameSpace — 命名空间

Docker、Podman 容器“扫盲“ 学习笔记【与云原生的故事】

是指可以对系统资源空间进行分割隔离的技术,例如:创建一个虚拟机,在虚拟机里的所有操

作,都不会对真实机造成影响。

命名空间分为六大类,可以从各个方面来对系统资源空间进行隔离;

UTS:主机名命名空间,作用:分割主机名,即在容器内修改主机名,不会对宿主机的系统造成影响,实现主机名的隔离;

NETWORK:网络命名空间,作用:分割网络,即容器内的网络配置和宿主机相互之间不受干扰的;例如在真实机器上的网卡名为eth0,IP地址为192.168.1.10/24;而在容器内的网卡名可以为ens33,ip地址为10.10.10.10/24;

MOUNT:挂载命名空间,作用:隔离文件系统,在容器内挂载的光盘或nfs共享目录,宿主机是无法看到里面的内

容的;例如:在linux系统上,创建一个虚拟机,在真机的/var/lib/ftp中挂载了一个光盘文件,但是在虚拟机的/var/lib/ftp中是没有光盘内容的,这就是MOUNT隔离;

USER:用户命名空间,作用:隔离用户,即容器内创建的用户不能用于登录宿主机,真机机里创建的用户也不能

作用于容器;

PID:进程命名空间,作用:为了防止容器和宿主机中的进程冲突;例如:在真实机中,有一个服务: nfs,PID为2250;在容器内,也有一个服务: chrony,PID为2250;真实机中用户,杀死(kill) PID号为2250的进程时,并不会对容器内的进程2250产生影响;而容器内的用户,杀死(kill) PID号为2250的进程时,也并不会对真实机内的进程2250产生影响;

IPC:信号向量命名空间,作用:通常和PID一起使用;用户杀死一个进程时,实际上是向进程发送一个信号(IPC),进程接收到这个信号后会执行对应的操作;

docker 的特性

优点:相比于传统的虚拟化技术,容器更加简洁高效,传统虚拟机需要给每个 VM 安装操作系统,容器使用的共享公共库和程序

缺点:容器的隔离性没有虚拟机强共用Linux内核,安全性有先天缺陷.

docker 与传统虚拟化的对比:

虚拟化:例如:虚拟机的使用,每一个虚拟机都要安装独立的操作系统;将一台服务器转变为多台服务器的物理硬件的抽象。系统管理程序允许多个VM在单台计算机上运行。每个VM包含操作系统,应用程序,必要的二进制文件和库的完整副本-占用数十GB。VM也可能启动缓慢。

容器:不需要安装独立的操作系统,只有一个Docker进程,和宿主机共享操作系统;容器没有操作系统,启动容器就跟开启一个进程一样,简单高效;是应用程序层的抽象,将代码和依赖项打包在一起。多个容器可以在同一台计算机上运行, 并与其他容器共享OS内核,每个容器在用户空间中作为隔离的进程运行。容器占用的空间少于VM(容器映像的大小通常为几十MB),可以处理更多的应用程序,并且需要的VM和操作系统更少。

运行区别( 容器的高效性):

启动虚拟机中的应用程序,需要先启动虚拟机的操作系统,然后再启动应用程序;

启动容器内的应用程序,直接启动应用程序即可;

二、docker 安装部署

docker安装

需要64位操作系统,至少 RHEL6.5 以上的版本,强烈推荐 RHEL7

docker安装时,内核要求在3.0以上,RHEL7的内核默认在3.0以上,不满足可以单独升级系统内核。

查看linux系统的内核版本,【uname -r】也可以

关闭防火墙 (不是必须):firewalld【RHEL7使用】,Iptables【RHEL6使用】,Docker安装时,会自动的接管防火墙,并向防火墙里添加配置,如果防火墙存在,会产生冲突。

配置 yum 源

在物理机的 http 目录下创建文件夹 extras: mkdir /var/www/html/extras

把光盘挂到这个目录下 : mount -t iso9660 -o ro,loop RHEL70OSP-extras.iso /var/www/html/extras

卸载防火墙 yum remove -y firewalld-*

安装软件包 yum install docker

开启路由转发 /etc/sysctl.conf net.ipv4.ip_forward=1 使用sysctl -p让配置立刻生效(否则需要重新虚拟机)docker是通过虚拟交互机来进行通讯的,需要开启路由转发的功能。

软件的 BUG :iptables -nL FORWARD 版本 大于 1.12 时会设置 FORWARD 的默认规则,被设置为 DROP,对于有些docker的版本中,FORWARD链的规则被设置成了DROP,会造成容器和宿主机之间无法通讯。

解决办法:

修改 /lib/systemd/system/docker.server

重载配置文件,重启服务 systemctl daemon-reload systemctl restart docker

[root@liruilong ~]# systemctl daemon-reload [root@liruilong ~]# systemctl restart docker

三、获取镜像

镜像、容器、仓库

镜像是启动容器的核心,在Docker 中容器是基于镜像启动的,镜像采用分层设计,使用COW技术

容器本身是没有操作系统,和宿主机共用一个操作系统;

容器是docker(容器的管理工具)使用镜像文件来启动的;

镜像是启动容器的模板,镜像中存放的是应用程序(服务软件),例如: 有一个http的镜像文件,在这个镜像中就存放的是http的所有文件和变量;

用户使用镜像启动容器时,会生成一个独立于镜像的容器层,并不会对镜像层产生任何影响;

而且容器采用了cow(写时复制)的技术,用户可以使用一个镜像文件创建多个容器,互不干扰;

镜像采用分层技术:用户可以根据自己的需求来制作镜像,例如:在镜像的第一层定义应用程序的变量,在镜像的第二层修改配置文件,在镜像的第三层进行应用软件的部署;分层做好镜像后,用户使用镜像启动容器时,可以选择根据镜像的哪一层来启动,类似快照还原;

镜像可以从官方镜像仓库下载,也可以自己制作

官方镜像仓库:https://hub.docker.com

查看本机镜像 docker images

#REPOSITORY 镜像名称

#TAG 镜像标签

#IMAGE ID 镜像ID号

#CREATED 镜像创建时间

#SIZE 镜像大小

#INDEX 索引名称,即网站域名

#NAME 镜像的名称

#DESCRIPTION 镜像的描述信息

#STARS 镜像被下载的次数

#OFFICIAL 是否是docker官方开发的

#AUTOMATED 是否自动构建镜像

镜像busybox,需要指定名字和标签,导出到/root目录下,名称为busybox.tar

[root@kube-node1 ~]$ docker save docker.io/busybox:latest -o /root/busybox.tar

拷贝备份镜像到其他机器上

[root@kube-node1 ~]$ scp /root/busybox.tar 192.168.1.22:/root/

docker load -i busybox.tar

四、第一个容器

运行容器

镜像名称:镜像标签这种形式,可以指定唯一的镜像,防止镜像名相同,内容不同的情况,latest为默认标签,创建镜像时,不指定标签,则为此默认标签

+run = 创建 + 启动 +进入,docker run 命令: 运行过程中,会先根据镜像来创建容器,然后会启动容器,最后进入容器

帮助文档:查看 run 的参数: docker help run man docker-run

参数: -i 交互式,-t终端,-d 后台运行, --name 容器名字 :docker run -it docker.io/centos:lasest /bin/bash(#/bin/bash为容器内的命令,容器内存在,才可以使用)

五、docker 镜像管理

镜像管理命令

查看镜像: docker images

查找镜像 docker search

删除镜像 docker rmi 镜像名称:镜像标签 && docker image rm fd1c5f7b6816

下载镜像 docker pull 镜像名称: 镜像标签

上传镜像 docker push 要上传的镜像名称: 镜像标签

备份镜像 docker save 镜像名称: 镜像标签 -o 备份文件名称

恢复镜像 docker load -i 备份文件名称

查看镜像的制作历史 docker history 镜像名称: 镜像标签

查看镜像的信息 docker inspect 镜像名称: 镜像标签

镜像的新名称和标签 docker tag 镜像名称: 镜像标签 新镜像名称: 新的标签

六、docker 容器管理

常用容器管理命令

启动容器 docker run -参数 镜像名称:镜像标签 启动命令

查看容器 docker ps [ -a 所有容器id ] [ -q 只显示容器 id ]

删除容器 docker rm 容器id、

容器管理启动 docker start 容器id

容器管理停止 docker stop 容器id

容器管理重启 docker restart 容器id

查看容器进程 docker top 容器id

查看容器信息 docker inspect 容器id

连接容器启动进程 docker attach 容器id

attach 以上帝进程的身份,进入容器内部,使用attach进入容器,是上帝进程的身份进入容器的,当执行exit退出容器时,会结束整个容器,查看进程树,systemd就是上帝进程,即:系统服务的最初进程,所有的进程都是在上帝进程下创建的;当systemd进程被结束时,整个系统也就会崩溃通常用于在测试时,查看报错信息;

连接容器,启动新进程 docker exec -it 容器id 命令

在对容器的使用过程中,都是使用exec,新开一个进程的方式进入容器,进行编辑的;而attach 往往应用于调试,终端输出的情况;

七,自定义镜像

commit 自定义镜像

自定义镜像原理 :镜像采用分层设计:1,创建读写层 2,修改配置 3,重新打包

使用镜像启动容器,在该容器基础上修改,另存为一个新镜像

docker run -it docker.io/centos:latest /bin/bash

配置 yum,安装软件,系统配置

docker commit 容器id 新镜像名称: 新镜像标签

############## 创建一个centos的容器,在kube-node1上操作 ############## ##查看所有的镜像 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox test 6858809bf669 5 weeks ago 1.232 MB docker.io/busybox latest 6858809bf669 5 weeks ago 1.232 MB docker.io/redis latest 82629e941a38 21 months ago 4.98 MB docker.io/nginx latest 42b4762643dc 21 months ago 109.2 MB docker.io/ubuntu latest 20bb25d32758 21 months ago 87.47 MB docker.io/centos latest 76d6bc25b8a5 2 years ago 199.7 MB ##-it 以交互式终端的方式,根据centos镜像启动一个容器 ##/bin/bash 为容器内的命令,容器内存在,才可以使用 [root@kube-node1 ~]# docker run -it docker.io/centos:latest /bin/bashh ################ 容器内安装yum, 在kube-node1上操作 ############## #清除网络yum文件,配置本地yum [root@d76e8f39e026 /]# rm -rf /etc/yum.repos.d/* [root@d76e8f39e026 /]# vi /etc/yum.repos.d/centos7.repo [centos] name=centos7.5 baseurl=http://192.168.1.100/centos-1804 enabled=1 gpgcheck=0 ##清空缓存,重新加载配置 [root@d76e8f39e026 /]# yum clean all [root@d76e8f39e026 /]# yum repolist ........ Determining fastest mirrors centos | 3.6 kB 00:00 (1/2): centos/group_gz | 166 kB 00:00 (2/2): centos/primary_db | 5.9 MB 00:00 repo id repo name status centos centos7.5 9911 repolist: 9911

################ 容器内安装基础工具软件包, 在kube-node1上操作 ############## ##安装基础工具软件包 [root@d76e8f39e026 /]# yum -y install net-tools psmisc iproute vim bashcompletion tree ##清除yum缓存,减小容器大小,用于镜像制作 [root@d76e8f39e026 /]# yum clean all ##退出容器,主机名就是容器的ID号 [root@d76e8f39e026 /]# exit

################# commit自定义镜像,在kube-node1上操作 ############## ##commit 提交容器,生成新的镜像;此ID为容器的ID号 [root@kube-node1 ~]# docker commit d76e8f39e026 myos:latest sha256:10a665c54e587d47756a00058abef86ef6b329b44937aaea34376482c9410878 ##myos镜像,就是新生成的镜像 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myos latest 10a665c54e58 About a minute ago 317.8 MB ........

使用 docker run 验证新的镜像

############## 验证新的镜像,在kube-node1上操作 ############## ##查看历史镜像,多出一个镜像层 [root@kube-node1 ~]# docker history myos:latest IMAGE CREATED CREATED BY SIZE COMMENT 10a665c54e58 3 minutes ago /bin/bash 118.1 MB ....... ##使用新的镜像生成一个容器,容器的yum已经部署,验证成功 [root@kube-node1 ~]# docker run -it myos:latest /bin/bash [root@5dbc2153d039 /]# yum repolist Loaded plugins: fastestmirror, ovl Loading mirror speeds from cached hostfile repo id repo name status centos centos7.5 9911 repolist: 9911

Dockerfile 自定义镜像

语法

FROM:基础镜像

RUN:制作镜像时执行的命令,可以有多个

ADD:复制文件到镜像,自动解压 (文件类型为: tar.gz 或 tar.bz2)

COPY:复制文件到镜像,不解压

MAINTAINER:镜像创建者信息

EXPOSE:开放的端口

ENV:设置变量

WORKDIR:定义容器默认工作目录

CMD: 容器启动时执行的命令,仅可以有一条CMD.

ENTRYPOINT:类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一具单独的可执行程序

与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。不过,docker run命令的–entrypoint 选项的参数可覆盖ENTRYPOINT指令指定的程序

Dockerfile 案例1

配置 yum、安装软件

FROM docker.io/centos:latest RUN rm -f /etc/yum.repos.d/* COPY local.repo /etc/yum.repos.d/local.repo RUN yum install -y bash-completion net-tools iproute psmisc

创建镜像

使用 Dockerfile 工作流程,根据Dockerfile生成新的镜像,build创建新的镜像;-t指定新镜像的名字和标签;. 指定Dockerfile文件所在的目录

mkdir build

cd build

编写 Dockerfile

########### 获取制作镜像的历史命令,在kube-node1上操作 ############## ##利用myos镜像,创建一个容器,可以查看之前制作镜像的历史命令 [root@kube-node1 ~]# docker run -it myos:latest docker build -t imagename Dockerfile 所在目录 [root@096875f0df8d /]# history 1 rm -rf /etc/yum.repos.d/* 2 vi /etc/yum.repos.d/centos7.repo 3 yum clean all 4 yum repolist 5 yum -y install net-tools psmisc vim iproute vim bash-completiono tree 6 exit 7 history ##exit 退出,并关闭容器 [root@096875f0df8d /]# exit

########## 制作Dockerfile自动创建镜像脚本,在kube-node1上操作 ############## ##创建一个目录,名称任意定义 [root@kube-node1 ~]# mkdir aa ##进入到aa目录下 [root@kube-node1 ~]# cd aa/ ##创建Dockerfile文件,文件名不能改变 [root@kube-node1 ~]# touch Dockerfile ##复制repo文件到aa目录下,用户Dockerfile中的文件复制 [root@kube-node1 aa]# cp /etc/yum.repos.d/centos7.repo . ##编写Dockerfile文件,文件名不能改变 ##Dockerfile中所有的指令,必须是大写的(例如: FROM, RUN, COPY等) #FROM 指定基础镜像,Dockerfile会对基础镜像进行编辑,生成新的镜像 #RUN 指定制作命令, 一条RUN,就代表一条要在容器内执行的命令 #COPY 复制,#即把当前目录下的文件,拷贝到容器内 [root@kube-node1 aa]# vim Dockerfile FROM docker.io/centos:latest RUN rm -rf /etc/yum.repos.d/* COPY centos7.repo /etc/yum.repos.d/centos7.repo RUN yum -y install net-tools psmisc vim iproute vim bash-completiono tree && yum clean all

docker build -t imagename Dockerfile 所在目录

########### 根据Dockerfile生成新的镜像,在kube-node1上操作 ############ ##build 创建新的镜像;-t 指定新镜像的名字和标签;. 指定Dockerfile文件所在的目录 [root@kube-node1 aa]# docker build -t newos:latest . Sending build context to Docker daemon 3.072 kB Step 1 : FROM docker.io/centos:latest ---> 76d6bc25b8a5 Step 2 : RUN rm -rf /etc/yum.repos.d/* ---> Running in ade538eaf11c ---> a934f7feea65 Removing intermediate container ade538eaf11c Step 3 : COPY centos7.repo /etc/yum.repos.d/centos7.repo ---> bd5e3914cda6 Removing intermediate container 80ea3d53088e Step 4 : RUN yum -y install net-tools psmisc vim iproute vim bash-completiono tree && yum clean all ........ ##查看本地仓库镜像,newos创建成功 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE newos latest fb3d85796504 33 minutes ago 280.8 MB myos latest 10a665c54e58 58 minutes ago 317.8 MB .......

八,Dockerfile 入门

Dockerfile 创建服务镜像

Dockfile中,不指定CMD时,则使用默认的启动命令;如果没有使用CMD指定启动命令,则会继承上一个镜像的默认启动命令;CMD 容器的默认启动命令,有且只能有一条;

FROM myos:latest MAINTAINER Jacob redhat@163.com RUN yum -y install httpd ENV LANG=C WORKDIR /var/www/html/ EXPOSE 80 443 CMD ["httpd", "-DFOREGROUND"]

######## WORKDIR 在Dockerfile中用于定义容器默认工作目录 ########### #使用ssh远程执行以下三条命令,f1和f2文件,最终都是创建在/root目录下 #因为每次ssh连接都是代表不同的连接,无法保持上次连接时,命令的执行状态 [root@localhost ~]# ssh host1 touch f1 [root@localhost ~]# ssh host1 cd /tmp [root@localhost ~]# ssh host1 touch f2 ##### Dockerfile和ssh类似,所以要使用 WORKDIR容器默认工作目录的指定 #####

###### 使用myos镜像创建一个容器,在kube-node1上操作 ############ ##查看本地仓库镜像,myos镜像已经部署好了yum和基本软件包 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myos latest 10a665c54e58 58 minutes ago 317.8 MB ....... ####-it 以交互式终端的方式,根据centos镜像启动一个容器 ##/bin/bash 为容器内的命令,容器内存在,才可以使用,不指定则会选择默认容器命令 [root@kube-node1 ~]# docker run -it myos:latest /bin/bash [root@a670096c60ad /]#

############ 部署并启动apache服务,在kube-node1上操作 ############ ####安装apache的服务软件httpd [root@a670096c60ad /]# yum -y install httpd #因为容器内并没有systemd的服务,无法使用systemctl来启动httpd的服务 #查看httpd的服务文件,获取环境变量文件和服务启动命令 [root@a670096c60ad /]# cat /lib/systemd/system/httpd.service ........ [Service] ........ #环境变量文件 EnvironmentFile=/etc/sysconfig/httpd #启动命令,$OPTIONS 此环境变量为空,可以不用写 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ........ ####从环境变量文件中,获取环境变量 [root@a670096c60ad /]# vim /etc/sysconfig/httpd ...... LANG=C ####设置环境变量 [root@a670096c60ad /]# LANG=C #启动httpd服务,$OPTIONS 此环境变量为空,可以不用写 #Ctrl + C 退出 [root@54cb8bfa063d /]# /usr/sbin/httpd -DFOREGROUND AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message

########## 制作Dockerfile自动创建镜像脚本,在kube-node1上操作 ########### ##创建一个目录,名称任意定义 [root@kube-node1 ~]# mkdir bb ##进入到aa目录下 [root@kube-node1 ~]# cd bb/ ##创建Dockerfile文件,文件名不能改变 [root@kube-node1 ~]# touch Dockerfile ##Dockerfile中所有的指令,必须是大写的(例如: FROM, RUN, COPY等) #FROM 指定基础镜像,Dockerfile会对基础镜像进行编辑,生成新的镜像 #MAINTAINER 指定创建镜像者的信息 #RUN 指定制作命令, 一条RUN,就代表一条要在容器内执行的命令 #ENV 指定环境变量 #EXPOSE 开启httpd服务要使用的端口,80和443 #WORKDIR 指定启动容器后的,默认工作目录 #ADD 指拷贝,Dockerfile目录下的文件,拷贝到容器内(tar.gz,tar.bz2格式会自动解压) #CMD 指定默认启动命令,格式示例:#ls -la 则: CMD ["ls", "-l", "-a"] [root@kube-node1 bb]# vim Dockerfile FROM myos:latest MAINTAINER tarena RUN yum -y install httpd ENV LANG=C EXPOSE 80 443 WORKDIR /var/www/html ADD index.html /var/www/html/index.html CMD ["/usr/sbin/httpd","-DFOREGROUND"]

############ 创建apache的默认访问页面,在kube-node1上操作 ############## [root@kube-node1 bb]# echo "hello world" > index.html

创建服务镜像:docker build -t myos:httpd

########## 使用Dockerfile文件,创建新的镜像,在kube-node1上操作 ########## ##build 创建新的镜像;-t 指定新镜像的名字和标签;. 指定Dockerfile文件所在的目录 [root@kube-node1 bb]# docker build -t myos:httpd . Sending build context to Docker daemon 3.072 kB Step 1 : FROM myos:latest ---> 10a665c54e58 Step 2 : RUN yum -y install httpd ---> Running in b3226773e826 .......

运行容器验证服务

dockeer run -itd myos:httpd

docker inspect 容器id

curl http://ip.xx.xx.xx/ 验证结果

############# 验证查看镜像,在kube-node1上操作 ############# ##查看镜像,myos:httpd 镜像创建成功 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myos httpd 019f5b48a5a0 About a minute ago 372.4 MB ...... ##使用myos:httpd 镜像,创建一个容器 [root@kube-node1 ~]# docker run -itd myos:httpd 800b21aa9736bd68a521e7d5667835710b24829a136c5a0baa3e24cc319d3b70 ##查看正在使用的容器 [root@kube-node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 800b21aa9736 myos:httpd "/usr/sbin/httpd -DFO" About a minute ago Up About a minute 80/tcp, 443/tcp reverent_thompson ##查看容器的详细信息 [root@kube-node1 ~]# docker inspect 800b21aa9736 ........ ........ ########## ENV中, PATH 指定可执行文件的搜索路径,为命令的默认查找路径 ########### ############# 如果没有指定PATH,则执行所有命令,都需要指定绝对路径 ########### "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "LANG=C" ], ############# Cmd 默认的启动命令,即:启动容器时,默认的启动命令 ############# "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"/usr/sbin/httpd\" \"-DFOREGROUND\"]" ], ........ ........ "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "b0cf7b16b65e272fa685ac975bce1f13647379beb8e22191d6623e30817829bc", "EndpointID": "f010d043874446d28892fa52903165f7370cccbc7cf449d325ad07c1c58fe6c4", ################## 容器的网关和IP地址 ######################### "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02" ........ ........

####### 根据容器的IP地址,访问容器内的httpd服务,在kube-node1上操作 ######## ##访问容器内的apache服务 [root@kube-node1 ~]# curl http://172.17.0.2 hello world

九、私有仓库

安装部署私有仓库

安装私有仓库(服务端) yum install docker-distribution

启动私有仓库,并设置开机自启动 :systemctl start docker-distribution systemctl enable docker-distribution

私有仓库的配置:

仓库配置文件 /etc/docker-distribution/registry/config.yml

数据存储路径:/var/lib/registry

默认端口号:5000

我们可以通过 curl 命令访问仓库 curl http://仓库ip:5000/v2

docker主机修改配置文件 /etc/sysconfig/docker

允许非加密方式访问仓库 INSECURE_REGISTRY='--insecure-registry 仓库IP:5000'

docker仓库地址 ADD_REGISTRY='--add-registry 仓库IP:5000'

重启docker 服务 systemctl restart docker

十、外部存储卷

卷的用途

Docker容器不保持任何数据,重要数据请使用外部卷存储(数据持久化),容器可以挂在真实机目录或共享存储为卷

首先,Docker 是一个进程(随着机器的启动而运行,随着机器的停止而消失);

然后,所以Docker容器内不适合存放任何的数据,容易丢失;

最后,需要对Docker进行数据解耦(把Docker应用和数据存放进行分离);

将真实机目录挂载到容器中提供持久化存储,目录不存在就自动创建,目录存在就直接覆盖掉,多个容器可以映射同一个目录,来达到数据共享的目的

启动容器时,使用 -v 参数映射卷 docker run -it -v 真实目录: 容器内目录 docker.io/centos: latest

有多台 docker 主机的情况下,我们也可以使用共享存储,来作为docker的卷服务,可以实现多主机之间多容器的共享卷服务

十一,发布 docker 服务

怎么访问 docker 服务

默认容器可以访问宿主机,但外部网络的主机不可以访问容器内的资源,解决这个问题的最佳方法是端口绑定,容器可以与宿主机的端口进行绑定,从而把宿主机变成对应的服务。宿主机和容器内部的服务端口绑定以后,用户在访问宿主机的服务端口时,就是在访问容器内部的服务

我们使用 -p参数把容器端口和宿主机端口绑定 -p 宿主机端口: 容器端口

例如:把宿主机变成 httpd

docker run -itd -p 80:80 docker.io/myos:httpd

例如:把宿主机变成nginx

docker run -itd -p 80:80 docker.io/nginx:latest

Podman(podmanager):

是一个功能齐全的容器引擎,它是一个简单的无需守护的用来管理镜像、容器的工具。Podman提供了一个与Docker CLI兼容的操作方式,简单地说:alias docker=podman。大多数Podman命令都可以普通用户运行,而无需其他额外的权限。

图片

指的是针对应用所需的运行环境资源(依赖库/目录/网络/用户……等)进行整体封装的技术。封装好的镜像相比虚拟机的粒度要更细,可移植性强。每个容器采用沙箱机制,相互隔离。

传统虚拟化与容器技术对比:

图片

仓库=》镜像=》容器 的关系:

仓库:用来提供/存放镜像,有官方仓库(比如红帽的registry.redhat.io、刀客的docker.io),或自建私有仓库。

镜像:针对某个虚拟机或某个应用封装的独立环境,作为容器的模板。

容器:基于某个镜像启动的在内存中运行的实例。

图片

# yum module install -y container-tools //安装容器工具及其模块配置 # yum install -y podman-docker //安装docker兼容包(可选)

1)设置默认的仓库地址(全局配置)

可以使用官方仓库(比如registry.access.redhat.com)、第三方仓库(比如docker.io),或者私有仓库(比如registry.lab.example.com)。

# vim /etc/containers/registries.conf [registries.search] registries = ['registry.lab.example.com'] //设置搜索镜像的默认仓库地址 .. .. [registries.insecure] registries = ['registry.lab.example.com'] //允许访问不安全的仓库(比如HTTPS证书无效或过期等情况) .. ..

2)登录仓库(如果需要的话,比如push上传镜像时)

# podman login registry.lab.example.com Username: admin Password: *********** Login Succeeded!

3)搜索仓库中的镜像(比如nginx)

# podman search nginx INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED example.com registry.lab.example.com/library/nginx

1)下载镜像到本地

# podman pull registry.lab.example.com/library/nginx .. .. //容器存储默认工作目录 /var/lib/containers/

2)查看镜像

# podman images //列出本地镜像 REPOSITORY TAG IMAGE ID CREATED SIZE registry.lab.example.com/nginx latest 4bb46517cac3 3 months ago 137 MB # podman image inspect 4bb4 //查看xxxx镜像的详细配置信息 .. ..

3)导出/备份镜像

# podman save nginx > /root/nginx.tar

4)导入镜像

# podman load -i /root/nginx.tar nginx-new:latest

5)删除镜像

# podman rmi xxxx //删除ID为xxxx的镜像 # podman rmi -a //删除所有镜像

1)在后台启动一个容器(-d 后台运行)

# podman run -d registry.lab.example.com/library/nginx 80b22e7bd4d789773223f5afc85808ea472e82ec72f162903cd658ed6d98091c # podman ps //列出启用中的容器(结合-a选项可以列出所有) .. .. # podman container inspect 4bb4 //查看xxxx容器的详细信息 .. ..

2)新启动一个容器并执行其中的命令“cat /etc/os-release”,然后删除此容器

# podman run --rm registry.lab.example.com/library/nginx cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 10 (buster)" NAME="Debian GNU/Linux" .. ..

3)启动一个容器,并进入容器内的/bin/bash命令行环境(-i 允许交互,-t 开启终端)

# podman run -it registry.lab.example.com/library/nginx /bin/bash root@840b592a6d3f:/# nginx -v //检查nginx版本 nginx version: nginx/1.19.2 root@840b592a6d3f:/# ls /usr/share/nginx/html/ //检查网页目录 50x.html index.html root@840b592a6d3f:/# exit //退出容器 exit #

4)在后台启动一个nginx容器,添加端口映射(-p 本地端口:容器端口)

[root@red ~]# podman run -d -p 8000:80 nginx 2b9ef8c0864149e2cf7860e903e36ba9deaa1717863f172b2bf2e5c5f3f6600c [root@red ~]# podman ps //列出活动中的容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2b9ef8c08641 registry.lab.example.com/library/nginx:latest nginx -g daemon o... 2 minutes ago Up 2 minutes ago 0.0.0.0:8000->80/tcp ecstatic_maxwell .. .. [root@red ~]# curl http://127.0.0.1:8000 //通过主机端口访问容器中的web站点 Welcome to nginx! .. ..

5)在后台启动一个nginx容器,将主机的/opt/webroot映射为此nginx容器的web目录(-v 本地目录:容器内目录)【持久存储】

# mkdir /opt/webroot //准备网页目录 # echo "Podman Test" > /opt/webroot/index.html //准备默认测试网页 # podman run -d -p 8001:80 -v /opt/webroot:/usr/share/nginx/html nginx ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca # curl http://127.0.0.1:8001 //测试结果 Podman Test

1)连接到ID值以ba64开头的(或者以-l表示最近一个容器)容器的命令行

[root@red ~]# podman exec -it ba64 bash root@ba64a15abdce:/# service nginx status [ ok ] nginx is running. root@ba64a15abdce:/# exit exit [root@red ~]#

2)检查容器的IP地址

[root@red ~]# podman inspect ba64 | grep IPAddress .. .. "SecondaryIPAddresses": null, "IPAddress": "10.88.0.6", .. ..

3)从主机向ID值为ba64的(或者以-l表示最近一个容器)容器传输文件

[root@red ~]# echo AAAA > /root/a.html //建立测试网页 [root@red ~]# podman cp /root/a.html ba64:/usr/share/nginx/html/a.html //复制文件到容器 [root@red ~]# curl http://127.0.0.1:8001/a.html //确认结果 AAAA

4)通过映射端口访问容器中的Web服务

[root@red ~]# curl http://localhost:8001/ //浏览8001端口访问目标容器首页 Podman Test [root@red ~]# curl http://localhost:8001/a.html //浏览指定页面 AAAA

1)关闭/杀死ID值为ba64的容器

[root@red ~]# podman stop ba64 //若要杀容器改用kill ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca [root@red ~]# podman ps -a | grep ba64 //检查容器状态 ba64a15abdce registry.lab.example.com/library/nginx:latest nginx -g daemon o... 47 minutes ago Exited (0) 25 seconds ago 0.0.0.0:8001->80/tcp dreamy_swirles

2)重新启动被关闭的ID值为ba64的容器

[root@red ~]# podman start ba64 //启用已关闭的xx容器 ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca [root@red ~]# podman ps -a | grep ba64 //检查容器状态 ba64a15abdce registry.lab.example.com/library/nginx:latest nginx -g daemon o... 48 minutes ago Up 2 seconds ago 0.0.0.0:8001->80/tcp dreamy_swirles

3)强制删除ID值为ba64的容器

[root@red ~]# podman rm -f ba64 //删除已关闭的xx容器(如果不加-f,则需要先stop此容器) ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca [root@red ~]# podman ps -a | grep ba64 //检查删除结果(无输出) [root@red ~]#

1)启动一个容器,命名为myweb

[root@red ~]# podman run --name myweb -d -p 80:80 -v /opt/webroot:/usr/share/nginx/html nginx 52e6996bef86c501731115216c84a2f48d1a03f8c1a2cad70d27e281bd642b18

2)为名称为myweb的容器创建对应的systemd服务配置

[root@red ~]# cd /etc/systemd/system/ //进入服务配置目录 [root@red system]# podman generate systemd -n myweb --files /etc/systemd/system/container-myweb.service

3)更新systemd服务配置

[root@red system]# systemctl daemon-reload

4)配置congtainer-myweb服务开机自启

[root@red system]# systemctl enable container-myweb Created symlink /etc/systemd/system/multi-user.target.wants/container-myweb.service → /etc/systemd/system/container-myweb.service.

5)关闭当前运行的容器

[root@red system]# podman stop 52e6 52e6996bef86c501731115216c84a2f48d1a03f8c1a2cad70d27e281bd642b18

6)重启主机后,检查是否可以访问此web

[root@red system]# reboot .. .. [root@server1 ~]# curl http://172.25.0.26/ Podman Test

通过rootless无根模式,非特权用户也可以很方便的运行容器(允许开启1024以上端口),以提高服务管理的安全性。

!!! 确认非特权用户的起始可用端口(需要时可更改)

# cat /proc/sys/net/ipv4/ip_unprivileged_port_start 1024

使用systemctl --user会话时,注意要直接以普通用户SSH或console控制台登录,不要使用su或sudo的方式执行。

1)配置仓库

可参考man containers-registries.conf手册,

如果已经在/etc/containers/registries.conf 文件全局设置过,这里可以不做。

[zaniu@red ~]$ mkdir -p ~/.config/containers [zaniu@red ~]$ vim ~/.config/containers/registries.conf unqualified-search-registries = ['registry.lab.example.com'] [[registry]] location = "registry.lab.example.com" insecure = true //允许访问不安全的仓库(全局配置中也需要添加仓库地址) blocked = false

2)下载(或导入)镜像

[zaniu@red ~]$ podman login registry.lab.example.com //登录仓库(如果仓库要求的话) Username: admin Password: Login Succeeded! [zaniu@red ~]$ podman pull registry.lab.example.com/library/nginx //下载镜像到本地 .. .. //用户容器存储默认工作目录 ~/.local/share/containers/ [zaniu@red ~]$ podman images //检查本地镜像 REPOSITORY TAG IMAGE ID CREATED SIZE registry.lab.example.com/library/nginx latest 4bb46517cac3 3 months ago 137 MB

2)启动一个名为xxnginx的容器(如果SELinux要求启用的话,可以通过:Z传递安全标签)

[zaniu@red ~]$ mkdir /home/zaniu/html [zaniu@red ~]$ echo zaniu > /home/zaniu//html/index.html [zaniu@red ~]$ podman run --name xxnginx -d -p 8080:80 -v /home/zaniu/html:/usr/share/nginx/html:Z nginx 8fa1bc2ccd14ddc57e187ffe8e0035b6bfb1c3189460b3470b3935365f5d9a85 [zaniu@red ~]$ curl http://127.0.0.1:8080 zaniu

3)创建container-xxnginx服务配置

[zaniu@red ~]$ mkdir -p ~/.config/systemd/user //创建用户服务配置目录 [zaniu@red ~]$ cd ~/.config/systemd/user //进入用户服务配置目录 [zaniu@red user]$ podman generate systemd --name xxnginx --files //生成container-xxnginx服务配置 /home/zaniu/.config/systemd/user/container-xxnginx.service

4)更新用户服务配置,设置开机自启动

[zaniu@red user]$ systemctl --user daemon-reload //更新用户服务配置 [zaniu@red user]$ systemctl --user enable container-xxnginx.service //配置自启动 Created symlink /home/zaniu/.config/systemd/user/multi-user.target.wants/container-xxnginx.service → /home/zaniu/.config/systemd/user/container-xxnginx.service. [zaniu@red user]$ loginctl enable-linger //允许为未登录的用户启动/保持后台服务 //如果linger方式无效,也可以通过用户计划任务实现开机自启动 [zhsan@red user]$ crontab -e @reboot systemctl --user start container-xxnginx.service

5)测试用户服务控制

【与云原生的故事】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/345260

Docker 云原生

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【docker系列】使用Dockerfile构建镜像
下一篇:为防止交通事故,95后学生运用“黑科技”这样做!
相关文章