東川印記

一本東川,笑看爭龍斗虎;寰茫兦者,度橫佰昧人生。

简单学习docker

2022年7月8日星期五



之前学过多次,学了忘,忘了学,一直没有系统化学习过。。。。

之前的方式 部署应用复杂,时间成本、服务器成本高,迁移麻烦。

虚拟化Virtualization是一种计算机资源管理技术。

硬件级虚拟化:核心Hypervisor。vmware、virtualBox都是使用此技术。

操作系统级虚拟化:运行在操作系统之上的虚拟化技术。如Docker,基于LXC(Linux Container)。

Docker是一个开源的应用容器引擎。基于Go实现。

docker本身不是容器,是管理容器的引擎。

CE社区免费版,EE企业收费版。

docker使用C/S架构模式。

docker client 发送命令 -> docker daemon -> 内部外部操作

1,核心组件

镜像 image、容器 container、仓库 repository。

镜像就是一个只读的模板,用来创建容器。

镜像由多层文件系统叠加构成,从下往上为引导文件系统bootfs -> root文件系统rootfs,如centos -> 继续叠加其他文件系统。


docker利用容器来运行应用,容器是从镜像创建的运行实例。容器在启动的时候创建一层可写层作为最上层。

停止并删除所有容器

docker stop $(docker ps -q) & docker rm -f $(docker ps -aq)


仓库中存放镜像文件。仓库注册服务器Registry中一般放着多个仓库。

公开仓库docker hub。也可以在本地搭建私有仓库。


2,dockerfile

dockerfile分四个部分:基础镜像信息、维护者信息、镜像操作指令、容器启动时执行指令。

常用指令

FROM
格式为 FROM <image> 或 FROM <image>:<tag>
Dockerfile 文件的第一条指令必须为 FROM 指令。并且,如果在同一
个 Dockerfile 中创建多个镜像时,可以使用多个 FROM 指令(每个镜
像一次);

MAINTAINER
格式为 MAINTAINER <name>,指定维护者信息;
ENV
格式为 ENV <key> <value>,指定一个环境变量,会被后续 RUN 指令
使用,并在容器运行时保持;

ADD
格式为 ADD <src> <dest>;
复制指定的<src>到容器中的<dest>;

EXPOSE
格式为 EXPOSE <port> [<port>...]
告诉 Docker 服务端容器暴露的端口号,供互联系统使用,在启动容
器时需要通过 -p 映射端口,Docker 主机会自动分配一个端口转发到
指定的端口;

RUN
格式为 RUN <command>
RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像,
当命令较长时可以使用 \ 来换行;

CMD
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。
如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的
命令。

2.1)自定义JDK docker

SENRSL:test senrsl$ docker build --platform linux/x86_64 -t jdk1.8u202:v4 .
SENRSL:test senrsl$ docker run --platform linux/x86_64 -d -it --name jdk8u202 jdk1.8u202:v4
2d37f62b8cd4febb191e0f84e2dd2ddc335b475af2d2091d8b6e1d899a5b3bc3
SENRSL:test senrsl$ docker ps
CONTAINER ID   IMAGE           COMMAND       CREATED         STATUS         PORTS     NAMES
2d37f62b8cd4   jdk1.8u202:v4   "/bin/bash"   6 seconds ago   Up 5 seconds             jdk8u202
SENRSL:test senrsl$ docker exec -it jdk8u202 /bin/bash
[root@2d37f62b8cd4 /]# java -version
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
[root@2d37f62b8cd4 /]# exit
exit
SENRSL:test senrsl$ docker ps
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS          PORTS     NAMES
2d37f62b8cd4   jdk1.8u202:v4   "/bin/bash"   24 seconds ago   Up 23 seconds             jdk8u202
SENRSL:test senrsl$ cat Dockerfile

FROM centos:centos8
MAINTAINER senRsl
ADD jdk-8u202-linux-x64.tar.gz /usr/local
 
ENV JAVA_HOME /usr/local/jdk1.8.0_202
ENV JRE_HOME /usr/local/jdk1.8.0_202/jre
ENV PATH $JAVA_HOME/bin:$PATH

SENRSL:test senrsl$

当前使用的Apple M1芯片,ARM64的,jdk用的是x64的,所以需要指定平台--platform linux/x86_64,不然会找不到x64链接。

ADD jdk-8u202-linux-x64.tar.gz /usr/local 会自动解压到/usr/local目录,tar.gz包解压后目录名就是/usr/local/jdk1.8.0_202

2.3)自定义Tomcat

SENRSL:test senrsl$ mv Dockerfile Dockerfile_JDK1.8
SENRSL:test senrsl$ touch Dockerfile


SENRSL:test senrsl$ docker build --platform linux/x86_64 -t tomcat8.5.81:v1 .
                                                                                       0.0s
SENRSL:test senrsl$ docker images
REPOSITORY     TAG               IMAGE ID       CREATED          SIZE
tomcat8.5.81   v1                83f1163f396a   6 seconds ago    649MB
jdk1.8u202     v4                bb8ff3aaf15a   20 minutes ago   634MB
redis          5.0.14-bullseye   d96d28c1917c   2 weeks ago      104MB
nginx          latest            cd4e03b35a8e   2 weeks ago      134MB

SENRSL:test senrsl$ docker run --platform linux/x86_64 -d -it -p 8080:8080 --name tomcat8581 tomcat8.5.81:v1
d07f77c6bf70449b59417d8ba4c6d2b0c9c882283126980bba8beb00d0542136
SENRSL:test senrsl$ docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                    NAMES
d07f77c6bf70   tomcat8.5.81:v1   "/bin/sh -c '/usr/lo…"   3 seconds ago    Up 2 seconds    0.0.0.0:8080->8080/tcp   tomcat8581
2d37f62b8cd4   jdk1.8u202:v4     "/bin/bash"              16 minutes ago   Up 16 minutes                            jdk8u202
SENRSL:test senrsl$ cat Dockerfile

FROM jdk1.8u202:v4
MAINTAINER senRsl
ADD apache-tomcat-8.5.81.tar.gz /usr/local/
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.81
ENV PATH $PATH:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.81/bin/catalina.sh run

SENRSL:test senrsl$

本机访问 http://localhost:8080/ 验证

2.3)mysql

FROM centos:centos7
MAINTAINER senRsl
RUN yum install mysql-server mysql -y
RUN /etc/init.d/mysqld start &&\
mysql -e "grant all privileges on *.* to 'root'@'%' identified by '0123456' WITH GRANT OPTION ;"&&\
mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by '0123456' WITH GRANT OPTION ;"&&\
mysql -uroot -p0123456 -e "show databases;"
EXPOSE 3306
CMD /usr/bin/mysqld_safe

 /etc/init.d/mysqld 位置貌似挪了,算了。。。。

3,镜像仓库

除官方的外,阿里云也有 提供 容器镜像服务

研究了一下,发现阿里云可以 代码托管 -> 自动打包 -> 自动容器化部署 一站式服务。。。。


4,应用部署

先新建一个SpringBoot应用

SpringBoot应用,通过http rest访问接口,接口访问Redis,Redis访问mysql数据库。

1)docker 部署mysql

mysql5没有arm64版本,下载mysql8....

5.7.38: Pulling from library/mysql
no matching manifest for linux/arm64/v8 in the manifest list entries

SENRSL:test senrsl$ docker pull mysql:8.0.29

SENRSL:test senrsl$ docker run -d  -p 3306:3306 -e MYSQL_ROOT_PASSWORD=0123456 --name mysql8029 mysql:8.0.29
c6992362082c6b5ab4c123e3262d1806ae6657d3389cbaa549f337fadd982613
SENRSL:test senrsl$ docker ps
SENRSL:test senrsl$ docker exec -it mysql8029 bash
bash-4.4# mysql -uroot -p0123456

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '0123456'; //修改root密码
Query OK, 0 rows affected (0.03 sec)

mysql> CREATE USER 'dockerUsr'@'%' IDENTIFIED WITH mysql_native_password BY 'dockerPasswd';   //创建远程用户
Query OK, 0 rows affected (0.02 sec)

mysql> GRANT ALL PRIVILEGES ON *.* TO 'dockerUsr'@'%';  //给远程用户授予权限
Query OK, 0 rows affected (0.02 sec)

建库建表填数据

mysql> create database test20220708;
Query OK, 1 row affected (0.03 sec)

mysql> use test20220708;
Database changed

mysql> create table t_user(
    -> id int(4) primary key not null auto_increment,
    -> name varchar(128),
    -> age int(3)
    -> );
Query OK, 0 rows affected, 2 warnings (0.05 sec)

mysql> insert into t_user(name,age) values("zhangsan",100);
Query OK, 1 row affected (0.03 sec)

mysql> insert into t_user(name,age) values("lisi",50);
Query OK, 1 row affected (0.02 sec)

mysql> select * from t_user;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |  100 |
|  2 | lisi     |   50 |
+----+----------+------+
2 rows in set (0.01 sec)

mysql>


2)docker 部署Redis

SENRSL:test senrsl$ docker run --name redis5014 -p 6379:6379 -d redis:5.0.14-bullseye
03ae0681579b8b40b9906343373b76e5965bb486cd3fa54f56af2dc01ee2b630
SENRSL:test senrsl$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED          STATUS          PORTS                               NAMES
03ae0681579b   redis:5.0.14-bullseye   "docker-entrypoint.s…"   3 seconds ago    Up 2 seconds    0.0.0.0:6379->6379/tcp              redis5014
c6992362082c   mysql:8.0.29            "docker-entrypoint.s…"   25 minutes ago   Up 25 minutes   0.0.0.0:3306->3306/tcp, 33060/tcp   mysql8029
SENRSL:test senrsl$


3)编写SpringBoot应用测试流程

pom.xml引入 redis、mysql、spring web

<build>
    <plugins>
        <!--  编译打包插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <!--MyBatis自动生成代码的Maven插件-->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.6</version>
            <configuration>
                <!--配置文件位置-->
                <configurationFile>GeneratorMapper.xml</configurationFile>
                <verbose>true</verbose>
                <overwrite>true</overwrite>
            </configuration>
        </plugin>



    </plugins>

    <!-- javaresources目录下的资源都编译到classpath下,否则运行会找不到资源-->
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.*</include>
            </includes>
        </resource>
        <resource>
            <!-- 指定webapp的资源编译到classpath-->
            <directory>src/main/webapp</directory>
            <!--webapp的资源必须编译到此目录下才能被访问到 -->
            <targetPath>META-INF/resources</targetPath>
            <includes>
                <include>**/*.*</include>
            </includes>
        </resource>
    </resources>
</build>

配置myibatis生成mapper

编写实现逻辑

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;


    @Override
    public List<User> listUser() {
        redisTemplate.setKeySerializer(new StringRedisSerializer()); //redis序列化字符串

        List<User> list = (List<User>) redisTemplate.opsForValue().get("redis:users"); //获取缓存的user list

        if (null == list) {
            //redis中取不到,就去数据库中取
            list = userMapper.selectAll();
            //数据库中取出来的数据放入Redis缓存
            redisTemplate.opsForValue().set("redis:users", list);
        }

        return list;
    }
}

调用

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/listUser")
    public Object listUser() {
        return userService.listUser();
    }


}

编写application.yml

server:
  port: 8080
  servlet:
    context-path: /test
spring:
  redis:
    host: 127.0.0.1
    port: 6379
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test20220708?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
    username: dockerUsr
    password: dockerPasswd
    driver-class-name: com.mysql.cj.jdbc.Driver
  mvc:
    view:
      prefix: /
      suffix: .jsp


这里用root账号竟然不好使,改成dockerUser才行。。。。

运行 http://localhost:8080/test/listUser  获取到了数据库中内容

5,容器部署jar包

打jar、war包,上传、dockerfile创建镜像。

1)修改pom中packing为jar

2)打jar包

Lifecycle中package,生成jar包位于 target/TestDocker-0.0.1-SNAPSHOT.jar

3)做jdk镜像

SENRSL:test senrsl$ docker build -t jdk1.8u202:v5 .
SENRSL:test senrsl$ docker images
REPOSITORY   TAG               IMAGE ID       CREATED         SIZE
jdk1.8u202   v5                cf99cba415ec   4 seconds ago   439MB
mysql        8.0.29            64e1d555ec03   2 days ago      482MB
redis        5.0.14-bullseye   d96d28c1917c   2 weeks ago     104MB
nginx        latest            cd4e03b35a8e   2 weeks ago     134MB
SENRSL:test senrsl$ docker run  -dit --name jdk8u202 jdk1.8u202:v5
4ac04d26bafe6554a0f80234254b43025429d797e5b426506b3cb8d296a2f7c8
SENRSL:test senrsl$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED             STATUS             PORTS                               NAMES
4ac04d26bafe   jdk1.8u202:v5           "/bin/bash"              3 seconds ago       Up 2 seconds                                           jdk8u202
03ae0681579b   redis:5.0.14-bullseye   "docker-entrypoint.s…"   About an hour ago   Up About an hour   0.0.0.0:6379->6379/tcp              redis5014
c6992362082c   mysql:8.0.29            "docker-entrypoint.s…"   2 hours ago         Up 2 hours         0.0.0.0:3306->3306/tcp, 33060/tcp   mysql8029
SENRSL:test senrsl$ docker exec -it jdk8u202 bash
[root@4ac04d26bafe /]# java -version
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
[root@4ac04d26bafe /]# exit
exit
SENRSL:test senrsl$ cat Dockerfile

FROM centos:centos8
MAINTAINER senRsl
ADD jdk-8u202-linux-arm64-vfp-hflt.tar.gz /usr/local
 
ENV JAVA_HOME /usr/local/jdk1.8.0_202
ENV JRE_HOME /usr/local/jdk1.8.0_202/jre
ENV PATH $JAVA_HOME/bin:$PATH

SENRSL:test senrsl$

4)做jar镜像


SENRSL:test senrsl$ docker build -t test_docker_jar .
SENRSL:test senrsl$ docker run -dit -p 8080:8080 --name docker_jar test_docker_jar:latest
e02aa12df159d30bc057bd5b1ab337b90f38e66c5d6c59403dad7cda4de53e59
SENRSL:test senrsl$ docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS         PORTS                               NAMES
e02aa12df159   test_docker_jar:latest   "/bin/sh -c 'java -j…"   2 seconds ago   Up 2 seconds   0.0.0.0:8080->8080/tcp              docker_jar
4ac04d26bafe   jdk1.8u202:v5            "/bin/bash"              7 minutes ago   Up 7 minutes                                       jdk8u202
03ae0681579b   redis:5.0.14-bullseye    "docker-entrypoint.s…"   2 hours ago     Up 2 hours     0.0.0.0:6379->6379/tcp              redis5014
c6992362082c   mysql:8.0.29             "docker-entrypoint.s…"   2 hours ago     Up 2 hours     0.0.0.0:3306->3306/tcp, 33060/tcp   mysql8029
SENRSL:test senrsl$ docker logs docker_jar

java.net.ConnectException: Connection refused
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) ~[na:1.8.0_202]
    at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717) ~[na:1.8.0_202]
    at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:337) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:334) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:710) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) ~[netty-transport-4.1.78.Final.jar!/:4.1.78.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.78.Final.jar!/:4.1.78.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.78.Final.jar!/:4.1.78.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.78.Final.jar!/:4.1.78.Final]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_202]

SENRSL:test senrsl$

修改Redis和mysq连接地址,重新打包。。。。

 docker build -t test_docker_jar .

 docker run -dit -p 8080:8080 --name docker_jar test_docker_jar:latest

docker logs docker_jar

测试连接正常即可。。。。 http://localhost:8080/test/listUser

SENRSL:test senrsl$ cat Dockerfile
FROM jdk1.8u202:v5
MAINTAINER senRsl
ADD TestDocker-0.0.1-SNAPSHOT.jar /opt
RUN chmod +x /opt/TestDocker-0.0.1-SNAPSHOT.jar
CMD java -jar /opt/TestDocker-0.0.1-SNAPSHOT.jar

SENRSL:test senrsl$


6,容器部署war包

1)重写builder

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//        return super.configure(builder);
        return builder.sources(TestDockerApplication.class);
    }
}

2)pom中改war包,clean

3)package,生成war

得到 TestDocker-0.0.1-SNAPSHOT.war

4)做tomcat镜像

docker build  -t tomcat8.5.81:v2 .

docker run -dit -p 8080:8080 --name tomcat8581 tomcat8.5.81:v2

SENRSL:test senrsl$ cat Dockerfile

FROM jdk1.8u202:v5
MAINTAINER senRsl
ADD apache-tomcat-8.5.81.tar.gz /usr/local/
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.81
ENV PATH $PATH:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.81/bin/catalina.sh run

SENRSL:test senrsl$

5)做war镜像

SENRSL:test senrsl$ docker build -t test_docker_war .

SENRSL:test senrsl$ docker run -dit -p 8080:8080 --name docker_war test_docker_war:latest
SENRSL:test senrsl$ docker logs docker_war
[root@c188f73d15d9 /]# cd /usr/local/apache-tomcat-8.5.81/webapps/
[root@c188f73d15d9 webapps]# ls
ROOT  TestDocker-0.0.1-SNAPSHOT  TestDocker-0.0.1-SNAPSHOT.war    docs  examples    host-manager  manager
[root@c188f73d15d9 webapps]#

SENRSL:test senrsl$ cat Dockerfile

FROM tomcat8.5.81:v2
MAINTAINER senRsl
ADD TestDocker-0.0.1-SNAPSHOT.war /usr/local/apache-tomcat-8.5.81/webapps
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.81/bin/catalina.sh run

SENRSL:test senrsl$

测试 http://localhost:8080/TestDocker-0.0.1-SNAPSHOT/listUser 运行


--
senRsl
2022年07月07日15:59:13

没有评论 :

发表评论