赞
踩
docker官网地址:https://www.docker.com/
docker镜像地址:https://hub.docker.com/
docker安装教程:https://docs.docker.com/engine/install/centos/
安装只需要注意将仓库源改为国内就好,推荐去阿里云注册自己的账号获得加速地址:
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/ docker-ce/linux/centos/docker-ce.repo
docker 的基本组成 :镜像,容器,仓库
Docker运行的基本流程为:
1 用户是使用Docker Client与Docker Daemon建立通信,并发送请求给后者。
2 Docker Daemon作为Docker架构中的主体部分,首先提供Docker Server的功能使其可以接受Docker Client的请求。
3 Docker Engine执行Docker内部的一系列工作,每-项工作都是以一个Job的形式的存在。
4 Job的运行过程中,当需要容器镜像时,则从Docker Registry中下载镜像,并通过镜像管理驱动Graph driver将下载镜像以Graph的形式存
5 当需要为Docker创建网络环境时,通过网络管理驱动Network driver 创建并配置Docker容器网络环境。
6 当需要限制Docker容器运行资源或执行用户指令等操作时,则通过Exec driver来完成。
7 Libcontainer是一项独 立的容器管理包,Network driver以及Exec driver都是通过Libcontainer来实现具体对容器进行的操作。
systemctl start docker 启动docker
systemctl stop docker 停止docker
systemctl restart docker 重启docker
systemctl status docker 查看docker状态
systemctl enable docker 开机自启动
docker search mysql 搜索是否有mysql镜像
docker search --limit 5 mysql 查找用的最多的镜像top5
docker pull ubuntu:20.04:拉取一个镜像
docker system df 查看镜像/容器的数据卷大小
docker images:列出本地所有镜像
docker image rm ubuntu:20.04 或 docker rmi ubuntu:20.04:删除镜像ubuntu:20.04
docker [container] commit CONTAINER IMAGE_NAME:TAG:创建某个container的镜像
docker save -o ubuntu_20_04.tar ubuntu:20.04:将镜像ubuntu:20.04导出到本地文件ubuntu_20_04.tar中
docker load -i ubuntu_20_04.tar:将镜像ubuntu:20.04从本地文件ubuntu_20_04.tar中加载出来
docker [container] create -it ubuntu:20.04:利用镜像ubuntu:20.04创建一个容器。 docker ps -a:查看本地的所有容器 docker start CONTAINER:启动容器 docker stop CONTAINER:停止容器 docker restart CONTAINER:重启容器 docker run -itd ubuntu:20.04:创建并启动一个容器 docker attach CONTAINER:进入容器先按Ctrl-p,再按Ctrl-q可以挂起容器 docker exec CONTAINER COMMAND:在容器中执行命令 docker rm CONTAINER:删除容器 docker container prune:删除所有已停止的容器 docker inspect 容器id 查看容器的信息 docker export -o xxx.tar CONTAINER:将容器CONTAINER导出到本地文件xxx.tar中 docker import xxx.tar image_name:tag:将本地文件xxx.tar导入成镜像,并将镜像命名为image_name:tag docker export/import与docker save/load的区别: export/import会丢弃历史记录和元数据信息,仅保存容器当时的快照状态 save/load会保存完整记录,体积更大 docker top CONTAINER:查看某个容器内的所有进程 docker stats:查看所有容器的统计信息,包括CPU、内存、存储、网络等信息 docker cp xxx CONTAINER:xxx 或 docker cp CONTAINER:xxx xxx:在本地和容器间复制文件 docker rename CONTAINER1 CONTAINER2:重命名容器 docker update CONTAINER --memory 500MB:修改容器限制 docker commit -m "提交描述信息" 容器id demo:1.0 这样就可以提交当前的容器为镜像存到镜像仓库中,相当于对原来的镜像做了拓展
以上命令来源于其它作者:作者:yxc 链接:https://www.acwing.com/blog/content/10878/ 来源:AcWing
用于数据持久化,需要注意点是一般启动容器的时候需要加–privileged=true否则可能没有权限操作挂载目录。
docker run -d -p 13306:3306 --privileged=true -v /data/mysql/logs:/var/log/mysql -v /data/mysql/data:/var/lib/mysql -v /opt/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=654321 --name mysql mysql:5.7
容器之间的继承也就是说一个容器可以完全复用另一个容器的数据卷,且当前的这个容器不会受被继承者的影响,也就是说被继承者挂掉了,当前容器的运行也不会有任何影响。
一个简单的例子如下:
docker run -itd ---privileged=true --volumes-from 父容器 --name newcontainer mysql
docker pull tomcat 拉去镜像,可以指定标签不指定默认为最新
docker run -itd -p 8080:8080 --name tomcat tomcat:latest 这里也可以用P随机生成一个端口 docker run -itd -P tomcat 这样内部默认80端口,主机的映射端口会随机分配一个
netstat -ntlp 可以用这个命令查看端口8080是否已经监听
这里需要注意的是可能访问8080的时候会出现404(往往出现在新版中),是因为新版webapp目录下没有任何呢内容。
docker exec -it tomcat /bin/bash
mv webapps.dist/ webapps 官方吧欢迎页面放到了另一个位置
docker pull mysql:5.7
docker run -d -p 13306:3306 --privileged=true -v /data/mysql/logs:/var/log/mysql -v /data/mysql/data:/var/lib/mysql -v /opt/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=654321 --name mysql mysql:5.7
注意我们需要解决乱码的问题
修改配置文件,设置编码
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
bind-address = 0.0.0.0 #允许所有IP连接,生产环境中不允许这么配置
character_set_server = utf8
配置修改后可以,用下面的命令查看字符集,可以在容器内部用客户端连接也可以用连接工具。
show variables like '%char%'
docker pull redis
docker run -p 16379:6379 --name redis --privileged=true -v /opt/conf/redis/redis.conf:/etc/redis/redis.conf -v /data/redis/data:/data -d redis:latest redis-server /etc/redis/redis.conf
配置文件,注意生成环境中别这样配置,除了daemonize no这个,这样配置不安全。
bind 127.0.0.1
daemonize no
protected-mode no
FROM 基础镜像,基于那个镜像 MAINTAINER 镜像的维护者 RUN 构建容器需要执行的命令支持两种格式 shell格式:RUN yum -y install vim exec格式: RUN["./test.sh", "dev", "offile"] 等价于 RUN ./test.sh dev offline EXPOSE 暴露端口 WORKDIR 指定容器创建后终端默认登陆进来的工作目录,一个落脚点 USER 指定以什么用户执行,默认root ENV 设置环境变量 ADD 将宿主机下的文件拷贝进镜像,会自动处理RUL和解压tar压缩包 COPY 复制文件,类似于docker cp CMD 启动容器后需要执行什么命令在docker run的时候执行,也支持shell和exec格式,dockerfile总可以有多个指令,但是只有最后一个生效(之前的命令还是会执行,知识会保留最后一个CMD可被替换),会被docker run之后的参数替换 ENTRYPOINT 可以和CMD一起使用不会被覆盖 如果它后面跟着CMD 则CMD的内容会被当做参数传递,这里比较绕看一个例子就懂了 ex: ENTRYPOINT ["nginx", "-c"] CMD["/etc/nginx/nginx.conf"] 如果运行docker run nginx:latest -c /etc/nginx/new.conf CMD 会被run后面的参数替换 所以CMD此时的值为/etc/nginx/new.conf 然后他紧挨着ENTRYPOINT 所以最终执行的命令为nginx -c /etc/nginx/new.conf
FROM centos MAINTAINER liyong ENV MYPATH /usr/local WORKDIR $MYPATH #安装vim编辑器 RUN yum -y install vim #安装ifconfig命令查看网络IP RUN yum -y install net-tools #安装java8及lib库 RUN yum -y install glibc.i686 RUN mkdir /usr/local/java #ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置 ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/ #配置java环境变量,这里相当于是写死容器内部,如果启动的时候需要更改也可以-e 去修改 ENV JAVA_HOME /usr/local/java/jdk1.8.0_171 ENV JRE_HOME $JAVA_HOME/jre ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH ENV PATH $JAVA_HOME/bin:$PATH EXPOSE 80 CMD echo $MYPATH CMD echo "success--------------ok" CMD /bin/bash
构建镜像
docker build -t centosjava8:1.5 .
构建一个微服务应用
# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER liyong
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为zzyy_docker.jar
ADD docker_boot-0.0.1-SNAPSHOT.jar spring.jar
# 运行jar包
RUN bash -c 'touch /spring.jar'
ENTRYPOINT ["java","-jar","/spring.jar"]
#暴露6001端口作为微服务
EXPOSE 6001
构建一个前端应用(Tomcat,Nginx)
FROM nginx
WORKDIR /usr/share/nginx/html/
USER root
COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY ./dist /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
docker images ls -f dangling=true 列出虚悬镜像
docker image prune 删除虚悬镜像
docker run -p 13307:3306 --name mysql-master \
-v /data/mysql-master/log:/var/log/mysql \
-v /data/mysql-master/data:/var/lib/mysql \
-v /data/mysql-master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=654321 \
-d mysql:5.7
修改配置文件并重启容器
[mysqld] ## 设置server_id,同一局域网中需要唯一 server_id=101 ## 指定不需要同步的数据库名称 binlog-ignore-db=mysql ## 开启二进制日志功能 log-bin=mall-mysql-bin ## 设置二进制日志使用内存大小(事务) binlog_cache_size=1M ## 设置使用的二进制日志格式(mixed,statement,row) binlog_format=mixed ## 二进制日志过期清理时间。默认值为0,表示不自动清理。 expire_logs_days=7 ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。 ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致 slave_skip_errors=1062```
master容器实例内创建数据同步用户,这是为了安全控制权限
CREATE USER 'slave' @'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave' @'%';
安装从节点
docker run -p 13308:3306 --name mysql-slave \
-v /data/mysql-slave/log:/var/log/mysql \
-v /data/mysql-slave/data:/var/lib/mysql \
-v /data/mysql-slave/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=654321 \
-d mysql:5.7
修改配置文件
[mysqld] ## 设置server_id,同一局域网中需要唯一 server_id=102 ## 指定不需要同步的数据库名称 binlog-ignore-db=mysql ## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用 log-bin=mall-mysql-slave1-bin ## 设置二进制日志使用内存大小(事务) binlog_cache_size=1M ## 设置使用的二进制日志格式(mixed,statement,row) binlog_format=mixed ## 二进制日志过期清理时间。默认值为0,表示不自动清理。 expire_logs_days=7 ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。 ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致 slave_skip_errors=1062 ## relay_log配置中继日志 relay_log=mall-mysql-relay-bin ## log_slave_updates表示slave将复制事件写进自己的二进制日志 log_slave_updates=1 ## slave设置为只读(具有super权限的用户除外) read_only=1
在主数据库中查看同步状态,需要进入容器然后 mysql -uroot -p 客户端连接后输入此命令
show master status; 注意啦一定要有分号否则你只会看到输出一个箭头
在从数据库中配置主从复制,注意也是进入容器内部mysql客户端连接后执行
#这里的参数值都是之前配置的
change master to master_host='宿主机ip', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
#参数说明
master_host:主数据库的IP地址;
master_port:主数据库的运行端口;
master_user:在主数据库创建的用于同步数据的用户账号;
master_password:在主数据库创建的用于同步数据的用户密码;
master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;
master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;
master_connect_retry:连接失败重试的时间间隔,单位为秒。
查看从数据库的同步状态
show slave status \G; \G只是换一种方式展示结果
在从数据库开启主从同步
start slave; #需要看到这两个参数是yes
这里踩坑了,怎么弄第一个都显示connecting, 后面看了下文,是端口不通的问题。
https://dba.stackexchange.com/questions/140929/slave-io-running-connecting-in-master-slave-replication
下面就是在master建表,看看从机有没有就OK。
#这里注意网络模式都是主机,生成环境中推荐用bridge模式,创建一个自定义网络,将它们部署到统一网络下,这样可以通过服务名访问到服务
docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
随便进入一台redis的内部搭建集群关系
redis-cli --cluster create ip:6381 ip:6382 ip:6383 ip:6384 ip:6385 ip:6386 --cluster-replicas 1
然后连接客户端查看相关信息,需要注意我们要指定端口因为我们启动的时候已经指定了端口 redis-cli -p 6381
cluster info
cluster nodes
下面注意了我们存储key的时候就需要连接集群了,如果单机只有一部分槽位那能存,如果集群就会自动跳过去。
redis-cli -p 6381 -c #下图展示了如果不是当前机器的槽位会自动跳
redis-cli --cluster check 127.0.0.1:6381
下面可以测试一下(比较简单这里不再演示),停掉一个实例,slave就会上位变成master,保证集群照样可用,后面恢复后也不会复原master的地位变成了slave。
集群扩容
新增节点
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
添加节点
redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
我们看到虽然加入了集群但是没有分配槽位
分配槽位(每一台机器各出一些槽位分配给新机器):
redis-cli --cluster reshard 127.0.0.1:6381 #执行会提示填入分区的大小,一般采用均分,然后还需要填入新节点的ID
为主节点分配从节点:
redis-cli --cluster add-node 127.0.0.1:6388 127.0.0.1:6387 --cluster-slave --cluster-master-id 8b242a216d91366916054fca6b5c1ee4129d05b9
集群缩容
redis-cli --cluster del-node 127.0.0.1:6388 5d149074b7e57b802287d1797a874ed7a1a284a8 删除88节点
redis-cli --cluster reshard 192.168.111.147:6381 重新分配槽位,注意将槽位全部删除才能继续删除87节点
docker network ls 查看网络模式 更多命令docker network --help
docker network inspect bridge 查看网络模式的详细信息
docker inspect redis | tail -n 20 #查看容器网络
#容器内部IP是会发生变化的,随着服务的停止重启创建,会被分配到其它的IP。
docker network inspect bridge | grep name #查看bride网络详细信息
具体的容器在启动的时候网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。
整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主1)机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
2)每个容器实例内部也有一块网卡,每个接口叫eth0;
3)docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。
如下图一个veth对应这一个eth
我们随便查看一个网桥模式的容器:
从上图可以看到网桥模式每个容器有自己的IP和网关。
主机模式
容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
案例验证:
docker run -d -p 8083:8080 --network host --name tomcattest tomcat:latest
这里会出现警告因为你不是网桥模式是直接用主机的端口,添加端口映射没有意义。
docker run -d --network host --name tomcattest tomcat:latest
可以看到没有自己的IP和网关,都是借用主机的
none模式
禁用网络功能,只有lo标识
docker run -d -p 8083:8080 --network none --name tomcattest tomcat:latest
container模式
新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
docker run -d --network container:容器名称 --name demo
注意如果被共用的容器挂了,这这个共享的容器也没有网络了,只有本地回环。
docker network create custom_network #创建自定义网络
在同一个网络下启动容器,这样这个容器就能够通过服务名互通
docker run -d -p 8081:8080 --network custom_network --name tomcat81 tomat:latest
docker run -d -p 8082:8080 --network custom_network --name tomcat82 tomat:latest
Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器。
#安装compose
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
基础指令
Compose常用命令
docker-compose -h # 查看帮助
docker-compose up # 启动所有docker-compose服务
docker-compose up -d # 启动所有docker-compose服务并后台运行
docker-compose down # 停止并删除容器、网络、卷、镜像。
docker-compose exec yml里面的服务id # 进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
docker-compose ps # 展示当前docker-compose编排过的运行的所有容器
docker-compose top # 展示当前docker-compose编排过的容器进程
docker-compose logs yml里面的服务id # 查看容器输出日志
docker-compose config # 检查配置
docker-compose config -q # 检查配置,有问题才有输出
docker-compose restart # 重启服务
docker-compose start # 启动服务
docker-compose stop # 停止服务
实战
传统的部署存在的问题:
顺序要求,当前的服务依赖于其它服务的启动,需要按顺序启动服务才能够访问成功。
里面的配置写死后,基于docker的部署容器的IP可能会发生变化。
docker compose yaml文件引用自尚硅谷。
version: "3" #版本 #服务容器实例 services: microService: image: zzyy_docker:1.6 #镜像名 container_name: ms01 #容器名 ports: - "6001:6001" #端口映射 volumes: - /app/microService:/data #数据卷挂载,持久化数据 networks: - atguigu_net #网络,如果同一个网络下可以通过服务名称去访问容器实例,我们可以看到后面用的都是同一个网络,就类似于我们在网络篇创建一个网络 depends_on: - redis - mysql redis: image: redis:6.0.8 ports: - "6379:6379" volumes: - /app/redis/redis.conf:/etc/redis/redis.conf - /app/redis/data:/data networks: - atguigu_net command: redis-server /etc/redis/redis.conf mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: '123456' MYSQL_ALLOW_EMPTY_PASSWORD: 'no' MYSQL_DATABASE: 'db2021' MYSQL_USER: 'zzyy' MYSQL_PASSWORD: 'zzyy123' ports: - "3306:3306" volumes: - /app/mysql/db:/var/lib/mysql - /app/mysql/conf/my.cnf:/etc/my.cnf - /app/mysql/init:/docker-entrypoint-initdb.d networks: - atguigu_net command: --default-authentication-plugin=mysql_native_password #解决外部无法访问 networks: atguigu_net:
在用的时候将IP换为服务名
spring.datasource.url=jdbc:mysql://mysql:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
docker-compose config -q #先检查一下配置
docker-compose up -d #启动服务一键ok
目前我很少用,用到的时候再去看吧。
https://www.bilibili.com/video/BV1gr4y1U7CY/?p=95&spm_id_from=pageDriver&vd_source=4450073c75ea9195fc5f0b1a2b7ff576
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。