Docker笔记2

Dockerfile、Docker网络、Docker-compose、swarm及docker简单实现redis高可用集群

DockerFile

dockerfile介绍

dockerfile是用来构建docker镜像的文件,命令参数脚本

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(dockerhub、阿里云镜像仓库)

Centos官方dockerfile

image-20230226151736580

很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建镜像

dockerfile构建过程

基础知识

  1. 每个保留关键字(指令)必须是大写字母
  2. 执行从上到下执行
  3. #号表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交
  5. dockerfile 是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单
  6. Docker镜像逐渐成为企业交付的标准。
  7. DockerFile:构建文件,定义了一切的步骤,源代码
  8. DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品,原来是jar,war
  9. docker容器:容器就是镜像运行起来提供服务

DockerFile的指令

FROM  # 基础镜像,一切从这里开始构建
MAINTAINER  # 镜像是谁写的,姓名+邮箱
RUN  # 镜像构建的时候需要运行的命令
ADD  # 步骤:tomcat镜像,tomcat的压缩包就是添加内容
WORKDIR  # 镜像的工作目录 
VOLUME  # 挂载的目录
EXPOSE  # 暴漏端口配置
CMD  # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT  # 指定这个容器启动的时候要运行的命令,可以追加命令,
ONBUILD  # 当构建一个被继承 DockerFile 这个时候会运行ONBUILD的指令,触发指令
COPY  # 类型ADD, 将我们文件拷贝到镜像中
ENV  # 构建的时候设置环境变量

实战测试

创建一个自己的centos

# 1. 编写DockerFile文件
FROM centos:7
MAINTAINER jhonny<jhonny22@163.com>

ENV MYPATH /usr/local
WORKDIR MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echoMYPATH

CMD echo "-----end-----"
CMD /bin/bash

2. 通过这个文件构建镜像
docker build -f mydockerfile -t mycentos:0.1 .

3. 测试
[root@localhost dockerfile]# docker run -it mycentos:0.1
[root@a9517c1b115f local]# pwd
/usr/local # 默认工作目录与dockerfile中定义一致
[root@a9517c1b115f local]# ifconfig  # 官方centos镜像不带的命令,自定义添加
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:3  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 9  bytes 737 (737.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 656 (656.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

4. 镜像构建过程
docker history 容器id

image-20230226155239319

CMD ENTRYPOINT 区别

CMD   # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT  # 指定这个容器启动的时候要运行的命令,可以追加命令
# 编写dockerfile-cmd-test:
FROM centos:7

CMD ["ls","-a"]

# build构建容器
[root@localhost dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
Sending build context to Docker daemon 3.072 kB
Step 1/2 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/2 : CMD ls -a
 ---> Running in 2396112c2418
 ---> 5cd24db8f903
Removing intermediate container 2396112c2418
Successfully built 5cd24db8f903

# run运行测试

image-20230226155850086

# 想追加一个命令 -l ls -al 会报错
# 原因:使用CMD后,追加命令-l 会替换原先的CMD ["ls","-a"],-l不是命令,所以会报错
[root@localhost dockerfile]# docker run 5cd24db8f903 -l
container_linux.go:290: starting container process caused "exec: \"-l\": executable file not found in PATH"
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:290: starting container proc
ess caused "exec: \"-l\": executable file not found inPATH".ERRO[0000] error getting events from daemon: net/http: request canceled 

# 编写测试ENTRYPOINT 
vim dockerfile-cmd-entrypoint

[root@localhost dockerfile]# docker build -f dockerfile-cmd-entrypoint -t entrypoint-test .
Sending build context to Docker daemon 4.096 kB
Step 1/2 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/2 : ENTRYPOINT ls -a
 ---> Running in 71022071db60
 ---> fc2869d69a34
Removing intermediate container 71022071db60
Successfully built fc2869d69a34
[root@localhost dockerfile]# docker run fc2869d69a34
.
..
.dockerenv
anaconda-post.log
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@localhost dockerfile]# docker run fc2869d69a34 -l
total 12
drwxr-xr-x.   1 root root    17 Feb 26 08:06 .
drwxr-xr-x.   1 root root    17 Feb 26 08:06 ..
-rwxr-xr-x.   1 root root     0 Feb 26 08:06 .dockerenv
-rw-r--r--.   1 root root 12114 Nov 13  2020 anaconda-post.log
lrwxrwxrwx.   1 root root     7 Nov 13  2020 bin -> usr/bin
drwxr-xr-x.   5 root root   340 Feb 26 08:06 dev
drwxr-xr-x.   1 root root    66 Feb 26 08:06 etc
drwxr-xr-x.   2 root root     6 Apr 11  2018 home
lrwxrwxrwx.   1 root root     7 Nov 13  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root     9 Nov 13  2020 lib64 -> usr/lib64
drwxr-xr-x.   2 root root     6 Apr 11  2018 media
drwxr-xr-x.   2 root root     6 Apr 11  2018 mnt
drwxr-xr-x.   2 root root     6 Apr 11  2018 opt
dr-xr-xr-x. 266 root root     0 Feb 26 08:06 proc
dr-xr-x---.   2 root root   114 Nov 13  2020 root
drwxr-xr-x.   1 root root    21 Feb 26 08:06 run
lrwxrwxrwx.   1 root root     8 Nov 13  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root     6 Apr 11  2018 srv
dr-xr-xr-x.  13 root root     0 Feb 26 07:09 sys
drwxrwxrwt.   7 root root   132 Nov 13  2020 tmp
drwxr-xr-x.  13 root root   155 Nov 13  2020 usr
drwxr-xr-x.  18 root root   238 Nov 13  2020 var

实战测试:Tomcat+jdk

  1. 准备镜像文件tomcat压缩包,jdk的压缩包

    image-20230227202542496

  2. 编写dockerfile,官网命名Dockerfile ,build会自动寻找这个文件,就不需要-f指定

    # 编写DockerFile
    FROM centos:7
    MAINTAINER jhonny<jhonny22@163.com>
    
    COPY readme.txt /usr/local/readme.txt
    
    ADD jdk-8u171-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.72.tar.gz /usr/local/
    
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    WORKDIR MYPATH
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_11
    ENV CLASSPATHJAVA_HOME/lib/dt.jar:JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.72
    ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.72
    ENV PATHPATH:JAVA_HOME/bin:CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    EXPOSE 8080
    
    CMD /usr/local/apache-tomcat-9.0.72/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.72/logs/catalina.out
    
  3. 构建镜像
    docker build -t diytomcat .
    
  4. 启动测试
    docker run -d -p 9090:8080 --name jhonnytomcat -v /home/jhonny/build/tomcat/test:/usr/local/apache-tomcat-9.0.72/webapps/test -v /home/jhonny/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.72/bin/logs --privileged=true  diytomcat
    
  5. 自定义页面访问
    <%@ page language="java" contentType="text/html; charset=UTF-8"
       pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>菜鸟教程(runoob.com)</title>
    </head>
    <body>
    Hello World!<br/>
    <%
    out.println("你的 IP 地址 " + request.getRemoteAddr());
    %>
    </body>
    </html>
    
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
     version="4.0"
     metadata-complete="true">
    
    </web-app>
    

    访问:localhost:9090/test

发布自己的镜像

DockerHub

  1. 地址 https://hub.docker.com/

  2. 在服务器提交镜像

    docker login --help
    
    Usage:   docker login [OPTIONS] [SERVER]
    
    Log in to a Docker registry
    
    Options:
         --help              Print usage
     -p, --password string   Password
     -u, --username string   Username
    
    
    [root@localhost test]# docker login -u bybing
    Password: 
    Login Succeeded
    
  3. 发布镜像前需增加标签,并且作者名必须与dockerhub账号一致
    docker tag 容器id bybing/tomcat:1.0
    

    image-20230227224740041

阿里云镜像

  1. 登录阿里云
  2. 找到容器镜像服务

Docker网络

理解Docker0

lo:本地回环地址

image-20230302221930670

image-20230302221953580

原理

  1. 我们每启动一个docker容器,docker就会给容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0 桥接模式使用的技术是veth_pair技术

image-20230302222838664

–link

场景:微服务,database url=ip 项目部重启,数据库ip更换,如何处理。

–link原理:是在指定容器的hosts配置中添加了需要访问容器的地址

现在docker不推荐使用–link,推荐自定义网络,不使用docker0,docker0存在的问题:不支持容器名连接访问。

自定义网络

查看所有docker网络

image-20230303225157071

网络模式

bridge:桥接docker 默认

none :不配置网络

host:和宿主机共享网络

container:容器网络连通 很少用,局限很大

测试

# 我们直接启动的命令 --net bridge 这个就是docker0
docker run -d -P --name tomcat01 tomcat 
docker run -d -P --name tomcat01 --net bridge tomcat

# docker0 特点:域名不能访问,--link可以打通连接
# 自定义网络
--driver bridge
--subnet 192.168.0.0/16 # 后面的16代表前16位固定,就是192.168不变,分配ip数量为255*255-2
--gateway 192.168.0.1
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

image-20230303230936440

# 将tomcat01加入到mynet网络里
docker network connect mynet tomcat01

结论:

假设要夸网络操作别人,就需要使用docker network connect 连通

实战:部署Redis集群

# 创建网卡
docker network create redis --subnet 172.38.0.0/16

# 通过脚本创建6个redis配置
for port in (seq 1 6);\
do \
mkdir -p /mydata/redis/node-{port}/conf
touch /mydata/redis/node-{port}/conf/redis.conf
cat << EOF >>/mydata/redis/node-{port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1{port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

# 自动启动6个容器脚本
for port in(seq 1 6); \
do \
docker run -p 637{port}:6379 -p 1637{port}:16379 --privileged=true --name redis-{port} \
-v /mydata/redis/node-{port}/data:/data \
-v /mydata/redis/node-{port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1{port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done

# 手动启动命令
docker run -p 6371:6379 -p 16371:16379 --privileged=true --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

image-20230304134919299

检查redis集群信息

image-20230304135028612

存数据测试高可用集群

127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK

# 数据存在redis-3,手动停止redis-3容器 
docker stop redis-3

127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b" # 数据从redis-3的从机redis-4取出

image-20230304135814133

SpringBoot微服务打包Docker镜像

  1. 构建springboot项目
  2. 打包应用
  3. 编写dockerfile
  4. 构建镜像
  5. 发布运行

以后我们使用docker之后,交付的就是一个镜像即可。

Docker Compose

docker compose是什么?

Docker Compose能够在 Docker 节点上,以单引擎模式(Single-Engine Mode)进行多容器应用的部 署和管理。多数的现代应用通过多个更小的微服务互相协同来组成一个完整可用的应用。

定义、运行多个容器,使用docker-compose.yml配置文件

部署和管理繁多的服务是困难的。而这正是 Docker Compose 要解决的问题。Docker Compose 并不 是通过脚本和各种冗长的 docker 命令来将应用组件组织起来,而是通过一个声明式的配置文件描述整 个应用,从而使用一条命令完成部署。应用部署成功后,还可以通过一系列简单的命令实现对其完整声 明周期的管理。甚至,配置文件还可以置于版本控制系统中进行存储和管理。

三步骤

  1. dockerfile,dockerfile保证我们的项目在任何地方可以运行
  2. docker-compose.yml services
  3. docker-compose -up 启动项目

作用:批量容器编排

compose是docker官方的开源项目,需要安装

docker-compose安装

# 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

# daocloud
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

# 2.添加权限
sudo chmod +x /usr/local/bin/docker-compose

# 3. 创建软链
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 4. 测试
docker-compose version

官方文件-compose

version: '2.0' # 版本
services:
    web: # 服务1
        build: .
        ports:
        - "5000:5000"
        volumes:
        - .:/code
        - logvolume01:/var/log
        links:
        - redis
    redis:
        images: redis
volumes:
    logvolume01: {}

docker-compose up 100个服务

compose:重要概念

  • 服务services,容器,应用 :web、redis、mysql….
  • 项目project 一组关联的容器,博客:web+mysql

Docker Swarm

初始化节点docker swarm init

docker swarm join 加入一个节点

# 获取令牌
docker swarm join-token manager  #创建manager 主节点
docker swarm join-token worker   #创建一个worker 工作节点 

留下评论

您的电子邮箱地址不会被公开。 必填项已用*标注