diff --git a/source/_posts/linux/3.1、Docker(1)-初见.md b/source/_posts/linux/3.1、Docker(1)-初见.md index 4e1bfd8..ce2b8b6 100644 --- a/source/_posts/linux/3.1、Docker(1)-初见.md +++ b/source/_posts/linux/3.1、Docker(1)-初见.md @@ -244,4 +244,9 @@ DOCKER_OPTS="--registry-mirror=https://docker.mirrors.ustc.edu.cn" "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"] } ``` +修改完成后重启dokcer服务 +```bash +systemctl daemon-reload +systemctl restart docker +``` > 新版的docker比较推荐方法3 \ No newline at end of file diff --git a/source/_posts/linux/3.5、Docker(5)-容器连接.md b/source/_posts/linux/3.5、Docker(5)-容器连接.md new file mode 100644 index 0000000..ce2d34d --- /dev/null +++ b/source/_posts/linux/3.5、Docker(5)-容器连接.md @@ -0,0 +1,217 @@ +--- +title: 3.5、Docker(5)-容器连接 +date: 2018-7-9 10:02:52 +tags: + - linux + - docker +categories: + - linux +--- +容器在运行当中, 经常需要连接到其他容器, 比如web程序需要连接到数据库 +docker容器使用`link`参数来实现容器之间的连接, 从而可以完成不同容器之间的交互工作 + + +### SpringBoot程序容器化 +例如在这个程序当中需要连接mysql与redis + + +#### 启动reids与mysql容器 +拉取镜像 +```bash +docker pull redis:4.0 +docker pull mysql:5.7 +``` +启动容器 +```bash +# 启动redis容器 +docker run \ + -d \ + --name redis-server \ + redis:4.0 \ + --requirepass "xyz654321" + +# 启动mysql容器 +docker run \ + -d \ + --name mysql-server \ + --env MYSQL_ROOT_PASSWORD=123456 \ + mysql:5.7 +``` +这里指定了容器的名字( 在之后的容器连接当中要用到 ) +并且设置redis和mysql的密码 +查看容器的运行情况 +![mysql与redis容器](/images/linux/mysql与redis容器.jpg) +我们在启动mysql容器的时候没有映射到宿主机端口 +如果要连接进行数据库导入操作 +可以查看这个容器的IP +![mysql容器IP地址](/images/linux/mysql_ip.jpg) + +> 这里推荐一个mysql的命令行客户端工具[mycli](https://github.com/dbcli/mycli) +具备语法补全功能, 是python写的 +![mycli](/images/linux/mycli.gif) +在ubuntu下使用`apt install mycli`安装 +在centos下使用`pip install mycli`安装 + +这里我们就要根据容器的虚拟IP进行连接了 +```bash +mycli -h 172.17.0.3 +``` +之后创建数据库testdb +创建用户test_user, 设置密码为abc123456, 并进行授权 + +#### SpringBoot配置文件 +application.yml +```yaml +server: + port: 9000 + +mysql-host: 127.0.0.1 +redis-host: 127.0.0.1 + +spring: + datasource: + url: jdbc:mysql://${mysql-host}:3306/testdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + username: test_user + password: abc123456 + redis: + host: ${redis-host} + port: 6379 + password: xyz654321 +``` +这里把mysql与redis的主机地址单独拿出来作为一个配置项, 为了容器启动时可以方便进行传参控制 + +#### 项目代码 +需要引入redis连接以及mysql连接相关的jar包 +pom.xml +```xml + + + org.springframework.boot + spring-boot-starter-data-redis + ${spring-boot.version} + + + redis.clients + jedis + 2.9.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + ${spring-boot.version} + + + mysql + mysql-connector-java + ${mysql-connector.version} + +``` +配置执行连接redis的bean +```java +@Configuration +public class RedisConfig { + @Value("${spring.redis.host}") + private String host; + + @Value("${spring.redis.port}") + private int port; + + @Value("${spring.redis.password}") + private String password; + + @Bean + public JedisConnectionFactory redisConnectionFactory() { + RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(); + redisConfiguration.setHostName(host); + redisConfiguration.setPort(port); + redisConfiguration.setPassword(RedisPassword.of(password)); + + JedisClientConfigurationBuilder clientConfig = JedisClientConfiguration.builder(); + clientConfig.connectTimeout(Duration.ofSeconds(60));// 60s connection timeout + + return new JedisConnectionFactory(redisConfiguration, clientConfig.build()); + } + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + // 使用JdkSerializationRedisSerializer来序列化和反序列化redis的value值 + RedisSerializer serializer = new JdkSerializationRedisSerializer(); + template.setValueSerializer(serializer); + template.afterPropertiesSet(); + return template; + } +} +``` + +#### 构建镜像 +将项目打包的jar文件放在一个独立目录当中(这里打包的文件是 **demo-1.0.0.jar**) +创建Dockerfile文件 +```docker +FROM java:openjdk-8-jre +COPY . /app +WORKDIR /app +RUN /bin/bash ./init.sh +EXPOSE 9000 +ENTRYPOINT ["java","-jar","demo-1.0.0.jar", \ + "--mysql-host=mysqlhost", \ + "--redis-host=redishost"] +``` ++ `RUN`指定运行了一个在打包镜像时执行的初始化脚本 +如果没有可执行的, 可以去掉 ++ `ENTRYPOINT`在容器运行时执行, 也可以使用CMD ++ 传递mysql-host与redis-host是springboot本身支持的特性, 命令行传参的优先级比配置文件更高, 将会在运行时生效 + +```bash +# 打包镜像 +docker build -t demo:1.0.0 /root/demo +``` + +#### 启动容器 +```bash +docker run -d \ + --rm \ + --link redis-server:redishost \ + --link mysql-server:mysqlhost \ + -p 9000:9000 \ + demo:1.0.0 +``` +link是用来指定与哪个容器进行连接 +例如`redis-server`是容器的名称, 后面的`redishost`是给这个连接指定一个别名 + +#### 原理浅析 +这里我创建的容器ID是6f1e5d0844c5 +我们可以通过shell进入这个容器查看内容 +```bash +docker exec -it 6f1e5d0844c5 bash +# 此时会切换到 root@6f1e5d0844c5 的shell +cat /etc/hosts +``` +内容如下 +``` +127.0.0.1 localhost +::1 localhost ip6-localhost ip6-loopback +fe00::0 ip6-localnet +ff00::0 ip6-mcastprefix +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +172.17.0.2 redishost 7bb1eb2c8edc redis-server +172.17.0.3 mysqlhost b71e6ce961f0 mysql-server +172.17.0.4 6f1e5d0844c5 +``` +显然, 运行容器时link参数的作用只是在hosts里面给另外几个容器的添加了别名 +所以我们执行数据库连接时才可以使用 +`jdbc:mysql://mysqlhost:3306/testdb`作为URL地址 +那么同理 +使用`mysql-server`或者直接用IP`172.17.0.3`都没问题 + +至此也就可以理解了, link参数并不是必须的 +在一台宿主机上运行的所有容器, 之间构成了一个虚拟的局域网 +他们之间都可以直接进行访问 + +> 当然知道应用容器的IP之后, 我们可以指定mysql数据库里面test_user的绑定IP是`172.17.0.4`而不是% +以便保证安全 \ No newline at end of file diff --git a/source/images/linux/mycli.gif b/source/images/linux/mycli.gif new file mode 100644 index 0000000..8973195 Binary files /dev/null and b/source/images/linux/mycli.gif differ diff --git a/source/images/linux/mysql_ip.jpg b/source/images/linux/mysql_ip.jpg new file mode 100644 index 0000000..3e5a769 Binary files /dev/null and b/source/images/linux/mysql_ip.jpg differ diff --git a/source/images/linux/mysql与redis容器.jpg b/source/images/linux/mysql与redis容器.jpg new file mode 100644 index 0000000..bf400e3 Binary files /dev/null and b/source/images/linux/mysql与redis容器.jpg differ