docker阶段02 端口映射,挂载数据卷,容器传递环境变量,容器内安装软件,容器的生命周期,Dockerfile,Docker registry,Docker网络模型,Docker-Compose,跨主机容器之间的通信
#1. 端口映射 -p #端口映射 -p80:81 -p宿主机端口:容器内部端口 #拉nginx镜像 [root@docker01 ~]# docker pull nginx:1.18.0 #打个标签(习惯问题,可以不打) [root@docker01 ~]# docker tag c2c45d506085 qls123/nginx:v1.18.0 [root@docker01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx 1.18.0 c2c45d506085 3 years ago 133MB qls123/nginx v1.18.0 c2c45d506085 3 years ago 133MB #启动容器,81端口映射内部80端口 [root@docker01 ~]# docker run --name nginx01 -d -p81:80 qls123/nginx:v1.18.0 4c4fe08a3ee146050d14060e3f6e0410da7ea10f0aaab9d2e5a295eb4264f6fe [root@docker01 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4c4fe08a3ee1 qls123/nginx:v1.18.0 "/docker-entrypoint.…" 19 seconds ago Up 18 seconds 0.0.0.0:81->80/tcp, :::81->80/tcp nginx01 [root@docker01 ~]# netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name ... tcp 0 0 0.0.0.0:81 0.0.0.0:* LISTEN 12218/docker-proxy ... #浏览器输入测试 http://10.0.0.181:81/
#baidu的首页 [root@docker01 ~]# mkdir html [root@docker01 ~]# cd html [root@docker01 html]# wget www.baidu.com -O index.html [root@docker01 html]# ll total 4 -rw-r--r-- 1 root root 2381 Jun 17 05:44 index.html #运行容器进行挂载 -v -v宿主机的目录:容器的目录 [root@docker01 html]# docker run --name nginx02 -d -p82:80 -v/root/html:/usr/share/nginx/html qls123/nginx:v1.18.0 5df0e11580ac58154c8a71836dcffe95c311761e6396cf1f7aed9cdf5c17b815 #浏览器测试 http://10.0.0.181:82/ [root@docker01 html]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5df0e11580ac qls123/nginx:v1.18.0 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:82->80/tcp, :::82->80/tcp nginx02 #查看容器信息 [root@docker01 html]# docker inspect 5df0e11580ac #查看挂载信息 [root@docker01 html]# docker inspect 5df0e11580ac|grep /usr/share "/root/html:/usr/share/nginx/html" "Destination": "/usr/share/nginx/html",
-e #传递环境变量 [root@docker01 html]# docker run --rm -e TEST=hello qls123/nginx:v1.18.0 printenv HOSTNAME=465a72c30930 HOME=/root PKG_RELEASE=2~buster NGINX_VERSION=1.18.0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin NJS_VERSION=0.4.4 TEST=hello PWD=/
#进去前面放百度的容器 [root@docker01 html]# docker exec -ti nginx02 /bin/bash #nginx镜像默认使用debian系统,没有yum,下载apt-get(一般的服务都是debian系统) #下载要准备一个源 tee /etc/apt/sources.list << EOF #如果里面有命令会替换,可以用cat查看 deb http://mirrors.163.com/debian-archive/debian/ stretch main non-free contrib deb http://mirrors.163.com/debian-archive/debian/ stretch-backports main non-free contrib deb-src http://mirrors.163.com/debian-archive/debian/ stretch main non-free contrib deb-src http://mirrors.163.com/debian-archive/debian/ stretch-backports main non-free contrib deb http://mirrors.163.com/debian-archive/debian-security/ stretch/updates main non-free contrib deb-src http://mirrors.163.com/debian-archive/debian-security/ stretch/updates main non-free contrib EOF #更新源然后下载命令 root@5df0e11580ac:/# apt-get update && apt-get install curl -y #安装ping命令 apt-get install inetutils-ping -y #后期要用到带有curl命令nginx镜像,提交一个新镜像 [root@docker01 ~]# docker commit -p 5df0e11580ac qls123/nginx:1.18.0-curl sha256:a5a9350747d3b6e8f94fe72e248faca6f3b2f38d323dfd4810031fac8028816d [root@docker01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE qls123/nginx 1.18.0-curl a5a9350747d3 16 seconds ago 169MB qls123/nginx v1.18.0 c2c45d506085 3 years ago 133MB nginx 1.18.0 c2c45d506085 3 years ago 133MB #上传镜像(仓库里有基础镜像,所以只会传新增部分30m) [root@docker01 ~]# docker push qls123/nginx:1.18.0-curl
1.检查本地是否存在镜像,如果没有则从远程官方仓库查询下载 2.利用镜像启动容器 3.分配一个文件系统,并在只读的镜像层外挂载一层可读可写层 这个就是容器 4.从宿主机配置的网桥接口中桥接一个虚拟接口到容器 5.从地址池配置一个IP地址给容器 6.执行用户指定的命令 7.执行完毕后容器终止 #了解更多的docker指令 [root@docker01 ~]# docker --help
如何自定义一个镜像
docker commit
黑箱操作: 不知道别人在里面做了什么,维护非常困难 不建议通过commit方式来创建镜像
简单,方便
Dockerfile制作镜像
就是一个文本文件 文件名只能是dockerfile 里面其实就是一组组命令
docker build 进行构建镜像
Dockerfile的规则: 1.格式 #注释 指令大写, 内容小写(大小写是没有太多的强制要求,我们强烈要求使用指令大写,内容小写) 2.Dockerfile是按照顺序执行里面的指令的 从上到下依次执行 3.每一个dockerfile的第一个非注释指令,必须是"FROM" 用户为镜像文件创建的过程中,指定的基础镜像 4.在实践中,基础镜像可以是任何可用的镜像文件,默认情况下,docker build会在本地查找dockerfile上面指定的镜像,当本地不存在这个镜像时,则会从官方远程仓库拉取 Dockerfile核心指令 FROM #指定基础镜像 USER #指定运行的用户(容器内运行的用户) WORKDIR #指定的工作目录(进入容器后的根目录,相当于cd命令进入) COPY #复制文件 ADD #高级复制,会自动解压文件 RUN #执行的命令 EXPOSE #指定对外的端口,用到的不多(docker -p直接就能指定,如写EXPOSE,外面调用要用-P) ENV #设置环境变量 CMD #容器启动后执行的命令 ENTRYPOINT #容器启动后执行的命令(用的不多)
LABEL #指定镜像元数据(标签,就是备注,可有可无) docker inspect命令可以查看LABEL
VOLUME #匿名卷(创建一个宿主机和容器挂载点,即使容器后期被删除,宿主机的目录依然会被保留,功能鸡肋,主要是提醒别人目录重要)
ONBUILD #子镜像引用父镜像的指令
HEALTHCHECK #健康检查
RUN命令执行命令并创建新的镜像层,通常用于安装软件包 CMD命令设置容器启动后默认执行的命令和其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换 ENTRYPOING配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行docker run时指定了其他命令)
#按照业务类型或系统类型等方式划分创建目录环境,方便后期镜像比较多的时候进行分类 [root@ubuntu1804 ~]#mkdir /data/dockerfile/{web/{nginx,apache,tomcat,jdk},system/{centos,ubuntu,alpine,deb ian}} -p [root@ubuntu1804 ~]#tree /data/dockerfile/ /data/dockerfile/ ├── system │ ├── alpine │ ├── centos │ ├── debian │ └── ubuntu └── web ├── apache ├── jdk ├── nginx └── tomcat 10 directories, 0 files
#编写dockerfile文件 [root@docker01 ~]# mkdir /data/dockerfile -p [root@docker01 ~]# cd /data/dockerfile/ [root@docker01 dockerfile]# vim Dockerfile FROM qls123/nginx:v1.18.0 USER nginx #以nginx身份管理登录,服务以nginx身份启动 WORKDIR /usr/share/nginx /html #构建镜像 #.表示当前目录,或者写成其他dockerfile所在路径(不包含dockerfile) -t指定镜像名字 [root@docker01 dockerfile]# docker build . -t qls123/nginx:v1.18.0_with_user_workdir #创建容器并进入 [root@docker01 dockerfile]# docker run --rm -ti --name nginx03 qls123/nginx:v1.18.0_with_user_workdir /bin/bash nginx@85c595397752:/usr/share/nginx/html$ whoami #根路径 nginx #登录用户
EXPOSE: 暴露端口 #配合-P用,小p指定端口无所谓。这个主要是提示别人暴露的端口
[root@docker01 ~]# cd /data/dockerfile/ #把html文件复制到dockerfile路径下,因ADD的宿主机路径是相对于Dockerfile文件所在的路径的 [root@docker01 dockerfile]# cp -a /root/html/ ./ [root@docker01 dockerfile]# ls Dockerfile Dockerfile1 html [root@docker01 dockerfile]# vim Dockerfile FROM qls123/nginx:v1.18.0 ADD html/index.html /usr/share/nginx/html/index.html#把本地文件(dockerfile相对路径)复制到镜像中 EXPOSE 80 #把容器80端口映射出去 [root@docker01 dockerfile]# docker build . -t qls123/nginx:v1.18.0_with_index_expose [root@docker01 dockerfile]# docker images|grep with_index_expose qls123/nginx v1.18.0_with_index_expose 355a5cb38423 53 seconds ago 133MB #创建容器 -P表示EXPOSE的端口映射(无法指定端口,会随机映射一个端口) #这里可以给参数-p,会覆盖EXPOSE参数,优先级更高 [root@docker01 dockerfile]# docker run --rm -d --name nginx04 -P qls123/nginx:v1.18.0_with_index_expose [root@docker01 dockerfile]# netstat -lntp #32768是随机端口的开始,这个可以系统设置 ... tcp 0 0 0.0.0.0:32768 0.0.0.0:* LISTEN 11704/docker-proxy #访问测试,看拷贝进去的文件是否有效 [root@docker01 dockerfile]# curl 127.0.0.1:32768 <!DOCTYPE html> <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8>... [root@docker01 dockerfile]# docker exec -it nginx04 /bin/bash root@411075dcee16:/# ls /usr/share/nginx/html 50x.html index.html
RUN 指令用来在构建镜像阶段需要执行 FROM 指定镜像所支持的Shell命令。 通常各种基础镜像一般都支持丰富的shell命令 注意: RUN 可以写多个,每一个RUN指令都会建立一个镜像层,所以尽可能合并成一条指令,比如将多个shell命令通过 && 连接一起成为在一条指令(太长用\换行) 每个RUN都是独立运行的,和前一个RUN无关 #shell 格式: 相当于 /bin/sh -c <命令> 此种形式支持环境变量 RUN <命令> #exec 格式: 此种形式不支持环境变量,注意:是双引号,不能是单引号 RUN ["executable","param1","param2"...] #exec格式可以指定其它shell RUN ["/bin/bash","-c","echo hello wang"] #例 FROM alpine:3.19 RUN sed -i 's/.../.../' /etc/apk/repositories && apk update && apk add bash vim # 范例: 多个 前后RUN 命令独立无关和shell命令不同 #world.txt并不存放在/app内 RUN cd /app RUN echo "hello" > world.txt #下面写法可以实现关联关系 RUN cd /app && echo "hello" > world.txt
#centos7镜像本地没有,从官网下载centos镜像 [root@docker01 dockerfile]# vim Dockerfile FROM centos:7.7.1908 ENV VER 4.9.2 RUN yum install -y tcpdump-$VER #如果遇到红色警告Import GPG key,不用管,下载没有key不影响 [root@docker01 dockerfile]# docker build . -t qls123/centos:7.7.1908_with_env_run [root@docker01 dockerfile]# docker images|grep centos qls123/centos 7.7.1908_with_env_run a9977daa7213 About a minute ago 461MB [root@docker01 dockerfile]# docker run --rm -it qls123/centos:7.7.1908_with_env_run /bin/bash [root@4681b0277807 /]# cat /etc/redhat-release CentOS Linux release 7.7.1908 (Core) #看环境变量只能用printenv,其他命令看不了 [root@4681b0277807 /]# printenv|grep VER VER=4.9.2 [root@4681b0277807 /]# tcpdump --version tcpdump version 4.9.2 libpcap version 1.5.3 OpenSSL 1.0.2k-fips 26 Jan 2017
复制本地宿主机的到容器中的 。 #范例: COPY hom* /mydir/ COPY hom?.txt /mydir/
docker run后面如果跟command的话会替代容器内的CMD命令 # 使用 exec 执行,推荐方式,第一个参数必须是命令的全路径,此种形式不支持环境变量,注意:是双引号, 不能是单引号 CMD ["executable","param1","param2"] # 在 /bin/sh 中执行,提供给需要交互的应用;此种形式支持环境变量 CMD command param1 param2 # 提供给 ENTRYPOINT 命令的默认参数 CMD ["param1","param2"] #例 CMD tail -f /etc/hosts
ENTRYPOINT: 入口点
#功能类似于CMD,配置容器启动后执行的命令及参数 如果同时有ENTRYPOINT和CMD,会把CMD作为ENTRYPOINT命令的参数 如果有ENTRYPOINT,docker run后面命令会变成参数,而不是替换执行命令 一般情况分工: CMD 定义默认容器启动进程 ENTRYPOINT 环境准备(一般用entrypoint.sh命名脚本) # 范例: 利用脚本实现指定环境变量动态生成配置文件内容 [root@ubuntu1804 ~]#echo 'Nginx Website in Dockerfile' > index.html [root@ubuntu1804 ~]#cat Dockerfile FROM nginx:1.16-alpine LABEL maintainer="wangxiaochun <root@wangxiaochun.com>" ENV DOC_ROOT='/data/website/' ADD index.html ${DOC_ROOT} ADD entrypoint.sh /bin/ EXPOSE 80/tcp 8080 #HEALTHCHECK --start-period=3s CMD wget -0 - -q http://${IP:-0.0.0.0}: {PORT:-80}/ ENTRYPOINT [ "/bin/entrypoint.sh"] #CMD指令的内容都成为了ENTRYPOINT的参数 CMD ["/usr/sbin/nginx","-g", "daemon off;"] [root@ubuntu1804 ~]#cat entrypoint.sh #!/bin/sh #注意:alpine镜像没有bash,此处使用sh cat > /etc/nginx/conf.d/www.conf <<EOF server { server_name ${HOSTNAME:-"www.wangxiaochun.com"}; listen ${IP:-0.0.0.0}:${PORT:-80}; root ${DOC_ROOT:-/usr/share/nginx/html}; } EOF exec "$@" #把参数传入,exec执行命令并把进程从shell执行改为此命令执行 [root@ubuntu1804 ~]#chmod +x entrypoint.sh [root@ubuntu1804 ~]#docker build -t nginx:v1.0 . [root@ubuntu1804 ~]#docker run --name n1 --rm -P -e "PORT=8080" -e "HOSTNAME=www.wang.org" nginx:v1.0
#CMD指令 #下载httpd服务,并在后台能够运行 [root@docker01 dockerfile]# vim Dockerfile FROM centos:7.7.1908 RUN yum install httpd -y CMD ["httpd","-D","FOREGROUND"] #httpd容器里的启动方式 [root@docker01 dockerfile]# docker build . -t qls123/centos:7.7.1908_with_httpd [root@docker01 dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE qls123/centos 7.7.1908_with_httpd ce50da75b274 7 seconds ago 493MB [root@docker01 dockerfile]# docker run --rm -d --name httpd01 -p83:80 qls123/centos:7.7.1908_with_httpd [root@docker01 dockerfile]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 47481a6678ef qls123/centos:7.7.1908_with_httpd "httpd -D FOREGROUND" 17 seconds ago Up 16 seconds 0.0.0.0:83->80/tcp, :::83->80/tcp httpd01 #浏览器访问测试 http://10.0.0.181:83/ #ENTRYPOINT指令 [root@docker01 dockerfile]# vim Dockerfile FROM centos:7.7.1908 COPY entrypoint.sh /entrypoint.sh RUN yum install epel-release -y && yum install -y nginx #安装nginx需要epel源,先安装epel源 ENTRYPOINT /entrypoint.sh #编写脚本 [root@docker01 dockerfile]# vim entrypoint.sh #!/bin/bash /sbin/nginx -g "daemon off;" #启动nginx,放入后台 #脚本加上执行权限 [root@docker01 dockerfile]# chmod +x entrypoint.sh [root@docker01 dockerfile]# docker build . -t qls123/centos:7.7.1908_with_entrypoint [root@docker01 dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE qls123/centos 7.7.1908_with_entrypoint 9d64b48765dc About a minute ago 535MB [root@docker01 dockerfile]# docker run -d --name nginx06 -p84:80 qls123/centos:7.7.1908_with_entrypoint #浏览器访问测试 http://10.0.0.181:84/
ARG指令在build 阶段指定变量
和ENV不同的是,容器运行时并不存在ARG定义的环境变量
在容器中创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据 等,默认会将宿主机上的目录挂载至VOLUME 指令指定的容器目录。即使容器后期被删除,此宿主机的 目录仍会保留,从而实现容器数据的持久保存。 宿主机目录为 /var/lib/docker/volumes/<volume_id>/_data #volume_id太长,比较难记,这功能比较鸡肋,主要是给人提示作用 #例: VOLUME /data/website #容器里没有该目录会自动生成 #删除容器时,同时想把匿名卷也删了 docker rm -v mynginx3 #查看所有卷 docker volume ls #删所有匿名卷 docker system prune --volumes
ONBUILD [INSTRUCTION] ONBUILD RUN rm -rf /* #谁引用谁死 #谁引用,谁执行命令。本身写这条命令的父镜像不执行该命令
#对自己80端口进行访问检查 HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://localhost/ #如果健康性检查成功,STATUS会显示 (healthy) [root@centos8 nginx-1.18]#docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fad976015cad nginx-centos7.9:v1.18-11 "/apps/nginx/sbin/ng…" 6 seconds ago Up 5 seconds (healthy) 0.0.0.0:80->80/tcp, 443/tcp n1 #如果健康性检查不通过,STATUS会显示(unhealthy) [root@centos8 nginx-1.18]#docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fad976015cad nginx-centos7.9:v1.18-11 "/apps/nginx/sbin/ng…" About a minute ago Up About a minute (unhealthy) 0.0.0.0:80->80/tcp, 443/tcp n1
#使用域名的方式访问百度首页 [root@docker01 dockerfile]# vim Dockerfile FROM qls123/nginx:v1.18.0 USER root ENV WWW /usr/share/nginx/html ENV CONF /etc/nginx/conf.d RUN echo 'Asia/Shanghai' >/etc/timezone WORKDIR $WWW ADD html/index.html $WWW/index.html ADD qls.baidu.com.conf $CONF/qls.baidu.com.conf CMD ["nginx","-g","daemon off;"] #在dockerfile启动nginx命令 [root@docker01 dockerfile]# vim qls.baidu.com.conf server { listen 80; server_name qls.baidu.com; root /usr/share/nginx/html; } [root@docker01 dockerfile]# docker build . -t qls123/nginx:v1.18.0_with_baidu [root@docker01 dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE qls123/nginx v1.18.0_with_baidu cf8d45620a06 10 seconds ago 133MB [root@docker01 dockerfile]# docker run --rm -d -p80:80 qls123/nginx:v1.18.0_with_baidu #修改宿主机hosts文件 C:\Windows\System32\drivers\etc\hosts 10.0.0.181 qls.baidu.com #浏览器访问测试 qls.baidu.com #实现一个小游戏 [root@docker01 dockerfile]# rz xiaoniao.tar.gz (不需要解压,add命令会解压) [root@docker01 dockerfile]# vim Dockerfile FROM qls123/nginx:v1.18.0 USER root ENV WWW /usr/share/nginx/html ENV CONF /etc/nginx/conf.d RUN echo 'Asia/Shanghai' >/etc/timezone ADD xiaoniao.tar.gz $WWW/ ADD xiaoniao.com.conf $CONF/xiaoniao.com.conf CMD ["nginx","-g","daemon off;"] #启动nginx [root@docker01 dockerfile]# vim xiaoniao.com.conf server { listen 80; server_name xiaoniao.com; root /usr/share/nginx/html/xiaoniao; } [root@docker01 dockerfile]# docker build . -t qls123/nginx:v1.18.0_with_xiaoniao [root@docker01 dockerfile]# docker run --rm -d --name xiaoniao -p81:80 qls123/nginx:v1.18.0_with_xiaoniao #删除nginx默认配置 [root@docker01 dockerfile]# docker exec -it xiaonaio /bin/bash # rm -f /etc/nginx/conf.d/default.conf # nginx -s reload #浏览器访问测试 10.0.0.181:81
本地镜像仓库 镜像注册中心 #普通的registry(企业里用的比较少,没有加密,不太安全,界面简单) #直接运行,没有自动下载 #--restart容器出现问题,自己重启恢复(daemon.json中已经配了live-restore,和这个效果一样) #-v挂载,把镜像挂载,方便查看。registry端口为5000 [root@docker01 dockerfile]# docker run -d -p5000:5000 --restart always --name registry -v/data/myregistry:/var/lib/registry registry [root@docker01 dockerfile]# docker images |grep registry registry latest b8604a3fe854 2 years ago 26.2MB [root@docker01 dockerfile]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 908d83f099d5 registry "/entrypoint.sh /etc…" 54 seconds ago Up 53 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry #打tag(不打tag推送不知道推送到哪),也可以通过镜像id指定 [root@docker01 dockerfile]# docker tag nginx:1.18.0 10.0.0.181:5000/qls/nginx:v1.18.0 #推送镜像到本地仓库(返回报错,要用https,但是这里用了http) [root@docker01 dockerfile]# docker push 10.0.0.181:5000/qls/nginx:v1.18.0 The push refers to repository [10.0.0.181:5000/qls/nginx] Get "https://10.0.0.181:5000/v2/": http: server gave HTTP response to HTTPS client #修改配置,追加本地注册中心(允许使用http推送到本地镜像) [root@docker01 dockerfile]# vim /etc/docker/daemon.json { "data-root": "/data/docker", "storage-driver": "overlay2", "insecure-registries": ["registry.access.redhat.com","quay.io","10.0.0.181:5000"], "registry-mirrors": ["https://pee6w651.mirror.aliyuncs.com"], "bip": "172.0.181.1/24", "exec-opts": ["native.cgroupdriver=systemd"], "live-restore": true } #重启生效 [root@docker01 dockerfile]# systemctl restart docker #推送成功 [root@docker01 dockerfile]# docker push 10.0.0.181:5000/qls/nginx:v1.18.0 The push refers to repository [10.0.0.181:5000/qls/nginx] 4fa6704c8474: Pushed 4fe7d87c8e14: Pushed 6fcbf7acaafd: Pushed f3fdf88f1cb7: Pushed 7e718b9c0c8c: Pushed v1.18.0: digest: sha256:9b0fc8e09ae1abb0144ce57018fc1e13d23abd108540f135dc83c0ed661081cf size: 1362 #查看本地镜像 [root@docker01 dockerfile]# ll /data/myregistry/docker/registry/v2/repositories/qls/nginx/ total 0 drwxr-xr-x 3 root root 20 Jun 19 00:53 _layers drwxr-xr-x 4 root root 35 Jun 19 00:53 _manifests drwxr-xr-x 2 root root 6 Jun 19 00:53 _uploads #浏览器也可以测试 http://10.0.0.181:5000/v2/_catalog 返回{"repositories":["qls/nginx"]} http://10.0.0.181:5000/v2/qls_nginx/tags/list 返回{"errors":[{"code":"NAME_UNKNOWN","message":"repository name not known to registry","detail":{"name":"qls_nginx"}}]} #从本地镜像仓库拉取镜像 #先删除本地镜像 [root@docker01 dockerfile]# docker rmi 10.0.0.181:5000/qls/nginx:v1.18.0 #拉取本地仓库镜像 [root@docker01 dockerfile]# docker pull 10.0.0.181:5000/qls/nginx:v1.18.0 v1.18.0: Pulling from qls/nginx Digest: sha256:9b0fc8e09ae1abb0144ce57018fc1e13d23abd108540f135dc83c0ed661081cf Status: Downloaded newer image for 10.0.0.181:5000/qls/nginx:v1.18.0 10.0.0.181:5000/qls/nginx:v1.18.0
#下载一个生成密码的软件 [root@docker01 dockerfile]# yum install httpd-tools -y [root@docker01 dockerfile]# mkdir -p /data/registry-var/auth #生成密码文件 [root@docker01 dockerfile]# htpasswd -Bbn qls 123456 >>/data/registry-var/auth/htpasswd [root@docker01 dockerfile]# cat /data/registry-var/auth/htpasswd qls:$2y$05$rk0g2TMKGZFOsqG25Necje7srqkho7Rc/xwM7rpZA3T8Sw0WrWPAS #删除之前的容器 [root@docker01 dockerfile]# docker rm -f registry registry #挂载两处:仓库,认证文件(容器认证目录/auth) -e参数是官方的,就这么用就行 [root@docker01 dockerfile]# docker run -d -p5000:5000 -v/data/registry-var/auth/:/auth/ -v/data/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry #打标签 [root@docker01 dockerfile]# docker tag a5a9350747d3 10.0.0.181:5000/qls/nginx:v1.18.0-curl [root@docker01 dockerfile]# docker images 10.0.0.181:5000/qls/nginx v1.18.0-curl a5a9350747d3 30 hours ago 169MB #推送报错 [root@docker01 dockerfile]# docker push 10.0.0.181:5000/qls/nginx:v1.18.0-curl Error response from daemon: Head "http://10.0.0.181:5000/v2/qls/nginx/manifests/v1.18.0-curl": no basic auth credentials #登录 [root@docker01 dockerfile]# docker login 10.0.0.181:5000 Username: qls Password: ... Login Succeeded #再次推送成功 [root@docker01 dockerfile]# docker push 10.0.0.181:5000/qls/nginx:v1.18.0-curl #下载镜像(另一台机器) [root@docker02 dockerfile]# docker login 10.0.0.181:5000 [root@docker02 dockerfile]# docker pull 10.0.0.181:5000/qls/nginx:v1.18.0-curl #删除本地仓库的镜像 #进入容器 [root@docker01 dockerfile]# docker exec -it 99db3faccbc5 /bin/sh #1.删除repo / # rm -rf /var/lib/registry/docker/registry/v2/repositories/qls/nginx/ #2.清楚blob(数据文件) / # registry garbage-collect /etc/docker/registry/config.yml
1.NAT(默认) Bridge 2.None 不为容器配置任何网络 [root@docker01 ~]# docker run -it --rm --net=none alpine /bin/sh / # ip a #没有配置任何网络 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 3.Host 与宿主机共享网络 性能最高 [root@docker01 ~]# docker run -it --rm --net=host alpine /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:d7:46:71 brd ff:ff:ff:ff:ff:ff inet 10.0.0.181/24 brd 10.0.0.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fed7:4671/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:d7:46:7b brd ff:ff:ff:ff:ff:ff inet 172.16.1.181/24 brd 172.16.1.255 scope global noprefixroute eth1 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fed7:467b/64 scope link valid_lft forever preferred_lft forever 4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP ... 4.联合网络 与另一个运行中的容器共享网络 [root@docker01 dockerfile]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 99db3faccbc5 registry "/entrypoint.sh /etc…" 59 minutes ago Up 59 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp heuristic_dewdney [root@docker01 ~]# docker exec -it 99db3faccbc5 /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:00:b5:02 brd ff:ff:ff:ff:ff:ff inet 172.0.181.2/24 brd 172.0.181.255 scope global eth0 valid_lft forever preferred_lft forever #启动一个容器,基于上面的容器去写 [root@docker01 ~]# docker run -it --rm --net=container:99db3faccbc5 alpine /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:00:b5:02 brd ff:ff:ff:ff:ff:ff inet 172.0.181.2/24 brd 172.0.181.255 scope global eth0 valid_lft forever preferred_lft forever
docker-23.0.0以上会自带compose插件,可以直接通过docker compose 子命令进行使用
docker-20.10.24以前版本没有内置,需要单独安装docker-compose
一键生成 Docker Compose
#利用网站将docker 命令自动生成 Docker Compse https://www.composerize.com/
#查看当前目录下的项目 docker compose ps #查看所有项目 docker compose ls
#单机编排工具 通过yaml文件进行 工程 project 服务 service 容器 container #安装Docker-compose [root@docker01 ~]# yum install -y docker-compose [root@docker01 ~]# docker-compose -v docker-compose version 1.18.0, build 8dd22a9 [root@docker01 ~]# mkdir /data/docker-compose/wordpress [root@docker01 ~]# cd /data/docker-compose/wordpress #文件名不要改,后缀名可以少a (文件不用知道怎么写,只要能用就行) [root@docker01 wordpress]# vim docker-compose.yaml version: "3" services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always #故障重启 environment: MYSQL_ROOT_PASSWORD: somewordpress #容器里定义好的 MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest volumes: - web_data:/var/www/html ports: - "80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress volumes: db_data: web_data: #启动容器(里面没有镜像会自动下载) docker-compose down表示关闭 [root@docker01 wordpress]# docker-compose up #这个是前台安装,会一直hang住 #建议放到后台运行 [root@docker01 wordpress]# docker-compose up -d #打开一个新窗口,连接docker虚拟机 [root@docker01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0f5316439e0e wordpress:latest "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:32768->80/tcp, :::32768->80/tcp wordpress_wordpress_1 cb67cc3b18ec mysql:5.7 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 3306/tcp, 33060/tcp wordpress_db_1 #浏览器登录wordpress http://10.0.0.181:32768/ 注册用户:admin/123 #关闭wordpress相关镜像(必须在docker-compose路径下) [root@docker01 wordpress]# docker-compose down Stopping wordpress_wordpress_1 ... done Stopping wordpress_db_1 ... done Removing wordpress_wordpress_1 ... done Removing wordpress_db_1 ... done Removing network wordpress_default
docker-compose 常用命令 docker-compose up 启动所有容器 -d #放入到后台运行 docker-compose down 停止Docker Compose中定义的所有服务并删除这些服务对应的容器 docker-compose start 启动所有容器 docker-compose stop 停止Docker Compose中定义的所有服务,但不会删除这些服务对应的容器 docker-compose logs 查看日志 #显示所有列表 [root@docker01 wordpress]# docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------- wordpress_db_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp wordpress_wordpress_1 docker-entrypoint.sh apach ... Up 0.0.0.0:32769->80/tcp,:::32769->80/tcp
用的不多
#列出所有网络 [root@docker01 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE dd8139a8d571 bridge bridge local d02505a38786 host host local e557594d8834 none null local #创建macvlan网络 #--driver创建驱动 --subnet网络ip地址 -o指定网卡 起名macvlan_1 [root@docker01 ~]# docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_1 #删除macvlan网络 #[root@docker01 wordpress]# docker network rm macvlan_1 #macvlan_1 [root@docker01 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE dd8139a8d571 bridge bridge local d02505a38786 host host local 3c256c6f36fe macvlan_1 macvlan local e557594d8834 none null local #启动容器 --ip指定ip,要指定ip,不然会抢宿主机的ip [root@docker01 ~]# docker run --rm -it --network macvlan_1 --ip=10.0.0.101 alpine:latest /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 25: eth0@if24: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN link/ether 02:42:0a:00:00:65 brd ff:ff:ff:ff:ff:ff inet 10.0.0.101/24 brd 10.0.0.255 scope global eth0 valid_lft forever preferred_lft forever / # ping 10.0.0.102 #等docker02虚拟机建好,macvlan网络和容器启动,才能ping PING 10.0.0.102 (10.0.0.102): 56 data bytes 64 bytes from 10.0.0.102: seq=0 ttl=64 time=0.567 ms #准备docker-10.0.0.182虚拟机 [root@docker02 ~]# yum install -y yum-utils #国内存储库(阿里云库) [root@docker02 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo [root@docker02 ~]# yum install -y docker-ce [root@docker02 ~]# systemctl start docker.service #配置docker [root@docker02 ~]# mkdir -p /data/docker [root@docker02 ~]# vim /etc/docker/daemon.json { "data-root": "/data/docker", "storage-driver": "overlay2", "insecure-registries": ["registry.access.redhat.com","quay.io"], "registry-mirrors": ["https://pee6w651.mirror.aliyuncs.com"], "bip": "172.0.182.1/24", "exec-opts": ["native.cgroupdriver=systemd"], "live-restore": true } [root@docker02 ~]# systemctl restart docker.service #创建macvlan网络 [root@docker02 ~]# docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_1 [root@docker02 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE eb58a6957249 bridge bridge local 9cd70af880e8 host host local a49a35e18bc4 macvlan_1 macvlan local 9c9e30a68ea9 none null local [root@docker02 ~]# docker run --rm -it --network macvlan_1 --ip=10.0.0.102 alpine:latest /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 7: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN link/ether 02:42:0a:00:00:66 brd ff:ff:ff:ff:ff:ff inet 10.0.0.102/24 brd 10.0.0.255 scope global eth0 valid_lft forever preferred_lft forever / # ping 10.0.0.101 PING 10.0.0.101 (10.0.0.101): 56 data bytes 64 bytes from 10.0.0.101: seq=0 ttl=64 time=0.729 ms