目錄
- 介紹和安裝
- 安裝
- 啟動
- 鏡像加速
- Docker基本操作
- 鏡像操作
- 容器操作
- 數據卷操作
- Dockerfile
- 鏡像結構
- Dockerfile
- Docker-Compose
- 安裝
- 基本命令
- Docker 私 服搭建
- 練習
- 練習1:save和load
- 練習2:docker部署nginx
- 練習3:部署MySQL
- 練習4:基于Ubuntu構建一個新鏡像,運行一個java項目
- 練習5:部署微服務集群
- 問題:微服務注冊失敗
介紹和安裝
Docker 是一個開源的應用容器引擎,基于 Go 語言 并遵從 Apache2.0 協議開源。
Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然后發布到任何流行的 Linux 機器上,也可以實現虛擬化。
容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷極低。
幾個概念:
- 鏡像(image):Docker將應用程序及其所需要的依賴、函數庫等打包在一起,即為鏡像。
- 容器:鏡像中的應用程序運行后形成的進程。
- Docker Registry:鏡像托管平臺,如DockerHub,網易云鏡像服務,阿里云鏡像服務。
docker架構:
安裝
可以先選擇卸載:
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine \ docker-ce
安裝存儲驅動等:
yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 --skip-broken
設置docker倉庫:
# 設置docker鏡像源 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo yum makecache fast
安裝社區版docker:
yum install -y docker-ce
啟動
# 關閉防火墻 systemctl stop firewalld # 禁止開機啟動防火墻 systemctl disable firewalld # 啟動docker服務 systemctl start docker # 停止docker服務 systemctl stop docker # 重啟docker服務 systemctl restart docker # 查看docker版本 docker -v
鏡像加速
參考阿里云的鏡像加速文檔:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
Docker基本操作
鏡像操作
一些簡單的操作:
# 查看鏡像 docker images # 刪除鏡像 docker rmi # 拉取鏡像 docker pull # 推送鏡像到Docker Registry docker push # 保存鏡像為tar包 docker save # 加載tar包為鏡像 docker load …………
命令有很多,不必記憶,勤用
--help
例如:
docker images --help
容器操作
一些簡單的容器操作:
# 創建容器 docker run # 進入容器 docker exec # 查看容器日志(添加-f可以持續查看) docker logs # 查看容器 docker ps # 刪除容器 docker rm …………
數據卷操作
數據卷是一個虛擬目錄,指向宿主機文件系統中的某個目錄。
docker volume [COMMAND]
create 創建數據卷inspect 顯示一個或多個數據卷的信息ls 列出所有數據卷prune 刪除未使用數據卷rm 刪除一個或多個數據卷
后文練習123幫助理解。
Dockerfile
很多時候需要自己構建鏡像,構建鏡像需要寫Dockerfile。
鏡像結構
首先介紹鏡像結構,鏡像是應用程序及其所需要的系統函數庫、環境、配置、依賴一層一層構建出來的,以mysql為例:
底層是系統函數庫(例如Ubuntu),這一層也叫做基礎鏡像(BaseImage),相當于地基。
然后在地基上添加安裝包,配置環境變量、配置、依賴等等。
最后需要提供一個入口(Entrypoint),也就是程序啟動的腳本和參數。
Dockerfile
Dockerfile是一個文本文件,名為Dockerfile,沒有后綴,其中包含一些指令,每一個指令就是一層。
常用指令:
寫好Dockerfile后使用
docker build
命令構建鏡像
詳見練習4
Docker-Compose
若是部署微服務集群,一個個docker去構建會很繁瑣,所以需要DOcker-Compose。
DockerCompose基于Compose文件快速部署分布式應用,無需手動一個個的創建和運行。
Compose文件也是一個文本文件,通過指令定義集群中的每個容器如何運行。
安裝
# 下載docker-compose curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose # 添加執行權限 chmod +x /usr/local/bin/docker-compose # 下載自動補全 curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
基本命令
# 后臺啟動當前項目 也可以指定服務 docker-compose up -d # 查看項目容器 docker-compose ps # 停止容器運行 可以指定服務 docker-compose stop # 停止并刪除容器 可以加參數來刪除鏡像、數據卷等 docker-compose down # 持續查看日志 docker-compose logs -f # 構建或重新構建鏡像 可以指定服務 docker-compose build …………
和docker操作差不多
Docker 私 服搭建
搭建一個docker 私 服。
docker-compose.yml:
version: '3.0' services: registry: image: registry volumes: - ./registry-data:/var/lib/registry ui: image: joxit/docker-registry-ui:static ports: - 5000:80 environment: - REGISTRY_TITLE=docker私 服 - REGISTRY_URL=http://registry:5000 depends_on: - registry
存放鏡像的目錄得準備好。
還得給docker設置信任地址。
我們的私 服采用的是http協議,默認不被Docker信任,所以需要做一個配置:
# 打開要修改的文件 vi /etc/docker/daemon.json # 添加內容: "insecure-registries":["http://yourip:port"] # 重加載 systemctl daemon-reload # 重啟docker systemctl restart docker
然后就可以
docker-compose up -d
啟動
訪問ip+端口,成功:
上傳一個鏡像試試:
# 標記鏡像,歸入私 服,有格式要求,名稱前綴為私 服地址 docker tag nginx:latest xxx:xxx/nginx:1.0 # 推送 docker push xxx:xxx/nginx:1.0 # 拉取 docker pull xxx:xxx/nginx:1.0
練習
練習1:save和load
打包鏡像:
docker save -o mynginx.tar nginx:latest
加載鏡像:
docker load -i mynginx.tar
練習2:docker部署nginx
# 拉取 docker pull nginx # 啟動 docker run --name mynginx -p 8080:80 -d nginx # -p 后面的端口 左邊是宿主機 右邊是容器 # -d 后臺運行
此時訪問宿主機的8080端口即可訪問到nginx服務。
問題:修改主頁
方式一:進入容器修改/usr/share/nginx/html/index.html文件(這個路徑dockerhub的nginx鏡像官方文檔中可以找到)
# 進入容器 docker exec -it mynginx bash # -it 給當前進入的容器創建一個標準輸入輸出的終端,允許我們與容器交互 # bash 進入容器執行的命令 # 因為沒有vi等文本編輯器,所以使用替換命令 sed -i 's#Welcome to nginx#替換#g' index.html sed -i 's#<head>#</head><meta charset="utf-8">#g' index.html
這種方式明顯是有很大局限性的!容器和數據耦合度非常高,操作繁瑣不說,數據也不可復用,維護也非常困難。
方式二:將數據卷掛載到/usr/share/nginx/html目錄。
# 強行刪除容器 docker rm -f mynginx # 準備一個目錄 mkdir -p /tmp/nginx/html # 啟動 docker run --name mynginx -v /tmp/nginx/html:/usr/share/nginx/html -p 8080:80 -d nginx # -p 后面的端口 左邊是宿主機 右邊是容器 # -d 后臺運行 # -v 數據卷掛載 左邊是宿主機目錄 右邊是容器
這樣 就可以把數據和容器解耦了。
練習3:部署MySQL
# 拉取鏡像(先去dockerhub看看鏡像名和版本) docker pull mysql:5.7.25 # 準備存放數據和配置的數據卷 mkdir -p /tmp/mysql/data mkdir -p /tmp/mysql/conf
準備mysql配置文件后綴是.conf例如my.conf,內容如下:
[mysqld] skip-name-resolve character_set_server=utf8 datadir=/var/lib/mysql server-id=1000
# 啟動mysql docker run \ --name mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -p 3306:3306 \ -v /tmp/mysql/conf:/etc/mysql/conf.d \ -v /tmp/mysql/data:/var/lib/mysql \ -d \ mysql:5.7.25 # -e 后面表示這個容器的環境變量 這里我們將環境變量MYSQL_ROOT_PASSWORD賦值為123456 # -p 端口 左宿主 右容器 # -v 數據卷掛載 # -d 后臺運行
這里面的一些數據是需要取看官方文檔的,例如環境變量、配置文件目錄等。
練習4:基于Ubuntu構建一個新鏡像,運行一個java項目
Dockerfile內容:
# 指定基礎鏡像 FROM ubuntu:16.04 # 配置環境變量,JDK的安裝目錄 ENV JAVA_DIR=/usr/local # 拷貝jdk和java項目的包 COPY ./jdk8.tar.gz $JAVA_DIR/ COPY ./docker-demo.jar /tmp/app.jar # 安裝JDK RUN cd $JAVA_DIR \ && tar -xf ./jdk8.tar.gz \ && mv ./jdk1.8.0_144 ./java8 # 配置環境變量 ENV JAVA_HOME=$JAVA_DIR/java8 ENV PATH=$PATH:$JAVA_HOME/bin # 暴露端口 EXPOSE 8090 # 入口,java項目的啟動命令 ENTRYPOINT java -jar /tmp/app.jar
構建鏡像
# 構建鏡像 docker build -t javaweb:1.0 . # -t 表示后面是 name:tag #. 表示Dockerfile所在的目錄 . 表示當前目錄 # 啟動容器 docker run --name web -p 8090:8090 -d javaweb:1.0
問題 層數太多,每次都要安裝jdk
這樣做有缺陷,有很多層都用來做安裝jdk了:
# 指定基礎鏡像 FROM ubuntu:16.04 # 配置環境變量,JDK的安裝目錄 ENV JAVA_DIR=/usr/local # 拷貝jdk COPY ./jdk8.tar.gz $JAVA_DIR/ # 安裝JDK RUN cd $JAVA_DIR \ && tar -xf ./jdk8.tar.gz \ && mv ./jdk1.8.0_144 ./java8 # 配置環境變量 ENV JAVA_HOME=$JAVA_DIR/java8 ENV PATH=$PATH:$JAVA_HOME/bin
所以改進后:
# 指定基礎鏡像 FROM java:8-alpine # 拷貝項目 COPY ./docker-demo.jar /tmp/app.jar # 暴露端口 EXPOSE 8090 # 入口,java項目的啟動命令 ENTRYPOINT java -jar /tmp/app.jar
練習5:部署微服務集群
部署之前的cloud-demo。
修改cloud-demo中的配置,nacos和mysql的地址改為docker-compose中的服務名,例如:
spring: datasource: url: jdbc:mysql://mysql:3306/cloud_order?useSSL=false username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver application: name: orderservice cloud: nacos: server-addr: nacos:8848
打包,然后寫對應的Dockerfile,例如:
打包有個小坑 如果之前feign-api這個公共模塊是創建的spring項目而不是maven項目,那么會order-service打包失敗,換一個打包插件就好:
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins>
然后install一下這個模塊就行。
FROM java:8-alpine COPY ./app1.jar /tmp/app.jar ENTRYPOINT java -jar /tmp/app.jar
完成后:
編寫docker-compose.yml:
version: "3.2" services: nacos: image: nacos/nacos-server environment: MODE: standalone ports: - "8848:8848" mysql: image: mysql:5.7.25 environment: MYSQL_ROOT_PASSWORD: 123 volumes: - "$PWD/mysql/data:/var/lib/mysql" - "$PWD/mysql/conf:/etc/mysql/conf.d/" userservice: build: ./user-service orderservice: build: ./order-service gateway: build: ./gateway ports: - "10010:10010"
啟動docker-compose
docker-compose up -d # 后臺運 docker-compose logs -f # 持續查看日志
問題:微服務注冊失敗
原因:nacos啟動慢,微服務啟動時nacos還沒有啟動完成。
解決:重啟指定微服務,下次部署時先部署好nacos,使用depends_on也不行不知道啥問題。
docker-compose restart gateway userservice orderservice # 重啟指定服務 docker-compose logs -f # 持續查看日志