目录
认识Docker
安装Docker
安装yum工具
配置Docker的yum源
更新yum,建立缓存
安装Docker
启动并校验
配置镜像加速
Docker常见命令
命令
演示
给命令起别名
Docker数据卷
认识数据卷
数据卷常见命令
nginx的html目录挂载演示
数据卷挂载本地目录或者文件
Docker镜像
认识镜像
镜像结构
制作镜像
Docker网络
认识Docker
Docker 允许将微服务及其依赖项打包到一个独立的容器中。每个微服务运行在自己的容器中,确保了环境的一致性。容器化使得微服务可以在任何支持 Docker 的环境中运行,无论是开发、测试还是生产环境。
每个微服务运行在自己的容器中,与其他服务隔离。这种隔离性确保了不同服务之间的依赖冲突不会影响彼此的运行,提高了系统的稳定性和安全性。
Docker 在微服务架构中提供了强大的容器化能力,使得微服务的开发、部署、管理和扩展变得更加简单和高效。通过 Docker,团队可以更好地实现微服务的独立性和可移植性,从而提高开发效率和系统稳定性。
安装Docker
安装yum工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
配置Docker的yum源
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.reposudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
更新yum,建立缓存
sudo yum makecache fast
安装Docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
启动并校验
# 启动Docker
systemctl start docker# 停止Docker
systemctl stop docker# 重启
systemctl restart docker# 设置开机自启
systemctl enable docker# 执行docker ps命令,如果不报错,说明安装启动成功
docker ps
配置镜像加速
# 创建目录
mkdir -p /etc/docker# 配置加速地址
tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://docker.fxxk.dedyn.io"]
}
EOF# 重新加载配置
systemctl daemon-reload# 重启Docker
systemctl restart docker
Docker常见命令
命令
命令 | 说明 | 文档地址 |
---|---|---|
docker pull | 拉取镜像 | docker pull |
docker push | 推送镜像到DockerRegistry | docker push |
docker images | 查看本地镜像 | docker images |
docker rmi | 删除本地镜像 | docker rmi |
docker run | 创建并运行容器(不能重复创建) | docker run |
docker stop | 停止指定容器 | docker stop |
docker start | 启动指定容器 | docker start |
docker restart | 重新启动容器 | docker restart |
docker rm | 删除指定容器 | docs.docker.com |
docker ps | 查看容器 | docker ps |
docker logs | 查看容器运行日志 | docker logs |
docker exec | 进入容器 | docker exec |
docker save | 保存镜像到本地压缩文件 | docker save |
docker load | 加载本地压缩文件到镜像 | docker load |
docker inspect | 查看容器详细信息 | docker inspect |
演示
以redis为例演示上述命令
#拉取redis镜像
[root@localhost ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
a2318d6c47ec: Already exists
ed7fd66f27f2: Pull complete
410a3d5b3155: Pull complete
9312cf3f6b3e: Pull complete
c39877ab23d0: Pull complete
01394ffc7248: Pull complete
4f4fb700ef54: Pull complete
5a03cb6163ab: Pull complete
Digest: sha256:eadf354977d428e347d93046bb1a5569d701e8deb68f090215534a99dbcb23b9
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
#查看所有镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hmall latest 20869e211ddb 25 hours ago 365MB
docker-demo 1.0 9a0404a24db1 39 hours ago 315MB
nginx latest 39286ab8a5e1 5 weeks ago 188MB
redis latest 590b81f2fea1 8 weeks ago 117MB
mysql latest c757d623b190 2 months ago 586MB
#创建并运行redis容器
[root@localhost ~]# docker run -d --name my-redis -p 6379:6379 redis
1ff3db543590bf2e2fa8c25d7b4c0d3f607931bd8fa395454d0325aa5b3e882d#要知道,不同操作系统下其安装包、运行环境是都不相同的!
如果是手动安装,必须手动解决安装包不同、环境不同的、配置不同的问题!而使用Docker,这些完全不用考虑。就是因为Docker会自动搜索并下载MySQL。
注意:这里下载的不是安装包,而是镜像。镜像中不仅包含了MySQL本身,
还包含了其运行所需要的环境、配置、系统级函数库。因此它在运行时就有自己独立的
环境(独立的内存空间,独立的网络空间,独立的文件系统),就可以跨系统运行,
也不需要手动再次配置环境了。这套独立运行的隔离环境我们称为容器。#查看正在运行的容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1ff3db543590 redis "docker-entrypoint.s…" 21 seconds ago Up 20 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp my-redis
#停止my-redis这个容器
[root@localhost ~]# docker stop my-redis
my-redis
[root@localhost ~]# docker start my-redis
my-redis
#查看my-redis这个容器的详细信息
[root@localhost ~]# docker inspect my-redis#进入容器,查看容器内目录,并同时可以操纵这个容器输入命令
[root@localhost ~]# docker exec -it my-redis bash
root@1ff3db543590:/data# set mykey "Hello, Redis!"
#退出这个容器
root@1ff3db543590:/data# exit
exit
#重启mysql容器
[root@localhost ~]# docker restart mysql
mysql
#进入MySQL容器
[root@localhost ~]# docker exec -it mysql mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 9.0.1 MySQL Community Server - GPLCopyright (c) 2000, 2024, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> exit
Bye
#删除my-redis容器,但是由于这个容器在运行中,删除失败
[root@localhost ~]# docker rm my-redis
Error response from daemon: cannot remove container "/my-redis": container is running: stop the container before removing or force remove
#强制删除正在运行的容器
[root@localhost ~]# docker rm -f my-redis
my-redis
[root@localhost ~]#
给命令起别名
# 修改/root/.bashrc文件
vi /root/.bashrc
内容如下:
# .bashrc# User specific aliases and functionsalias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'# Source global definitions
if [ -f /etc/bashrc ]; then. /etc/bashrc
fi#最后执行命令使别名生效
source /root/.bashrc
如:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bec96deb1c95 mysql "docker-entrypoint.s…" 23 hours ago Up 7 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
#使用dps代替docker ps命令
[root@localhost ~]# dps
CONTAINER ID IMAGE PORTS STATUS NAMES
bec96deb1c95 mysql 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp Up 7 minutes mysql
[root@localhost ~]#
Docker数据卷
认识数据卷
一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。
以Nginx为例,我们知道Nginx中有两个关键的目录:
html:放置一些静态资源conf:放置配置文件
如果我们要让Nginx代理我们的静态资源,最好是放到html
目录;如果我们要修改Nginx的配置,最好是找到conf
下的nginx.conf
文件。
但遗憾的是,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。如图:
数据卷常见命令
命令 | 说明 | 文档地址 |
---|---|---|
docker volume create | 创建数据卷 | docker volume create |
docker volume ls | 查看所有数据卷 | docs.docker.com |
docker volume rm | 删除指定数据卷 | docs.docker.com |
docker volume inspect | 查看某个数据卷的详情 | docs.docker.com |
docker volume prune | 清除数据卷 | docker volume prune |
nginx的html目录挂载演示
# 1.首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
#-v html:/usr/share/nginx/html:这是卷挂载选项,用于将主机上的一个
目录(在这里是 html)挂载到容器内的 /usr/share/nginx/html 目录。
这样,容器内部的 Nginx 可以直接访问并服务于这个目录下的文件
var/lib/docker/volumes/html这个路径就是自己服务器上对应
容器内/usr/share/nginx/html目录的目录
/var/lib/docker/volumes这个目录就是默认的存放所有容器数据卷的目录,
其下再根据数据卷名称创建新目录,格式为/数据卷名/_data。# 2.然后查看数据卷
docker volume ls
# 结果
DRIVER VOLUME NAME
local 29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f
local html# 3.查看数据卷详情
docker volume inspect html
# 结果
[{"CreatedAt": "2024-05-17T19:57:08+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/html/_data","Name": "html","Options": null,"Scope": "local"}
]# 4.查看/var/lib/docker/volumes/html/_data目录
ll /var/lib/docker/volumes/html/_data
# 可以看到与nginx的html目录内容一样,结果如下:
总用量 8
-rw-r--r--. 1 root root 497 12月 28 2021 50x.html
-rw-r--r--. 1 root root 615 12月 28 2021 index.html# 5.进入该目录,并随意修改index.html内容
cd /var/lib/docker/volumes/html/_data
vi index.html# 6.打开页面,查看效果# 7.进入容器内部,查看/usr/share/nginx/html目录内的文件是否变化
docker exec -it nginx bash
数据卷挂载本地目录或者文件
由于数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:
# 挂载本地目录
-v 本地目录:容器内目录
# 挂载本地文件
-v 本地文件:容器内文件
-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
Docker镜像
认识镜像
镜像是一堆文件的集合。
镜像结构
制作镜像
一般使用Dockerfile辅助制作镜像
指令 | 说明 | 示例 |
---|---|---|
FROM | 指定基础镜像 |
|
ENV | 设置环境变量,可在后面指令使用 |
|
COPY | 拷贝本地文件到镜像的指定目录 |
|
RUN | 执行Linux的shell命令,一般是安装过程的命令 |
|
EXPOSE | 指定容器运行时监听的端口,是给镜像使用者看的 | EXPOSE 8080 |
ENTRYPOINT | 镜像中应用的启动命令,容器运行时调用 | ENTRYPOINT java -jar xx.jar |
基于Ubuntu镜像来构建一个Java应用,其Dockerfile内容如下:
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装JDK
RUN cd $JAVA_DIR \&& tar -xf ./jdk8.tar.gz \&& mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 指定项目监听的端口
EXPOSE 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去JDK的配置了
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
Docker网络
容器之间可以通过各容器的虚拟IP地址来互联,但是这个IP地址是变化的,可能有时会导致部署失败,于是需要用到Docker网络功能
常见的docker网络命令:
命令 | 说明 | 文档地址 |
---|---|---|
docker network create | 创建一个网络 | docker network create |
docker network ls | 查看所有网络 | docs.docker.com |
docker network rm | 删除指定网络 | docs.docker.com |
docker network prune | 清除未使用的网络 | docs.docker.com |
docker network connect | 使指定容器连接加入某网络 | docs.docker.com |
docker network disconnect | 使指定容器连接离开某网络 | docker network disconnect |
docker network inspect | 查看网络详细信息 | docker network inspect |
演示:
# 1.首先通过命令创建一个网络
docker network create hmall# 2.然后查看网络
docker network ls
# 结果:
NETWORK ID NAME DRIVER SCOPE
639bc44d0a87 bridge bridge local
403f16ec62a2 hmall bridge local
0dc0f72a0fbb host host local
cd8d3e8df47b none null local
# 其中,除了hmall以外,其它都是默认的网络# 3.让dd和mysql都加入该网络,注意,在加入网络时可以通过--alias给容器起别名
# 这样该网络内的其它容器可以用别名互相访问!
# 3.1.mysql容器,指定别名为db,另外每一个容器都有一个别名是容器名
docker network connect hmall mysql --alias db
# 3.2.db容器,也就是我们的java项目
docker network connect hmall dd# 4.进入dd容器,尝试利用别名访问db
# 4.1.进入容器
docker exec -it dd bash
# 4.2.用db别名访问
ping db
# 结果
PING db (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.056 ms
# 4.3.用容器名访问
ping mysql
# 结果:
PING mysql (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms