--- title: Docker date: 2021-03-23 10:30:31 author: 文永达 top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/67239FBB-E15D-4F4F-8EE8-0F1C9F3C4E7C.jpeg --- # Docker 简介 --- Docker:海豚,身上背着一堆集装箱 场景: 传统的服务器 Docker 1G左右 几十兆几百兆 CentOS占CPU Docker CPU引擎占用低 1-2分钟 几秒 安装软件 安装方便 部署应用 部署应用,挂载,数据卷 多个应用放到一起 每个应用服务都是一个容器,相互隔离 一个独立的操作系统 必须依赖于操作系统,推荐使用Linux # Docker 安装 ```shell curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun # 另一种方式 curl -sSL https://get.daocloud.io/docker | sh # 如上述两种方式都不行 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 查看所有可安装版本 yum list docker-ce --showduplicates | sort -r # 安装 yum install docker-ce-18.03.1.ce # almalinux centos8 # 添加必要的Docker存储库 dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo # 找到Docker CE的可安装版本 dnf list docker-ce --showduplicates | sort -r # 安装Docker CE dnf install docker-ce-3:24.0.7-1.el9 ``` 1、镜像:image。一个镜像代表一个软件。如:redis镜像,mysql镜像,tomcat镜像。。 特点:只读 2、容器:container。一个镜像只要一启动,称之为启动了一个容器。 3、仓库:repository。存储docker中的镜像具体位置 远程仓库:在全球范围内有一个远程仓库 本地仓库:当前自己机器中下载的镜像存储位置 Docker配置阿里云镜像加速 https://www.cnblogs.com/LUA123/p/11401962.html # Docker 使用 ## 查看 Docker 信息 ```shell docker info ``` ## 查看 Docker 镜像 image ```shell docker images ``` ## Docker 安装镜像 image MySQL 5.7 ```shell docker pull mysql:5.7 ``` ## Docker 移除镜像 image 若已有镜像用于容器,请先将容器删除 ```shell docker rm -f ``` ```shell docker image rm hello-world docker rmi hello-world ``` ```shell # 第一个8080是外部海豚上的 第二个8080是内部集装箱上的 docker run -p 8080:8080 ``` -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项; -d: 后台运行容器,并返回容器 ID; -i: 以交互模式运行容器,通常与 -t 同时使用; -P: 随机端口映射,容器内部端口随机映射到主机的端口 -p: 指定端口映射,格式为:主机 (宿主) 端口:容器端口 -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用; --name="nginx-lb": 为容器指定一个名称; --dns 8.8.8.8: 指定容器使用的 DNS 服务器,默认和宿主一致; --dns-search example.com: 指定容器 DNS 搜索域名,默认和宿主一致; -h "mars": 指定容器的 hostname; -e username="ritchie": 设置环境变量; --env-file=[]: 从指定文件读入环境变量; --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定 CPU 运行; -m : 设置容器使用内存最大值; --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型; --link=[]: 添加链接到另一个容器; --expose=[]: 开放一个端口或一组端口; --volume , -v 绑定一个卷 docker启动容器 ```shell docker start ``` docker停止容器 ```shell docker stop ``` docker重启容器 ```shell docker restart ``` ## Docker 容器与宿主机时间不同步 对于已创建的容器: ```shell docker cp /usr/share/zoneinfo/Asia/Shanghai :/etc/localtime ``` 创建容器前 ```shell docker run -d -p 8080:80 -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone ``` ## 修改运行中的 Docker 容器的端口映射和挂载目录 方法一:删除原有容器,重建新容器 参考以上移除容器,启动容器 方法二:修改配置文件,重启docker服务 容器配置文件路径: /var/lib/docker/containers/[[hash_of_the_container]/hostconfig.json] 其中的hashofthecontainer是docker镜像的hash值,可以通过docker ps或者docker inspect containername查看。(CONTAINER ID就可以看出来) 可以到/var/lib/docker/containers目录下,ls -l ```json {"Binds":["/usr/docker/redis/redis-slave2.conf:/usr/local/etc/redis/redis.conf"],"ContainerIDFile":"","LogConfig":{"Type":"json-file","Config":{}},"NetworkMode":"default","PortBindings":{"6379/tcp":[{"HostIp":"","HostPort":"6381"}]},"RestartPolicy":{"Name":"no","MaximumRetryCount":0},"AutoRemove":false,"VolumeDriver":"","VolumesFrom":null,"CapAdd":null,"CapDrop":null,"Dns":[],"DnsOptions":[],"DnsSearch":[],"ExtraHosts":null,"GroupAdd":null,"IpcMode":"shareable","Cgroup":"","Links":null,"OomScoreAdj":0,"PidMode":"","Privileged":false,"PublishAllPorts":false,"ReadonlyRootfs":false,"SecurityOpt":null,"UTSMode":"","UsernsMode":"","ShmSize":67108864,"Runtime":"runc","ConsoleSize":[0,0],"Isolation":"","CpuShares":0,"Memory":0,"NanoCpus":0,"CgroupParent":"","BlkioWeight":0,"BlkioWeightDevice":[],"BlkioDeviceReadBps":null,"BlkioDeviceWriteBps":null,"BlkioDeviceReadIOps":null,"BlkioDeviceWriteIOps":null,"CpuPeriod":0,"CpuQuota":0,"CpuRealtimePeriod":0,"CpuRealtimeRuntime":0,"CpusetCpus":"","CpusetMems":"","Devices":[],"DeviceCgroupRules":null,"DiskQuota":0,"KernelMemory":0,"MemoryReservation":0,"MemorySwap":0,"MemorySwappiness":null,"OomKillDisable":false,"PidsLimit":0,"Ulimits":null,"CpuCount":0,"CpuPercent":0,"IOMaximumIOps":0,"IOMaximumBandwidth":0} ``` 重启docker服务,再启动容器服务就可以了。 ```shell systemctl restart docker docker ps -a docker start ``` ## Docker 的镜像迁移到另一台服务器 ```shell # 找到想要移动的docker容器ID dockerCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 58ac9237b040 redis:4.0.11 "docker-entrypoint.s…" 5 hours ago Up 2 hours 0.0.0.0:6380->6379/tcp redis-slave1 454bb484f90a redis:4.0.11 "docker-entrypoint.s…" 5 hours ago Up 2 hours 0.0.0.0:6379->6379/tcp redis-master ps -a # 提交变更,并且把容器保存成镜像,命名为redis-master docker commit 454bb484f90a redis-master # 把redis-master镜像保存成tar文件 docker save redis-master > /root/mysoftware/docker-file/redis/redis-master.tar # 拷贝到新的机器,执行load命令 docker load < ./redis-master.tar ``` ## Docker中 ``镜像的来历及快速删除操作 ```shell docker rmi -f $(docker images | grep "none" | awk '{print $3}') ``` 来历:在docker反复build一个Dockerfile,并且使用相同tag(或者不用tag)会存留很多none镜像。第一次build生成一个image id, 再次build后,会重新生成一个image id, 命名和上一个一样,所以上一个镜像的tag和名字就会自动变成 ``。 ## Docker Dockerfile ### 什么是 Dockerfile? Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。 ### 使用 Dockerfile 定制镜像 1. 定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件) 在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容: ```dockerfile FROM nginx RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html ``` 2. FROM 和 RUN 指令的作用 **FROM**: 定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。 **RUN**: 用于执行后面跟着的命令行命令。有以下俩种格式: shell 格式: ```dockerfile RUN <命令行命令> # <命令行命令> 等同于,在终端操作的 shell 命令。 ``` exec 格式: ```dockerfile RUN ["可执行文件", "参数1", "参数2"] # 例如: # RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline ``` **注意**: Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如: ```dockerfile FROM centos RUN yum -y install wget RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" RUN tar -xvf redis.tar.gz ``` 以上执行会创建 3 层镜像。可简化为以下格式: ```dockerfile FROM centos RUN yum -y install wget \     && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \     && tar -xvf redis.tar.gz ``` 如上,以 **&&** 符号连接命令,这样执行后,只会创建 1 层镜像。 ### 开始构建镜像 在 Dockerfile 文件的存放目录下,执行构建动作。 以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。 **注**: 最后的`.`代表本次执行的上下文路径,下一节会介绍。 ```shell docker build -t nginx:v3 . ``` ![img](E:\source\repos\XiaodaBlogSource\source\_posts\Docker\dockerfile2.png) ### 上下文路径 上一节中,有提到指令最后一个 **.** 是上下文路径,那么什么是上下文路径呢? ```shell docker build -t nginx:v3 . ``` 上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。 **解析**:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。 如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。 **注意**:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。 ### 指令详解 | Dockerfile 指令 | 说明 | | --------------- | ------------------------------------------------------------ | | FROM | 指定基础镜像,用于后续的指令构建。 | | MAINTAINER | 指定Dockerfile的作者/维护者。(已启用,推荐使用LABEL指令) | | LABEL | 添加镜像的元数据,使用键值对的形式。 | | RUN | 在构建过程中在镜像中执行命令。 | | CMD | 指定容器创建时的默认命令。(可以被覆盖) | | ENTRYPOINT | 设置容器创建时的主要命令。(不可被覆盖) | | EXPOSE | 声明容器运行时监听的特定网络端口。 | | ENV | 在容器内部设置环境变量。 | | ADD | 将文件、目录或远程URL复制到镜像中。 | | COPY | 将文件或目录复制到镜像中。 | | VOLUME | 为容器创建挂载点或声明卷。 | | WORKDIR | 设置后续指令的工作目录。 | | USER | 指定后续指令的用户上下文。 | | ARG | 定义在构建过程中传递给构建器的变量,可使用"docker build"命令设置。 | | ONBUILD | 当该镜像被用作另一个构建过程的基础时,添加触发器。 | | STOPSIGNAL | 设置发送给容器以退出的系统调用信号。 | | HEALTHCHECK | 定义周期性检查容器健康状态的命令。 | | SHELL | 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT。 | #### COPY 复制指令,从上下文目录中复制文件或者目录到容器里指定路径。 格式: ```dockerfile COPY [--chown=:] <源路径1>... <目标路径> COPY [--chown=:] ["<源路径1>",... "<目标路径>"] ``` **[--chown=:]**:可选参数,用户改变复制到容器内文件的拥有者和属组。 **<源路径>**:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如: ```dockerfile COPY hom* /mydir/ COPY hom?.txt /mydir/ ``` **<目标路径>**:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。 # Docker 实例 ## Docker 启动 MariaDB 拉取mariadb镜像 ```shell docker pull mariadb:10.2 docker images docker run --name mariadb10.2 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mariadb:10.2 ``` ## Docker Redis 主从复制集群搭建 拉取redis4.0.11镜像 ```shell docker pull redis:4.0.11 ``` 编辑redis.conf redis-master.conf ```shell vim /root/mysoftware/docker-file/redis/redis-master.conf bind 0.0.0.0 #让redis可以被任意ip访问 daemonize yes #让redis服务后台运行 # 如需设定密码 requirepass masterpassword # 设定密码 ``` redis-slave1.conf ```shell vim /root/mysoftware/docker-file/redis/redis-slave1 bind 0.0.0.0 #让redis可以被任意ip访问 daemonize yes #让redis服务后台运行 # 如需设定密码 requirepass masterpassword # 设定密码 # 设置主机地址端口 redis5.0以上为 replicaof slaveof # 查看master ip docker inspect # 主库有密码必需要配置,代表主库的访问密码 masterauth ``` 运行redis容器 redis-master ```shell # 运行服务 docker run -it --name redis-master -v /usr/docker/redis/redis-master.conf:/usr/etc/redis/redis.conf -v /usr/docker/redis/data/:/data -d -p 35379:6379 redis:4.0.11 /bin/bash # 进入容器 docker exec -it redis-master bash # 加载配置 redis-server /usr/local/etc/redis/redis.conf # 如报错 mkdir -p /usr/redis/bin # 测试连接 redis-cli -a ``` redis-slave1 ```shell # 运行服务 docker run -it --name redis-slave1 -v /usr/docker/redis/redis-slave1.conf:/usr/etc/redis/redis.conf -v /usr/docker/redis/data/:/data -d -p 35380:6379 redis:4.0.11 /bin/bash # 进入容器 docker exec -it redis-slave1 bash # 加载配置 redis-server /usr/local/etc/redis/redis.conf # 如报错 Can't chdir to '/usr/redis/bin': No such file or directory mkdir -p /usr/redis/bin # 测试连接 redis-cli # 查看主从信息 info Replication # 密码认证 auth ``` ## Docker Redis 哨兵高可用集群搭建 ## Docker 安装 code-server ```shell # 拉取镜像 docker pull codercom/code-server # 创建宿主机目录 mkdir /usr/docker/codeserver # 创建配置文件 vim /usr/docker/codeserver/config.yaml bind-addr: 127.0.0.1:8080 auth: password password: 123456 cert: false # 创建并启动容器 # -u 表示以 root用户运行 docker run -d -u root -p 8088:8080 --name code-server -v /usr/docker/codeserver/config.yaml:/root/.config/code-server/config.yaml -v /usr/docker/codeserver:/home/code codercom/code-server ``` ## Docker 安装 Jenkins 搜索Jenkins镜像 ```shell docker search jenkins ``` ![image-20221121125608385](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221121125608385.png) 拉取镜像 ```shell docker pull jenkins/jenkins ``` 查看镜像 ```shell docker images ``` ![image-20221121131216876](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221121131216876.png) 启动镜像 ```shell cd /usr/local mkdir jenkins_home docker run -d -uroot -p 8889:8080 -p 50000:50000 --name jenkins -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -v /etc/sysconfig/docker:/etc/sysconfig/docker -v /usr/local/jenkins_home:/var/jenkins_home -v /etc/localtime:/etc/localtime jenkins/jenkins ``` 启动后查看日志 ```shell docker logs jenkins ``` ![image-20221121131635658](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221121131635658.png)可以找到初始密码 ## Docker 安装 Nginx ```shell docker pull nginx docker run -d \ -p 80:80 \ -p 443:443 \ --name nginx \ --privileged=true \ --restart=always \ -v /usr/local/docker/nginx/html:/usr/share/nginx/html \ -v /usr/local/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ -v /usr/local/docker/nginx/conf/conf.d:/etc/nginx/conf.d \ -v /usr/local/docker/nginx/logs:/var/log/nginx nginx:1.25.2 ps aux | grep "nginx: worker process" | awk '{print $1}' ``` ## Docker 安装 SQL Server ```shell mkdir /etc/sqlserver_data chmod -R 777 /etc/sqlserver_data docker pull mcr.microsoft.com/mssql/server docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Wyd210213" -p 1433:1433 --memory 2000M --name sqlserver2022 -v /etc/sqlserver_data:/var/opt/mssql -d mcr.microsoft.com/mssql/server ``` ## Docker 安装 PostgreSQL ```shell docker pull postgres:latest docker run -d --name=pgsql -p 5432:5432 -e POSTGRES_PASSWORD=Wyd210213 postgres:latest ``` ## Docker 安装 MySQL 8 ```shell docker run \ -p 3306:3306 \ --name mysql \ --restart=always \ -v /usr/local/docker/mysql/mysql-files:/var/lib/mysql-files \ -v /usr/local/docker/mysql/conf:/etc/mysql \ -v /usr/local/docker/mysql/logs:/var/log/mysql \ -v /usr/local/docker/mysql/data:/var/lib/mysql \ -v /etc/localtime:/etc/localtime \ -e MYSQL_ROOT_PASSWORD=Wyd210213 \ -e TZ=Asia/Shanghai \ -d mysql:8.0.21 \ --lower_case_table_names=1 ``` ## Docker 安装 Redis 7 ```shell # 首先得需要redis.conf,否则会映射成文件夹 docker run --restart=always \ -p 6379:6379 \ --name redis \ -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf \ -v /usr/local/docker/redis/data:/data \ -v /etc/localtime:/etc/localtime \ -d redis:7.0.13 redis-server /etc/redis/redis.conf ```