docker
说明
概观
镜像: 软件包
容器: 启动的一个软件
容器和虚拟机部署的区别
-
-
容器类似轻量级的VM 容器共享操作系统的内核
-
容器相互隔离
-
容器有自己的文件系统, cpu, 内存,进程空间等
-
容器可以跨平台
常用命令(镜像)
# 以nginx举例
检索镜像
1
docker search nginx
#下载镜像
1
docker pull nginx
删除镜像
1
docker rmi
查看已经下载的镜像
1
docker images
启动应用
1
docker run 镜像名/id
特定版本的镜像
- docker pull 下载的是latest版本的
要下载特定版本需要在dockerhub查看版本tag
1
docker pull nginx:1.26.0
删除特定版本的docker rmi nginx:1.26.0 或者docker rmi 镜像id
常用命令(容器)
#查看运行的容器
1
docker ps
#查看所有的容器
1
docker ps -a
#启动容器
1
docker start 容器名
#停止
1
docker stop 容器id
#重启
1
docker restart 容器id
#删除容器(停止的)
1
docker rm
一键删除(慎用)
#-a 所有容器, -q 只显示id dokcer rm -f $(docker ps -aq)
端口映射
# –name 容器名为myNginx666
-p 端口宿主机27182映射到myNginx666的80端口
-d 后台运行
1
docker run -d --name myNginx666 -p 27182:80 nginx
进入容器
docker exec -it ed9ccdba0d4f bash
修改nginx的index.html页面
1
echo "<h1>Hello,Docker</h1>" > /usr/share/nginx/html/index.html
在宿主机查看
1
curl localhost:27182
分享/使用容器镜像
#分享,打包自己的容器镜像
commit : Create a new image from a container’s change
-a:author , -m : commit message
1
docker commit -a "zangxin_test" -m "update index.html" myNginx666 zangxin_nginx:v1.0
把镜像保存一个文件 zangxinNginx.tar
1
docker save -o zangxinNginx.tar zangxin_nginx:v1.0
加载文件
1
2
docker load -i zangxinNginx.tar
docker run -d --name mynginx -p 22222:80 zangxin_nginx:v1.0
访问: curl localhost:22222
分享镜像到DockerHub
- #1.需要登录到dockerhub, zangxin51是用户名,zangxin51/zangxin_nginx是仓库名
#2.修改tag为自己的用户名/镜像名, 否则推不上去
1
docker tag zangxin_nginx:v1.0 zangxin51/zangxin_nginx:v1.0
#推送镜像, 相当于在dockerhub创建了一个respository
1
docker push zangxin51/zangxin_nginx:v1.0
#3.创建latest分支, 别人拉的时候不用写版本好也可拉取
1 2
docker tag zangxin51/zangxin_nginx:v1.0 zangxin51/zangxin_nginx:latest docker push zangxin51/zangxin_nginx:lates
目录挂载,以外文件为准
痛点
- 1.在容器内部编写文件不方便 2.重启容器后,文件销毁
#宿主机~~/devtools/docker_mount/app/nginx_html映射到nginx容器的/usr/share/nginx/html目录下
#如果宿主机没有文件夹,会自动创建
1
docker run -d -p 15000:80 --name app01
1
-v ~/devtools/docker_mount/app/nginx_html:/usr/share/nginx/html nginx:latest
配置了挂载后, 在容器内修改可以影响到外部文件, 在挂载文件修改也能影响到容器, 其实本质上就是一份文件
同步容器时间问题
- -v /etc/localtime:/etc/localtime
卷映射(volumes) 以内部文件为准
痛点
-
1.目录挂载可以无法再启动时使用nginx容器中默认配置文件, 挂载了目录导致原来/etc/nginx/nginx.conf文件消失了, 导致nginx启动不了
-
卷映射可以把nginx中默认配置文件给映射到宿主机磁盘中
语法 -v ngconf:/etc/nginx
- 与目录挂载的区别, 目录挂载是你指定目录的 而卷映射是docker统一管理
在linux上卷目录在放在
- /var/lib/docker/volumes/
在mac上!!!
- 执行
1
docker run --pid=host --privileged -it --rm justincormack/nsenter1
然后再
1
cd /var/lib/docker/volumes/
命令
列出所有卷
1
docker volume ls
#创建卷
1
docker volume create ggstar
#查看卷的明细
1
docker volume inspect ggstar
删除docker容器并不会把卷也删除掉, 保证数据不会丢失
网络
在两个容器之间访问
-
比较傻的方法
- 通过外部端口映射来访问, 饶了一大圈,明明两个容器是邻居
1
curl 192.168.2.42:15000
- 通过外部端口映射来访问, 饶了一大圈,明明两个容器是邻居
docker0默认网络
- ifconfig
查看容器网络网关
1
docker instpect app01
容器网关默认是172.17.0.1
docker 为每个容器提供默认ip
- 访问别的容器, 可以通过容器ip + 容器端口
1
curl http:172.17.0.3:80
缺点
- 容器重启后ip变化
解决docker0的ip变化
-
dokcer0默认不支持主机域名
-
创建自定义网络, 容器名就是稳定域名
自定义网络容器名,就是稳定域名
- #创建网络
1
docker network create mynet
#查看网络
1
docker network ls
创建容器时加入网络
1
docker run -d -p 88:80 --name app1 --network mynet nginx:latest
#在容器之间访问(进入到容器中,使用curl)
1 2
curl http://app1 curl http://app2
实例,搭建redis容器
通过配置环境变量
- master(redis01)
1
2
3
4
docker run -d -p 6379:6379 -v ~/devtools/docker_mount/app/rd1:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=master \
-e REDIS_PASSWORD=root \
--network mynet --name redis01 \
- salve(redis02)
1
2
3
4
5
6
7
8
docker run -d -p 6380:6379 -v ~/devtools/docker_mount/app/rd2:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=slave \
-e REDIS_PASSWORD=root \
-e REDIS_MASTER_HOST=redis01 \
-e REDIS_MASTER_PORT_NUMBER=6379 \
-e REDIS_MASTER_PASSWORD=root \
--network mynet --name redis02 \
bitnami/redis
- 在master中写入数据, 查看slave中是否有数据 在anoter redis desktop这个可视化app中查看
环境变量
-e
最佳实践
是否需要端口访问
- 端口映射
是否需要配置挂载
- 卷挂载
是否需要数据挂载
- 目录挂载
是否需要配置环境变量
安装mysql
1
2
3
4
5
docker run -d -p 3307:3306 \
-v ~/devtools/docker_mount/app/myconf:/etc/mysql/conf.d \
-v ~/devtools/docker_mount/app/mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
--name zangxin_mysql mysql:latest
docker compose
说明
- docker pose用来批量管理容器
how to
- 配置compose.yaml
命令
- 上线
1
docker compose up -d
下线
1
docker compose down
- 启动
1
docker compose start x1 x2 x3
停止
1
docker compose stop x1 x3
扩容,启动x2三个实例
1
docker compose scale x2=3
编写compose file
-
文档
- https://docs.docker.com/reference/compose-file/
安装一个wordpress blog
-
docker_compose.yaml
- name: myblog
services:
```bash
mysql:
container_name: myblog_mysql
image: mysql:8.0
ports:
- “3306:3306” environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=wordpress volumes: 挂载
- /Users/qingsongcai/devtools/docker_mount/myblog/mysql-data:/var/lib/mysql
- /Users/qingsongcai/devtools/docker_mount/myblog/myconf:/etc/mysql/conf.d restart: always # 开机自启 networks:
- myblog
wordpress: image: wordpress ports: - “8080:80” environment: WORDPRESS_DB_HOST: myblog_mysql WORDPRESS_DB_USER: root WORDPRESS_DB_PASSWORD: root WORDPRESS_DB_NAME: wordpress volumes: - wordpress:/var/www/html restart: always networks: - myblog depends_on: #指定依service赖顺序, mysql先启动, 然后再启动这个 - mysql ```
- name: myblog
services:
```bash
mysql:
container_name: myblog_mysql
image: mysql:8.0
ports:
volumes: #卷挂载要声明
1
wordpress:
networks: #定义网络
1
myblog:
-
docker compose -f docker_compose.yaml up -d
- 启动 会判断是否修改过,只启动修改过的
-
docker compose -f docker_compose.yaml down
- 停止, 并删除容器和网络, 但是不会删除volumes和挂载目录和镜像
● 增量更新
1
○ 修改 Docker Compose 文件。重新启动应用。只会触发修改项的重新启动。
● 数据不删
1
默认就算down了容器,所有挂载的卷不会被移除。比较安全
Dockerfile
作用,制作镜像
文档
- https://docs.docker.com/reference/dockerfile/
常用指令
文件名固定Dockerfile
- FROM openjdk:17
1
LABEL author=zangxin
把当前目录下的app.jar放到容器的根目录下/
1
COPY app.jar /app.jar
#暴露端口
1
EXPOSE 8080
#执行 java -jar /app.jar
1
ENTRYPOINT ["java", "-jar","/app.jar"]
构建镜像
-
.点表示在当前目录构建
1
docker build -f Dockerfile -t myjavapp:v1.0 .
镜像分层机制
查看镜像层和读写层内存占用量
- docker ps -s
安装常用中间件
https://www.yuque.com/leifengyang/sutong/au0lv3sv3eldsmn8
查看容器日志
1
docker logs names
docker RemoteAPI + idea集成工具使用
开启docker服务器守护进程绑定到2375接口
-
vim /usr/lib/systemd/system/docker.service
-
[Service] Type=notify
the default is not to use systemd for cgroups because the delegate issues still
exists and systemd currently does not support the cgroup feature set required
for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 –containerd=/run/containerd/containerd.sock
-
在上面那个文件中[Service]的块中的ExecStart添加-H tcp://0.0.0.0:2375 使得远程可以连接,暴露端口
- 先重启服务,两个都要执行
1
systemctl daemon-reload
sudo systemctl restart docker.service
-
还要注意关闭防火墙或者开放端口
-
远程连接测试
- 先在本机测试可以OK吗
1
docker -H tcp://127.0.0.1:2375 ps
然后在其他机器测试可以OK吗
1
docker -H tcp://192.168.2.85:2375 ps
- 先在本机测试可以OK吗
-
idea连接
- services中选择docker 编辑配置 选择TCP socket engine api url填写为: tcp://192.168.2.85:2375