Docker筆記

 

簡介html

Docker 是 dotCloud 最近幾個月剛宣佈的開源引擎,旨在提供一種應用程序的自動化部署解決方案,簡單的說就是,在 Linux 系統上迅速建立一個容器(相似虛擬機)並在容器上部署和運行應用程序,並經過配置文件能夠輕鬆實現應用程序的自動化安裝、部署和升級,很是方便。由於使用了容器,因此能夠很方便的把生產環境和開發環境分開,互不影響,這是 docker 最廣泛的一個玩法。更多的玩法還有大規模 web 應用、數據庫部署、持續部署、集羣、測試環境、面向服務的雲計算、虛擬桌面 VDI 等等。python

Docker 使用 Go 語言編寫,用 cgroup 實現資源隔離,容器技術採用 LXC. LXC 已經足夠成熟,被多個主流 PaaS 服務商採用(好比 dotCloud),國內的一些互聯網公司也在用(好比騰訊)。雖然都是企圖解決自動化部署方面的問題,Docker 的解決方式有別於咱們常提到的 Puppet/Chef,他們雖然走的是不一樣的路,但也能夠拿來一塊兒用。linux

安裝 (ubuntu 12.04)nginx

Due to a bug in LXC, Docker works best on the 3.8 kernel. Precise comes with a 3.2 kernel, so we need to upgrade it. The kernel you’ll install when following these steps comes with AUFS built in. We also include the generic headers to enable packages that depend on them, like ZFS and the VirtualBox guest additions.web

sudo apt-get install python-software-properties
sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
sudo rebootdocker

添加docker源並安裝docker數據庫

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker
上面兩步也能夠替換成執行curl -s https://get.docker.io/ubuntu/ | sudo sh,更簡單。ubuntu

建立容器centos

首先從https://index.docker.io/下載一個預約義的鏡像安全

sudo docker pull ubuntu
啓動一個容器:

sudo docker run -i -t ubuntu /bin/bash
Starting a long-running worker process

# Start a very useful long-running process
JOB=$(sudo docker run -d ubuntu /bin/sh -c "while true; do echo Hello world; sleep 1; done")

# Collect the output of the job so far
sudo docker logs $JOB

# Kill the job
sudo docker kill $JOB
Bind a service on a TCP port

# Bind port 4444 of this container, and tell netcat to listen on it
JOB=$(sudo docker run -d -p 4444 ubuntu:12.10 /bin/nc -l 4444)

# Which public port is NATed to my container?
PORT=$(sudo docker port $JOB 4444 | awk -F: '{ print $2 }')

# Connect to the public port
echo hello world | nc 127.0.0.1 $PORT

# Verify that the network connection worked
echo "Daemon received: $(sudo docker logs $JOB)"
Committing (saving) a container state¶

Save your containers state to a container image, so the state can be re-used.

When you commit your container only the differences between the image the container was created from and the current state of the container will be stored (as a diff). See which images you already have using the docker images command.

# Commit your container to a new named image
sudo docker commit <container_id> <some_name>

# List your containers
sudo docker images
You now have a image state from which you can create new instances.

更多功能見http://docs.docker.io/


 

什麼是docker


Docker 是 Docker.Inc 公司開源的一個基於LXC技術之上構建的Container容器引擎, 源代碼託管在 GitHub 上, 基於Go語言並聽從Apache2.0協議開源。 Docker在2014年6月召開DockerConf 2014技術大會吸引了IBM、Google、RedHat等業界知名公司的關注和技術支持,不管是從 GitHub 上的代碼活躍度,仍是Redhat宣佈在RHEL7中正式支持Docker, 都給業界一個信號,這是一項創新型的技術解決方案。

docker的基本概念

①鏡像:用來建立Docker容器的只讀模板 ②容器:從鏡像建立而來的運行實例,各個容器之間相互隔離 ③倉庫:存放鏡像的場所,如https://hub.docker.com/和http://www.dockerpool.com/

安裝docker
對於centos7,直接執行yum -y install docker便可安裝,安裝完成後須要執行systemctl start docker來啓動docker服務。

其餘操做系統中的安裝方法見https://docs.docker.com/installation/#installation

獲取鏡像
從Docker Hub倉庫下載一個Ubuntu 12.04操做系統的鏡像

$ sudo docker pull ubuntu:12.04 Pulling repository ubuntu ab8e2728644c: Pulling dependent layers 511136ea3c5a: Download complete 5f0ffaa9455e: Download complete a300658979be: Download complete 904483ae0c30: Download complete ffdaafd1ca50: Download complete d047ae21eeaf: Download complete

官方鏡像比較慢的時候能夠從其餘倉庫下載鏡像,如 $ sudo docker pull www.dockerpool.com:5000/library/centos:centos7

查詢本地已下載的鏡像

$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 12.04 0a51fcc173d8 2 days ago 111 MB centos httpd 9ad57da2b81c 6 weeks ago 336.5 MB e01000c7bac8 6 weeks ago 336.5 MB centos latest b157b77b1a65 8 weeks ago 243.7 MB

其中,鏡像id惟一標識了鏡像,TAG信息用來標記來自同一個倉庫的不一樣鏡像。例如ubuntu倉庫中有多個鏡像,經過TAG信息來區分發行版本,例如10.0四、12.0四、12.十、13.0四、14.04等。建立容器時,若是不指定具體的標記,則默認使用latest標記信息。

除了從容器中下載已有鏡像外,也能夠根據已有鏡像建立新的鏡像。建立新鏡像有多種方法:

①修改已有鏡像後commit

$ sudo docker run -t -i ubuntu:12.04 /bin/bash root@a439b6e894bb:/# apt-get update root@a439b6e894bb:/# apt-get install nginx root@a439b6e894bb:/# /etc/init.d/nginx start root@a439b6e894bb:/# exit $ sudo docker commit -m 'add ngnix' -a 'feisky' a439b6e894bb ubuntu:nginx 0a693112c443ce4fb21bc57a26d67f0648b9415e052f929be7e06701f5f3ca2d $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu nginx 0a693112c443 9 seconds ago 153.1 MB ubuntu 12.04 0a51fcc173d8 2 days ago 111 MB

②用dockerfile來建立鏡像

首先建立一個Dockerfile:

$ cat Dockerfile

yet another ngnix
FROM ubuntu:12.04 MAINTAINER feisky feisky@root RUN apt-get update RUN apt-get -y install nginx

put my local site to /var/www
ADD index.html /var/www/html/

expose httpd port
EXPOSE 80

the command to run
CMD ["/usr/sbin/nginx"]

$ sudo docker build -t 'ubuntu:www' .

③導入已有鏡像

要從本地文件系統導入一個鏡像,可使用openvz(容器虛擬化的先鋒技術)的模板來建立: openvz的模板下載地址爲http://openvz.org/Download/templates/precreated

$ sudo cat ubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04

④導入docker save保存的鏡像

$ sudo docker save -o ubuntu_12.04.tar ubuntu:12.04 $ sudo docker load --input ubuntu_14.04.tar $ sudo docker load < ubuntu_14.04.tar #同上

⑤導入已保存的容器

保存一個容器的方法

$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7691a814370e ubuntu:14.04 "/bin/bash" 36 hours ago Exited (0) 21 hours ago test $ sudo docker export 7691a814370e > ubuntu.tar

從新做爲鏡像導入進來

$ cat ubuntu.tar | sudo docker import - test/buntu:v1.0

注:用戶既可使用docker load來導入鏡像存儲文件到本地鏡像庫,也可使用docker import來導入一個容器快照到本地鏡像庫。這二者的區別在於容器快照文件將丟棄全部的歷史記錄和元數據信息(即僅保存容器當時的快照狀態),而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導入時能夠從新指定標籤等元數據信息。

鏡像製做好後,能夠經過docker push命令,把本身建立的鏡像上傳到倉庫中來共享 $ sudo docker push ubuntu

若是一個鏡像不須要了,能夠刪除它: $ sudo docker rmi e01000c7bac8

容器管理
容器是獨立運行的一個或一組應用,以及它們的運行態環境。

啓動容器

下面的命令輸出一個"Hello World",以後終止容器: $ sudo docker run ubuntu:nginx /bin/echo 'hello world' hello world

下面的命令則啓動一個bash終端,可讓用戶進行交互。 $ sudo docker run -t -i ubuntu:12.04 /bin/bash root@af8bae53bdd3:/# 其中,-t選項讓Docker分配一個僞終端(pseudo-tty)並綁定到容器的標準輸入上, -i則讓容器的標準輸入保持打開。

對於已經中止的容器,能夠用start命令從新啓動: $ sudo docker start 7fb349365baf 7fb349365baf $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7fb349365baf ubuntu:nginx /bin/bash 29 minutes ago Up 6 seconds goofy_ritchie0

docker run的一些有用參數: ①-d:以守護進程形式運行容器 ②

其餘命令:

nsenter --target $PID --mount --uts --ipc --net --pid鏈接容器終端 docker attach鏈接容器終端 docker stop來終止一個運行中的容器 docker restart命令會將一個運行態的容器終止,而後再從新啓動它 docker logs獲取容器的輸出信息 docker ps查看正在運行的容器 docker ps查看正在運行和已經中止的容器

注意:當多個窗口同時attach到同一個容器的時候,全部窗口都會同步顯示。當某個窗口因命令阻塞時,其餘窗口也沒法執行操做了。

倉庫管理
對於默認Docker Hub倉庫,經過執行docker login命令來輸入用戶名、密碼和郵箱來完成註冊和登陸。 註冊成功後,本地用戶目錄的.dockercfg中將保存用戶的認證信息。

能夠經過sudo docker search centos來搜索鏡像,經過sudo docker pull centos來下載鏡像。

https://registry.hub.docker.com/builds/add/提供的自動構建功能對於須要常常升級程序的鏡像比較有用,目前僅支持Github和BitBucket。

私有倉庫的搭建

① $ sudo docker run -d -p 5000:5000 registry

② $ sudo pip install docker-registry

③ $ cp config/config_sample.yml config/config.yml

④ $ sudo gunicorn --access-logfile - --error-logfile - -k gevent -b 0.0.0.0:5000 -w 4 --max-requests 100 docker_registry.wsgi:application

如何向私有倉庫上傳鏡像

① $ sudo docker tag ba58 192.168.7.26:5000/test

② $ sudo docker push 192.168.7.26:5000/test

經過$ curl http://192.168.7.26:5000/v1/search能夠查詢私有倉庫的鏡像,經過sudo docker pull 192.168.7.26:5000/test能夠下載私有倉庫的鏡像。

 

數據管理


建立一個web容器,並加載一個數據捲到容器的/webapp目錄:

$ sudo docker run -d -P --name web -v /webapp training/webapp python app.py

掛載一個主機目錄做爲數據卷:

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

Docker掛載數據卷的默認權限是讀寫,用戶也能夠經過:ro指定爲只讀:

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py

也能夠掛載一個本地主機文件做爲數據卷:$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash,注意這會致使報錯誤信息,最好仍是直接掛載文件的父目錄

若是你有一些持續更新的數據須要在容器之間共享,最好建立數據卷容器。數據卷容器,其實就是一個正常的容器,專門用來提供數據卷供其它容器掛載的:

$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres

而後,在其餘容器中使用--volumes-from來掛載dbdata容器中的數據卷。

$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres

$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres

 

網絡管理

當Docker啓動時,會自動在主機上建立一個docker0虛擬網橋,其實是Linux的一個bridge,能夠理解爲一個軟件交換機。它會在掛載到它的網口之間進行轉發。

同時,Docker隨機分配一個本地未佔用的私有網段(在RFC1918中定義)中的一個地址給docker0接口。好比典型的172.17.42.1,掩碼爲255.255.0.0。此後啓動的容器內的網口也會自動分配一個同一網段.

① 端口映射: 使用docker port 來查看當前映射的端口配置

$ sudo docker run -P ... #隨機映射一個49000~49900的端口到內部容器開放的網絡端口

$ sudo docker run -d -p 5000:5000 #映射到指定端口

$ sudo docker run -d -p 127.0.0.1:5000:5000 #映射到指定HOST+端口

$ sudo docker run -d -p 127.0.0.1::5000 #映射到指定HOST,端口隨機生成

$ sudo docker run -d -p 127.0.0.1:5000:5000/udp #映射到指定UDP端口

② 容器互聯

啓動容器時指定容器名稱: $ sudo docker run -d --name db training/postgres

根據名稱鏈接db容器 $ sudo docker run -d -P --name web --link db:db training/webapp python app.py

注意:--link參數的格式爲--link name:alias,其中name是要連接的容器的名稱,alias是這個鏈接的別名;若是名稱未知,能夠經過下面的命令查詢: $ sudo docker inspect -f "{{ .Name }}" aed84ee21bde

Docker在兩個互聯的容器之間建立了一個安全隧道,並且不用映射它們的端口到宿主主機上。在啓動db容器的時候並無使用-p和-P標記,從而避免了暴露數據庫端口到外部網絡上。

Docker 經過2種方式爲容器公開鏈接信息:

其一是環境變量:

$ sudo docker run --rm --name web2 --link db:db training/webapp env . . . DB_NAME=/web2/db DB_PORT=tcp://172.17.0.5:5432 DB_PORT_5000_TCP=tcp://172.17.0.5:5432 DB_PORT_5000_TCP_PROTO=tcp DB_PORT_5000_TCP_PORT=5432 DB_PORT_5000_TCP_ADDR=172.17.0.5 . . .

其二是hosts:

$ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash root@aed84ee21bde:/opt/webapp

# cat /etc/hosts 172.17.0.7 aed84ee21bde . . . 172.17.0.5 db

③ 其餘選項

只有在Docker服務啓動的時候才能配置:

-b BRIDGE or --bridge=BRIDGE --指定容器掛載的網橋

--bip=CIDR --定製docker0的掩碼

-H SOCKET... or --host=SOCKET... --Docker服務端接收命令的通道

--icc=true|false --是否支持容器之間進行通訊

--ip-forward=true|false --請看下文容器之間的通訊

-iptables=true|false --禁止Docker添加iptables規則

--mtu=BYTES --容器網絡中的MTU

既能夠在啓動服務時指定,也能夠Docker容器啓動(docker run)時候指定:

--dns=IP_ADDRESS... --使用指定的DNS服務器

--dns-search=DOMAIN... --指定DNS搜索域

只有在docker run執行時使用:

-h HOSTNAME or --hostname=HOSTNAME --配置容器主機名

--link=CONTAINER_NAME:ALIAS --添加到另外一個容器的鏈接

--net=bridge|none|container:NAME_or_ID|host --配置容器的橋接模式

-p SPEC or --publish=SPEC --映射容器端口到宿主主機

-P or --publish-all=true|false --映射容器全部端口到宿主主機

相關文章
相關標籤/搜索