容器之间的交互
docker容器互相独立,容器与宿主机之间可以进行端口映射,这样可以通过映射到宿主机的端口进行交互.
-
直接通过宿主机的ip和映射的端口进行交互:
例如宿主机ip为192.168.139.128, 启动一个容器A并映射到宿主机的80端口,再启动一个容器B映射到宿主机的81端口, 这两个容器可以通过宿主机的80端口和81端口进行交互.
这种通信方式存在缺陷:
导致容器提供的服务直接暴露在外.
宿主机ip改变之后容器之间的通信地址需要修改
-
使用docker提供的稳定的互联机制进行通信
容器的互联是一种让多个容器中的应用进行快速交互的方式, 它会在源和接收容器之间建立连接关系, 接收容器可以通过容器名快速访问到源容器,无需指定具体的IP地址.
容器互联
以redis为例,进行容器互联.
-
拉取一个redis镜像并创建一个redis容器,映射redis容器的6379端口到宿主机的6379端口
zack@ubuntu:~$ docker run -d -p 6379:6379 --name docker-redis redis:latest\n8c165f82579d
zack@ubuntu:~$docker ps -a
8c165f82579d redis:latest "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:6379->6379/tcp docker-redis
-
通过宿主机映射的端口测试redis容器可以正常连接
-
编写一个redis测试应用,打一个jar包,并制作为镜像
- 创建测试应用
编辑pom文件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 指定该Main Class为全局的唯一入口 -->
<mainClass>cn.zack.RedisApplication</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<!--可以把依赖的包都打包到生成的Jar包中-->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
编辑应用的application.yml配置文件
spring:
redis:
database: 1
# 使用容器互联不需要使用ip,只需要写redis容器的别名
host: docker-redis
port: 6379
编写此应用存取redis的方法
package cn.zack.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(path = "redis")
public class RedisController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@RequestMapping(path = "save")
public String saveOne(){
stringRedisTemplate.opsForValue().set("test","111111");
return "OK";
}
@RequestMapping(path = "get")
public String getOne(){
String s = stringRedisTemplate.opsForValue().get("test");
return s;
}
}
使用mvn clean package将应用打成jar包,并创建Dockerfile文件
zack@ubuntu:~/imagetest$ ls
Dockerfile spring-data-redis.jar
zack@ubuntu:~/imagetest$
编辑Dockerfile文件,编写镜像构建信息
FROM livingobjects/jre8:latest
VOLUME /tmp
COPY spring-data-redis.jar app.jar
RUN bash -c 'touch /app.jar'
# 由于jar包未指定端口,spring默认为8080端口,这里则指定镜像暴露8080端口
EXPOSE 8080
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
构建redis容器测试镜像
zack@ubuntu:~/imagetest$docker build -t redistest:v1.00 .
...
zack@ubuntu:~/imagetest$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redistest v1.00 b8ac51af88c0 3 hours ago 175MB
eureka v2.00 84017c788076 22 hours ago 217MB
eureka v1.00 e17436f031f4 23 hours ago 217MB
portainer/portainer latest ff4ee4caaa23 7 days ago 81.6MB
redis latest dcf9ec9265e0 2 weeks ago 98.2MB
nginx latest 231d40e811cd 2 weeks ago 126MB
ubuntu latest 775349758637 5 weeks ago 64.2MB
registry 2 f32a97de94e1 9 months ago 25.8MB
tobegit3hub/seagull latest bca211111ba5 2 years ago 315MB
java 8 d23bdf5b1b1b 2 years ago 643MB
livingobjects/jre8 latest 16e881b54ec0 3 years ago 128MB
zack@ubuntu:~/imagetest$
-
使用redis容器测试镜像启动一个容器,并与redis容器进行互联
启动redis测试容器时,使用--link 目标容器名:别名
子命令进行容器互联
其中,别名必须与应用的配置文件中写入的redis地址别名一致
zack@ubuntu:~/imagetest$docker run -d -p 8080:8080 --name redistest --link docker-redis:docker-redis redistest:v1.00
-
查看容器启动情况
zack@ubuntu:~/imagetest$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3529c85d9bfc redistest:v1.00 "/bin/sh -c 'java -D…" 3 hours ago Up 3 hours 0.0.0.0:8080->8080/tcp redistest
8c165f82579d redis:latest "docker-entrypoint.s…" 4 hours ago Up 3 hours 0.0.0.0:6379->6379/tcp docker-redis
zack@ubuntu:~/imagetest$
-
通过redis测试容器映射到宿主机的8080端口测试数据存取
存入数据到redis容器
此时redis中可以看到存入成功
获取redis容器中的数据