Docker
Docker

uname -r # 系统内核
cat /etc/os-release # 系统版本
sudo su # 管理员权限
联合文件系统
-
对文件分层,相同的东西可以反复使用
-
pull下来的镜像是只读的,无法修改
常用命令
docker version # 显示版本信息
docker info # 显示系统信息,包括镜像和容器的数量
docker [command] --help # 帮助信息
镜像命令
docker images # 查看本机所有镜像
-a # 列出所有镜像
-q # 只显示镜像的ID
docker search [image] # 搜索镜像
--filter=STARS=3000 # 搜索STARS大于3000的镜像
docker pull [image] # 下载镜像
lct@VM-4-7-ubuntu:~$ docker pull mysql
Using default tag: latest # 不写tag,默认latest
latest: Pulling from library/mysql
328ba678bf27: Pull complete # 分层下载,docker images的核心,联合文件系统
f3f5ff008d73: Pull complete
dd7054d6d0c7: Pull complete
70b5d4e8750e: Pull complete
cdc4a7b43bdd: Pull complete
3e9c0b61a8f3: Pull complete
806a08b6c085: Pull complete
021b2cebd832: Pull complete
ad31ba45b26b: Pull complete
0d4c2bd59d1c: Pull complete
148dcef42e3b: Pull complete
Digest: sha256:f496c25da703053a6e0717f1d52092205775304ea57535cc9fcaa6f35867800b # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
# 等价
docker pull mysql
docker pull docker.io/library/mysql:latest
# 指定版本
docker pull mysql:5.7
docker rmi [imageID] [imageID] # 删除镜像
docker rmi -f $(docker images -aq) # 全删了
docker images -a -q | xargs docker rm -f # 也是全删了
docker save [存放路径]
docker load [要解压的压缩包的路径]
Commit镜像
docker commit -m="描述信息" -a="作者" [containerID] [imageName]:[tag]
lct@VM-4-7-ubuntu:~$ docker commit -a="lct" -m="add webapp" 96f4f872439c tomcat02:1.0
sha256:ff07eb7b6df3c138f6a33cf5a4266acaa61d348ae0001dfaa33a0530ff537f03
lct@VM-4-7-ubuntu:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 ff07eb7b6df3 4 seconds ago 479MB
redis latest 33e3db53b328 2 hours ago 117MB
nginx latest 080ed0ed8312 2 weeks ago 142MB
tomcat latest 608294908754 2 weeks ago 475MB
ubuntu latest 08d22c0ceb15 5 weeks ago 77.8MB
django_lesson 1.1 e884c48091a4 8 months ago 1.95GB
elasticsearch 7.6.2 f29a1ee41030 3 years ago 791MB
lct@VM-4-7-ubuntu:~$ docker run -d -p 8000:8080 --name tomcat tomcat02:1.0
21f77232a8096d76cba2443393c167d0ec370e9145626f0fb5a2b86c01707e4e
容器命令
docker pull ubuntu
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-P 随机指定端口
--rm 用完退出后会自动退出
# 测试,进入与退出
lct@VM-4-7-ubuntu:~$ docker run -it ubuntu /bin/bash
root@543be16bd2b6:/# ls
root@543be16bd2b6:/# exit
exit
lct@VM-4-7-ubuntu:~$ ls
docker ps [command]
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器,带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示容器编号
exit # 停止容器并退出
Crtl + P + Q # 容器不停止退出
docker rm [containerID] # 删除容器,正在运行的删不了,非要删就 -f
docker start [containerID] # 启动容器
docker restart [containerID] # 重启容器
docker stop [containerID] # 停止容器
docker kill [containerID] # 强制停止容器
其他
docker run -d [image] # 后台运行镜像
# 发现它直接停止了
# 如果要后台运行,则必须有一个前台进程,否则docker会自动停止
# 类似nginx
docker logs -tf --tail 10 [containerID] # 显示10条日志
docker top [containerID] # 查看容器内部进程信息
docker inspect [containerID] # 查看容器详细信息
docker exec -it [containerID] [shell] # 进入容器后开启一个新的终端,可以在里面操作
docker attach [containerID] # 进入容器正在执行的终端,不会启动新的进程
docker cp [containerID:containerPath] [destPath] # 从容器像主机拷贝文件
容器与镜像练习
nginx
# 启动容器
lct@VM-4-7-ubuntu:~$ docker run -d --name nginx01 -p 3344:80 nginx
e4668b52fdce9ecb2509485e33f408e8df75adaf983ad87bf807e8e35c5f6398
# 测试容器
lct@VM-4-7-ubuntu:~$ curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
# 进入容器查看是否存在nginx
lct@VM-4-7-ubuntu:~$ docker exec -it nginx01 /bin/bash
root@e4668b52fdce:/# where nginx
bash: where: command not found
root@e4668b52fdce:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@e4668b52fdce:/#
tomcat
lct@VM-4-7-ubuntu:~$ docker pull tomcat
lct@VM-4-7-ubuntu:~$ docker run -d -p 8000:8080 --name tomcat01 tomcat
# 测试,外网登陆 http://公网IP:8000/
# 404 Error
# 没有webapps,因为镜像默认为可运行的最小,剔除一切不必要
# 即保证最小可运行环境
root@96f4f872439c:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@96f4f872439c:/usr/local/tomcat#
# 通过以上操作后,可通过外网访问
es+kibana
lct@VM-4-7-ubuntu:~$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
# 访问 http://公网IP:9200/
lct@VM-4-7-ubuntu:~$ curl localhost:9200
{
"name" : "c3b46ca13399",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "n29ev-FgTzaMWo-YZZRN_w",
"version" : {
"number" : "7.6.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date" : "2020-03-26T06:34:37.794943Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
容器数据卷
容器的持久化和同步操作 | 容器间也可以数据共享
- 双向同步
# 方式一
docker run -it -v 主机目录:容器目录 [image] /bin/bash
docker run -it -v /home/lct/Test:/home ubuntu /bin/bash
优点
- 文件或配置类的修改只需要在本地
- 容器删除后,挂载到本地的数据不会丢失
mysql
docker pull mysql:5.7
docker run -d -p 3310:3306 -v /home/lct/mysql/conf:/etc/mysql/conf.d -v /home/lct/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=lu123 --name mysql01 mysql:5.7
具名和匿名挂载
即不写主机目录的两种形式
# 匿名
docker run -it -v 容器目录 [image] /bin/bash
# 具名,用的多一些
docker run -it -v 卷名:容器目录 [image] /bin/bash
-v 容器目录后可加后缀
:ro # readonly,只能通过主机操作,容器无权修改
:rw # read & write
数据卷之Dockerfile
- 构建docker镜像的构建文件,其实就是命令脚本
- 实现数据卷的另一种方式
FROM ubuntu
VOLUME ["volume01", "volume02"] # 匿名挂载
CMD echo "------end------"
CMD /bin/bash
docker build -f /home/lct/docker-volume-test/dockerfile1 -t lct/ubuntu:1.0 .
docker run -it lct/ubuntu:1.0 /bin/bash
# 数据卷在 /var/lib/docker/volumes
docker inspect [containerID] # 查看卷的位置
数据卷容器
多个容器共享数据
docker build -f /home/lct/docker-volume-test/dockerfile1 -t lct/ubuntu:1.0 .
docker run -it --name="d01" lct/ubuntu:1.0 /bin/bash
docker run -it --name="d02" --volumes-from d01 lct/ubuntu:1.0 /bin/bash
docker run -it --name="d03" --volumes-from d01 lct/ubuntu:1.0 /bin/bash
# ���个容器共享
root@2416c5b4de58:/# cd volume01/
root@2416c5b4de58:/volume01# ls
helloWorld.txt
- 删除父容器,数据卷不会丢失,并且依旧可以同步
DockerFile
构建docker镜像的文件,其实就是命令脚本
构建步骤:
- 编写一个 dockerfile 文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像
官方基本都是基础镜像,很多功能没有,我们通常需要自己搭
构建过程
面向开发,以后发布项目就要编写dockerfile文件
交付标准,必须要掌握
- 步骤:开发、部署、上线
- DockerFile:构建文件,定义了一切的步骤,源代码
- Docker镜像:通过DockerFile构建生成的镜像,最终发布和运行的产品
- Docker容器:容器就是镜像运行起来提供的服务器
指令
FROM # 基础镜像
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 构建镜像的时候需要运行的命令
ADD # 添加内容,如tomcat压缩包
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 指定暴露端口
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个生效,可被替代
ENTYRPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBILD # 当构建一个被继承 DockerFile 会触发指令
COPY # 将文件拷贝到镜像中
ENV # 构建的时候设置环境变量
DockerFile练习
最基础的镜像FROM scratch
创建myUbuntu
# 1、mydockerfile
FROM ubuntu
MAINTAINER lct<example@163.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN apt-get update
RUN apt-get install -y vim
EXPOSE 80
CMD echo $MYPATH
CMD /bin/bash
# 2、build
docker build -f /home/lct/dockerfile/mydockerfile -t myubuntu:0.1 .
# 3、run
docker run -it myubuntu:0.1
# 4、验证
root@a05335b7579c:/usr/local# pwd
/usr/local
# vim 也能成功进入
遇到的问题
系统提示了错误 E: Unable to locate package vim
执行以下命令,成功解决
apt-get update
apt-get install -y vim
mytom
# 1. 创建Dockerfile
vim Dockerfile
# 2. 编写内容
FROM ubuntu
MAINTAINER lct<hahah@153.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.87.tar.gz /usr/local
RUN apt-get update
RUN apt-get install -y vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME $MYPATH/jdk1.8.0_301
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME $MYPATH/apache-tomcat-8.5.87
ENV CATALINA_BASE $MYPATH/apache-tomcat-8.5.87
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.87/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.87/logs/catalina.out
# 3. build 镜像
docker build -t mytom . # 名字不能有大写,压缩包要在Dockerfile同个文件夹
# 4. run 镜像
docker run -d -p 8000:8080 --name lctomcat -v /home/lct/build/tomcat/test:/usr/local/apache-tomcat-8.5.87/webapps/test -v /home/lct/build/tomcat/tomcatlogs:/usr/local/apache-tomcat-8.5.87/logs mytom
- 编辑以下两个文件
/home/lct/build/tomcat/test/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
</web-app>
/home/lct/build/tomcat/test/index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>helloWorld</h2>
<%
System.out.println("helloWorld");
%>
</body>
</html>
- 访问
http://公网IP:8000/test/
Docker网络
docker network
ls # 展示网络列表
create # 创建一个网络
rm # 删除一个网络
inspect # 查看网络的详细信息
connect # 将容器连接到一个网络
disconnect # 将容器与一个网络的连接断开
evth-pair

--link
可以通过名字连通,不用通过IP
docker run -d -P --name tomcat03 --link tomcat02 tomcat
docker exec -it tomcat02 ping tomcat03
# 可以ping通,但是反向不行
# 就是在 tomcat03 的 /etc/hosts 中,配置写死了一个 tomcat02
- 不推荐使用
自定义网络
可直接通过名字ping通,非常推荐
lct@VM-4-7-ubuntu:~$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
281fa6d64b0e1cbf3eac6e92587cc48d6e416cbc69337c595fd37f0475a70db4
lct@VM-4-7-ubuntu:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
37d5fa3f583b bridge bridge local
02f042ab54b5 host host local
281fa6d64b0e mynet bridge local
lct@VM-4-7-ubuntu:~$ docker run -d -P --name tomcat01 --net mynet tomcat
86eb7d6593427a4159bebde9bb4bf24a3c8c90c4fea2a0a4bf5de1cdb3b2e7c3
lct@VM-4-7-ubuntu:~$ docker run -d -P --name tomcat02 --net mynet tomcat
58e7f47d3f31c34eb8732cba4310a062edf982a50c22e3d51168d5328145655c
lct@VM-4-7-ubuntu:~$ docker inspect mynet
# 截取部分
"Containers": {
"58e7f47d3f31c34eb8732cba4310a062edf982a50c22e3d51168d5328145655c": {
"Name": "tomcat02",
"EndpointID": "dd3a0e303ea1d41b434adda38a24ce6e1706d84bc05984bc800bbd154a794847",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"86eb7d6593427a4159bebde9bb4bf24a3c8c90c4fea2a0a4bf5de1cdb3b2e7c3": {
"Name": "tomcat01",
"EndpointID": "9234c6e7bf610c2ce67dac92cfe0e6edabe70cf47f404f4be4fd9ebc63f39875",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
# 进入 tomcat01
apt-get update
apt-get install inetutils-ping
# 返回主机
lct@VM-4-7-ubuntu:~$ docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.3): 56 data bytes
64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.076 ms
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.086 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.071 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.084 ms
^C--- tomcat02 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.071/0.079/0.086/0.000 ms
网络连通
lct@VM-4-7-ubuntu:~$ docker run -d -P --name tomcat03 tomcat
lct@VM-4-7-ubuntu:~$ docker network connect mynet tomcat03
# 不同网段下的容器连通
lct@VM-4-7-ubuntu:~$ docker exec -it tomcat03 ping tomcat01
实战
创建网络
docker network create redis --subnet 172.38.0.0/16
通过脚本创建6个redis
配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
启动容器
for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done
进入其中一个容器
docer exec -it redis-1 /bin/sh
配置集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
进入redis
服务
redis-cli -c
set a b
# 此时发现数据存储于 redis-3
docker stop redis-3
get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
# 成功搜索,slave变为master
# 集群配置成功
Idea项目推送
创建SpringBoot
项目
问题1:M2
芯片支持的Spring
需要Java 17
# 安装Java 17
brew install openjdk@17
# 配置环境变量
sudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk
# 安装成功
(base) lct@Huawei-MateBook-X-Pro ~ % java -version
openjdk version "17.0.6" 2023-01-17
OpenJDK Runtime Environment Homebrew (build 17.0.6+0)
OpenJDK 64-Bit Server VM Homebrew (build 17.0.6+0, mixed mode, sharing)
问题2:Maven下载非常慢
配置/Users/lct/.m2
下的settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<!-- 阿里云仓库 -->
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
<!-- 中央仓库1 -->
<mirror>
<id>repo1</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo1.maven.org/maven2/</url>
</mirror>
<!-- 中央仓库2 -->
<mirror>
<id>repo2</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo2.maven.org/maven2/</url>
</mirror>
</mirrors>
</settings>
打包项目

编写Dockerfile
FROM openjdk:17-slim
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
build
和run
docker build -t helloidea .
docker run -d -p 8000:8080 --name helloworld helloidea
访问http://公网IP:8000/hello
成功部署!
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决