docker 学习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 额外仓库 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo yum clean all yum makecache iptables -F iptables -X iptables -Z getenforce yum install -y bash-completion vim lrzsz wget expect net-tools nc nmap tree dos2unix htop iftop iotop unzip telnet sl psmisc nethogs glances bc ntpdate openldap-devel systemctl disable firewalld systemctl stop firewalld 查看uname -r cat <<EOF > /etc/sysctl.d/docker.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.conf.default.rp_filter = 0 net.ipv4.conf.all.rp_filter = 0 net.ipv4.ip_forward = 1 EOF modprobe br_netfilter sysctl -p /etc/sysctl.d/docker.conf curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum clean all && yum makecache yum install docker-ce-20.10.6 -y yum list docker-ce --showduplicates | sort -r yum remove -y docker-xx
镜像加速器
使用docker首要操作就是获取镜像文件,默认下载是从Docker Hub下载,网速慢,国内很多云服务商都提供了加速器服务,阿里云加速器,Daocloud加速器,灵雀云加速器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 mkdir -p /etc/docker touch /etc/docker/daemon.json vim /etc/docker/daemon.json { "registry-mirrors" :[ "https://8xpk5wnt.mirror.aliyuncs.com" ] } systemctl daemon-reload systemctl enable docker systemctl restart docker docker images docker version
启动第一个docker容器
1 2 3 4 5 6 7 8 docker pull image_name docker run param image_name/id docker stop id docker start id
docker的生命周期
学习docker的核心要素
诞生——使用——销毁
Dockerfile 通过docker build. 生成一个images,dockerfile是构建镜像的脚本。
通过docker push送到docker hub(公开仓库)上
通过docker pull拉到机器本地
docker save导出镜像
docker load导入镜像(传递镜像)
docker run镜像
docker stop、docker start、docker restart 容器id
docker commit 容器id,生成一个安装了软件的镜像
docker 镜像的原理
获取redis镜像时,下载了多行信息,最终得到了完整的镜像文件
1 2 3 4 5 6 7 8 9 10 11 [root@jueye docker] Using default tag: latest latest: Pulling from library/redis a2abf6c4d29d: Already exists c7a4e4382001: Pull complete 4044b9ba67c9: Pull complete c8388a79482f: Pull complete 413c8bb60be2: Pull complete 1abfd3011519: Pull complete Digest: sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339 Status: Downloaded newer image for redis:latestdocker.io/library/redis:latest
一直以来使用的vmware虚拟机,安装的系统是一个完整的系统文件
linux内核,作用是提供操作系统基本功能,与硬件交互
centos7发行版,作用是提供软件功能,例如yum安装包管理
linux内核+centos发行版,组成了一个系统
docker绕过发行版使用系统,技术手段就是docker images
1 2 3 4 [root@jueye docker] CentOS Linux release 7.8.2003 (Core) [root@jueye docker] 3.10.0-1127.el7.x86_64
使用docker切换不同的发行版,内核使用的都是宿主机的内核
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [root@jueye docker] [root@jueye docker] [root@jueye docker] CentOS Linux release 7.8.2003 (Core) [root@jueye docker] REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 605c77e624dd 2 years ago 141MB redis latest 7614ae9453d1 2 years ago 113MB ubuntu latest ba6acccedd29 2 years ago 72.8MB centos 7.5.1804 cf49811e3cdb 5 years ago 200MB [root@jueye docker] [root@f9148c20e12c /] [root@f9148c20e12c home] CentOS Linux release 7.5.1804 (Core) [root@jueye docker] root@5221c6ac5f55:/ DISTRIB_ID=Ubuntu DISTRIB_RELEASE=20.04 DISTRIB_CODENAME=focal DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS" [root@jueye docker] ce16015d4dd6:/ openSUSE 42.3 (x86_64) VERSION = 42.3 CODENAME = Malachite
一个完整的系统是由一个linux内核加发行版组成了一个可以使用的完整的系统
利用docker容器可以方便获取不同的发行版镜像,然后基于该镜像,运行各种容器使用
理解什么是docker镜像
docker images搜索地址 https://hub.docker.com/
docker解决了环境的兼容问题,在容器中运行linux发行版,以及各种软件
环境干净,安装的所有内容都在容器里,不想要了直接删除容器,不影响宿主机
比如想把mysql容器内的数据,配置,全部迁移到服务器上,只需要提交该容器,生成镜像,再把镜像放到服务器上,docker run就能运行
一个 完整的docker镜像可以创建出docker容器并运行,我们获取的是发行版,镜像文件不包含内核。
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@jueye docker] root@50a7346bec6b:/ PRETTY_NAME="Debian GNU/Linux 11 (bullseye)" NAME="Debian GNU/Linux" VERSION_ID="11" VERSION="11 (bullseye)" VERSION_CODENAME=bullseye ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/"
docker 为什么分层镜像
镜像分层资源共享,多个镜像来自同一个base镜像,docker host只需要存储一个base镜像
内存只需要加载一份host,即可为多个容器服务
修改只限制在单个容器内,其他容器不受影响
顶层为可写的容器层
下面是只读的镜像层
获取镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 docker search 镜像名:tag tag就是具体的标签版本 docker search centos docker images docker image ls docker pull centos docker pull centos:7.8.2003 [root@jueye docker] [root@jueye docker] Docker Root Dir: /var/lib/docker [root@jueye docker] 总用量 28 -rw------- 1 root root 7656 3月 26 17:03 605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85 -rw------- 1 root root 7700 3月 27 10:02 7614ae9453d1d87e740a2056257a6de7135c84037c367e1fffa92ae922784631 -rw------- 1 root root 1462 3月 27 14:21 ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1 -rw------- 1 root root 2205 3月 27 14:25 cf49811e3cdb94cbdfd645f3888d7add06a315449cf2c7ca7b81c312f1e46c63 -rw------- 1 root root 1866 3月 27 14:57 d9e50bf288963ff3a78d1decfcd1deda5acd15a0e3094c9e4b317cf8299bd465 [root@jueye docker] [root@cce87e7d1088 /] CentOS Linux release 8.4.2105 [root@jueye docker] REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 5d0da3dc9764 2 years ago 231MB centos 7.8.2003 afb6fca791e0 3 years ago 203MB [root@jueye docker] 605c77e624dd 7614ae9453d1 ba6acccedd29 5d0da3dc9764 afb6fca791e0 d9e50bf28896 [root@jueye docker] 605c77e624dd--nginx 7614ae9453d1--redis ba6acccedd29--ubuntu 5d0da3dc9764--centos afb6fca791e0--centos d9e50bf28896--opensuse [root@jueye docker] IMAGE ID REPOSITORY TAG 605c77e624dd nginx latest 7614ae9453d1 redis latest ba6acccedd29 ubuntu latest 5d0da3dc9764 centos latest afb6fca791e0 centos 7.8.2003 d9e50bf28896 opensuse latest [root@jueye docker]
删除镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@jueye docker] Untagged: hello-world:latest Untagged: hello-world@sha256:2498fce14358aa50ead0cc6c19990fc6ff866ce72aeb5546e1d59caac3d0d60f Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412 Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359 [root@jueye docker] [root@jueye docker] docker rm `docker ps -aq`
管理镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 docker commit docker image save centos:7.8.2003 > /opt/centos7.8.2003.tgz docker image load -i /opt/centos7.8.2003.tgz docker info docker image inspect 镜像id [root@jueye docker] root@58bff6aab067:/ NAME="Ubuntu" VERSION="20.04.3 LTS (Focal Fossa)" [root@jueye docker] PING baidu.com (39.156.66.10) 56(84) bytes of data. 64 bytes from 39.156.66.10 (39.156.66.10): icmp_seq=1 ttl=127 time=27.9 ms [root@jueye docker] b6d1bf78c5d3bd296e878bb92ecae3297a2dbf50fd3d1e70ae581d14fa283a97 [root@jueye docker] [root@jueye docker] [root@jueye docker] [root@7d89cce28ce5 /] UID PID PPID C STIME TTY TIME CMD root 1 0 0 03:04 ? 00:00:00 ping baidu.com [root@jueye docker] [root@jueye docker] 3aeafcac21330851109ff5675439558446059e8e1df4069fc6218c75b4666660 [root@jueye docker]
提交容器
1 2 3 [root@jueye docker] [root@jueye docker] sha256:e240a15cbd4862dd3ad7294cdfe035dc3c93a75e8f59d61ac5b11f75d3dcd5d2
镜像是多层存储,每一层在前一层的基础上进行修改;
容器也是多层存储,以镜像为基础层,在其基础上加一层作为容器运行时的存储层
创建镜像的两个方法
手动修改容器内容,然后docker commit提交容器为新的镜像
通过dockerfile中定义一系列命令和参数构成的脚本,然后这些命令应用于基础镜像,依次添加层,最终生成一个新的镜像
dockerfile主要组成部分
基础镜像信息 FROM centos:6.8
制作镜像操作指令 RUN yum Install openssh-server -y
容器启动时执行指令 CMD [“/bin/bash”]
dockerfile 学习
需求:
让你安装一个mysql,且启动
开启虚拟机VMware
运行某个虚拟机,centos7
centos7安装mysql yum install mysql-server
通过脚本,或者命令,启动mysql即可
部署缓慢,且修改了宿主机的环境,删除较为麻烦,占用宿主机的一个端口
基于容器运行mysql
开始VMware
运行虚拟机centos7(宿主机)
安装docker容器软件
获取mysql镜像即可,docker pull mysql:tag获得的基础镜像是别人定制好的
直接运行该镜像,通过端口映射,运行mysql,docker run mysql:5.6
容器能够运行,必须在容器内有一个进程在前台运行,该容器内,有mysql在前台运行
访问宿主机的一个映射端口,访问到容器内的mysql
想自定义镜像,就要自己写dockerfile
dockerfile 指令
FROM
这个镜像的母体是谁?基础镜像
MAINTAINER
告诉别人,谁负责维护它?指定维护者信息,可以没有
RUN
你想让它干啥 在命令前面加上RUN
ADD
给它点创业资金 添加宿主机的文件到容器内,COPY文件,会自动解压
COPY
作用和 ADD
是一样的,都是拷贝宿主机的文件到容器内,但是 ADD
还能顺带解压
WORKDIR
我是cd,换了个妆 设置当前工作目录
VOLUME
给它一个存放数据的地方 设置卷,挂载主机目录
EXPOSE
它要打开的门户是啥 指定对外的端口
CMD
运行 指定容器启动后要干的事
dockerfile 实践
需求:通过dockerfile,构建nginx镜像,且运行容器后,生成的页面是 “HELLO WORLD!”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@jueye learn_docker] /learn_docker [root@jueye learn_docker] FROM nginx [root@jueye learn_docker] FROM nginx RUN echo '<meta charset=utf-8>HELLO WORLD!' > /usr/share/nginx/html/index.html [root@jueye learn_docker] [root@jueye learn_docker] REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 2edb4024387b 4 minutes ago 141MB [root@jueye learn_docker] docker run -d -p 80:80 my-nginx
COPY
1 2 3 4 5 copy hello-world.py /home/ copy hello* /tmp/cc?.txt. /home/
ADD
特性和COPY基本一致,不过多了些功能
源文件是一个URL,此时docker引擎会下载该链接,放入目标路径,且权限自动设为600
源文件是一个URL,且是一个压缩包,不会自动解压,也得单独用RUN指令解压
源文件是一个压缩文件,且是gzip,bzip2,xz,tar情况,ADD指令会自动解压缩该文件到目标路径
CMD
1 2 3 4 5 6 7 8 9 10 11 CMD ["参数1" , "参数2" ] CMD echo $PATH CMD ["sh" , "-c" , "echo $PATH " ]
容器内运行程序
docker不是虚拟机的概念,虚拟机里的程序运行,基本都是在后台,利用systemctl运行,但容器内没有后台进程的概念,必须在前台运行。容器就是为了主进程而存在的,主进程如何退出了,容器就失去了意义,自动退出
1 2 3 4 5 6 7 CMD systemctl start nginx CMD ["sh" , "-c" , "systemctl start nginx" ] CMD ["nginx" , "-g" , "daemon off;" ]
把宿主机安装,启动nginx的理念放入到dockerfile
RUN yum install nginx
RUN
配置文件修改 sed
RUN systemctl start nginx
❌ 容器内的程序必须是前台运行,否则启动不了
正确的应该是CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT
作用和 CMD
一样,都是在指定容器启动程序以及参数
当制定了 ENTRYPOINT
之后,CMD
指令的语义就有了变化
把 CMD
的内容当作参数传递给 ENTRYPOINT
指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 FROM centos:7.8.2003 RUN rpm --rebuilddb && yum install epel-release -y RUN rpm --rebuilddb && yum install curl -y CMD ["curl" , "-s" , "http://ipinfo.io/ip" ] docker build . docker tag 9d6fecfd8b8c centos_curl [root@jueye learn_docker] 117.147.106.3[root@jueye learn_docker] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@jueye learn_docker]
ARG 和 ENV 指令
设置环境变量
1 2 3 4 5 6 7 ENV NAME="JUEYE" ENV AGE='18' ENV MYSQL_VERSION=5.6
VOLUME
容器在运行时,应该保证在存储层不写入任何数据,运行在容器内产生的数据,推荐挂载写入到宿主机上进行维护
1 2 3 4 5 6 7 8 9 10 VOLUME /data FROM centos MAINTAINER Jueye VOLUME ["/data1" , "/data2" ] docker build . docker run f2aa80379f53 docker inspect
容器数据挂载的方式,通过dockerfile,指定VOLUME目录
通过 docker run -v
参数,直接设置需要映射挂载的目录
EXPOSE
指定容器运行时对外提供的端口服务
WORKDIR
用于在dockerfile中, 目录切换更改工作目录
USER
用于改变环境, 用于切换用户
构建一个网站镜像
nginx, 修改首页内容的html网站就跑起来了, web server, 提供web服务, 提供代理转发, 提供网关, 限流等… apache
web framework, web框架, 一般由开发通过某个开发语言基于某个web框架, 自己去开发一个web站点, python, django框架
用python语言,基于flask web框架,开发一个自己的网站,写了一个后端的网站代码
开发dockerfile,部署该代码,生成镜像
其他人基于该镜像,docker run就可以在电脑跑起来你的网站
比如安装一个etcd,nacos,都是比较复复杂的软件
需要依赖go语言环境,java语言环境,在自己的机器安装好对应的开发环境,以及对应的版本和依赖。
tomcat,jdk环境
当你有了docker
docker pull tomcat # 这些主流的镜像都可以找到,并且该镜像中就已经打包好了java环境
docker pull nacos # 打包好了各种依赖环境
docker run tomcat xxxx # 可以直接访问tomcat了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [root@jueye learn_docker] from flask import Flask app=Flask(__name__) @app.route('/' ) def hello(): return "hello docker, I'm Jueye." if __name__=='__main__' : app.run(host='0.0.0.0' , port=8080) touch Dockerfile vim Dockerfile FROM centos:7.8.2003 RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo; RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo; RUN yum makecache fast; RUN yum install python3-devel python3-pip -y RUN pip3 install flask COPY Jueye._flask.py /opt WORKDIR /opt EXPOSE 8080 CMD ["python3" , "Jueye_flask.py" ] docker build -t 'jueye/my_flask_web' . docker run -d --name myflask_web1 -p 90:8080 jueye/my_flask_web http://192.168.72.128:90/
如何修改该网站的内容
修改宿主机的代码以及dockerfile,重新构建
可以进入到已经运行的容器内修改代码,重启容器即可
1 2 3 4 5 6 7 docker exec -it id bash vi Jueye_flask.py exit docker restart id
docker 容器管理总结
1 2 3 docker run --name my_nginx -d --restart=always -p 7070:80 nginx
docker run 启动容器的时候,docker 后台操作流程
检查本地是否有该镜像,没有就下载
利用镜像创建且启动一个容器
分配容器文件系统,在只读的镜像层挂载读写层
宿主机的网桥接口会分配一个虚拟接口到容器中
容器获得地址池里的ip地址
执行用户指定的程序
若程序里没有进程在运行,容器执行完毕后立即终止
docker start
可以启动一个处于 stop
状态的容器
docker logs -f
查看容器内是否写入日志,-f
表示刷新日志
docker ps
查看在运行的容器,等同于 docker container ls
docker ps -a
查看挂掉以及活着的容器
docker start id
启动容器
docker stop id
停止容器
docker exec -it id bash
进入容器内
docker rm id
删除容器
docker rm `docker ps -aq`
删除所有容器
docker rm -f id
强制杀死容器
docker top
查看容器内进程信息,PID
docker stats id
查看容器内资源信息,CPU
docker inspect id
查看容器的具体信息
docker inspect --format '{{.NetworkSettings.IPAddress}}' id
拿到容器IP