日趨複雜的運維開發環境,對虛擬服務器及應用服務的要求更加的多元化。咱們須要更加容易擴展、性能優越、方便監控的管理服務,容器化應用、容器化運維應運而生。javascript
【工欲善其事,必先利其器】須要準備的環境(三選一):php
若是,你有了上面的環境,就能夠很快速的學習。html
【收穫什麼】:前端
容器化是將應用程序或服務、其依賴項及其配置(抽象化爲部署清單文件)一塊兒打包爲容器映像的一種軟件開發方法。vue
軟件容器充當軟件部署的標準單元,其中能夠包含不一樣的代碼和依賴項。 按照這種方式容器化軟件,開發人員和 IT 專業人員只需進行極少修改或不修改,便可將其部署到不一樣的環境。java
容器化應用程序在容器主機上運行,而容器主機在 OS(Linux 或 Windows)上運行。所以,容器的佔用比虛擬機 (VM) 映像小得多。node
【容器化的特色】:mysql
Docker是用GO語言開發的應用容器引擎,基於容器化,沙箱機制的應用部署技術。可適用於自動化測試、打包,持續集成和發佈應用程序等場景,包括阿里雲,亞馬遜在內的雲計算服務商都採用了docker來打造serverless服務平臺。它不只僅能夠部署項目,還能夠用於數據庫搭建,nginx服務搭建,nodejs、php等編程語言環境搭建。nginx
PS: docker現已更名爲mobygit
Docker中的三個重要概念:
鏡像(image):
分片的(只讀)文件系統,由Dockerfile建立,它獨立、易擴展、更效率
容器(container):
由Docker進程建立和管理的:文件系統 + 系統資源 + 網絡配置 + 日誌管理 Docker是docker鏡像的運行環境,因此容器的概念就比較好理解了
倉庫(registry):
用來遠端存儲docker鏡像版本控制、變動管理、爲持續集成與快速部署提供便利
容器與鏡像的關係相似於面向對象編程中的對象與類。
Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和建立Docker容器。
Docker 容器經過 Docker 鏡像來建立。
【區別】:
【總結】:
特性 | 容器 | 虛擬機 |
---|---|---|
啓動 | 秒級 | 分鐘級 |
硬盤使用 | 通常爲 MB |
通常爲 GB |
性能 | 接近原生 | 弱於 |
系統支持量 | 單機支持上千個容器 | 通常幾十個 |
開發/環境定製 | 方便(命令行、面向對象式) | 進入虛擬機 |
【相同點】:
【不一樣點】:
Docker是容器化部署技術,它主要做用在於經過運行容器來實現應用部署,而容器基於鏡像運行。
簡單地說,就是將你的項目和依賴包(基礎鏡像)打成一個帶有啓動指令的項目鏡像,而後在服務器建立一個容器,讓鏡像在容器內運行,從而實現項目的部署。
服務器就是容器的宿主機,docker容器與宿主機之間是相互隔離的。
Docker 的基礎是Linux容器(LXC:Linux Containers)等技術。
通常狀況流程:
Docker流程:
這其中,發生了什麼?
Docker的價值:
從應用架構角度:統一複雜的構建環境;
從應用部署角度:解決依賴不一樣、構建麻煩的問題,結合自動化工具(如jenkins)提升效率。
從集羣管理角度:規範的服務調度,服務發現,負載均衡
安裝教程地址:
配置鏡像加速地址:
docker --version
複製代碼
// 使用docker run命令
docker run hell-world
// 下載ubuntu鏡像打印「from ububtu」
// -i: 以交互模式運行容器,一般與 -t 同時使用
// -t: 爲容器從新分配一個僞輸入終端,一般與 -i 同時使用
docker run -it ubuntu echo "from ubuntu"
複製代碼
使用docker ps
命令來查看正在運行的容器的狀態,-a
參數來查看全部的已經運行的容器(不管是否中止)
run
建立一個新的容器並運行一個命令
exec
能夠進入到容器裏面去
-it
是提供交互式的終端工具
-d
是讓鏡像容器在後臺去持續運行
--name
指定容器的名稱
-p
容器內部端口映射到主機的端口
-v
掛載宿主機的文件目錄到鏡像裏面去
-e
設置環境變量
// 運行鏡像
docker run -it -d --name test ubuntu
// 進入容器
docker exec -it test /bin/bash
// 把本機的Downloads文件映射到ubuntu的home文件下
docker run -v ~/Downloads/:/home -itd --name test1 ubuntu
複製代碼
start
stop
restart
rm
docker stop test
複製代碼
Docker提供了輕量級的虛擬化,相比於虛擬機,能夠在同一臺機器上建立更多數量的容器。
【常見的應用場景】:
咱們嘗試着來部署一個mysql:
docker run -d --name mysql-test -e MYSQL_ROOT_PASSWORD=123456 mysql
複製代碼
一樣的道理,咱們來部署一個nginx:
注意:這裏沒有映射服務端口,因此在80
端口是看不到index.html
中的內容的。須要加入-p
參數來映射端口!!
docker run -d --name web -p 8000:80 -v ${your_dir}:/usr/share/nginx/html nginx
複製代碼
咱們能夠同時跑兩個mysql,兩個nginx,指定不一樣的端口進行映射:
把mysql-test1
映射到8001
端口,把mysql-test2
映射到8002
端口。
docker run -d --name mysql-test1 -p 8001:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
docker run -d --name mysql-test2 -p 8002:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
複製代碼
把web1映射到8100端口,把web2映射到8200端口。
docker run -d --name web1 -p 8100:80 -v ${your_dir}:/usr/share/nginx/html nginx
docker run -d --name web2 -p 8200:80 -v ${your_dir}:/usr/share/nginx/html nginx
複製代碼
一致的運行環境
因爲 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 能夠在不少平臺上運行,不管是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運行結果是一致的。所以用戶能夠很輕易的將在一個平臺上運行的應用,遷移到另外一個平臺上,而不用擔憂運行環境的變化致使應用沒法正常運行的狀況。
更快速的啓動時間
傳統的虛擬機技術啓動應用服務每每須要數分鐘,而 Docker 容器應用,因爲直接運行於宿主內核,無需啓動完整的操做系統,所以能夠作到秒級、甚至毫秒級的啓動時間。大大的節約了開發、測試、部署的時間。
更高效的複用系統資源
因爲容器不須要進行硬件虛擬以及運行完整操做系統等額外開銷,Docker 對系統資源的利用率更高。不管是應用執行速度、內存損耗或者文件存儲速度,都要比傳統虛擬機技術更高效。所以,相比虛擬機技術,一個相同配置的主機,每每能夠運行更多數量的應用。
倉庫/鏡像機制
使用倉庫能夠方便的在任何有docker進程的虛擬機/服務器/主機上運行docker應用,環境的統一,讓它們的部署變的很是的簡單。
Docker容器還能夠像git倉庫同樣,可讓你提交變動到Docker鏡像中並經過不一樣的版原本管理它們,來看看下面的例子:
咱們以前建立了一個mysql
,如今,咱們使用commit
命令就能夠給它作一個快照,打上一個tag
。
在後面的課程中,咱們會詳細的介紹Docker的常見命令
Dockerfile 是一個由一堆命令+參數構成的腳本,使用
docker build
便可執行腳本構建鏡像,自動的去作一些事,主要用於進行持續集成。
通常,Dockerfile 共包括四部分:
FROM node:10
LABEL maintainer=atiedan666666@163.com
# 建立 app 目錄
WORKDIR /app
# 把 package.json,package-lock.json(npm@5+) 或 yarn.lock 複製到工做目錄(相對路徑)
COPY ["package.json","*.lock","./"]
# 打包 app 源碼
# 特別注意:要指定工做目錄中的文件名
COPY src ./src
# 使用.dockerignore文件,上面兩個COPY合併成一個
# COPY . .
# 使用Yarn安裝 app 依賴
# 若是你須要構建生產環境下的代碼,請使用:
# --prod參數
RUN yarn --prod --registry=https://registry.npm.taobao.org
# 對外暴露端口 -p 4000:3000
EXPOSE 3000
CMD [ "node", "src/index.js" ]
複製代碼
當Node.js碰見Docker,下面介紹Docker在前端中的應用:
一個簡單的Koa應用:
const Koa = require('koa');
const app = new Koa();
// response
app.use(ctx => {
ctx.body = 'Hello Koa!!';
});
app.listen(3000);
複製代碼
使用docker build
打包:
docker build -t ${your_name}/${image_name}:${tag} .
複製代碼
這裏的your_name
表明的是遠程倉庫中的用戶名,或者倉庫地址; image_name
爲鏡像名稱,tag
是給鏡像打的標籤,用於版本控制。.
表明當前目錄例如:
docker build -t tiedan/node-demo:1.0 .
複製代碼
使用docker run
運行
// 運行
docker run -d --name nodedemo -p 4000:3000 tiedan/node-demo:1.0
// 查看
docker ps
複製代碼
經過 Docker-Compose 用戶能夠很容易地用一個配置文件定義一個多容器的應用,而後使用一條指令安裝這個應用的全部依賴,完成構建。Docker-Compose 解決了容器與容器之間如何管理編排的問題。
Compose 中有兩個重要的概念:
Docker Compose 是 Docker 的獨立產品,所以須要安裝 Docker 以後在單獨安裝 Docker Compose .
Window和Mac 的 Docker 桌面版和 Docker Toolbox 已經包括 Compose 和其餘 Docker 應用程序,所以 Mac 用戶不須要單獨安裝 Compose, Linux 上咱們能夠從 Github 上下載它的二進制包來使用,
#下載
sudo curl -L https://github.com/docker/compose/releases/download/1.20.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
#安裝
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose --version
複製代碼
docker-compose.yml
改寫:
version: '3'
services:
mysql:
image: mysql
container_name: test-mysql
ports:
- "8001:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
複製代碼
在此文件的當前目錄下,使用docker-compose up -d
來執行。
生命週期管理:
建立:run
/up
啓動/中止/刪除/重啓:start/stop/rm/restart
檢視/日誌:logs
/ps
搭建本地mongo + mongo-express服務
# docker-compose.mongo.yml配置文件
version: '3.1'
services:
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: 123456
複製代碼
執行:
# 執行 docker-compose.mongo.yml 若是不加 docker-compose -f 默認執行 docker-compose.mongo.yml
docker-compose -f docker-compose.mongo.yml up -d
複製代碼
項目地址: github.com/sameersbn/d…
docker-compose.git.yml
文件
// 運行該文件 docker-compose -f docker-compose.git.yml up -d
version: '2.3'
services:
redis:
restart: always
image: redis:5.0.9
command:
- --loglevel warning
volumes:
- redis-data:/var/lib/redis:Z
postgresql:
restart: always
image: sameersbn/postgresql:12-20200524
volumes:
- postgresql-data:/var/lib/postgresql:Z
environment:
- DB_USER=gitlab
- DB_PASS=password
- DB_NAME=gitlabhq_production
- DB_EXTENSION=pg_trgm,btree_gist
gitlab:
restart: always
image: sameersbn/gitlab:13.11.2
depends_on:
- redis
- postgresql
ports:
- "10080:80"
- "10022:22"
volumes:
- gitlab-data:/home/git/data:Z
healthcheck:
test: ["CMD", "/usr/local/sbin/healthcheck"]
interval: 5m
timeout: 10s
retries: 3
start_period: 5m
environment:
- DEBUG=false
- DB_ADAPTER=postgresql
- DB_HOST=postgresql
- DB_PORT=5432
- DB_USER=gitlab
- DB_PASS=password
- DB_NAME=gitlabhq_production
- REDIS_HOST=redis
- REDIS_PORT=6379
- TZ=Asia/Kolkata
- GITLAB_TIMEZONE=Kolkata
- GITLAB_HTTPS=false
- SSL_SELF_SIGNED=false
- GITLAB_HOST=localhost
- GITLAB_PORT=10080
- GITLAB_SSH_PORT=10022
- GITLAB_RELATIVE_URL_ROOT=
- GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string
- GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string
- GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string
- GITLAB_ROOT_PASSWORD=12345678
- GITLAB_ROOT_EMAIL=atiedan666666@163.com
- GITLAB_NOTIFY_ON_BROKEN_BUILDS=true
- GITLAB_NOTIFY_PUSHER=false
- GITLAB_EMAIL=notifications@example.com
- GITLAB_EMAIL_REPLY_TO=noreply@example.com
- GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com
- GITLAB_BACKUP_SCHEDULE=daily
- GITLAB_BACKUP_TIME=01:00
- SMTP_ENABLED=false
- SMTP_DOMAIN=www.example.com
- SMTP_HOST=smtp.gmail.com
- SMTP_PORT=587
- SMTP_USER=mailer@example.com
- SMTP_PASS=password
- SMTP_STARTTLS=true
- SMTP_AUTHENTICATION=login
- IMAP_ENABLED=false
- IMAP_HOST=imap.gmail.com
- IMAP_PORT=993
- IMAP_USER=mailer@example.com
- IMAP_PASS=password
- IMAP_SSL=true
- IMAP_STARTTLS=false
- OAUTH_ENABLED=false
- OAUTH_AUTO_SIGN_IN_WITH_PROVIDER=
- OAUTH_ALLOW_SSO=
- OAUTH_BLOCK_AUTO_CREATED_USERS=true
- OAUTH_AUTO_LINK_LDAP_USER=false
- OAUTH_AUTO_LINK_SAML_USER=false
- OAUTH_EXTERNAL_PROVIDERS=
- OAUTH_CAS3_LABEL=cas3
- OAUTH_CAS3_SERVER=
- OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false
- OAUTH_CAS3_LOGIN_URL=/cas/login
- OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate
- OAUTH_CAS3_LOGOUT_URL=/cas/logout
- OAUTH_GOOGLE_API_KEY=
- OAUTH_GOOGLE_APP_SECRET=
- OAUTH_GOOGLE_RESTRICT_DOMAIN=
- OAUTH_FACEBOOK_API_KEY=
- OAUTH_FACEBOOK_APP_SECRET=
- OAUTH_TWITTER_API_KEY=
- OAUTH_TWITTER_APP_SECRET=
- OAUTH_GITHUB_API_KEY=
- OAUTH_GITHUB_APP_SECRET=
- OAUTH_GITHUB_URL=
- OAUTH_GITHUB_VERIFY_SSL=
- OAUTH_GITLAB_API_KEY=
- OAUTH_GITLAB_APP_SECRET=
- OAUTH_BITBUCKET_API_KEY=
- OAUTH_BITBUCKET_APP_SECRET=
- OAUTH_BITBUCKET_URL=
- OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL=
- OAUTH_SAML_IDP_CERT_FINGERPRINT=
- OAUTH_SAML_IDP_SSO_TARGET_URL=
- OAUTH_SAML_ISSUER=
- OAUTH_SAML_LABEL="Our SAML Provider"
- OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient
- OAUTH_SAML_GROUPS_ATTRIBUTE=
- OAUTH_SAML_EXTERNAL_GROUPS=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_USERNAME=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME=
- OAUTH_CROWD_SERVER_URL=
- OAUTH_CROWD_APP_NAME=
- OAUTH_CROWD_APP_PASSWORD=
- OAUTH_AUTH0_CLIENT_ID=
- OAUTH_AUTH0_CLIENT_SECRET=
- OAUTH_AUTH0_DOMAIN=
- OAUTH_AUTH0_SCOPE=
- OAUTH_AZURE_API_KEY=
- OAUTH_AZURE_API_SECRET=
- OAUTH_AZURE_TENANT_ID=
volumes:
redis-data:
postgresql-data:
gitlab-data:
複製代碼
docker-compose在前端裏面的使用:
Nodejs + mongodb + koa + vue的應用組合:
docker-compose.yml
version: '3'
services:
web:
image: web:1.0
ports:
- "8080:80"
server:
image: server:1.0
ports:
- "3000:3000"
depends_on:
- mongodb
links:
- mongodb:db
mongodb:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
複製代碼
depends_on
決定了容器加載的前後順序,這裏mongdb
、web
先加載,mongdb
建立完成以後,再來建立server
。