可以实现在不同进程中看到不同的挂载目录,以及容器内只能看到自己的挂载信息,在容器内的挂载操作不会影响主机的挂载目录
在不同的 PID Namespace 中,进程可以拥有相同的 PID 号
可以让每个进程拥有自己独立的 IP 地址,端口和网卡信息。例如主机 IP 地址为 172.16.4.1 ,容器内可以设置独立的 IP 地址为 192.168.1.1
PID Namespace和IPC Namespace一起使用可以实现同一IPC Namespace内的进程彼此可以通信,不同IPC Namespace的进程却不能通信。
它允许每个UTS Namespace拥有一个独立的主机名
主机上以非root用户运行的进程可以在一个单独的User Namespace中映射成root用户。使用 User Namespace可以实现进程在容器内拥有root权限,而在主机上却只是普通用户。
Time Namespace 提供时间隔离能力
Syslog Namespace(没有合并到linux内核中) 提供syslog隔离能力
Control group Namespace 提供进程所属的控制组的身份隔离
docker常用查询命令
# docker version #显示docker client和docker server的版本信息
# docker info #显示系统信息
# docker inspect 容器ID #显示docker对象(镜像、网络、容器等)的详细信息
# docker stats #显示容器资源的实时统计信息
# docker diff 8ddf4ce923ef #对比容器和镜像有差异的文件或目录
# docker events #获取dockerd的实时事件,创建删除容器等操作
# docker logs -f nginx-container-test1 #持续查看容器标准输出和错误输出的日志
# docker port 81b344cff55d #列出一个容器端口映射关系镜像管理:
容器管理
第一种,使用yum进行安装(这里以centos为例)
1.安装必要的一些系统工具
#yum install -y yum-utils device-mapper-persistent-data lvm2 2.添加软件源信息
#yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo 3.更新并安装Docker-CE
#yum makecache fast yum -y install docker-ce 4,开启Docker服务
#service docker start 提示:
官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等
#vim /etc/yum.repos.d/docker-ce.repo 将[docker-ce-test]下方的enabled=0修改为enabled=1
1.安装指定版本的Docker-CE:
查找Docker-CE的版本:
2.安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
#yum -y install docker-ce-[VERSION] 其他l发行版参考:https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/
官方文档:https://docs.docker.com/engine/install/
第二种,使用rpm包安装(适合没有外网的环境下)
rpm安装需要先把所有依赖的包提前准备好,然后打包到服务器里,所以这里可以在一台能访问外网的机器,提前把包下载好。
1.安装必要的一些系统工具
#yum install -y yum-utils device-mapper-persistent-data lvm22.添加软件源信息
#yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo3.更新并安装Docker-ce
#yum makecache fast
#yum list docker-ce.x86_64 --showduplicates | sort -r #查找docker-ce版本4.下载所有安装依赖到指定路径下
#mkdir -vp /home/docker-rpm/
#yum install docker-ce-19.03.15-3.el7 --downloadonly --downloaddir=/home/docker-rpm/
--downloadonly --downloaddi #仅下载,不安装5.查看并打包下载的所有docker依赖包
#ll /home/docker-rpm/
#tar -czvf docker-ce-19.03-centos7.6-rpm.tar.gz docker-rpm/6.把压缩包上传到服务器解压并安装
#tar -xvf docker-ce-19.03-centos7.6-rpm.tar.gz
#cd docker-rpm
#yum -y localinstall *.rpm7.检验是否安装成功
docker version提示:rpm包安装,一般我们可以用脚本完成,包括二进制安装
官网rpm包下载地址:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
第三种,使用二进制安装
官网下载地址:https://download.docker.com/linux/static/stable/x86_64/
1.根据需求下载对应的二进制包,并解压到服务器
tar -xvf docker-19.03.0-ce.tgz2,修改权限
chown root:root docker/* 3,将解压出的docker目录下的可执行文件复制到/usr/bin
cp -p docker/* /usr/bin/4,创建docker用户组
groupadd -r docker 5,检查是否生效
docker version 6.配置相关服务文件(docker.socket、 containerd.service、 docker.service)
把三个准备好的文件拷贝到/usr/lib/systemd/system/
7,启动docker服务,并设置开机自启
8.查看进程
ps aux | grep docker 9.检验是否正确安装
docker pull hello-world docker run hello-world overlay : UnionFS文件系统,Linux内核3.18后支持
**overlay2(推荐使用) :**overlay的升级版,到目前为止,所有linux发行版都推荐使用的存储类型
**devicemapper:**是CentOS和RHEL的早期使用的存储驱动程序,因为之前的内核版本较低不支持overlay2,相对性能比较差
**vfs:**用于测试环境或者无法使用写时复制文件系统的情况下,性能较差,通常不推荐用于生产环境,
**ZFS(sun-2005)/btrfs(Oracle-2007):**目前没有广泛应用,这些文件系统允许使用高级选项,例如创建“快照”,但需要更多的维护和设置。并且每一个都依赖于正确配置的后备文件系统。需要大量内存,zfs对于高密度工作负载(例如PaaS)是个不错的选择
1.查看docker存储引擎
[root@localhost.localdomain ~]#docker info |grep "Storage Driver"
Storage Driver: overlay2修改docker存储引擎(不建议在生产环境修改),同时修改docker的数据目录
注意:更换存储引擎会重新初始化你的目录,数据会丢失,更换之前需要先备份好数据
2.加一块新磁盘,挂载上
mkfs.xfs /dev/vdc -n ftype=1
mount /dev/vdc /data3.把旧数据复制到新盘,再重启服务
systemctl daemon-reload
systemctl restart docker扩展:
1,devicemapper默认只使用100G的磁盘空间,需要额外去做配置修改,附带一个真实案例:
https://www.cnblogs.com/youruncloud/p/5736718.html
2,overlay2,overlay,支持的后端文件系统为xfs(ftype=1),ext4
3,新版的docker已经不支持overlay了,默认使用overlay2
4,centos7.2及以前的版本默认使用的devicemapper存储引擎,不能直接使用overlay,除非新添加一块磁盘作为docker的数据盘,并在格式化的时候指定参数-n ftype=1,否侧报错:without d_type support
1.-v的几种常用方式
1.1 把宿主的数据卷提供给容器挂载(可以是本地目录/文件,也可以是本地磁盘,共享存储),web2的ro表示在容器内对该目录只读,默认权限是可读写的
1.2 把宿主机的多个卷挂载到容器
docker run1.3 数据卷容器(把上面创建的web3容器的卷挂载继承给其他容器使用)
docker run -d --name web4 --volumes=from web3 -p 84:80 nginx:1.20.21.4 数据卷的使用场景:
1.5 数据卷的特点及使用:
2,-p的几种常用方式
2.1 把宿主机的80端口映射给容器的80端口
docker run -it -d -p 80:80 nginx:1.20.22.2 把宿主机IP为192.168.10.100的80端口映射给容器的80端口
docker run -it -d -p 192.168.10.100:80:80 nginx:1.20.22.3 把宿主机的80端口映射到容器的UDP80端口
docker run -it -d -p 80:80/udp nginx:1.20.22.4 把宿主机的80端口映射到容器的UDP80端口跟TCP80端口
docker run -it -d -p 80:80/udp -p 80:80/tcp nginx:1.20.22.5 把宿主机的多个端口同时映射到容器的多个端口
docker run -it -d -p 80:80 -p 443:443 nginx:1.20.2提示:-p 参数默认绑定tcp端口
容器跨主机通信实验:

1.准备两台主机
A:192.168.100.226
B:192.168.100.209
2.修改两台机器的docker默认子网范围
vi /lib/systemd/system/docker.service
systemctl daemon-reload
systemctl restart docker3.添加路由规则
注意:检查是否开启核心路由转发,net.ipv4.ip_forward = 1
A主机:
route add -net 20.20.20.0/24 gw 192.168.100.209B主机:
route add -net 10.10.10.0/24 gw 192.168.100.2264.修改iptables允许响应报文的转发(两台主机操作)
iptables -A FORWARD -s 192.168.100.0/24 -j ACCEPT5.两台主机分别运行一个容器,并测试ping
docker run -it centos:7.9.2009 bash
容器跨主机通信过程总结:
1.源容器产生请求报文发给网关docker0
2.docker0检查报文的目的IP,如何是本机就直接转发,如果不是本机就转发给宿主机。
3.源宿主机收到报文后检查路由表,将源地址替换为本机IP并发送报文。
1.创建并编辑一个Dockerfile
2.把ubuntu的源配置文件拷贝到对应目录里
3.下载nginx1.22.0
nginx官方下载地址:https://nginx.org/en/download.html
wget https://nginx.org/download/nginx-1.22.0.tar.gz4.构建
docker build -t harbor.magedu.com/m43/ubuntu22.04-nginx:1.22.0 .5.运行镜像并访问网址,测试是否正确构建
docker run -it --rm -p 80:80 harbor.magedu.com/m43/ubuntu22.04-nginx:1.22.0
服务端(harbor) :
1.去github下载安装包
安装包地址:https://github.com/goharbor/harbor/releases
第一步:把安装包解压到/usr/local/src/
2.搭建harbor需要的环境docker+docker-compose(这里用脚本安装)
解压完直接在目录里
./runtime-install.sh docker3.配置harbor.yml,启动harbor安装脚本
最后执行安装
./install.sh --with-clair #v2.2.0版本以下,可以用这个参数开启镜像扫描 --with-clair
./install.sh --with-trivy #harbor v2.2.0版本开始已经弃用clair了,改用trivy4.配置docker service的本地信任仓库
第一种方法:
第二种方法:
vim /etc/docker/daemon.json
"insecure-registries": ["harbor.magedu.com"],systemd对资源限制更严格、性能更好,因此在kubernetes环境推荐使用systemd进行资源限制
1.查看docker的cgroup驱动类型
docker info | grep "Cgroup Driver"
Cgroup Driver: cgroupfs2.修改cgroupfs为systemd
vi /etc/docker/daemon.json
添加 "exec-opts": ["native.cgroupdriver=systemd"]3.重启docker并查看cgroup驱动类型
systemctl
4.下载一个测试镜像来验证资源限制
docker pull lorel/docker-stress-ng
5.启动两个内存工作进程,每个内存工作进程最大允许使用内存256M,且宿主机不限制当前容器最大内存

6.限制容器最大内存为100M(参数 -m 100m )
7.限制容器CPU
7.1.只给容器分配最多0.5核宿主机CPU利用率 ( 参数 --cpus 0.5 )

提示:CPU资源限制是将分配给容器的0.5核心分配到了宿主机每一核心CPU上,也就是容器的总CPU值是在宿主机的每一个核心CPU分配了部分比例,且不一定是平均分配的。

7.2.将容器运行到指定的CPU上:
7.3基于cpu--shares值(共享值)对CPU进行限制,分别启动两个容器,magedu-c1的--cpu-shares值为1000,magedu-c2的--cpu-shares为500,观察最终效果,--cpu-shares值为1000的magedu-c1的CPU利用率基本是--cpu-shares为500的magedu-c2的两倍:
8.systemd限制验证(以ubuntu20.04为例)
8.1.创建一个nginx容器,并做cpu跟内存限制
docker run -it --rm --cpus 1.5 -m 256m -p8.2.过滤出目的容器的进程号
cat /proc/44483/cpuset
8.3.查询进程的限制
cat /proc/44483/cpuset
8.4.查询cpu限制范围
cat /sys/fs/cgroup/cpu/system.slice/docker-c47a55b3ac4f74be1a5de02a8305d1df34503c4f93559d8c24086b48569cbd18.scope/cpu.cfs_quota_us
8.5.查询内存的限制范围
cat /sys/fs/cgroup/memory/system.slice/docker-c47a55b3ac4f74be1a5de02a8305d1df34503c4f93559d8c24086b48569cbd18.scope/memory.limit_in_bytes
memory.limit_in_bytes显示的是字节数,通过换算为256M
补充:
在ubuntu22.04版本中,cpu的限制范围如下:
cat /sys/fs/cgroup/system.slice/docker-容器ID.scope/cpu.max在ubuntu22.04版本中,内存限制范围如下:
cat /sys/fs/cgroup/system.slice/docker- 容器ID.scope/memory.max扩展:
一,总结镜像的分层构建流程
1. 先构建一个基础镜像baseimage,包括系统的发行版,以及一些必要的工具
2. 以baseimage为父镜像,安装jdk/ningx/tomcat等,构建基本的业务环境镜像
3. 以业务环境镜像为父镜像,上传代码文件,构建业务镜像
4. 通过业务镜像运行容器,实现业务部署二,总结基于lxcfs对容器的内存及CPU的资源限制
1,使用lxcfs需要先安装
ubuntu系统:
apt install lxcfs -ycentos系统:https://github.com/lxc/lxcfs
2,限制内存为指定大小
3,限制只能使用1核cpu并绑定至id为2的cpu核心
总结:
容器内⾥⾯是从/proc/cpuinfo中获取到 CPU 的核数,但是容器⾥⾯的/proc⽂件系统是物理机的,内存也是显示的宿主机的/proc/meminfo的信息,因此不准确,⽽lxcfs 则是通过⽂件挂载的⽅式,把宿主机cgroup中关于系统的相关信息读取出来,通过docker的volume挂载给容器内部的proc系统,然后让docker内的应⽤读取proc中信息的时候就是读取的容器的真实的proc。
三,harbor高可用的实现
haproxy官网文档:http://cbonte.github.io/haproxy-dconv/2.4/configuration.html#3
架构图:
http的harbor做镜像复制,
1,先做仓库复制,然后测试连接性(另一个harbor做同样的操作,URL指向对方)
2,新建规则(另一个harbor也做同样同步操作)
3,在客户端上传镜像到其中一台harbor
[root@docker]# docker pull ubuntu
[root@docker]# docker tag ubuntu:latest qbnharbor.top/baseimages/ubuntu:666
[root@docker]# docker push qbnharbor.top/baseimages/ubuntu:666上传后看两台harbor是否同步了ubuntu:666镜像
https://github.com/containerd/containerd
https://github.com/opencontainers/runc/
1.1.apt/yum安装
yum安装containerd
apt安装containerd:
1.2.二进制安装containerd
下载二进制包,解压并把程序放到/usr/local/bin/
创建service文件跟containerd配置文件

ExecStart=/usr/local/bin/containerd #换成你对应二进制文件的路径
修改containerd配置文件
重启containerd
systemctl enable containerd
systemctl restart containerd部署runc
wget https://github.com/opencontainers/runc/releases/download/v1.1.5/runc.amd64
chmod +x runc.amd64
mv runc.amd64下载测试镜像并验证
ctr客户端创建测试容器
ctr run -t --net-host docker.io/library/alpine:latest test-container
1.3.安装nerdctl(推荐使⽤的containerd客户端工具
https://github.com/containerd/nerdctl #nerdctl下载地址
1.4.安装CNI
1.创建一个ubuntu:22.04容器
nerdctl run ubuntu:22.042.创建Nginx测试容器并指定端⼝
nerdctl run -d -p 80:80 nginx:1.20.23.创建Tomcat测试容器并指定端⼝
nerdctl run -d -p 8080:8080 tomcat4.创建MySQL测试容器并指定端⼝
https://goharbor.io/docs/2.6.0/install-config/configure-https/ #官方文档
去github下载harbor安装包
安装包地址:https://github.com/goharbor/harbor/releases
创建/apps目录,把安装包解压到/apps
mkdir /apps
签发证书
第一种方式(自签发)
自建 CA,用于后续的 harbor 做证书签发
去到harbor目录,拷贝harbor文件并配置
3.8,执行harbor安装脚本
./install.sh --with-trivy创建一个业务镜像构建目录
https://github.com/docker/compose #二进制包地址
https://docs.docker.com/compose/compose-file/compose-versioning/ #官方文档ompose单机编排运行Nginx+Java APP+MySQL服务
下载二进制文件到服务器
wget https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-linux-x86_64给二进制文件执行权限
chmod +x docker-compose-linux-x86_64 复制二进制文件到/usr/bin/
cp -p docker-compose-linux-x86_64 /usr/bin/docker-compose检查版本
docker-compose version创建一个目录编辑docker-compose的yml文件
运行docker-compose运行容器
docker-compose up -d# docker images #查看本地所有镜像
# docker search nginx #搜索镜像
# docker pull nginx:1.20.2 #从镜像仓库下载镜像
# docker build #从dockerfile 构建镜像
# docker history centos:7.9.2009 #查看的镜像的构建历史
# docker login #登录镜像仓库
# docker logout #登出镜像仓库
# docker tag nginx:1.20.2 harbor.magedu.net/myserver/nginx:1.20.2 #为镜像添加一个新的tag
# docker push nginx:1.20.2 #从本地上传镜像到镜像仓库(需要登录认证)
# docker rmi -f 53ec353d8dc4 90a4cd9dfe4c #删除一个或多个镜像
# docker save 50fe74b50e0d > nginx-1.20.2.tar.gz #保存一个或多个镜像到一个压缩文件(默认是标准输出)
# docker load -i nginx-1.20.2.tar.gz #从一个tar包或标准输入导入镜像
# docker export 8ddf4ce923ef -o new-nginx-image.tar.gz #将容器的文件系统导出为一个本地压缩包,非镜像格式
# docker import new-nginx-image.tar.gz #导入export导出的压缩包,导入后的镜像不完整,不能用于创建容器
# docker commit -a "qbn" -m "v2" --change="EXPOSE 80 443" 8ddf4ce923ef new-nginx-image #将容器提交为一个本地镜像# docker ps #列出容器,加上-a是列出包含为运行的所有容器
# docker create -it --name test1 nginx:1.20.2 #创建一个新的容器且创建后的容器处于退出状态
# docker run -it docker.io/centos bash #创建并进入容器,ctrl+p+q退出容器不注销
# docker run -d -p 80:80 --name nginx-container-test1 nginx:1.20.2 #后台运行容器
# docker run -it --rm --name nginx-delete-test nginx:1.20.2 bash #单次运行容器
# docker run -p 80:80/tcp -p 443:443/tcp -p 53:53/udp --name nginx-container-test1 nginx:1.20.2 #创建容器并指定多端口映射
# docker run -it --name nginx-test1 nginx:1.20.2 #自定义容器名称
# docker run -it -d centos:7.9.2009 /usr/bin/tail -f '/etc/hosts' #创建容器的时候传递命令及参数
# docker run -it centos:7.9.2009 ## docker attach 63fbc2d5a3ec #attach进入容器后操作会在多窗口同步且退出后其它终端也会一起退出。
# docker exec -it 40e6379cf371 sh/bash #推进入到容器执行命令操作,推荐使用此方式
# docker kill $(docker ps -a -q) 强制关闭所有运行中的容器
# docker rm -f 11445b3a84d3 #强制删除运行中的容器
# docker rm -f `docker ps -aq -f status=exited` #批量删除已退出容器
# docker rm -f $(docker ps -a -q) #批量删除所有容器
# docker cp 源 目的 #从容器和宿主机相互拷贝文件或目录
# docker rename awesome_cerf nginx-container1 #重命名容器
# docker start ID/容器名称 #启动一个或多个容器
# docker stop ID/容器名称 #停止一个或多个容器
# docker restart ID/容器名称 #重启容器
# docker pause 81b344cff55d #暂停一个或者多个容器
# docker unpause 81b344cff55d #取消一个或多个容器的暂停
# docker update 容器 --cpus 2 #更新容器配置信息,比如资源限制的值
# docker wait #一直等待容器退出并显示容器的退出状态码# yum list docker-ce.x86_64 --showduplicates | sort -r
\# Loading mirror speeds from cached hostfile
\# Loaded plugins: branch, fastestmirror, langpacks
\# docker-ce.x86_64 17.03.1.ce-1.el7.centos docker-ce-stable
\# docker-ce.x86_64 17.03.1.ce-1.el7.centos @docker-ce-stable
\# docker-ce.x86_64 17.03.0.ce-1.el7.centos docker-ce-stable
\# Available Packages[root@localhost.localdomain ~]#cat containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
[root@localhost.localdomain ~]#cat docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
[root@localhost.localdomain ~]#cat docker.socket
[Unit]
Description=Docker Socket for the API
PartOf=docker.service
[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.targetcp docker.socket /usr/lib/systemd/system/
cp docker.service /usr/lib/systemd/system/
cp containerd.service /usr/lib/systemd/system/
chmod a+x /usr/lib/systemd/system/docker.service
chmod a+x /usr/lib/systemd/system/docker.socket
chmod a+x /usr/lib/systemd/system/containerd.servicesystemctl enable containerd.service && systemctl restart containerd.service
systemctl enable docker.service && systemctl restart docker.service
systemctl enable docker.socket && systemctl restart docker.socket vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://05eotbde.mirror.aliyuncs.com"],
"storage-driver": "overlay",
"data-root":"/data"
}
把overlay替换成你要修改的存储引擎,添加 "data-root":"/data"docker run -d --name web1 -v /data/testapp:/usr/share/nginx/html/testapp -p 80:80 nginx:1.20.2
docker run -d --name web2 -v /data/testapp:/usr/share/nginx/html/testapp:ro -p 81:80 nginx:1.20.2docker pull mysql:5.7.38
docker run -it -d -p 3306:3306 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.38FROM#在整个dockfile文件中除了注释之外的第一行,要是FROM指令,FROM 指令用于指定当前镜像(base image)引用的父镜像(parent image)
MAINTAINER #(镜像的维护者信息,目前已经不推荐使用)
LABEL “key”=“value” #设置镜像的属性标签
LABEL author="xxx@gmail.com"
LABEL version="1"
ADD [--chown=<user>:<group>] <src>... <dest> #用于添加宿主机本地的文件、目录、压缩等资源到镜像里面去,会自动解压tar.gz格式的压缩包,但不会自动解压zip包
RUN yum install vim unzip -y && cd /etc/nginx #执行shell命令,但是一定要以非交互式的方式执行
VOLUME ["/data/data1","/data/data2"] #定义volume
COPY [--chown=<user>:<group>] <src>... <dest>
#用于添加宿主机本地的文件、目录、压缩等资源到镜像里面去,不会解压任何压缩包
WORKDIR /data/data1 #用于定义当前工作目录
ENV MY_NAME="John Doe" #设置容器环境变量
USER <user>[:<group>] or USER <UID>[:<GID>] #指定运行操作的用户
EXPOSE <port> [<port>/<protocol>...] #声明要把容器的某些端口映射到宿主机
CMD 跟 ENTRYPOINT
CMD有以上三种方式定义容器启动时所默认执行的命令或脚本
CMD ["executable","param1","param2"] #推荐的可执行程序方式
CMD ["param1","param2" #作为ENTRYPOINT默认参数
CMD command param1 param2 #基于shell命令的
如:基于CMD #镜像启动为一个容器时候的默认命令或脚本,
CMD ["/bin/bash"]
ENTRYPOINT #也可以用于定义容器在启动时候默认执行的命令或者脚本,如果是和CMD命令混合使用的时候,会将CMD的命令当做参数传递给ENTRYPOINT后面的脚本,可以在脚本中对参数做判断并相应的容器初始化操作。
案例1:
ENTRYPOINT ["top","-b"]
CMD ["-c"]
等于如下一行:
ENTRYPOINT ["top","-b","-c"]
案例2:
ENTRYPOINT ["docker-entrypoint.sh"] #定义一个入口点脚本,并传递mysqld 参数
CMD ["mysql"]
等于如下一行:
ENTRYPOINT ["docker-entrypoint.sh","mysql"]
使用总结:
当ENTRYPOINT跟CMD同时用时,
ENTRYPOINT(脚本) + CMD(当做参数传递给ENTRYPOINT)
Dockerfile官方文档:https://docs.docker.com/engine/reference/builder/[root@localhost.localdomain /opt/nginx]#ll
total 1104
-rw-r--r-- 1 root root 791 Jan 24 11:02 Dockerfile
-rw-r--r-- 1 root root 38751 Jan 18 10:06 frontend.tar.gz
-rw-r--r-- 1 root root 1073322 Jan 18 10:06 nginx-1.22.0.tar.gz
-rw-r--r-- 1 root root 2812 Jan 18 10:07 nginx.conf
-rw-r--r-- 1 root root 1139 Jan 18 10:07 sources.list
vi /opt/system/ubuntu/ubuntu22.04/Dockerfile
FROM ubuntu:22.04
MAINTAINER ""
LABEL nginx="1.22.0" ubuntu="22.04"
COPY sources.list /etc/apt/sources.list
RUN apt update && apt install -y iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev gcc openssh-server iotop unzip make net-tools iputils-ping vim
ADD nginx-1.22.0.tar.gz /usr/local/src/
RUN cd /usr/local/src/nginx-1.22.0 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin
RUN groupadd -g 2023 nginx && useradd -g nginx -s /usr/sbin/nologin -u 2023 nginx && chown -R nginx.nginx /apps/nginx
ADD nginx.conf /apps/nginx/conf/
ADD frontend.tar.gz /apps/nginx/html/
EXPOSE 80 443
ENTRYPOINT ["nginx"]
CMD ["-g","daemon off;"] cat sources.list
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-sr https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-sr https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiversecp /usr/local/src/harbor/harbor.yml.tmpl /usr/local/src/harbor/harbor.yml
vi /usr/local/src/harbor/harbor.yml
修改:
hostname: x.x.x.x
harbor_admin_password: 123456
database:
password: 123456
data_volume: /data
#把https注释掉,不然报错没https协议,/data建议挂载为数据盘vim /lib/systemd/system/docker.service
在 [Service] 添加 --insecure-registry harbor.magedu.com 或者 --insecure-registry x.x.x.x
systemctl daemon-reload
systemctl restart dockerdocker run -it --rm --name magedu-c1 lorel/docker-stress-ng --vm 2 --vm-bytes 256M
docker statsdocker run -it --rm -m 100m --name magedu-c1 lorel/docker-stress-ng --vm 2 --vm-bytes 256M
docker statsocker run -it --rm --name magedu-c1 --cpus 0.5 lorel/docker-stress-ng --cpu 0.5 --vm 2 --vm-bytes 256M
docker statsdocker run -it --rm --name magedu-c1 --cpus 2 --cpuset-cpus 1,3 lorel/docker-stress-ng --cpu 4 --vmdocker run -it --rm --name magedu-c1 --cpu-shares 1000 lorel/docker-stress-ng --cpu 4 --vm 4
docker run -it --rm --name magedu-c2 --cpu-shares 500 lorel/docker-stress-ng --cpu 4 --vm 4docker run -it -m 256m \
-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \
-v /var/lib/lxcfs/proc/diskstats:/proc//diskstats:rw \
-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
-v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
centos:7.9.2009 /bin/bashdocker run -it --cpus 1 --cpuset-cpus "2" \
-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \
-v /var/lib/lxcfs/proc/diskstats:/proc//diskstats:rw \
-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
-v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
centos:7.9.2009 /bin/bash 1.下载阿里云镜像源
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
2.查看仓库版本
yum list | grep containerd
3.安装containerd
yum install -y containerd
4.查看service文件
cat /lib/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
5.查看runc,containerd版本以及位置
whereis contained
whereis runc
contained -v
runc -v
6.修改containerd配置文件
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
vim /etc/containerd/config.toml
7.重启containerd
systemctl enable containerd
systemctl restart containerd
8.用ctr下载镜像(镜像名需要写全
containerd的命令⾏客户端有ctr、crictl、nerdctl等,containerd相⽐docker多了⼀个命名空间的逻辑概念,⾃身 的命令⾏客户端ctr命令默认是在default命名空间⾥、nerdctl也是在default,当使⽤crictl命令的时候,是在k8s.io 这个命名空间,⽽k8s的创建的pod也是在k8s.io命名空间,因此在使⽤nerdctl管理kubernetes环境的pod的时候 要指定命名空间为k8s.io,否则看不到kubernetes环境中的pod。
ctr images pull docker.io/library/ubuntu:latest
9.验证镜像
ctr images ls
10.ctr客户端创建测试容器
ctr run -t --net-host docker.io/library/alpine:latest test-container3 sh1.验证仓库版本
apt update
apt-cache madison containerd
2.安装containerd
apt install containerd
3.查看service文件
cat /lib/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
4.查看runc,containerd版本以及位置
whereis runc
whereis containerd
runc -v
containerd -v
5.修改配置文件
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
vim /etc/containerd/config.toml
6.重启containerd
systemctl enable containerd
systemctl restart containerd
7.用ctr下载镜像(镜像名需要写全)
ctr images pull docker.io/library/ubuntu:latest
8.验证镜像
ctr run -t --net-host docker.io/library/alpine:latest test-container sh
ctr images ls
9.指定namespaces为k8s.io
ctr -n k8s.io images ls
10.ctr客户端创建测试容器(--net-host 指定本机网络)
ctr run -t --net-host docker.io/library/alpine:latest test shwget https://github.com/containerd/containerd/releases/download/v1.7.2/containerd-1.7.2-linux-amd64.tar.gz
tar xvf containerd-1.7.2-linux-amd64.tar.gz
mv bin/* /usr/local/bin/
containerd -v #检查是否成功安装mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
vim /etc/containerd/config.toml
sandbox_image = "registry.k8s.io/pause:3.8"
[plugins."io.containerd.grpc.v1.cri".registry.mirrors] #后面添加镜像加速地址
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://9916w1ow.mirror.aliyuncs.com"]ctr images pull docker.io/library/alpine:latest
ctr images ls
ctr -n k8s.io images ls #指定namespaces1.安装nerdctl
wget https://github.com/containerd/nerdctl/releases/download/v1.4.0/nerdctl-1.4.0-linux-amd64.tar.gz
2.解压到/usr/local/bin/下
tar xvf nerdctl-1.3.0-linux-amd64.tar.gz -C /usr/local/bin/
3.查看版本
nerdctl version
4.修改nerdctl配置⽂件
mkdir /etc/nerdctl/
vim /etc/nerdctl/nerdctl.toml
namespace = "k8s.io"
debug = false
debug_full = false
insecure_registry = true1.下载cni
wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz
2.创建cni插件的路径
mkdir /opt/cni/bin -p
3.解压到cni到/opt/cni/bin/下
tar xvf cni-plugins-linux-amd64-v1.3.0.tgz -C /opt/cni/bin/
4.在containerd的配置文件里定义了cni的存放路径nerdctl run -t -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=MySQL127336 -d mysql:5.6.39
在另一台主机测试远程连接mysql
apt install mariadb-client
mysql -uroot -pMySQL127336
其他命令可参考docker或者用nerdctl --help查看
https://github.com/containerd/nerdctl/blob/main/docs/command-reference.md #nerdctl使用文档mkdir /apps/harbor/certs
cd /apps/harbor/certs
openssl genrsa -out ca.key 409 #生成CA证书私钥
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=magedu.com" \
-key ca.key \
-out ca.crt
harbor 域名证书申请
openssl genrsa -out magedu.net.key 4096
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=magedu.net" \
-key magedu.net.key \
-out magedu.net.csr
准备签发环境
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names #定义引用的域名
[alt_names]
DNS.1=magedu.com
DNS.2=harbor.magedu.net
DNS.3=harbor.magedu.local
EOF
使用自签名 CA 签发证书
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in magedu.net.csr \
-out magedu.net.crt
检查文件是否都生成了
ll /apps/harbor/certs
root@ubuntu20:/apps/harbor/certs# ll
total 36
drwxr-xr-x 2 root root 4096 Jul 26 10:35 ./
drwxr-xr-x 3 root root 4096 Jul 26 09:50 ../
-rw-r--r-- 1 root root 2041 Jul 26 10:03 ca.crt
-rw------- 1 root root 3247 Jul 26 09:54 ca.key
-rw-r--r-- 1 root root 41 Jul 26 10:35 ca.srl
-rw-r--r-- 1 root root 2126 Jul 26 10:35 magedu.net.crt #签发后的harbor公钥
-rw-r--r-- 1 root root 1704 Jul 26 10:26 magedu.net.csr
-rw------- 1 root root 3243 Jul 26 10:25 magedu.net.key
-rw-r--r-- 1 root root 279 Jul 26 10:24 v3.extcd /apps/harbor/
cp harbor.yml.tmpl harbor.yml
vi harbor.yml
hostname: harbor.magedu.net
https:
port: 443
certificate: /apps/harbor/certs/magedu.net.crt #harbor公钥
private_key: /apps/harbor/certs/magedu.net.key #harbor私钥(重要,勿泄露)
harbor_admin_password: 123123
database:
password: 123123
data_volume: /data创建一个业务镜像构建目录
mkdir /opt/dockerfile/alpine3.18-nginx1.24-dockerfile-case
创建并编写dockerfile
cd /opt/dockerfile/alpine3.18-nginx1.24-dockerfile-case
vim Dockerfile
FROM alpine:3.18.2
MAINTAINER zhangshijie 2973707860@qq.com
COPY repositories /etc/apk/repositories
RUN apk update && apk add vim iotop gcc libgcc libc-dev libcurl libc-utils gzip zlib zlib-dev libnfs make pcre pcre2 pcre-dev zip unzip net-tools pstree wget libevent libevent-dev iproute2
ARG VER=1.24.0
ADD nginx-${VER}.tar.gz /opt
RUN cd /opt/nginx-${VER} && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin
RUN addgroup -g 2088 -S nginx
RUN adduser nginx -u 2088 -D -S /bin/sh -G nginx
RUN echo -e "123456\n123456" | passwd nginx
RUN mkdir /data/nginx/html/ -pv
ADD nginx.conf /apps/nginx/conf/nginx.conf
ADD frontend.tar.gz /apps/nginx/html/
RUN chown nginx.nginx -R /data/nginx/ /apps/nginx/
EXPOSE 80 443
CMD ["nginx"]
把代码文件放拷贝到业务镜像构建目录下
[root@host-45-15-10-78 alpine3.18-nginx1.24-dockerfile-case]# ll
total 1144
-rw-r--r-- 1 root root 279 Jul 23 15:38 build-command.sh
-rw-r--r-- 1 root root 792 Jul 22 12:48 Dockerfile
-rw-r--r-- 1 root root 38751 Aug 5 2022 frontend.tar.gz
-rw-r--r-- 1 root root 1112471 Apr 12 00:04 nginx-1.24.0.tar.gz
-rw-r--r-- 1 root root 2866 Sep 12 2019 nginx.conf
-rw-r--r-- 1 root root 219 Jul 22 13:11 repositoriesmkdir /root/qbn/
vi docker-compose.yml
version: '3.8' #推荐3以上,写3也可以
services:
nginx-server:
image: nginx:1.22.0-alpine
container_name: nginx-web1
# network_mode: bridge #网络1,使用docker安装后的默认网桥
expose:
- 80
- 443
ports:
- "80:80"
- "443:443"
networks: #网络2,使用自定义的网络,如果网络不存在则会自动创建该网络并分配子网,并且容器会有两块网卡
- front
- backend
links:
- tomcat-server
volumes:
- /root/qbn/default.conf:/etc/nginx/conf.d/default.conf
- /root/qbn/index.html:/data/html/index.html
tomcat-server:
#image: tomcat:7.0.93-alpine
image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/tomcat-myapp:v1
container_name: tomcat-app1
##network_mode: bridge #网络1,使用docker安装后的默认网桥
#expose:
# - 8080
#ports:
# - "8080:8080"
networks: #网络2,使用自定义的网络,如果网络不存在则会自动创建该网络并分配子网,并且容器会有一块网卡
- backend
links:
- mysql-server
mysql-server:
image: mysql:5.6.48
container_name: mysql-container
# network_mode: bridge #网络1,使用docker安装后的默认网桥
volumes:
- /data/mysql:/var/lib/mysql
#- /etc/mysql/conf/my.cnf:/etc/my.cnf:ro
environment:
- "MYSQL_ROOT_PASSWORD=12345678"
- "TZ=Asia/Shanghai"
expose:
- 3306
ports:
- "3306:3306"
networks: #网络2,使用自定义的网络,如果网络不存在则会自动创建该网络并分配子网,并且容器会有一块网卡
- backend
networks:
front: #自定义前端服务网络,需要docker-compose创建
driver: bridge
backend: #自定义后端服务的网络,要docker-compose创建
driver: bridge
default: #使用已经存在的docker0默认172.17.0.1/16的网络
external:
name: bridge
[root@host-45-15-10-78 ]# ll
total 12
-rw-r--r-- 1 root root 1152 Jul 28 15:18 default.conf
-rw-r--r-- 1 root root 1911 Jul 28 15:18 docker-compose.yml
-rw-r--r-- 1 root root 20 Jul 28 15:12 index.html