Docker进阶

笔记来自
狂神视频
Dockerfile
swarm教程

前言

  • 看完docker的入门笔记后会发现虽然安装东西很容易
  • 但是启动,网络通信,端口映射,文件挂载还是麻烦得不行
  • 入门的操作都很麻烦,到了进阶和高级会现在这些东西都是一键完成
  • 能用配置文件解决的,绝对不打命令,因为配置文件可以保存,容易看得多

Docker Compose 安装

  • 当需要多次重复一样的docker操作时
  • 可以使用该技术,写好yml配置文件,然后用命令执行即可
  • 这个是启动在一个机器上的配置文件
  • 下载安装依赖
# 设置源
curl -L https://github.com/docker/compose/releases/download/1.8.0/run.sh > /usr/local/bin/docker-compose

# 授权并安装,需要等到几个 pull complete完成才行
chmod +x /usr/local/bin/docker-compose

# 查看版本
docker-compose --version

Compose 使用

  • 单机服务
  • 编写配置文件,执行运行命令就行
  • 配置文件操作的都是dockor文件
  • 配置文件教程,具体看官网
  • 启动命令
# -d 是后台运行
docker-compose up -d
  • 可以配合dockerfile使用,但是更建议先把dockerfile打包成镜像上传到镜像服务器,为什么,往下看【实操发布】有解释
  • 实例一:搭建一个wordpress博客,查看【无分类/搭个博客】笔记
  • 实例二:搭建一个微服务,狂神视频第7集,首先需要打包一个jar文件,然后把jar用dockorfile制作成dockor文件,然后写一份compose配置文件,然后把三个文件都丢到服务器上,运行命令就行

image.png

Swarm

  • 服务器集群技术
  • 集群技术练习需要租用云服务器,查看【租用服务器】笔记
  • 集群有两个身份
  • 一个叫管理者manager,需要有多个,至少三个
  • 一个叫工作中worker,无数个
  • 安装好dockor后docker swarm --help有反应就说明安装成功
# init操作
# 随便找一个服务器输入
# IP的获取方式是 ip addr
docker swarm init --advertise-addr 【内网IP地址】

# 查看集群的节点
docker node ls

# 在init身份或者manager身份的服务器上输入
docker swarm join-token worker
docker swarm join-token manager
# 其中一条就会生成一个token命令,把这个命令在另外安装有docker的服务器上执行就会加入到集群里
# 新加入的机器不享有原集群里的服务,需要删除服务,再添加才能共享

# worker离开集群
docker swarm leave
# manager离开集群
docker swarm leave --force
  • 创建服务
  • 服务创建后,哪怕只有一个也是所有的都可以访问
  • 但是如果正好运行了这个服务的那台机器死机了,所有的都不能访问
  • 所以应该多开几台
# --replicas 1 这个不写也是默认的
# 一点要加版本,就算是latest也一定要写上去
docker service create --replicas 1 --name web01 -p 88:80 nginx:latest
# 这个命令会在当前机器下载安装镜像,使用 docker image ls 可以看到
# 如果当前机器上有这个镜像,就不用下载直接启动
# 跟docker run 一样这个服务也是可以在ps里查看到并且进入进行修改的
# 查看ps服务
docker ps
# 进入服务
docker exec -it 【id】 /bin/bash

# 找到集群机器安装了上面服务器的机器后
# 查看详情
docker service inspect web01

# 查看本机器上运行的服务
docker service ls

# 查看某个服务运行在哪些机器上
docker service ps 【nginx】

# 扩容缩容
# 这样集群的机器又会
docker service scale web01=3

# 删除service
docker service rm 服务名

# docker或者docker swarm都是有一个默认网络的
# 只有在相同网络里才可以通信
# 创建网络
# docker network create -d [overlay|bridge] [自定义名称]
docker network create --driver overlay my_network
# 还有一种写法是写在yml里,运行yml时就会自动创建

# 查看网络
docker network ls
  • 运行自定义的镜像
# 找个文件夹放入 jar包和dockerfile
FROM java:8
ADD eureka-7001-1.0-SNAPSHOT.jar eureka.jar
EXPOSE 7001
ENTRYPOINT ["java","-jar","eureka.jar"]

# 打包命令
docker build -t eureka:v1 .
# swarm 集群运行的命令
docker service create --replicas 1 --name eureka -p 7001:7001 eureka:v1

Secret

  • 就是集群版的compose,通用也是用yml配置,如何配置查看官方文档
  • 可以配合dockerfile使用,但是更建议先把dockerfile打包成镜像上传到镜像服务器,为什么,往下看【实操发布】有解释
  • 两个可视化工具,Portainer 和 visualizer,结合secret写个配置
version: "3"

services:
  visualizer:
    image: dockersamples/visualizer
    ports:
      - "9001:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

  portainer:
    image: portainer/portainer
    ports:
      - "9000:9000"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
  • volumes是映射文件的配置,这些路径和文件一定要自己手动创建,如果是配置文件一定要配置正确
docker stack deploy --compose-file=docker-compose.yml 【name】

# 如果启动后 docker image ls没看到镜像说明下载太慢,应该修改镜像加速服务
# 如果启动后有镜像但是 docker service ls 是 0/n,说明没启动成功
# 没启动成功可以用 docker service ps 【name】 查看error原因

使用Compose和Secret发布项目注意

  • dockerfile使用需要先往机器上传文件,很麻烦,建议先在一个机器上生成镜像,上传镜像服务器,然后yml配置文件都配置成下载地址,方便
  • 不管是Secret或者Compose都有挂载文件的配置,挂载文件是需要自己提前创建好的,不会自动生成
  • Secret是个集群服务,在这个上面启动的服务仅限可以无限启动的服务,而且不需要不同的配置文件的服务,比如jar包,爬虫服务
  • 但是jar包也是会产生日志文件什么的,需要使用挂载功能,所以需要全部提前创建好,如果觉得麻烦可以直接挂载在服务器已有的文件夹下,就不需要自己一个个创建了
  • Secret不适用的服务都是用Compose启动,比如nginx,nginx的html文件夹和配置文件是需要不同的,比如数据库,数据库在Secret上启动几百个也是没用的,因为没有数据
  • 服务如果有启动顺序,需要配置好或者按顺序一个个执行

实操发布springcloud项目

  • 失败了两天之后我终于成功了,坑是真的多
  • 先到服务器安装mysql和redis
version: '2'
services:
  mysql:
    restart: always
    image: mysql:8
    ports:
      - "3306:3306"
    command:
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_general_ci
      --explicit_defaults_for_timestamp=true
      --lower_case_table_names=1
      --default-time-zone=+8:00
    environment:
      MYSQL_ROOT_PASSWORD: "password" #root登陆密码
    volumes:
      - "/docker/mysql/db:/var/lib/mysql"
      - "/docker/mysql/conf/my.cnf:/etc/my.cnf"
  redis:
    restart: always
    image: redis
    environment:
      - TZ=Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
    ports:
      - "6379:6379"
    volumes:
      - /docker/redis/data:/data
      - /docker/redis/redis.conf:/usr/local/etc/redis/redis.conf

# my.cnf
# [mysqld]
# user=mysql
# default-storage-engine=INNODB
# character-set-server=utf8mb4
# [client]
# default-character-set=utf8mb4
# [mysql]
# default-character-set=utf8mb4

# redis.conf
# requirepass redispassword # 指定密码
# appendonly yes  # 本地持久化
  • 这次的操作只启动eureka和order
  • 启动很容易,但是order一直连接不上eureka等等问题
  • 先把代码的配置改成服务的域名
# 这是eureka的
server:
  port: 7001

eureka:
  instance:
    hostname: a.pdt1997.top
  client:
    fetch-registry: false # 不用检索服务 自己是注册中心
    register-with-eureka: false #不向注册中心注册自己
    service-url:
      defaultZone: http://a.pdt1997.top:7001/eureka

# 这是order的,省略redis和mysql等连接配置
spring:
  application:
    name: order

eureka:  #设置eureka注册服务的地址
  client:
    service-url:
      defaultZone: http://a.pdt1997.top:7001/eureka/
  instance:
    instance-id: order-9001 #配置服务的别名
    prefer-ip-address: true # 注册的时候使用ip注册
  • 写两个dockerfile
FROM java:8
# 这里要根据打包文件去改名字
ADD eureka-7001-1.0-SNAPSHOT.jar eureka.jar
EXPOSE 7001
ENTRYPOINT ["java","-jar","eureka.jar"]
  • 把eureka和order打包成jar包和两个dockerfile一起丢到某一个服务器上
  • 目录如下
- /docker/springcloud-pdt
  - eureka
    - xxx.jar
    - dockerfile
  - order
    - xxx.jar
    - dockerfile
  - 这里要放一个 docker-compose.yml ,往下看
  • 把jar包打包成镜像,并且上传到阿里的dockerhub
  • 为什么不直接使用镜像启动,因为这个镜像只存在于当前服务器,而swarm扩容时别的机器是没有镜像的,就会报错:no such image,所以要像上面的nginx一样,上传,再下载下来
  • 去阿里控制台搜索 容器镜像服务 就能使用镜像了
  • 仓库创建操作如下

image.png

  • 下一步后选择本地仓库就行
  • 注意:第二天打开的时候会发现镜像怎么都不见了,因为在Logo旁边有个地区选择,打开地区不一样,镜像不一样,建议全部上传到同一个地区
  • 创建成功点击管理,里面所有的操作命令都写好了,复制直接使用
# 打包操作,打包后可以用 docker image ls查看
docker build -t eureka:v1 .

# 登陆,输入密码,连接成功就行,只需要登录一次
docker login --username=15013961618 registry.cn-hangzhou.aliyuncs.com

# 两步完成上传,ImageId上刚才打包出来的镜像的id
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/pdt/eureka:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/pdt/eureka:[镜像版本号]
  • 上传镜像成功后,去阿里刷新下页面看看是不是真的有,然后可以把本地的镜像删了,模拟新服务器启动的全新操作
  • 打包上传镜像是可以在idea实现的,就不需要上面这么麻烦的操作了,但是我不会
# 本地打包一份,上传时又打包一份,所以查看镜像的时候会发现两个一样的id,两个不一样的名字
docker image ls
# REPOSITORY                                    TAG   IMAGE  ID
# order                                         v1    8968ce1119f2   
# registry.cn-hangzhou.aliyuncs.com/pdt/order   v1    8968ce1119f2  

# 删除
docker rmi -f 8968ce1119f2
  • 删除完再检查下机器是不是足够干净
docker ps -a
docker image ls
docker service ls
  • 配置网络,在docker里所有的容器都是不相连的
# 创建网络
docker network create --driver overlay my_network
  • 写一个 docker-compose.yml 文件
version: '3'
services:
  eureka:
    restart: always
    image: registry.cn-hangzhou.aliyuncs.com/pdt/eureka:v2 # 镜像名:标签名
    hostname: a.pdt1997.top      # 注册中心的hostname一定要有,且必须和代码中配置文件里的hostname一致
    networks:
      - my_network           # 加入的网络
    environment:
      - TZ=Asia/Shanghai
    ports:
      - "7001:7001"             # 映射的端口号,和代码中配置文件里的端口号一致
  order:
    restart: always
    image: registry.cn-hangzhou.aliyuncs.com/pdt/order:v2
    depends_on:
      - eureka
    ports:
      - "9001:9001"
    links:
      - eureka
    networks:
      - my_network           # 加入的网络

#指定网络
networks:
  my_network:
    ##使用已有的网路
    external:
      name: my_network
  • 把配置文件上传到上面的备注位置上,进入这个位置,执行启动命令
docker stack deploy --compose-file=docker-compose.yml springcloud-pdt

# 他打印出下面两句话后就结束了
# Creating service springcloud-pdt_eureka
# Creating service springcloud-pdt_order

# 查看服务
docker service ls
# 如果服务是 0/1,就再等等,等到 1/1 启动完成
  • 记得需要打开防火墙端口 和 安全组端口
  • 访问可以看到,erueka启动成功,order启动成功,并且order连接上eureka了,需要等几分钟才会启动成功,连接上去,要有耐心

image.png

  • 扩容
# 扩容前在每个机器上执行
docker image ls
docker ps
# 查看上面的服务是下载安装启动在哪个机器上

# 扩容
docker service scale springcloud-pdt_order=2
# 扩容完成后,在每台机器上执行
docker service ls
docker image ls
docker ps
# 只要看到有一台原本没有image和ps的机器被扩容成功,就发布成功了
  • 测试mysql和redis
# 可以打开日志,然后调用接口,看看有没有打印日志
docker service logs -f --tail=50 服务名称

# 可以工具连接redis和mysql查看有没有存入数据什么的

image.png

  • 第一次调用接口打印sql日志,第二次取redis缓存,完美

image.png

镜像已经上传阿里镜像仓库,代码和docker-yml文件已经上传到github

原文地址:https://www.cnblogs.com/pengdt/p/13523204.html