从 Docker 镜像仓库获取镜像
挑选镜像的时候尽量选择体积更小的镜像;如镜像名称中包含alpine的镜像,就是基础镜像为alpine linux做的,所以体积小;
代码实例:
docker pull redis:7.0-rc3-alpine3.15
tips: 使用-v的时候小心空挂载
:ro表示只读,默认是rw可读写
代码实例1:redis
docker run --name nginx-app \
-v /app/nginx/html:/usr/share/nginx/html:ro \
-v /app/nginx/conf:/etc/nginx
-d nginx
代码实例2: mysql
docker run -p 3306:3306 --name mysql57-app \
-v /app/mysql/log:/var/log/mysql \
-v /app/mysql/data:/var/lib/mysql \
-v /app/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7
mysql 8.x版本,引入了 secure-file-priv 机制,磁盘挂载将没有权限读写data数据,所以需要将权限透传, 或者chmod -R 777 /app/mysql/data
代码实例:
docker exec -it alpine sh
清除没有被使用的镜像
docker image prune
查看镜像信息,能看到镜像的WorkDir、UpperDir、MergedDir等所有信息
docker inspect alpine
docker cp index.html text-nginx:/user/share/nginx/html
docker cp text-nginx:/user/share/nginx/html/index.html index2.html
将宿主机的端口映射到容器的端口
docker create -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name hello-mysql mysql
在容器1不暴露出去的情况下,让容器2可以访问容器1;
如:在mysql所在容器不暴露的情况下,让其他容器中的项目可以访问mysql
docker run -d -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d --link mysql01:mysql --name tomcat-test tomcat:7
docker exec -it tomcat-test bash
cat /etc/hosts
ping mysql
Docker 使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动时会根据Docker网桥的网段分配给容器一个Ip地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样这些容器就能通过容器的Container-IP直接通信;
Docker容器网络很好的利用了Linux的虚拟网络技术,在宿主机和容器内分别创建了一个虚拟接口,并让它们彼此联通(这样的接口称为veth pair);
虚拟接口的优势是转发效率极高;因为不需要通过外部的网络设备交换,而是在内核中进行数据的复制来实现虚拟接口之间的数据转发;
网络模式 | 配置 | 说明 |
---|---|---|
bridge | –net=bridge | 默认值,在Docker网桥docker0上为容器创建新的网络栈 |
none | –net=none | 不配置网络,用户可以稍后进入容器,自行配置 |
container | –net=container:name/id | 容器和另一个容器共享Network namespace;kubernetes中的pod就是多个容器共享一个Network namespace |
host | –net=host | 容器和宿主机共享Network namespace |
自定义 | –net=自定义网络 | 用户自己使用network相关命令定义网络,创建容器的时候可以指定为自己定义的网络 |
常用配置参数
name | 说明 |
---|---|
network | 指定网关 |
gateway | |
subnet | 自定义子网 |
创建mynet网络
# -d bridge可以省略,默认桥接模式
docker network create -d bridge --subnet=192.168.0.0/16 --gateway=192.168.0.1 mynet
# or
docker network create --subnet=192.168.0.0/16 --gateway=192.168.0.1 mynet
查看网络信息
docker network ls
docker network inspect mynet
让创建的容器使用自定义mynet网络,这样使用mynet网络启动的容器就可以相互连接了(检测:直接ping);
使用mynet创建容器
docker run -d -P --name=tomcat2 --network=mynet tomact:jre8-alpine
将已有容器加入到自定网络
已经创建了nginx2容器的情况下,其他容器需要用到nginx2容器,使用connect将nginx2容器加入到mynect网络中,容器就联通了;
docker network connect mynet nginx2
已有容器a,创建容器b的时候,让容器b使用容器a的网络;
实例:
# redisserver 是容器a的name
docker run -it --network container:redisserver alpine
docker run -it --network=host alpine
指令 | 说明 |
---|---|
FROM | 指定基础镜像 |
MAINTAINER | 指定维护者信息,已经过时,使用LABEL maintainer=xxx代替 |
LABEL | 指定维护者信息,LABEL maintainer=xxx |
RUN | 构建中运行命令 |
CMD | 启动容器时默认执行的命令 |
ENTERYPOINT | 指定镜像的默认入口,与CMD类似;区别是能够在运行命令时添加参数 |
EXPOSE | 声明镜像内服务监听的端口 |
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 --entrypoint 来指定。
当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:
<ENTRYPOINT> ""
会将CMD作为参数传入到ENTRYPOINT命令中
使用ENTRYPOINT的场景
1、让镜像变成命令一样使用时;
当CMD如下的时候,需要在运行的情况下加入其他参数,不能直接加入;
# dockerfile
CMD [ "curl", "-s", "http://myip.ipip.net" ]
如果用ENTRYPOINT的话可以随意添加参数:
# dockerfile
ENTRYPOINT [ "curl", "-s", "http://myip.ipip.net" ]
如build生成镜像后,创建并启动容器,执行 docker run name -i,最后在启动的时候,会执行:
curl -s http://myip.ipip.net -i
复杂应用中,启动一个项目需要启动多个容器,如:nginx、mysql、node等等;
docker-compose可以看作是命令集合,通过.yaml配置文件启动所有需要启动的容器;
# 需要能够访问github
sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#or
# 使用国内资源
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
参考:docker-compose v3 api文档
# compose.yaml 配置文件
version: '3' # docker版本号
services: # 所有需要启动的服务
web: # 第一个服务的name
build: . # 构建路径,就是docker build时的那个路径
ports:
- "5000:5000"
deploy: # 需要安装docker swarm
replicas: 6 #指定副本,创建6个web服务,高可用、负载均衡
redis: # 第二个服务的name
image: "redis:alpine" # 使用的镜像名
执行
docker-compose up -d #后台运行
docker-compose down #停掉服务
docker-compose执行步骤
因为使用得是同个网络,因此web、redis、web间是相互可以访问的;
了解即可,后面使用强大的k8s;
docker swarm init # 创建master节点
使用init时打印的docker join …,在需要加入集群的机器上执行
持续更新…
持续更新,加关注,不错过哦~