前幾天寫了一篇文章 前端部署發展史,前端部署的發展離不開 devops
的發展,而 devops
又得益於 docker
的發展。所以,前端掌握 docker
也勢在必行,況且它又不是很難html
docker
使應用部署更加輕量,可移植,可擴展。更好的環境隔離也更大程度地避免了生產環境與測試環境不一致的巨大尷尬。因爲 docker
輕即可移植的特色也極大促進了 CI/CD
的發展。前端
docker
的架構圖以下node
從圖中能夠看出幾個組成部分linux
docker client
: 即 docker
命令行工具docker host
: 宿主機,docker daemon
的運行環境服務器docker daemon
: docker
的守護進程,docker client
經過命令行與 docker daemon
交互container
: 最小型的一個操做系統環境,能夠對各類服務以及應用容器化image
: 鏡像,能夠理解爲一個容器的模板配置,經過一個鏡像能夠啓動多個容器registry
: 鏡像倉庫,存儲大量鏡像,能夠從鏡像倉庫拉取和推送鏡像參考在 centos 上安裝 docker 的官方文檔: docs.docker.com/install/lin…nginx
如下是在 centos
上安裝 docker
的命令示例過程git
安裝依賴github
$ yum install -y yum-utils device-mapper-persistent-data lvm2
複製代碼
添加 docker
的yum鏡像源,若是在國內,添加阿里雲的鏡像源web
# 安裝 docker 官方的鏡像源
$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 若是在國內,安裝阿里雲的鏡像
$ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
複製代碼
安裝指定版本的 docker
而且啓動服務面試
# 安裝 docker
$ yum install -y docker-ce
# 安裝指定版本號的 docker,如下是 k8s 官方推薦的 docker 版本號 (此時,k8s 的版本號在 v1.16)
$ yum install -y docker-ce-18.06.2.ce
$ systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
$ systemctl start docker
複製代碼
當 docker
安裝成功後,可使用如下命令查看版本號redis
$ docker --version
Docker version 18.06.2-ce, build 6d37f41
# 查看更詳細的版本號信息
$ docker version
# 查看docker的詳細配置信息
$ docker info
複製代碼
dockerd
是 docker
的守護進程,dockerd
能夠經過配置文件進行配置,在 linux 下的配置文件位置在 /etc/docker/daemon.json
,更詳細內容能夠參考 官方文檔。
日誌引擎爲 json-file
,對日誌結構化,結合合適的日誌系統,方便定位日誌。 存儲引擎爲 overrlay2
$ mkdir /etc/docker
# 設置 docker daemon
$ cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
# 重啓 docker
$ systemctl daemon-reload
$ systemctl restart docker
複製代碼
docker
底層使用了一些 linux
內核的特性,大概有 namespace
,cgroups
和 ufs
docker
使用 linux namespace
構建隔離的環境,它由如下 namespace
組成
pid
: 隔離進程net
: 隔離網絡ipc
: 隔離 IPCmnt
: 隔離文件系統掛載uts
: 隔離hostnameuser
: 隔離uid/gid也叫 cgroups
,限制資源配額,好比某個容器只能使用 100M
內存
UnionFS
是一種分層、輕量級而且高性能的文件系統,支持對文件系統的修改做爲一次提交來一層層的疊加。docker
的鏡像與容器就是分層存儲,可用的存儲引擎有 aufs
,overlay
等。
關於分層存儲的詳細內容能夠查看官方文檔 docker: About storage drivers
鏡像是一份用來創造容器的配置文件,而容器能夠視做最小型的一個操做系統。
docker
的鏡像和容器都使用了 unionFS
作分層存儲,鏡像做爲只讀層是共享的,而容器在鏡像之上附加了一層可寫層,最大程度地減小了空間的浪費,詳見下圖
大部分時候,咱們不須要本身構建鏡像,咱們能夠在官方鏡像倉庫拉取鏡像
能夠簡單使用命令 docker pull
拉取鏡像。拉取鏡像後可使用 docker inspect
查看鏡像信息
# 加入拉取一個 node:alpine 的鏡像
$ docker pull node:alpine
# 查看鏡像信息
$ docker inspect node:alpine
# 列出全部鏡像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
node alpine f20a6d8b6721 13 days ago 105MB
mongo latest 965553e202a4 2 weeks ago 363MB
centos latest 9f38484d220f 8 months ago 202MB
複製代碼
但並非全部的鏡像均可以在鏡像倉庫中找到,另外咱們也須要爲咱們本身的業務應用去構建鏡像。
使用 docker build
構建鏡像,docker build
會使用當前目錄的 dockerfile
構建鏡像,至於 dockerfile
的配置,參考下節。
-t
指定標籤
# -t node-base:10: 鏡像以及版本號
# .: 指當前路徑
$ docker build -t node-base:10 .
複製代碼
當構建鏡像成功後可使用 docker push
推送到鏡像倉庫
在使用 docker
部署本身應用時,每每須要本身構建鏡像。docker
使用 Dockerfile
做爲配置文件構建鏡像,簡單看一個 node
應用構建的 dockerfile
FROM node:alpine
ADD package.json package-lock.json /code/ WORKDIR /code
RUN npm install --production
ADD . /code
CMD npm start 複製代碼
基於一箇舊有的鏡像,格式以下
FROM <image> [AS <name>]
# 在多階段構建時會用到
FROM <image>[:<tag>] [AS <name>]
複製代碼
把目錄,或者 url 地址文件加入到鏡像的文件系統中
ADD [--chown=<user>:<group>] <src>... <dest> 複製代碼
執行命令,因爲 ufs
,它會在當前鏡像的頂層新增一層
RUN <command> 複製代碼
指定容器如何啓動
一個 Dockerfile
中只容許有一個 CMD
# exec form, this is the preferred form
CMD ["executable","param1","param2"]
# as default parameters to ENTRYPOINT
CMD ["param1","param2"]
# shell form
CMD command param1 param2 複製代碼
鏡像與容器的關係,相似於代碼與進程的關係。
docker run
建立容器docker stop
中止容器docker rm
刪除容器基於 nginx
鏡像建立一個最簡單的容器:啓動一個最簡單的 http 服務
使用 docker run
來啓動容器,docker ps
查看容器啓動狀態
$ docker run -d --name nginx -p 8888:80 nginx:alpine
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
404e88f0d90c nginx:alpine "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 0.0.0.0:8888->80/tcp nginx
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
複製代碼
其中:
-d
: 啓動一個 daemon
進程--name
: 爲容器指定名稱-p host-port:container-port
: 宿主機與容器端口映射,方便容器對外提供服務nginx:alpine
: 基於該鏡像建立容器此時在宿主機使用 curl
測試容器提供的服務是否正常
$ curl localhost:8888
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
複製代碼
那若是要進入容器環境中呢?使用 docker exec -it container-name sh
命令
$ docker exec -it nginx sh
/ #
/ #
/ #
複製代碼
docker ps
列出全部容器
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
404e88f0d90c nginx:alpine "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 0.0.0.0:8888->80/tcp nginx
498e7d74fb4f nginx:alpine "nginx -g 'daemon of…" 7 minutes ago Up 7 minutes 80/tcp lucid_mirzakhani
2ce10556dc8f redis:4.0.6-alpine "docker-entrypoint.s…" 2 months ago Up 2 months 0.0.0.0:6379->6379/tcp apolloserverstarter_redis_1
複製代碼
docker port
查看容器端口映射
$ docker port nginx
80/tcp -> 0.0.0.0:8888
複製代碼
docker stats
查看容器資源佔用
$ docker stats nginx
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
404e88f0d90c nginx 0.00% 1.395MiB / 1.796GiB 0.08% 632B / 1.27kB 0B / 0B 2
複製代碼
我是山月,我會按期分享全棧文章在我的公衆號中。若是你對全棧面試,前端工程化,graphql,devops,我的服務器運維以及微服務感興趣的話,能夠關注我。若是想進羣交流,能夠添加我微信 shanyue94,備註加羣。