date: 2017-12-19 14:04:30
title: tech share - docker 入門
團(tuán)隊(duì)內(nèi)很多同學(xué)對(duì) docker 感興趣, 于是準(zhǔn)備了這期分享, 希望可以幫助大家快速入門. 主要包含以下內(nèi)容:
- why docker
- docker 基礎(chǔ)概念
- 入門實(shí)戰(zhàn)
why docker
先講講我自己的經(jīng)歷. 作為一個(gè)典型的工具控, 這個(gè)可以通過(guò) 我的 wiki 看出一二, 比如 tmux / fish 等工具. 對(duì)環(huán)境的折騰幾乎是無(wú)底洞般消耗著, 而且在以前經(jīng)常 以重裝系統(tǒng)告終. 一方面是自己重裝系統(tǒng)實(shí)在確實(shí) 6, 大學(xué)里還找過(guò) 「計(jì)導(dǎo)」 的老師嘗試自己講一堂相關(guān)的課, 一方面是 太年輕, 基礎(chǔ)不夠好, 解決問(wèn)題的方式方法也不在路上, 經(jīng)常導(dǎo)致問(wèn)題 解決不了. 分享 2 句話:
在手里只有一把錘子的人眼里,世界就是一個(gè)釘子. -- <窮查理寶典>
工匠應(yīng)該專注于作品的創(chuàng)意,不應(yīng)該浪費(fèi)精力,沒限制地在折騰自己的工具.
簡(jiǎn)單記錄一下自己開發(fā)環(huán)境的變遷史:
- v4 2017年
上面的方式其實(shí)推薦一個(gè)機(jī)器只部署一個(gè)項(xiàng)目哨免,每個(gè)項(xiàng)目還是分開的撩穿,但是我只有一臺(tái)云主機(jī),卻有很多項(xiàng)目蚣抗,所以重新架構(gòu)了一次:
獨(dú)立一個(gè)通用的 docker 環(huán)境,目前包括 nginx(lnmp)+ cli(php-cli、npm扇售、git 等)
每個(gè)項(xiàng)目依舊在不同的 git 倉(cāng)庫(kù)中維護(hù)
一臺(tái)騰訊云上面部署所有項(xiàng)目
- v3 2016年
嘗試到了 docker-compose 的甜頭,開始信奉 dockerfile + 項(xiàng)目源碼 的方式
- v2 2015年
項(xiàng)目全部進(jìn) git
開發(fā)環(huán)境:vagrant 大量使用(當(dāng)時(shí) laravel 的 homestead)嚣艇,開始接觸 docker
部署環(huán)境:申請(qǐng)到一年的騰訊云承冰,裸搭、lnmp 一鍵環(huán)境
- v1 2014年
項(xiàng)目只包含源碼食零,有的使用 git困乒,有的沒使用
本地開發(fā)正式接觸 virtualbox 和 vagrant,大部分還是 window 下直接搭建或者集成環(huán)境
當(dāng)時(shí)的只有 blog 項(xiàng)目慌洪,嘗試了 各種 gitpage顶燕;開始接觸騰訊云
期間還有比如選 win / Ubuntu / mac 這樣的糾結(jié), 也花了大量時(shí)間嘗試, 這是我最后的答案:
- win: 在我看來(lái), win 的 GUI 既是更熟悉的, 也是更易用的(沒有挑起圣戰(zhàn)的意思, 同時(shí)為我的 小米筆記本Pro 打 call)
- docker: run, run, run
- 重度命令行使用者
PS: 我本人是 win 環(huán)境, 下面的講解都以此為基礎(chǔ).
再分享 2 句話:
關(guān)于 docker: 不要因?yàn)榄h(huán)境, 限制了我們的想象力
關(guān)于命令行: graphical user interfaces make easy tasks easy, while command line interfaces make difficult tasks possible
docker 基礎(chǔ)概念
在講解 docker 之前, 先對(duì)比一下 docker 和傳統(tǒng)虛擬機(jī):
- 虛擬機(jī)
- docker
[圖片上傳失敗...(image-8d2487-1513865934084)]
docker 使用的關(guān)鍵技術(shù)(我們是入門教程, 瞄一眼就好了):
- go 語(yǔ)言實(shí)現(xiàn)
- 操作系統(tǒng)層面的虛擬化技術(shù)
- 基于 Linux 內(nèi)核的 cgroup,namespace
- AUFS
Docker 包括三個(gè)基本概念
- 倉(cāng)庫(kù)(Repository)
- 鏡像(Image)
- 容器(Container)
從生命周期的角度來(lái)理解和學(xué)習(xí)新的概念和知識(shí).
鏡像和倉(cāng)庫(kù), 我們可以類比 git 倉(cāng)庫(kù)來(lái)理解, 只是 git 倉(cāng)庫(kù)放的代碼, 而 docker 倉(cāng)庫(kù), 放置的是鏡像. 其他倉(cāng)庫(kù)相關(guān)的操作, 都是一樣一樣滴.
鏡像和容器, 可以類比 類 和 對(duì)象 / 程序 和 進(jìn)程. 運(yùn)行容器, 就像實(shí)例化一個(gè)對(duì)象, 類起到定義的作用, 真正干活的是對(duì)象.
是不是感覺到觸類旁通?
入門實(shí)戰(zhàn)
入門了解 倉(cāng)庫(kù)/鏡像/容器 這些概念就可以開始實(shí)戰(zhàn)了. 在實(shí)踐的過(guò)程中, 要 刻意 去理解這些概念以及 生命周期.
工具鏈
docker: docker 環(huán)境安裝好后, 這是我們第一個(gè)接觸到的工具. 更確切的說(shuō)法是 docker client
. 用來(lái)和 docker daemon 進(jìn)行通信(流程見上面的圖). 了解幾個(gè)常用的就好:
# 鏡像相關(guān)
docker pull image:tag
docker images
docker rmi
# 容器相關(guān)
docker run xxx
docker ps
docker rm
# other
docker info
docker help
docker build # 馬上 Dockerfile 就要講到
到了這大家有沒有疑問(wèn):
- 鏡像哪來(lái)的?
- 剛才用 類 來(lái)類比鏡像, 類是可以用代碼定義的, 那鏡像可以么?
先回答第一個(gè)問(wèn)題, 我們可以通過(guò)容器來(lái)構(gòu)建鏡像, 命令是 docker commit
, 和 git 倉(cāng)庫(kù)確實(shí)很相似. 但是在上面的列表里, 我并沒有列舉這個(gè), 因?yàn)?非主流 -- 我們也可以用代碼來(lái)定義鏡像, 這就是 Dockerfile.
直接看個(gè)例子就好:
FROM mysql:8
MAINTAINER daydaygo <1252409767@qq.com>
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ADD my.cnf /etc/mysql/conf.d/my.cnf
RUN chmod -R 644 /etc/mysql/conf.d/*
CMD ["mysqld"]
EXPOSE 3306
Dockerfile 就是這樣一條一條 指令 組成, 我們從 基礎(chǔ)鏡像 開始, 一步一步構(gòu)建出我們需要的環(huán)境的. 每一條指令, 對(duì)應(yīng)我們?cè)谌萜髦袌?zhí)行相關(guān)操作, 然后把這個(gè)容器 commit 成新的鏡像.
到這一步, 怎么構(gòu)建環(huán)境和運(yùn)行環(huán)境折騰清楚了, 然后繼續(xù)實(shí)踐, 比如 phper 的經(jīng)典的環(huán)境: linux + nginx + php + mysql. 傳統(tǒng)的做法, 我們把這個(gè)都安裝到一個(gè)鏡像里面就好了.
此處可以有停頓.
既然鏡像都能一步一步的慢慢構(gòu)建起來(lái), 為什么我們不通過(guò)一個(gè)一個(gè)服務(wù)來(lái)組合成我們需要的環(huán)境呢? 于是到了 docker-compose 登場(chǎng).
直接看例子就能明白:
fpm:
build:
context: ./server
dockerfile: fpm.Dockerfile
volumes:
- ../:/var/www
- ./logs/nginx/:/var/log/nginx
- ./logs/fpm/:/var/log/php7
# 注意這里, 通過(guò) links 表示 fpm 這個(gè)服務(wù)需要 redis 和 fpm 服務(wù)
links:
- mysql
- redis
# - rabbitmq
dns:
- 223.5.5.5
- 223.6.6.6
extra_hosts:
- "fpm:127.0.0.1"
ports:
- "80:80"
- "443:443"
mysql:
build:
context: ./server
dockerfile: mysql.Dockerfile
volumes:
- ./data/mysql:/var/lib/mysql
ports:
- "3306:3306"
environment:
# MYSQL_DATABASE: test
# MYSQL_USER: test
# MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: root
redis:
build:
context: ./server
dockerfile: redis.Dockerfile
volumes:
- ./data/redis:/data
- ./logs/redis:/var/log/redis
ports:
- "6379:6379"
這個(gè)是 docker-compose 的配置文件, yaml 格式, yaml 的語(yǔ)法就不多講了, 簡(jiǎn)單程度和 json 一個(gè)級(jí)別. 配置內(nèi)容也很簡(jiǎn)單, 看 key 基本就能看懂.
然后, 跑起來(lái)吧:
docker-compose up -d fpm # 啟動(dòng) fpm, 應(yīng)為 fpm 需要 redis 和 mysql, 所以也會(huì)跟著啟動(dòng)
docker-compose stop fpm
docker-compose logs fpm
docker-compose exec fpm bash # 執(zhí)行容器中的命令
環(huán)境安裝 & 配置
win 下的安裝現(xiàn)在非常簡(jiǎn)單, 按照 阿里云容器 - 鏡像加速器 中的文檔操作就好了.
- 推薦 win10 + docker for window, 當(dāng)然 docker toolbox 也能玩, 希望現(xiàn)在沒有我以前踩過(guò)的坑了
- 配置阿里云鏡像加速
- 配置文件掛載
- 配置 docker 硬件資源, 推薦 2核4G
ok, 安裝及環(huán)境就好了
docker 的 lnmp 之旅
其實(shí)這部分內(nèi)容, 上面在講工具鏈的時(shí)候, 基本都提到了, 這里就演示一下最終效果就好.
寫在最后
程序員認(rèn)為自己需要交付的是代碼冈爹,只要代碼邏輯正確就好了涌攻,但實(shí)際上項(xiàng)目需要交付的是 代碼 + 代碼運(yùn)行所需的環(huán)境
純工具的角度來(lái)使用 docker, 其實(shí)相當(dāng)輕松. 這次分享之后, 希望對(duì) docker 有興趣的同學(xué)可以:
- 一定要實(shí)踐
- 實(shí)踐中鞏固這些概念
- 站在巨人的肩膀上 -- 讀官方鏡像的 Dockerfile, 看其他人的源碼
資源推薦:
- 入門值得一看的源碼 laradock
- 開源入門好書 《Docker — 從入門到實(shí)踐》
- 深入講解的好書 <Docker——容器與容器云(第2版)>