docker 架构 cs架构,使用客户端访问服务端client 客户端,server 服务端,接受请求处理客户端请求
docker client 客户端,向服务端发起请求
docker daemon 后台守护程序
server 服务端
engine 容器引擎,真正处理
registry 镜像仓库、用户信息等
docker 安装 安装docker 要求,linux 内核版本大于3.10 ,查看内核版本方法:
1 2 3 [root@MiWiFi-CR6609-srv ~]# uname -a Linux MiWiFi-CR6609-srv 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
CentOS 7(使用 yum 进行安装)
1 2 3 4 5 6 7 8 9 10 11 # step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息,将软件源修改为阿里云 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3 sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo # Step 4: 更新并安装Docker-CE sudo yum makecache fast sudo yum -y install docker-ce # Step 4: 开启Docker服务 sudo service docker start
配置阿里云镜像仓库加速
容器stop之后,自动rm
1 2 3 配置 --rm 参数,stop之后自动 rm 掉容器 [root@MiWiFi-CR6609-srv ~]# docker run -d -p 80:80 --rm nginx b8d4146001662f0dba57bde728f6e3219623ca9123b9486f9b011a65c21085b1
配置容器挂掉自动重启
1 2 3 4 5 6 7 三种策略可选: no(默认):默认不重启 on-failure:指定自动重启次数 always:无限次重启 docker run -d -p 80:80 --restart on-failure:3 --rm nginx docker run -d -p 80:80 --restart always --rm nginx
配置容器中的环境变量
1 2 3 4 5 6 7 docker run -d -p 80:80 -e JAVA_ENV=DEV -e JAVA_VM=G1 nginx 检查配置好的参数 docker inspect 容器名称 打印容器中的环境变量 docker exec -it 容器名称 bash -c 'echo "$JAVA_ENV"'
资源限制
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 ``` # 第三章、安装使用dockers <!--more--> ## 3.1 docker架构和底层技术 docker是一个平台platform,上层的是application应用,中间是docker Engine 引擎,底层是硬件平台,其中的docker Engine 又包括三部分 1).后台进程dockerd 2).REST API server通信 3).CLI接口docker命令行工具。 ```cmd # 查看docker客户端和服务端的版本 [root@shuoshuo ~]# docker version Client: #客户端版本 Version: 1.13.1 API version: 1.26 Package version: docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64 Go version: go1.10.3 Git commit: b2f74b2/1.13.1 Built: Wed May 1 14:55:20 2019 OS/Arch: linux/amd64 Server: #服务端版本 Version: 1.13.1 API version: 1.26 (minimum version 1.12) Package version: docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64 Go version: go1.10.3 Git commit: b2f74b2/1.13.1 Built: Wed May 1 14:55:20 2019 OS/Arch: linux/amd64 Experimental: false # 查看docker进程 [root@shuoshuo ~]# ps -ef | grep docker root 11056 1 0 21:12 ? 00:00:00 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json --selinux-enabled --log-driver=journald --signature-verification=false --storage-driver overlay2 root 11061 11056 0 21:12 ? 00:00:00 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --debug --runtime-args --systemd-cgroup=true root 11229 11211 0 21:15 pts/0 00:00:00 grep --color=auto docker
docker使用的一些底层技术 1). Namespace 应用隔离技术 2). contral groups 资源限制技术 3).unionfile systems 分层技术
Docker 的三大核心概念:
镜像(Image)
容器( Container )
仓库( Repository)
社区版本每个月会发布一次尝鲜( Edge )版本,每个季度( 3 、6 、9 、12 月)会发行一次稳定( Stable )版本。版本号命名格式为“年份.月份”,如2018 年6 月发布的版本号为vl8.06 。
1 2 3 4 5 6 uname -a #查看Linux内核版本需要高于3.1 yum update #可选更新Linux内核 yum install docker #安装docker systemctl start docker #启动dockers systemctl enable docker #设置docker开机启动 systemctl stop docker #关闭docker
3.2 docker image 镜像 image 由 文件和mate data组成,每一个镜像本身是只读的
1 2 3 4 5 image4 image3 image2 image1 ubuntImg centorImg debanImg #这三个都是baseImage Linux Kemel (bootfs) #Linux内核文件系统
3.3 DIY base Image 1 2 3 4 #将当前用户添加到docker组中,以便于可以使用docker命令 sudo groupadd docker sudo gpasswd -a vagrant docker sudo docker restart
1 2 3 4 5 6 7 8 9 10 11 12 #官方hello-world示例 [root@shuoshuo dockert]# docker pull hello-world [root@shuoshuo dockert]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/hello-world latest fce289e99eb9 6 months ago 1 .84 kB #运行镜像 [root@shuoshuo dockert]# docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #自己创建一个image,类似官方的hello-world #yum 查看所有安装的软件包 [root@shuoshuo dockert]# yum list installed #安装两个需要的软件,-y 默认选中yes [root@shuoshuo dockert]# yum install -y gcc [root@shuoshuo dockert]# yum install -y glibc-static #创建文件 [root@shuoshuo dockert]# vi hello-world-shuoshuo.c # 文件内容: #include<stdio.h> int main(){ printf("hello word --DIV docker image\n"); } #编译.c文件,生成一个 hello文件 [root@shuoshuo dockert]# gcc -static hello-world-shuoshuo.c -o hello [root@shuoshuo dockert]# ll -rwxr-xr-x. 1 root root 856792 7 月 20 21 :53 hello -rw-r--r--. 1 root root 76 7 月 20 21 :53 hello-world-shuoshuo.c # 执行hell文件 [root@shuoshuo dockert]# ./hello hello word --DIV docker image
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 # 接上面,正式docker指令 # 再dockert文件夹下创建一个文件 [root@shuoshuo dockert]# vi Dockerfile [root@shuoshuo dockert]# cat Dockerfile FROM scratch ADD hello / #两个参数 hello 是.c文件编译后的可执行文件 / 代表根目录 CMD ["/hello"]#正式构建一个image,名称为shuoshuo/hello-dockert,注意最后有一个英文点 [root@shuoshuo dockert]# docker build -t shuoshuo/hello-dockert . Sending build context to Docker daemon 860 .7 kB Step 1 /3 : FROM scratch ---> Step 2 /3 : ADD hello / ---> be49755d4013 Removing intermediate container f2e4cddd38a7 Step 3 /3 : CMD /hello ---> Running in efba8530587e ---> 668 ed64e0e91 Removing intermediate container efba8530587e Successfully built 668 ed64e0e91 [root@shuoshuo dockert]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE shuoshuo/hello-dockert latest 668 ed64e0e91 2 minutes ago 857 kB docker.io/hello-world latest fce289e99eb9 6 months ago 1 .84 kB #运行自己的镜像,打印hello word --DIV docker image 一行华 [root@shuoshuo dockert]# docker run shuoshuo/hello-dockert hello word --DIV docker image
3.4 容器 container
通过image创建
再image上再加一层可读可写的层,运行的时候修改的就是最顶上这一层,别的都不东
Image负责存储和分发,而container负责运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #创建container [root@shuoshuo dockert]# docker run shuoshuo/hello-dockert hello word --DIV docker image #查看正在运行中的容器,一个也没有 [root@shuoshuo dockert]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES #查看所有的容器,包括已经运行结束的 [root@shuoshuo dockert]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9 f58c6d0f2be shuoshuo/hello-dockert "/hello" 7 minutes ago Exited (30 ) 7 minutes ago pedantic_hopperbb6b7dc098b9 hello-world "/hello" 27 minutes ago Exited (0 ) 26 minutes ago loving_bhaskara
pull一个contos镜像,进到里面去,并且在里面安装vim,
1 2 3 docker pull centos docker run -it centos exit #退出
删除镜像或者容器,和简写
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 #镜像,删除镜像前需要先删除所有产生的容器, [root@shuoshuo dockert]# docker image rm fce289e99eb9 # 容器 [root@shuoshuo dockert]# docker container rm (容器ID,CONTAINER ID,48 c4e5f4c249,02 d23e56f) [root@shuoshuo dockert]# docker rm (容器ID,CONTAINER ID,48 c4e5f4c249,02 d23e56f) #批量删除容器,-q 只显示所有容器的ID [root@shuoshuo dockert]# docker ps -aq b1c4c8064eac 136 edede57ca#上面命令类似与下面命令只打印第一行 [root@shuoshuo dockert]# docker ps -a | awk {'print $1 '} CONTAINER b1c4c8064eac 136 edede57ca#删除所有容器 [root@shuoshuo dockert]# docker rm $( docker ps -aq ) #打印所有未运行的容器 [root@shuoshuo dockert]# docker container ls -f "status=exited" #删除所有未运行的容器 [root@shuoshuo dockert]# docker rm $( docker container ls -f "status=exited" -aq )
简写命令
1 2 3 4 5 6 7 [root@shuoshuo dockert]# docker container ls [root@shuoshuo dockert]# docker ps [root@shuoshuo dockert]# docker image ls [root@shuoshuo dockert]# docker images
3.5 构建自己的docker镜像 通过容器构建自己的image容器,两个命令
1 2 docker container commit 可以简写成 docker commit
1 2 3 4 5 6 7 8 9 #交互环境启动docker中的centos容器 #在centos里面yun install vim 然后退出 [root@shuoshuo ~]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 296 d6710237f docker.io/centos "/bin/bash" 6 minutes ago Exited (0 ) 3 minutes ago adoring_curie[root@shuoshuo ~]# docker commit adoring_curie shuoshuo/centos-vim #命令 docker commit 容器名称NAMES 镜像名称
第二种根据image创建镜像,然后根据镜像生成属于自己的image
1 2 3 4 5 6 7 [root@shuoshuo ~]# mkdir docker-contos-vim [root@shuoshuo ~]# cd docker-contos-vim/ [root@shuoshuo docker-contos-vim]# vi Dockerfile FROM centos RUN yum install -y vim [root@shuoshuo docker-contos-vim]# docker build -t shuoshuo2/centos-vim-new2 .
3.6Dockerfile语法梳理和实践 FROM 1 2 3 4 5 FROM #在哪个baseImage之上构建 FROM centos #使用base Image centos之上构建 FROM scratch #制作base image使用 ,helloworld没有用baseImage就from scratch FROM ubuntu:14 .04 #使用要点:尽量使用官方image作为base image
MAINTAINER 1 2 描述镜像作者,以及联系方式 MAINTAINER wolfcode<aaaa@bbbb.com>
LABEL 1 2 3 4 5 LABEL #保留一些帮助信息,就是注释LABEL maintainer="xxx@123 .com"LABEL version="1 .0 "LABEL description = "This is description"
RUN 1 2 3 4 5 6 7 8 9 10 11 RUN #执行的代码 RUN yum install -y vim RUN yum update && yum install -y vim python-dev RUN yum update && \ yum install -y vim python-dev RUN ["可执行文件","文件执行参数","文件执行参数"] # 直接调用sh文件写法 # 为了美观,复杂的RUN使用 \ 反斜线换行 # 避免无用分层,合并多头命令一行执行,中间用 && 连接 # 程序在build中使用的命令,执行的时候不会运行RUN命令
WORKDIR 1 2 3 4 5 6 7 8 WORKDIR #改变目录 WORKDIR /test #没有则创建目录 WORKDIR demo #进入目录demo RUN pwd #打印/test/demo # 使用 WORKDIR,不要使用 RUN cd !!! # 尽量使用绝对路径
VOLUME 1 2 3 4 # 镜像数据卷绑定,将主机中的指定目录挂载到容器中 VOLUME ["/roott/data/volume_1"] # 事实上dockerfile也不允许在file中指定数据卷的挂载,如果想挂载的话在docker run命令中指定
EXPOSE 1 2 3 4 # 运行后需要暴露端口,但仅仅表示该容器想要暴露端口,并不会具体暴露出来 # 具体暴露出来需要 在 run -p 参数指定 EXPOSE 80 # 表示容器要暴露80端口,和主机没有关系
ADD and COPY 1 2 3 4 5 6 7 8 9 10 ADD and COPY #将本地文件添加到镜像中 ADD hello / #将本地文件添加到镜像中的 / 路径下 ADD test.tar.gz / #将文件添加到根目录并解压 WORKDIR /root ADD hello test/ #将hello文件添加到 /root/test/目录中 ADD ["/root/data/file","/root/data/file"] # 大部分情况下copy 优于add # add除了copy 还有额外的解压功能 # 添加远程文件或者目录请使用 curl 或者 wget
ENV 1 2 3 4 5 6 ENV #设置环境变量 ENV MYSQL_VERSION 5 .6 #设置环境变量,一行一个 ENV mysql_version=5 .6 JAVA_HOME=/root/data/java # 一行写多个环境变量 RUN apt-get install -y mysql-service="$MYSQL_VERSION" #RUN 命令中 引用变量
其余命令 1 2 VOLUME 和 EXPOSE 存储和网络 CMD 和 ENTRYPOINT
3.7 RUN and CMD and ECTRYPOINT 1 2 3 4 5 6 7 8 RUN 指令:用于指定 docker build 过程中要运行的命令。 语法格式: RUN <command> 或 RUN ["<executeable>" ,"<param1>" ,"param2" ,...] RUN ["/bin/bash" ,"-c" ,"<executeable>" ,"param1" ,"param2" ,...] 例如: RUN yum install iproute nginx && yum clean all
CMD 和 ECTRYPOINT 选择一个就可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 CMD 指令:类似于 RUN 指令,用于运行程序,但二者运行的时间点不同;CMD 在docker run 时运行,而非docker build; CMD 指令的首要目的在于为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束;注意: CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。 语法格式: CMD <command> 或 CMD ["<executeable>" ,"<param1>" ,"<param2>" ,...] CMD ["<param1>" ,"<param2>" ,...] 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数; 例如: CMD ["/usr/sbin/httpd" ,"-c" ,"/etc/httpd/conf/httpd.conf" ] 注意:如果 dockerfile 中如果存在多个CMD指令,仅最后一个生效; 例如: FROM centos ENV name dockershuoshuo CMD echo "shuoshuo,$name" [root@shuoshuo cmd]# docker run shuo/cmd_shell shuoshuo,dockershuoshuo [root@shuoshuo cmd]# docker run shuo/cmd_shell /bin/bash #不打印那行话 [root@shuoshuo cmd]# # CMD ping 127.0 .0 .1 # CMD ["sh" , "-c" , "ping 127.0.0.1" ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ENTRYPOINT 指令:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序,让容器以应用程序或者服务的形式运行,不会被忽略,一定执行。 但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序; 比CMD使用的比较多 语法格式: ENTRYPOINT <command> 或 ENTRYPOINT ["<executeable>" ,"<param1>" ,"<param2>" ,...] 例如: CMD ["-c" ] ENTRYPOINT ["top" ,"-b" ] 最佳实践mongod安装: COPY mong.sh /user/local/bin ENTRYPOINT ["mong.sh" ] EXPOSE 27017 CMD ["mongod" ]
shell 和 exec 两种写法的区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 shell 格式 RUN apt-get install -y vim CMD echo "hello docker" ENTRYPOINT echo "hello docker" EXEC格式 RUN ["apt-get" ,"install" ,"-y" ,"vim" ] CMD ["/bin/echo" ,"hello docker" ] ENTRYPOINT ["/bin/echo" ,"hello docker" ] FROM centos ENTRYPOINT echo "hello,$name" #会替换变量 ENTRYPOINT [ "/bin/echo" ,"hello $name" ] #不会替换变量,执行echo命令,不是shell ENTRYPOINT [ "/bin/bash" ,"-c" ,"echo" ,"hello,$name" ] #不会替换变量 ENTRYPOINT [ "/bin/bash" ,"-c" ,"echo hello $name" ] #会替换变量 shell类型命令执行命令会识别$符号代表一个变量,会替换 EXEC格式打印字符串的时候,只是执行echo命令
1 2 3 4 5 6 7 8 9 10 FROM centosENV name dockershuoshuoCMD echo "shuoshuo,$name " FROM centosENV name shuohsuoCMD ["/bin/echo" ,"echo hello $name " ]
补充命令 ARG 1 2 3 4 5 6 7 8 9 10 11 ARG 命令,定义一个有默认值的变量,build的时候可以录入,也可以用默认值 语法:ARG <name>[=<default value>] dockerfile写法: ARG jdk=1.8 FROM openjdk:$jdk build 的时候的两种写法 docker build -t --build-arg jdk=11 # 指定版本为 11 docker build -t # 默认使用版本1.8
USER
ONBUILD 1 2 3 4 5 6 7 再有另外一个镜像,基于该镜像FROM 的时候会执行的命令。 镜像A设置如下命令: ONBUILD RUN ls -al 镜像B: FROM 镜像A ... 构建镜像B 时,会执行 ls -al 命令
docker官网服务 1 2 3 docker longin #登录 docker push 自己的名字/镜像名称:latest #上传 docker pull 自己的名字/镜像名称:latest #拉取
搭建私有的docker restart
1 docker run -d -p 5000 :5000 --restart always --name registry registry:2
1 2 telnet 10.75 .44 .222 5000 yum install telnet
1 2 3 4 5 6 7 8 9 10 11 12 docker build -t shuoshuo2/centos-vim-new2 . docker build -t 10.75 .44.222 :5000 /hello-world . docker push 10.75 .44.222 :5000 /hello-world vim /etc/docker/daemon.json { "insecure-registries" : ["10.75.44.222:5000" ] } vim /lib/systemd/system/docker.service EnvironmentFile=-/etc/docker/daemon.json
3.9 Dockerfile实战 创建文件app.py内容如下
1 2 3 4 5 6 7 from flask import Flaskapp = Flask(__name__) @app.route("/" ) def hello (): return "hello docker" if __name__ == '__main__' : app.run()
执行文件app.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 yum -y install wget wget https://bootstrap.pypa.io/get-pip.py python get-pip.py pip install flask python app.py FROM python:2.7 LABEL maintainer="Peng Xiao<soobaby@live.com>" RUN pip install flask COPY app.py /app/ WORKDIR /app EXPOSE 5000 CMD ["python" ,"app.py" ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Linux下载网站成一个本地文件 [root@shuoshuo ~]# wget http: 打印网站文件内容 [root@shuoshuo ~]# curl 127.0.0.1:5000 hello docker #查看进程 ps -ef # 查看后台运行的网站服务 [root@shuoshuo ~]# ps -ef | grep python root 1201 1 0 09 :15 ? 00 :00 :00 /usr/bin/python2 -Es /usr/sbin/tuned -l -P root 1645 1594 0 09 :20 pts/0 00 :00 :00 python app.py root 1883 1816 0 09 :31 pts/2 00 :00 :00 grep --color=auto python #结束程序 kill -9 1645
1 2 3 4 5 查看build中的错误 docker run -t 中间image编号 /bin/bash #后台运行 -d 参数 docker run -d shuo/flask-hallo-world2
3.10容器操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 docker exec docker exec -it 容器ID /bin /bash docker exec -it 容器ID python exit docker run -d --name=containerName shuo/stress docker container stop 容器ID或者容器名称 docker stop 容器ID或者容器名称 docker container start 容器ID或者容器名称 docker start 容器ID或者容器名称 docker inspect 容器ID docker logs 运行中的容器ID
3.11容器实战2 给容器提供输入参数
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 下载创建ubuntu镜像,进入容器内部,运行命令,安装stress压力测试工具 apt-get update && apt-get install -y stress root@fdde35612edc:/ /usr/bin /stress ps -ef docker stress --vm 1 --vm-bytes 200M (默认256 内存) --verbose (debug输出) top 命令 FROM ubuntu RUN apt-get update && apt-get install -y stress ENTRYPOINT ["/usr/bin/stress" ] CMD [] [root@shuoshuo ~] --vm 1 --verbose 都是传递给 里面的stress命令 -m --memory bytes --memory-swap bytes -c --cup-shares int [root@shuoshuo ~] [root@shuoshuo ~] [root@shuoshuo ~]
3.12操作 1 2 3 4 5 docker search redis #检索镜像 docker pull 镜像名:tag版本号 #名称:版本号 docker pull mysql #默认最新版稳定版latest版本 docker pull mysql:5.5 #指定版本 docker pull hub.c.163.com/public/ubuntu:18.04 #指定镜像仓库
1 2 3 # 配置国内镜像站点加速 vi /etc/docker/daemon.json "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"] #在json文件中加一句这个地址好像也错误的
查看镜像命令ls,tag,inspect三个命令
images查看本机镜像
1 2 3 4 5 6 7 8 9 10 11 docker images 输出信息包括 REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/mysql latest c7109f74d339 4 weeks ago 443 MB REPOSITORY:名称 TAG:版本 IMAGE ID:镜像的ID(唯一标识镜像)ID相同则指向同一个镜像 CREATED:创建事件 size:镜像大小
创建镜像的带标签别名版本
1 2 3 4 5 6 7 8 9 10 11 12 docker tag 原镜像名称:原镜像版本 别名:别名版本 [root@shuoshuo ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/mysql latest c7109f74d339 4 weeks ago 443 MB [root@shuoshuo ~]# docker tag docker.io/mysql:latest mysql:latest [root@shuoshuo ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/mysql latest c7109f74d339 4 weeks ago 443 MB mysql latest c7109f74d339 4 weeks ago 443 MB
配置容器自启动和
1 2 3 4 5 6 7 # 配置 docker 开机自动启动 systemctl enable docker # 容器已经启动情况下 docker update --restart=always 容器ID或者名称 # 容器创建的时候 docker run -d --restart=always xxx
批量删除脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # !/bin/bash # 输入需要删除的镜像名称 del_images=('weixin' 'qq') for i in ${del_images[*]}; do if [ -n "docker images | grep '\<${del_images[i]}\>'|awk '{print $1":"$2}' |awk 'NR>2'"] then # 执行后,只会保留最新的两个Docker镜像 docker images | grep '\<${del_images[i]}\>'|awk '{print $1":"$2}' |awk 'NR>2'|xargs docker rmi else echo "暂无可删除镜像" fi done
第四章、Docker Network 单机
Bridg Network
Host Network
None Network
多机网络
Overlay Network
环境准备 两台虚拟机IP分别位 192.168.205.10 192.168.205.11,两台机器可以ping通
4.2基础网络回顾 基于数据包的通讯方式,网络分层概念
ISO七层模型,TCP/IP五层模型,
IP地址 和 路由的概念,公有网络和内部私有网络
ping和telnet,
ping验证IP的可达性,ping不通有可能是防火墙阻断
telnet:服务可用性,端口可以访问
地址+端口 返回拒绝,代表服务不可达
地址+端口 返回通过,代表服务可达
ping 不通,但是80端口telnet可以达到,代表服务可以访问。
抓包工具 wire shark
4.3Linux网络命名空间 netnamespace 网络命名空间
启动一个linux
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 docker run -d --name test1 busybox /bin/sh -c "while true; do sleep 3600 ; done" # busybox 非常小的Linux binbash #再里面查看ip地址 ip a # 容器里面的ip a 和 外面宿主机的ip a是不同的,网络是隔离的 #创建和删除networknamespace ip netns list #查看networknamespace ip netns delete XXx #删除newworknamespace ip netns add test1 #创建两个 ip netns add test1 #查看信息test1 命名空间中的ip信息 ip netns exec test1 ip a ip link #查看信息
4.4 dockers Bridge0 详解 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 [root@shuoshuo ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 090 ac271d148 bridge bridge localfe4bafdb7bb7 host host local c7825e2ab4b4 none null local bridge #Linux最重要的网络 # [root@shuoshuo ~]# docker network inspect 090 ac271d148 [ ... "Containers": { "07 a45b7c3e9de15366570f4d1b40263971c7eb790cab8b7cadb1b08bb697da55": { "Name": "dockerTest2", "EndpointID": "331 a55ee0e90fe584eca935fbadc4469f4dad22989df88dd1a514054e0d23119", "MacAddress": "02 :42 :ac:11 :00 :02 ", "IPv4Address": "172 .17 .0 .2 /16 ", "IPv6Address": "" } ... ] [root@shuoshuo ~]# ip a #安装个软件 [root@shuoshuo ~]# sudo yum install bridge-utils [root@shuoshuo ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000 .0242900 f2f79 no veth1261a32
docker 里面两个容器如何通信,并且容器如何和外部通讯
4.5 容器之间的link 1 docker run -d --name test2 --link test1 busybox /bin/sh -c "while true; do sleep 3600 ; done"
-p 端口映射 -p 80:80
4.8多容器复杂应用的部署 app.py 程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from flask import Flaskfrom redis import Redisimport osimport socketapp = Flask(__name__) redis = Redis(host=os.environ.get('REDIS_HOST' , '127.0.0.1' ), port=6379 ) @app.route('/' ) def hello (): redis.incr('hits' ) return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits' ),socket.gethostname()) if __name__ == "__main__" : app.run(host="0.0.0.0" , port=5000 , debug=True )
Dockerfile
1 2 3 4 5 6 7 FROM python:2.7 LABEL maintaner="Peng Xiao xiaoquwl@gmail.com" COPY . /app WORKDIR /app RUN pip install flask redis EXPOSE 5000 CMD [ "python" , "app.py" ]
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 [root@shuoshuo pythonflastredis] [root@shuoshuo pythonflastredis] [root@shuoshuo pythonflastredis] root@b253efbc7a02:/app .... REDIS_HOST=redis .... root@b253efbc7a02:/app PING redis (172.17 .0 .3 ) 56 (84 ) bytes of data. 64 bytes from redis (172.17 .0 .3 ): icmp_seq=1 ttl=64 time=0.365 ms64 bytes from redis (172.17 .0 .3 ): icmp_seq=2 ttl=64 time=0.157 msroot@b253efbc7a02:/app Hello Container World! I have been seen 1 times and my hostname is b253efbc7a02. [root@shuoshuo pythonflastredis]
1 2 3 4 #run启动容器的时候设置环境变量 docker run -d PENG=VALUE 镜像ID #在Linux中查看环境变量 env
4.9多机器通信 python flast 部署在机器1
redis 部署在机器2上
创建两个虚拟机,之间可以互相ping通
docker-node1 192.168.205.10
docker-node2 192.168.205.11
1 2 3 4 5 6 7 8 9 10 Docker 安装mysql docker run -p 3306:3306 -it #端口映射 --name mysql3 #给容器起别名 -v /scy/mysql/conf:/etc/mysql/conf.d #文件挂载 -v /scy/mysql/logs:/logs -v /scy/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --privileged=true mysql
1 docker run -p 3306:3306 --name mysql -v /scy/mysql/conf:/etc/mysql/conf.d -v /scy/mysql/logs:/logs -v /scy/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d docker.io/mysql
docker run -p 3306:3306 –name mysql -v /scy/mysql/conf:/etc/mysql/conf.d -v /scy/mysql/logs:/logs -v /scy/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
第五章、持久化机制 1 2 3 正常启动docker mysql 错误,查看日志 dokcer logs mysql1(容器名称) docker logs 容器名称
Container容器里面写文件系统,默认会写道container layer可写层,容器删除则数据layer层也都没了,修改默认机制,将layer写到容器外面,将数据和容器隔离开,将数据写到外挂的本地文件系统中,容器被删除,数据改在。
两种数据持久化的方案
基于本地文件系统的volum
可以再执行Docker create 或者 Docker run时,通过 -v参数将本地的目录作为容器的数据卷,这部分功能,是基于本地文件系统的volume管理.
基于plugin的Volume
支持第三方的存储方法,比如NAS,aws
volume的两种类型
受管理的data volume,由docker后台自动创建
加不加-v都会自动创建后台的volume
绑定挂载的volume,具体挂载位置可以由用户指定
数据持久化1:Data Volume dicker file volume
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 docker volume ls [root@shuoshuo dockert] DRIVER VOLUME NAME local 4 fd996ab13b3f27fdd599519d4acf1607ba588f5f3649a1d75049aa1adbd6e77 local mysqlfile [root@shuoshuo dockert] --------------------------------------- [root@shuoshuo ~] [root@shuoshuo ~] [root@shuoshuo ~] [ { "Driver" : "local" , "Labels" : null, "Mountpoint" : "/var/lib/docker/volumes/f61f9028ccf7782fa4dd70800162a423089ef10ef667c73a5a032e1d1a8e664d/_data" , "Name" : "f61f9028ccf7782fa4dd70800162a423089ef10ef667c73a5a032e1d1a8e664d" , "Options" : {}, "Scope" : "local" } ] docker volume rm xxxxaaaffff -v mysql:/var/lib/mysql docker run -d -v mysql:/var/lib/mysql --name mysql -e MYSQL_ALLOW_EMPTY_SWORD=true mysql docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 mysql docker run -p 3306:3306 --name mysql -v $PWD /data:/mysql_data -e MYSQL_ROOT_PASSWORD=123456 -d mysql
数据持久化2:Bind Mounting 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 docker run -v /home/aaa:/root/aaa [root@shuoshuo docker-nginx] /root/docker-nginx [root@shuoshuo docker-nginx] 总用量 8 -rw-r--r--. 1 root root 78 8 月 2 22 :20 Dockerfile -rw-r--r--. 1 root root 10 8 月 2 22 :19 index.html [root@shuoshuo docker-nginx] FROM nginx:latestWORKDIR /user/share/nginx/html COPY index.html index.html [root@shuoshuo docker-nginx]
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 # 挂载.html文件演示样例 # 目录 [root@shuoshuo bindMounting]# pwd /root/bindMounting # Dockerfile文件内容 [root@shuoshuo bindMounting]# cat Dockerfile FROM nginx:latest WORKDIR /usr/share/nginx/html COPY index.html index.html# index主页内容 [root@shuoshuo bindMounting]# cat index.html 1237890 #执行命令 [root@shuoshuo bindMounting]# docker run -d -p 80 :80 -v $(pwd):/usr/share/nginx/html --name webbindmounting shuoshuo/web2 # 遇到的问题,docker 挂载没有权限问题,CentOS7中Docker文件挂载的权限 # https://blog.csdn.net /whatwhowhere/article/details/81092214 # 添加selinux规则,将要挂载的目录添加到白名单: # 示例:chcon -Rt svirt_sandbox_file_t /root/bindMounting # 之后执行:docker run -i -t -v /docker /root/bindMounting --name eureka1 centos:7 .5 .1804
演示实例python flask框架挂载演示
1 2 3 4 5 6 export APP_SETTINGS="skeleton.server.config.ProductionConfig" python manage.py create_db python manage.py create_adming python manage.py create_data python manage.py runserver -h 0.0.0.0
Dockerfile
1 2 3 4 5 6 7 8 FROM python:2.7 LABEL maintainer="Peng Xiao<xiaoquwl@gmail.com>" COPY . /skeleton WORKDIR /skeleton RUN pip install -r requirements.txt EXPOSE 5000 ENTRYPOINT ["scripts/dev.sh" ]
第六章、docker Compose 批处理
基于docker的命令行工具
通过一个yml文件定义多容器的docker应用
通过一条命令就可以根据yul文件的定义取创建或者管理多个容器
安装docker compose
1 https://docs.docker.com/compose/install/
文件名称:docker-compose.yml,版本选择version3,version2和3比较大的区别是2是单机版本的,3可以是多机器版本,其中的三大概念
Services
一个services代表一个container,可以从dockerhub直接pull下来,或者从本地Dockerfile的build出来一个image创建。 service的启动类似docker run,我们可以给其指定network和volume,所以可以给service指定network和volume的引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 services: db: image: postgres:9.4 volumes: - "db-data:/var/lib/postgresql/data" networks: - back-tier 等价于: docker run -d --network back-tier -v db-data:/var/lib/postgresql/data postgres:9.4 services: worker: build: ./worker links: - db - redis networks: - back-tier
Networks
Volumes
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 version: "3" services: wordpress: image: wordpress ports: - 8080 :80 environment: WORDPRESS_DB_HOST: mysql WORDPRESS_DB_PASSWORD: root networks: - my-bridge mysql: image: mysql_wordpress environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: wordpress volumes: - mysql-data:/ver/lib/mysql networks: - my-bridge volumes: mysql-data: networks: my-bridge: driver: bridge
docker Compose 安装和使用 1 2 3 4 https://docs.docker.com/compose/install/ #docker compose 网址 sudo curl -L "https://github.com/docker/compose/releases/download/1.2 # 下载 sudo chmod +x /usr/local/bin/docker-compose # 给可执行权限
docker compose是docker的一个命令行工具,一般情况下mac和win会一起安装
1 2 3 xshell6传递文件到虚拟机里面 [root@shuoshuo ~]# yum -y install lrzsz # 安装软件 [root@shuoshuo bin]# rz -y # 执行命令,弹出文本框,就可以选择文件上传。
docker-compose命令
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 # docker-compose up --help 默认的文件名是 docker-compose.yml,也可以指定 docker-compose -f docker-compose.yml up docker-compose up docker-compose up -d #-d 后台运行的参数 # 停止 docker-compose stop # 启动 docker-compose start # 停止并且删除 docker-compose down # 查看images [root@shuoshuo docker_compose]# docker-compose images Container Repository Tag Image Id Size --------------------------------------------------------------------------------- docker_compose_mysql_1 mysql latest c7109f74d339 422 MB docker_compose_wordpress_1 docker.io/wordpress latest d4f29e1a3462 478 MB # 进入容器里面 docker-compose exec mysql bash # 退出 exit
演示样例2 python+redis
1 2 3 4 5 6 7 8 9 10 11 12 version: "3" services: redis: image: redis web: build: context: . dockerfile: Dockerfile ports: - 8080 :5000 environment: REDID_HOST: redis
第七章、Swarm Mode 容器编排 节点角色
Manager管理节点,Manager之间数据同步使用分布式的存储数据库,使用Raft协议实现同步,保证Manager节点之间数据是同步的
Worker 实际的工作的节点,worker之间数据同步使用Gossip network网络来实现
service和Replicas
service和docker compose 里面的service意思基本一样,但是在replicas模式下横行做扩展的时候,一个replicas就是一个容器例如一个service是nginx,要给他做三个扩展,三个容器,会通过调度系统把他调度到不同的node上面,也就是通过swarm manage去部署一个service的时候,其实是不知道service会最终运行在哪些service 节点上面的,这个会有service 使用调度算法进行计算,例如哪些节点内存和cpu使用较少,则将服务部署在这个节点上
7-2创建一个三节点的swarm集群 1 2 3 docker swarm init --advertise-addr=192.168 .. #当前自己的IP,这个节点会称为Manage节点 会打印出来一些内容例如下面,只需要将中间的docker swarm join...2377 之间的文本复制到别的容器中执行就可以。别的linux主机就会称为一个子节点,
1 2 3 4 5 6 7 8 $ docker swarm init --advertise-addr=192 .168 .0 .48 Swarm initialized: current node (hhn2giwdrtuv4swp2y3lrvund) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1 -69 rmn2ok6xbp5jj37fsmuiw9ump5e4f2ao32t8eh2e1n1sgj0m-ek3g85keoan1sj7cqwlm7xiqc 192 .168 .0 .48 :2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
主节点查看自己所有的子节点的命令,子节点无法使用
1 docker node ls #查看当前swarm节点
使用docker play在新学习docker
1 网址:https://labs.play-with-docker.com/
7.3Service的维护和水平扩展 主要会介绍一个service的概念。service就类似与一个container容器,使用swarm启动容器的时候,可能会将service部署到任何一个节点上。
使用swarm创建一个service
1 2 3 命令:docker service docker servcice create 在swarm模式下不要使用docke run,docker run是在本地创建一个container,在swarm中创建容器的时候,不一定会运行在本地
在swarm模式中启动一个容器
1 docker service create --name demo busybox sh -c "while true;do sleep 3600;done"
查看所有运行的容器
查看service的详细信息,以及在哪台机器上运行
1 2 docker service ps [容器名称] docker service ps demo
查看swarm中运行的容器
其中REPLICAK 1/1代表可以横向扩展
将一个容器水平扩展成五个容器
1 2 3 docker service scale demo=3 docker service ls 5/5 代表五个容器都在运行
强行删除某个节点上的容器
1 2 3 docker rm -f 容器ID docker service ls #查看容器的数量,会发现自动重启了 docker service ps demo
7.4在swarm集群中通过service部署wordpress 使用组件一个mysql和wordpress。
swarm模式下mysql和wordpress随机部署在不同的机器上,为了让他们之间相互通信,需要先手动构建一个network overlay。
1 2 3 4 docker network create -d overlay demo 网络名称为demo docker network ls 查看网络信息
创建mysql
1 docker service create --name mysql --env MYSQL_ROOT_PASSWORK=ROOT --env MYSQL_DATABASE=wordpress --network demo --mount type=volume,source=mysql-data,destination=/var/lib/mysql mysql
查看musql在那里
安装wordpress
1 docker service create --name wordpress -p 80:80 --env WORDPRESS_DB_PASSWORD=root --env WORDPRESS_DB_HOST=mysql --network demo wordpress
7.5集群服务间通信 7.6RoutingMesh之Ingress负载均衡 搜索 lvs keepalived配置高可用负载均衡
JAVAWEB