1. 程式人生 > 實用技巧 >Docker進階

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配置檔案,然後把三個檔案都丟到伺服器上,執行命令就行

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一樣,上傳,再下載下來
  • 去阿里控制檯搜尋 容器映象服務 就能使用映象了
  • 倉庫建立操作如下

  • 下一步後選擇本地倉庫就行
  • 注意:第二天開啟的時候會發現映象怎麼都不見了,因為在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了,需要等幾分鐘才會啟動成功,連線上去,要有耐心

  • 擴容
# 擴容前在每個機器上執行
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檢視有沒有存入資料什麼的

  • 第一次呼叫介面列印sql日誌,第二次取redis快取,完美

映象已經上傳阿里映象倉庫,程式碼和docker-yml檔案已經上傳到github