本文是之前 docker从入门到实践 这篇文章的一个续集,用于记录docker在使用过程当中所遇到的一些问题与对应的解决方案。由于作者才疏学浅,难免会有错误或片面之处,还请谅解!
1. docker容器内vim命令中文乱码
进入docker容器内部后,利用vim命令打开文本文件,出现中文乱码。
解决方案1:在进入容器的时候,带上编码
docker exec -it container_id env LANG=C.UTF-8 /bin/bash
解决方案2:https://www.jianshu.com/p/ae367138b7e3
2. Error starting userland proxy: listen tcp0.0.0.0:3306: bind: address already in use
重启docker容器内mysql的时候,出现该错误。
解决方案:重启docker服务
systemctl restart docker
3. java连接docker容器内mysql
利用java连接docker容器内mysql,配置jdbc数据源时,配置如下数据源报错。
spring.datasource.url=jdbc:mysql://IP:3306/db_name?characterEncoding=utf8&useSSL=true
解决方案:将数据源配置中useSSL=true
去掉
spring.datasource.url=jdbc:mysql://IP:3306/db_name?characterEncoding=utf8
4. 多个容器之间互相协作通信
当涉及到多个docker容器之间互相通信时,如容器A
需要访问容器B
中的mysql,同时容器A
需要访问容器C
中的某个接口,此时需要将多个容器连接在一起,或者置于同一网络中。docker提供了二种方式来实现。
方式一:--link方式(不推荐,未来会被弃用)
docker run -itd -p 8080:8080 --name docker_A --link docker_B:docker_b --link docker_C:docker_c java_web:v1.0
# run 运行容器
# -itd 后台运行
# -p 8080:8080 将容器中8080端口映射到宿主主机的8080端口
# --name docker_A 运行镜像后,容器的名字
# --link docker_B:docker_b 将容器B连接到容器A,并将容器B取别名为docker_b
# --link docker_C:docker_b 将容器C连接到容器A,并将容器B取别名为docker_c
# java_web:v1.0 镜像名和tag
方式二:--network方式(推荐)
只需将多个容器置于同一个网络中即可,因此需要创建一个桥接来桥接多个容器,使它们处于同一网络中。
docker network create -d bridge my-bridge
docker内置host、bridge和none三种网桥,可用如下命令查看,当新建网桥my-bridge
后,其信息会添加到网桥列表中
[root@VM_1_7_centos ~] docker network ls
NETWORK ID NAME DRIVER SCOPE
1fdbc8764188 bridge bridge local
8d92c7b5cac2 bridge my-bridge local
3b982758d982 host host local
3ade55f86109 none null local
在启动容器时,加上--network
选项,并且名称相同,则容器A、B和C就会处于同一网络中,在程序中,可以直接用容器A、B或C的容器名字来访问该容器的对外接口即可。
docker run -itd --restart=always -p 6000:6000 --name docker_A --network my-bridge java_A:v1.0
docker run -itd --restart=always -p 3307:3306 --name docker_B --network my-bridge mysql_B:v1.0
docker run -itd --restart=always -p 6001:6001 --name docker_C --network my-bridge php_C:v1.0
# --restart=always 容器退出后,自动重启
# --network my-bridge 网桥名称,如果名称相同,则处于同一网络
例如:
如果容器A(java服务)需要访问容器B中的mysql数据库,则只需在配置文件application.properties
中引用容器B的名字即可
spring.datasource.url=jdbc:mysql://docker_B:3306/db_name?characterEncoding=utf8
注意1:需要将useSSL=true
去掉,参考第3小节;
注意2:此处访问的是容器B中的3306端口,因为3307端口是映射到宿主主机上的,容器B中对外提供的还是3306端口,而容器A和B处于同一网络,因此需要访问3306端口。而通过Navicat连接容器B中的mysql时候,需要3307端口。
5. docker容器重命名
docker rename old_container_name new_container_name
6. docker 镜像名与tag重命名
docker tag image_id new_image_name:new_tag
7. docker镜像导出压缩
导出镜像
docker save : | gzip > _.tar.gz
导入镜像
gunzip -c _.tar.gz | docker load