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