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镜像的文件,其实就是命令脚本

构建步骤:

  1. 编写一个 dockerfile 文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. 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
  1. 编辑以下两个文件

/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>
  1. 访问http://公网IP:8000/test/

Docker网络

docker network

ls				# 展示网络列表
create			# 创建一个网络
rm				# 删除一个网络
inspect			# 查看网络的详细信息
connect			# 将容器连接到一个网络
disconnect	# 将容器与一个网络的连接断开

evth-pair

image-20230413175202449

可以通过名字连通,不用通过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项目

问题1M2芯片支持的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>

打包项目

image-20230413175202449

编写Dockerfile

FROM openjdk:17-slim

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app.jar"]

buildrun

docker build -t helloidea .

docker run -d -p 8000:8080 --name helloworld helloidea

访问http://公网IP:8000/hello

成功部署!

posted @   James-Allen  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示