Docker使用實戰總結

Docker 最近很火,因此,也跟着將來的大趨勢學下docker,並將docker 應用到項目開發中。

1、什麼是docker

Docker 是一個開源的應用容器引擎,基於 Go 語言 並聽從Apache2.0協議開源。Docker 可讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,而後發佈到任何流行的 Linux 機器上,也能夠實現虛擬化。
容器是徹底使用沙箱機制,相互之間不會有任何接口(相似 iPhone 的 app),更重要的是容器性能開銷極低。php

2、爲什麼要使用容器?

那麼應用容器長什麼樣子呢,一個作好的應用容器長得就好像一個裝好了一組特定應用的虛擬機同樣。好比我如今想用MySQL那我就找個裝好MySQL的容器,運行起來,那麼我就可使用 MySQL了。nginx

那麼我直接裝個 MySQL不就行了,何須還須要這個容器這麼詭異的概念?話是這麼說,但是你要真裝MySQL的話可能要再裝一堆依賴庫,根據你的操做系統平臺和版本進行設置,有時候還要從源代碼編譯報出一堆莫名其妙的錯誤,可不是這麼好裝。並且萬一你機器掛了,全部的東西都要從新來,可能還要把配置在從新弄一遍。可是有了容器,你就至關於有了一個能夠運行起來的虛擬機,只要你能運行容器,MySQL的配置就全省了。並且一旦你想換臺機器,直接把這個容器端起來,再放到另外一個機器就行了。硬件,操做系統,運行環境什麼的都不須要考慮了git

在公司中的一個很大的用途就是能夠保證線下的開發環境、測試環境和線上的生產環境一致。當年在 Baidu 常常碰到這樣的事情,開發把東西作好了給測試去測,通常會給一坨代碼和一個介紹上線步驟的上線單。結果代碼在測試機跑不起來,開發就跑來跑去看問題,一下子啊這個配置文件忘了提交了,一下子啊這個上線命令寫錯了。找到了一個 bug 提上去,開發一看,啊我怎麼又忘了把這個命令寫在上線單上了。相似的事情在上線的時候還會發生,變成啊你這個軟件的版本和我機器上的不同……在 Amazon 的時候,因爲一個開發直接擔任上述三個職位,並且有一套自動化部署的機制因此問題會少一點,可是上線的時候你們仍是膽戰心驚。github

若果利用容器的話,那麼開發直接在容器裏開發,提測的時候把整個容器給測試,測好了把改動改在容器裏再上線就行了。經過容器,整個開發、測試和生產環境能夠保持高度的一致。redis

此外容器也和VM同樣具備着必定的隔離性,各個容器之間的數據和內存空間相互隔離,能夠保證必定的安全性。sql

3、安裝docker

在 ubuntu 下使用 curl 命令進行安裝docker

sudo apt install -y curl;
sudo curl -sSL https://get.docker.com/ | sh;

windows 安裝請參考 docker 官網。ubuntu

docker經常使用命令

容器生命週期管理 — docker [run|start|stop|restart|kill|rm|pause|unpause]
容器操做運維 — docker [ps|inspect|top|attach|events|logs|wait|export|port]
容器rootfs命令 — docker [commit|cp|diff]
鏡像倉庫 — docker [login|pull|push|search]
本地鏡像管理 — docker [images|rmi|tag|build|history|save|import]
其餘命令 — docker [info|version]vim

一、列出機器上的鏡像(images):

docker images

clipboard.png

其中咱們能夠根據REPOSITORY來判斷這個鏡像是來自哪一個服務器,若是沒有 / 則表示官方鏡像,相似於username/repos_name表示Github的我的公共庫,相似於regsistory.example.com:5000/repos_name則表示的是私服。
IMAGE ID列實際上是縮寫,要顯示完整則帶上--no-trunc選項。windows

二、在docker index中搜索image(search)

搜索的範圍是官方鏡像和全部我的公共鏡像。NAME列的 / 後面是倉庫的名字。

docker search sameersbn

三、從docker registry server 中下拉image或repository(pull)

Usage: docker pull [OPTIONS] NAME[:TAG]

上面的命令須要注意,在docker v1.2版本之前,會下載官方鏡像的centos倉庫裏的全部鏡像,而從v.13開始官方文檔裏的說明變了:will pull the centos:latest image, its intermediate layers and any aliases of the same id,也就是隻會下載tag爲latest的鏡像(以及同一images id的其餘tag)。
也能夠明確指定具體的鏡像:

四、從image啓動一個container(run)

docker run 命令首先會從特定的image創之上create一層可寫的container,而後經過start命令來啓動它。中止的container能夠從新啓動並保留原來的修改。run命令啓動參數有不少,如下是一些常規使用說明,更多部分請參考http://www.cnphp6.com/archive...
當利用 docker run 來建立容器時,Docker 在後臺運行的標準操做包括:

  • 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
  • 利用鏡像建立並啓動一個容器
  • 分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層
  • 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
  • 從地址池配置一個 ip 地址給容器
  • 執行用戶指定的應用程序
  • 執行完畢後容器被終止
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

啓動一個本地鏡像:鏡像名REPOSITORY+鏡像TAG

> docker run -d sameersbn/postgresql:9.6-2
e527ef6698ea52bb78803facd5d2a6a8cbcdeb98ba052b3a0cdf78478d9acc53

clipboard.png

五、中止運行容器

根據容器IDCONTAINER ID來使運行的容器中止 docker stop CONTAINER ID

➜  docker ps
CONTAINER ID        IMAGE                        COMMAND                 CREATED             STATUS              PORTS               NAMES
f72ed57c80f8        sameersbn/redis:latest       "/sbin/entrypoint.sh"   8 minutes ago       Up 8 minutes        6379/tcp            wonderful_bassi
e527ef6698ea        sameersbn/postgresql:9.6-2   "/sbin/entrypoint.sh"   14 minutes ago      Up 13 minutes       5432/tcp            pensive_keller
➜  docker stop f72ed57c80f8

或者使用容器的別名來啓動:

docker start MyWordPress

更多命令請看:docker經常使用命令詳解

4、幾個重要的概念

在使用docker時,咱們得先弄清楚docker的幾個重要的名詞。

Docker生態

Docker生態就像 iPhone 的生態同樣,Docker倉庫至關於 IPhone 的 App Storedocker自身程序至關於IOS系統

鏡像與容器

鏡像(image):指的是以分層的、能夠被 LXC/libcontainer 理解的文件存儲格式。Docker的應用都是以這種格式發佈到Docker倉庫中,供你們使用。
容器(container):把應用鏡像從 Docker 倉庫下載到本地機器上,以鏡像爲模板,在一個容器類虛擬機中把這個應用啓動,這個虛擬機叫作容器。

能夠先簡單的理解,倉庫中的應用都以鏡像存在,從倉庫中拉取鏡像到本地的,叫容器

5、安裝鏡像docker-gitlab

gitlab環境配置要求比較高,可用內存必須2G以上,2核CPU,不然跑不起來。

1.安裝

gitlab 鏡像地址:docker-gitlab

Step 1. Launch a postgresql container

docker run --name gitlab-postgresql -d \
    --env 'DB_NAME=gitlabhq_production' \
    --env 'DB_USER=gitlab' --env 'DB_PASS=password' \
    --env 'DB_EXTENSION=pg_trgm' \
    --volume $HOME/docker/gitlab/postgresql:/var/lib/postgresql \
    sameersbn/postgresql:9.6-2

Step 2. Launch a redis container

docker run --name gitlab-redis -d \
    --volume $HOME/docker/gitlab/redis:/var/lib/redis \
    sameersbn/redis:latest

Step 3. Launch the gitlab container

docker run --name gitlab -d \
    --link gitlab-postgresql:postgresql --link gitlab-redis:redisio \
    --publish 10022:22 --publish 10080:80 \
    --env 'GITLAB_PORT=10080' --env 'GITLAB_SSH_PORT=10022' \
    --env 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string' \
    --env 'GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alpha-numeric-string' \
    --env 'GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alpha-numeric-string' \
    --volume $HOME/docker/gitlab/gitlab:/home/git/data \
    sameersbn/gitlab:10.2.2

--volume 方法解釋:

--volume $HOME/docker/gitlab/postgresql:/var/lib/postgresql
➜  ~ echo $HOME
/Users/kaiyiwang

注意: --volume $HOME/docker 是宿主機的環境,/var/lib/爲容器環境.

OK,安裝好以後,咱們能夠經過命令來查看 docker 進程

docker ps

clipboard.png

再次啓動容器命令:
前邊咱們已經安裝鏡像到本地,若是關閉docker服務以後,容器就會中止運行,再次啓動docker以後,咱們不須要再次使用 docker run -d images,而只需啓動容器便可。

docker ps:查看運行的容器。
docker ps -a:查看全部已經安裝的容器

開啓容器:

docker start gitlab-postgresql

clipboard.png

2.測試gitlab

使用 ifconfig 命令查看本機IP,由於gitlab默認的服務爲 10080,因此,咱們能夠根據咱們的IP和端口訪問到gitlab服務:http://192.168.1.101:10080/

clipboard.png

gitlab頁面:

clipboard.png

在 gitlab 上新建一個 test 測試庫:

clipboard.png

使用 docker 搭建 gitlab服務是否是超級方便,不用作什麼配置^_^。

相關文章:GitLab的簡單使用

6、項目管理系統Redmine

Redmine 是一套跨平臺的管理系統,它經過「項目(project)」的形式把成員、任務(問題)、文檔、討論及各類形式的資源整合在一塊兒,你們參與更新任務、文檔等內容來推進項目的進度,另外,它還集成了wiki文檔、版本控制、bug跟蹤等功能。

1.搭建Redmine服務

在這裏,咱們使用 sameersbn/docker-redmine 鏡像,項目地址爲:https://github.com/sameersbn/...

拉取鏡像:

docker pull sameersbn/redmine:latest

快讀啓動:

Step 1. Launch a postgresql container

docker run --name=postgresql-redmine -d \
  --env='DB_NAME=redmine_production' \
  --env='DB_USER=redmine' --env='DB_PASS=password' \
  --volume=$HOME/docker/redmine/postgresql:/var/lib/postgresql \
  sameersbn/postgresql:9.6-2

Step 2. Launch the redmine container

docker run --name=redmine -d \
  --link=postgresql-redmine:postgresql --publish=10083:80 \
  --env='REDMINE_PORT=10083' \
  --volume=$HOME/docker/redmine/redmine:/home/redmine/data \
  sameersbn/redmine:latest

2.測試

Redmine
Docker指令中,咱們把Redmine的對外服務端口映射到10083,因此,咱們能夠經過
訪問該地址:http://192.168.1.101:10083/,查看該服務是否安裝成功。

clipboard.png

安裝成功,^_^

7、docker容器名稱衝突

clipboard.png

咱們使用ps -a這個命令,咱們能夠觀察到gitlab-postgresql的狀態爲已經存在了。

clipboard.png

咱們用rm命令刪除這個容器,以下面命令所示:

sudo docker rm gitlab-postgresql

從新創建gitlab-postgresql這個容器:

docker run --name gitlab-postgresql -d \
    --env 'DB_NAME=gitlabhq_production' \
    --env 'DB_USER=gitlab' --env 'DB_PASS=password' \
    --env 'DB_EXTENSION=pg_trgm' \
    --volume $HOME/docker/gitlab/postgresql:/var/lib/postgresql \
    sameersbn/postgresql:9.6-2

docker 容器名稱衝突問題解決

8、掛載目錄

使用鏡像 nginx:latest,之後臺模式啓動一個容器,將容器的 80 端口映射到主機的 80 端口,主機的目錄 /data 映射到容器的 /data

docker run -p 80:80 -v /data:/data -d nginx:latest

將Mac的本地目錄掛栽倒容器tensorflow/tensorflow/notebooks目錄

docker run -it  -v  /Users/kaiyiwang/Code/ai/notebooks:/notebooks -d tensorflow/tensorflow

若是直接掛載會報出這樣的錯誤:

44a574c965c83688221798c5d70fff2a7badd3aad04dd071246d8f487bda5225
docker: Error response from daemon: Mounts denied:
The path /AI/tensorflow
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.

在mac上面使用Docker掛載目錄時,須要先在Docker->preference中添加該目錄,才能進行掛載!

clipboard.png

再重試一次掛載:

➜  tensorflow docker run -it  -v  /Users/kaiyiwang/Code/ai/notebooks:/notebooks -d tensorflow/tensorflow
d1fceb76e44c4050c878a6ce996f59d8252c59d082293674db2ac043e8607f14
➜  tensorflow

能夠看到掛載成功

9、進入容器內部

// 進入容器內部
sudo docker exec -it c7efe /bin/bash

c7efe 爲容器ID前幾位,經過上邊的命令便可進入容器內部。

進入jupyter

➜  tensorflow docker exec -it c7efe /bin/bash
root@c7efe77f377a:/notebooks#
root@c7efe77f377a:/notebooks# jupyter notebook list
Currently running servers:
http://localhost:8888/?token=44077e3f129fdbf0b26676b5414a36ce8b6a56627ad84a6e :: /notebooks
root@c7efe77f377a:/notebooks#

10、Docker重啓

在宿主機環境下重啓容器或整個docker

[corwien@lnp php_log]$ sudo docker ps    # 查看docker進程
[corwien@lnp php_log]$ sudo docker restart bfc6    # docker 容器重啓
# service docker restart
sudo systemctl restart docker   若是網絡斷了,則重啓docker就能夠了

查看DNS(docker容器在建立實例的時候會拷貝宿主機的到容器裏邊,若是宿主機的DNS改變了,則須要從新加載容器的)

[root@bfc6f9d528a5 /]# cat /etc/resolv.conf

11、將對容器的修改提交到鏡像

在容器內部進行了一些修改以後,咱們想把這些保存下來,不想這些在退出或中止這個容器後丟失這些修改,而且咱們還想把這些修改做爲其餘容器的基礎進行重用。

經過 docker commit 命令提交對容器的修改,並建立一個新鏡像。

好比咱們新建了一個學習swoole的Ubuntu環境的容器,如今要對這個容器提交生成新的鏡像,即:

查看容器:

docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                        NAMES
5ee6bfcc1310        7698f               "/bin/bash"         4 days ago          Up About an hour    0.0.0.0:2221->22/tcp, 0.0.0.0:8880->80/tcp   confident_jones

新生成鏡像:

$ docker commit 5ee6 ubuntu:swoole

能夠看到,新生成了一個swoole標籤的鏡像:

$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ubuntu               swoole              2fb6cd672bdc        39 seconds ago      530MB
ubuntu               latest              a2a15febcdf3        2 weeks ago         64.2MB
daocloud.io/ubuntu   latest              7698f282e524        3 months ago        69.9MB
jaspeen/oracle-11g   latest              0c8711fe4f0f        3 years ago         281MB

docker diff

經過 docker diff 命令來查看在容器中對鏡像作出的修改:

$ docker diff 5ee6

...

A /lib/cpp
C /root
C /root/.profile
A /root/.rediscli_history
A /root/.ssh
A /root/.ssh/id_rsa
A /root/.ssh/id_rsa.pub
A /root/.ssh/known_hosts
A /root/.viminfo
A /root/.wget-hsts
A /root/.bash_history
A /root/.gitconfig
A /work
C /tmp
A /tmp/pear
A /tmp/pear/temp
C /var
C /var/lib
C /var/lib/systemd

A 表示文件或者文件夾是新增的,C表示文件內容有修改,D表示該項目已經被刪除。

將鏡像和容器保存爲tar文件進行共享

對於已有鏡像,可使用docker命令行的 saveload 命令來建立一個壓縮包;而對於容器,可使用 importexport 進行導入導出操做。

鏡像操做:

docker save -o update1.tar b2367

docker load < update1.tar

容器:

docker export e556 > update.tar
docker import - update < update.tar

將修改的鏡像發佈到 docker hub

https://hub.docker.com 和GitHub同樣須要註冊一個帳號。

~ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ubuntu               swoole              2fb6cd672bdc        24 minutes ago      530MB

使用docker tag 命令使用你在 Docker Hub上的倉庫爲這個鏡像打上標籤,以下所示:

➜  ~ docker tag 2fb6c digtime/ubuntu-swoole
➜  ~ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
digtime/ubuntu-swoole   latest              2fb6cd672bdc        27 minutes ago      530MB
ubuntu                  swoole              2fb6cd672bdc        27 minutes ago      530MB

推送到docker hub:

$ docker push digtime/ubuntu-swoole
The push refers to repository [docker.io/digtime/ubuntu-swoole]
f43e13b8cb69: Retrying in 1 second
相關文章
相關標籤/搜索