# 更改 Ubuntu 預設源地址
$ sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# 安裝必備的系統命令
$ sudo apt-get install -y python-software-properties
$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ apt-cache policy docker-ce # 列舉 docker-ce 版本
$ apt-get install docker-ce=17.03.2-ce....
# 配置開機自啟動
$ sudo systemctl enable docker
# 取消開機自啟動
$ sudo systemctl disable docker
# 使用 systemctl 命令列修改
$ sudo systemctl edit docker.service
# 或者查詢配置地址並使用 Vim 修改
$ systemctl status docker
# 修改檔案內容
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock --insecure-registry 10.196.108.176:5000 --dns 114.114.114.114 --dns 8.8.8.8 --dns 8.8.4.4 -g /mnt
# 重新載入服務配置
$ sudo systemctl daemon-reload
# 重啟 Docker
$ sudo systemctl restart docker.service
# 判斷是否配置成功
$ sudo netstat -lntp | grep dockerd
# 在主節點啟動 Swarm
$ docker swarm init
# 檢視 Swarm 金鑰
$ docker swarm join-token -q worker
# 在主節點啟動 Procontainer
$ docker run -it -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
# 在主節點啟動 Registry
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
# 將子節點加入到 Swarm
$ docker swarm join \
--token ${TOKEN} \
10.196.108.176:2377
$ docker run -i -t -e SERVER_ADDR=ss.server.ip -e SERVER_PORT=port -e PASSWORD=123456 bluebu/shadowsocks-privoxy
$ apt install python3-pip
$ pip3 install https://github.com/shadowsocks/shadowsocks/archive/master.zip -U
{
"server": "...",
"server_port": ...,
"local_port": 1080,
"password": "..."
"method": "chacha20-ietf-poly1305",
"timeout": 600
}
$ sslocal -c config.json
listen-address 0.0.0.0:8118 # 所有 interface 上監聽流量
forward-socks5 / 127.0.0.1:1080 . # 流量導向本機上的 ss 代理
HTTP_PROXY=127.0.0.1:8118 HTTPS_PROXY=127.0.0.1:8118 curl https://www.google.com
[Environment]
Environment="HTTP_PROXY=127.0.0.1:8118" "HTTPS_PROXY=127.0.0.1:8118" "NO_PROXY=localhost,127.0.0.1,1.1.1.2,1.1.1.3,1.1.1.4"
...
$ sudo docker build -t myrepo/myapp /tmp/test1/
$ docker build -t username/image_name:tag_name .
$ docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
# 拉取映象
$ docker pull image_name
# 將某個容器儲存為映象
$ docker commit -m “commit message” -a “author” container_name username/image_name:tag
複製程式碼Docker 支援將映象儲存為檔案,以方便映象的匯出與載入:
# 儲存映象
$ docker save --output saved-image.tar my-image:1.0.0
$ docker save my-image:1.0.0 > saved-image.tar
$ docker save my_image:my_tag | gzip > my_image.tar.gz
# 匯入映象
$ docker load --input saved-image.tar
$ docker load
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mynewimage latest 4d2eab1c0b9a 5 minutes ago 278.1 MB
ubuntu 14.04 ad892dd21d60 11 days ago 275.5 MB
<none> <none> 6b0a59aa7c48 11 days ago 169.4 MB
<none> <none> 6cfa4d1f33fb 7 weeks ago 0 B
-
已使用映象(used image): 指所有已被容器(包括已停止的)關聯的映象。即 docker ps -a 看到的所有容器使用的映象。
-
未取用映象(unreferenced image):沒有被分配或使用在容器中的映象,但它有 Tag 資訊。
-
懸空映象(dangling image):未配置任何 Tag (也就無法被取用)的映象,所以懸空。這通常是由於映象 build 的時候沒有指定 -t 引數配置 Tag 導致的。
# 列舉未使用的
$ docker images --filter "dangling=true"
# 刪除所有無用的映象
$ docker rmi $(docker images -q -f dangling=true)
#
# MongoDB Dockerfile
#
# https://github.com/dockerfile/mongodb
#
# Pull base image.
FROM dockerfile/ubuntu
ENV SOURCE http://downloads-distro.mongodb.org/repo/ubuntu-upstart
# Install MongoDB.
RUN \
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 && \
echo 'deb $SOURCE dist 10gen' > /etc/apt/sources.list.d/mongodb.list && \
apt-get update && \
apt-get install -y mongodb-org && \
rm -rf /var/lib/apt/lists/*
ENV PATH /usr/local/mongo/bin:$PATH
# Define mountable directories.
VOLUME ["/data/db"]
# Define working directory.
WORKDIR /data
# Define default command.
CMD ["mongod"]
# Expose ports.
# - 27017: process
# - 28017: http
EXPOSE 27017
EXPOSE 28017
指令名 | 格式 | 描述 | 備註 |
---|---|---|---|
FROM | 格式為 FROM 或FROM |
第一條指令必須為 FROM 指令。 |
如果在同一個 Dockerfile 中建立多個映象時,可以使用多個 FROM 指令(每個映象一次) |
MAINTAINER | 格式為 MAINTAINER |
指定維護者資訊。 | |
RUN | RUN 或 RUN ["executable", "param1", "param2"] |
前者將在 shell 終端中執行命令,即 /bin/sh -c ;後者則使用 exec 執行。指定使用其它終端可以透過第二種方式實現,例如 RUN ["/bin/bash", "-c", "echo hello"] |
每條 RUN 指令將在當前映象基礎上執行指定命令,並提交為新的映象。當命令較長時可以使用 \ 來換行。 |
CMD | 支援三種格式,CMD ["executable","param1","param2"] 使用 exec 執行,推薦方式;CMD command param1 param2 在 /bin/sh 中執行,提供給需要互動的應用;CMD ["param1","param2"] 提供給 ENTRYPOINT 的預設引數; |
指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令。如果指定了多條命令,只有最後一條會被執行。如果使用者啟動容器時候指定了執行的命令,則會改寫掉 CMD 指定的命令。 |
|
EXPOSE | EXPOSE |
告訴 Docker 服務端容器暴露的埠號,供互聯絡統使用 | 在啟動容器時需要透過 -p 來指定埠對映,Docker 主機會自動分配一個埠轉發到指定的埠 |
ENV | ENV 。指定一個環境變數,會被後續 RUN 指令使用,併在容器執行時保持 |
||
ADD | ADD |
該命令將複製指定的 到容器中的 。 |
可以是 Dockerfile 所在目錄的一個相對路徑;也可以是一個 URL;還可以是一個 tar 檔案(自動解壓為目錄) |
COPY | COPY |
複製本地主機的 (為 Dockerfile 所在目錄的相對路徑)到容器中的 dest |
當使用本地目錄為源目錄時,推薦使用 COPY |
ENTRYPOINT | ENTRYPOINT ["executable", "param1", "param2"] ,使用指定可執行檔案執行;ENTRYPOINT command param1 param2 ,會在 Shell 中執行 |
配置容器啟動後執行的命令,並且不可被 docker run 提供的引數改寫。每個 Dockerfile 中只能有一個 ENTRYPOINT ,當指定多個時,只有最後一個起效。 |
|
VOLUME | VOLUME ["/data"] |
建立一個可以從本地主機或其他容器掛載的掛載點,一般用來存放資料庫和需要保持的資料等 | |
USER | USER daemon |
指定執行容器時的使用者名稱或 UID,後續的 RUN 也會使用指定使用者 |
|
WORKDIR | WORKDIR /path/to/workdir |
為後續的 RUN 、CMD 、ENTRYPOINT 指令配置工作目錄 |
可以使用多個 WORKDIR 指令,後續命令如果引數是相對路徑,則會基於之前命令指定的路徑 |
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
# docker run -it
# Hello world
# docker run -it John
# Hello John
FROM ubuntu:latest
RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY my_first_process my_first_process
COPY my_second_process my_second_process
CMD ["/usr/bin/supervisord"]
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
# 拉取公共映象
$ docker pull ubuntu:16.04
# 為映象新增 Registry 資訊
$ docker tag ubuntu:16.04 custom-domain:5000/my-ubuntu
# 將其推送到私有映象庫
$ docker push custom-domain:5000/my-ubuntu
# 從私有映象庫中拉取映象
$ docker pull custom-domain:5000/my-ubuntu
-v /mnt/registry:/var/lib/registry
{ "insecure-registries": ["myregistry.example.com:5000"] }
$ mkdir auth
$ docker run \
--entrypoint htpasswd \
registry:2 -Bbn cscan cscancscan > ~/auth/htpasswd
$ openssl req -new -newkey rsa:4096 -days 365 \
-subj "/CN=localhost" \
-nodes -x509 \
-keyout ~/certs/domain.key \
-out ~/certs/domain.crt
registry-srv:
restart: always
image: registry:2
ports:
- 5000:5000
environment:
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
volumes:
- /opt/registry:/var/lib/registry
- ~/certs:/certs
- ~/auth:/auth
$ docker-compose up -d
# 登入到映象伺服器
$ docker login myregistrydomain.com:5000
-
docker create:建立一個容器但是不啟動。
-
docker rename:允許重新命名容器。
-
docker run:在同一個操作中建立並啟動一個容器。
-
docker rm:刪除容器。
-
docker update:更新容器的資源限制。
-
-i 即使在沒有附著的情況下依然保持 STDIN 處於開啟。單純使用 -i 命令是不會出現 root@689d580b6416:/ 這種字首
-
-t 分配一個偽 TTY 控制檯
# 建立,並且啟動某個容器以執行某個命令
$ docker run -ti --name container_name image_name command
# 建立,啟動容器執行某個命令然後刪除該容器
$ docker run --rm -ti image_name command
# 建立,啟動容器,並且對映捲與埠,同時設定環境變數
$ docker run -it --rm -p 8080:8080 -v /path/to/agent.jar:/agent.jar -e JAVA_OPTS=”-javaagent:/agent.jar” tomcat:8.0.29-jre8
# 建立容器,指定網路
$ docker run --network=
標誌值 | 描述 |
---|---|
-p 8080:80 |
將容器的 80 埠對映到 Docker 主機的 8080 埠(TCP) |
-p 8080:80/udp |
將容器的 80 埠對映到 Docker 主機的 8080 埠(UDP) |
-p 8080:80/tcp -p 8080:80/udp |
將容器的 80 埠對映到 Docker 主機的 8080 埠(TCP 和 UDP) |
# 啟動/停止某個容器
$ docker [start|stop] container_name
# 在某個容器內執行某條命令
$ docker exec -ti container_name command.sh
# 檢視某個容器的輸出日誌
$ docker logs -ft container_name
-
docker ps 檢視執行中的所有容器。
-
docker logs 從容器中獲取日誌。(你也可以使用自定義日誌驅動,不過在 1.10 中,它只支援 json-file 和 journald)
-
docker inspect 檢視某個容器的所有資訊(包括 IP 地址)。
-
docker events 從容器中獲取事件(events)。
-
docker port 檢視容器的公開埠。
-
docker top 檢視容器中活動行程。
-
docker stats 檢視容器的資源使用情況統計資訊。
-
docker diff 檢視容器的 FS 中有變化檔案資訊。
# 根據條件過濾查詢
$ docker ps --filter "name=nostalgic"
# 顯示正在執行的容器串列
$ docker stats --all
-
no:不進行重啟
-
on-failure:當容器以非零狀態碼退出時重啟容器
-
unless-stopped:當某個容器被顯性關閉或者 Docker 本身關閉或重啟時重啟
-
always:無論出現任何情況都重啟容器
# 設定重啟策略
# Off, On-failure, Unless-stopped, Always
$ docker run -dit — restart unless-stopped [CONTAINER]
# 關閉所有正在執行的容器
$ docker kill $(docker ps -q)
# 移除所有停止的容器
$ docker rm $(docker ps -a -q)
# 根據狀態移除
$ docker rm $(docker ps -q -f 'status=exited')
# 根據標簽移除
$ docker rm $(docker ps -a | grep rabbitmq | awk '{print $1}')
$ docker rm $(docker ps -a | grep "46 hours ago")
-
docker cp 在容器和本地檔案系統之間複製檔案或檔案夾。
-
docker export 將容器的檔案系統切換為壓縮包(tarball archive stream)輸出到 STDOUT。
$ docker stats redis1 redis2
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
redis1 0.07% 796 KB / 64 MB 1.21% 788 B / 648 B 3.568 MB / 512 KB
$ docker run -it -m 300M ubuntu:14.04 /bin/bash
# 指定容器可佔用的 CPU 核編號,0-3 表示佔用四個核,1、3 表示佔用兩個核
$ docker run -it --cpuset-cpus="1,3" ubuntu /bin/bash
# 最多允許佔用單 CPU 50% 的計算資源,如果雙核 CPU,則可以設定為 1.5 等
$ docker run -it --cpus=".5" ubuntu /bin/bash
# 不同的值能夠指定不同的容器權重,用於動態分配 CPU 資源
$ docker run -it --cpu-shares="512" ubuntu /bin/bash
# 限制單個容器最多佔用 20G 空間,將應用於任何新建容器。
$ --storage-opt dm.basesize=20G
$ btrfs qgroup limit -e 50G /var/lib/docker/btrfs/subvolumes/<CONTAINER_ID>
docker run -it --device=/dev/ttyUSB0 debian bash
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
-
資料捲可以在容器之間共享和重用
-
對資料捲的修改會立馬生效
-
對資料捲的更新,不會影響映象
-
捲會一直存在,直到沒有容器使用
-
資料捲的使用,類似於 Linux 下對目錄或檔案進行 mount
# the following creates a tmpfs volume called foo with a size of 100 megabyte and uid of 1000.
$ docker volume create --driver local \
--opt type=tmpfs \
--opt device=tmpfs \
--opt o=size=100m,uid=1000 \
foo
$ docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.1.1,rw \
--opt device=:/path/to/dir \
foo
$ docker run -d \
-it \
--name devtest \
-v myvol2:/app \
nginx:latest
"Mounts": [
{
"Type": "volume",
"Name": "myvol2",
"Source": "/var/lib/docker/volumes/myvol2/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
# 掛載目錄
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
# 掛載檔案
$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
# Docker 掛載資料捲的預設許可權是讀寫,使用者也可以透過 `:ro` 指定為只讀。
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro
training/webapp python app.py
VOLUME /data
-
bridge:預設的網路驅動,常用於多個應用執行與獨立容器中並且需要相互通訊的時候。
-
host:移除容器與 Docker 主機之間的網路隔離,直接使用宿主機所在的網路。底層與宿主機共用一個 Network Namespace,容器將不會虛擬出自己的網絡卡,配置自己的 IP 等,而是使用宿主機的 IP 和埠。
-
Overlay:Overlay 網路用語連線多個 Docker Daemon,保證 Docker Swarm 服務的正常執行;獨立的容器與 Swarm 服務,或者不同宿主機上的容器同樣能夠透過 Overlay 進行通訊。
-
none:對於指定容器禁止所有的網路通訊。
-
Macvlan:Macvlan 網路會允許直接為容器分配 MAC 地址,使其作為真正的物理裝置接入到宿主機所在的網路中。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
f707aa0ef50d bridge bridge local
97dd7a032d96 host host local
d5a1bed0b12d none null local
# 建立新的網路
$ docker network create --driver bridge isolated
# 指定網段,宿主機會作為預設閘道器
$ docker network create --driver=bridge --subnet=192.168.2.0/24 --gateway=192.168.2.10 new_subnet
# 建立時將某個容器連線到網路
$ docker run --network=isolated -itd --name=docker-nginx nginx
# 將某個執行中容器連線到某個網路
$ docker network connect multi-host-network container1
-
-h HOSTNAME or –hostname=HOSTNAME 設定容器的主機名,它會被寫到容器內的 /etc/hostname 和 /etc/hosts 。但它在容器外部看不到,既不會在 docker ps 中顯示,也不會在其他的容器的 /etc/hosts 看到。
-
–link=CONTAINER_NAME:ALIAS 選項會在建立容器的時候,新增一個其他容器的主機名到 /etc/hosts 檔案中,讓新容器的行程可以使用主機名 ALIAS 就可以連線它。
-
–dns=IP_ADDRESS 新增 DNS 伺服器到容器的 /etc/resolv.conf 中,讓容器用這個伺服器來解析所有不在 /etc/hosts 中的主機名。
-
–dns-search=DOMAIN 設定容器的搜尋域,當設定搜尋域為 .example.com 時,在搜尋一個名為 host 的 主機時,DNS 不僅搜尋 host,還會搜尋 host.example.com 。 註意:如果沒有上述最後 2 個選項, Docker 會預設用主機上的 /etc/resolv.conf 來配置容器。
# 檢視當前目錄下的檔案空間佔用
$ du -h --max-depth=1 | sort
# 空間佔用總體分析
$ docker system df
# 輸出空間佔用細節
$ docker system df -v
# 輸出容器的空間佔用
$ docker ps -s
# 一併清除所有未使用的映象和懸空映象
$ docker system prune --all
# 列舉懸空映象
$ docker images -f dangling=true
# 刪除全部懸空映象
$ docker image prune
# 刪除所有未被使用的映象
$ docker image prune -a
# 刪除指定樣式的映象
$ docker images -a | grep "pattern" | awk '{print $3}' | xargs docker rmi
# 刪除全部映象
$ docker rmi $(docker images -a -q)
# 刪除全部停止的容器
$ docker rm $(docker ps -a -f status=exited -q)
# 根據指定樣式刪除容器
$ docker rm $(docker ps -a -f status=exited -f status=created -q)
$ docker rm $(docker ps -a | grep rabbitmq | awk '{print $1}')
# 刪除全部容器
$ docker stop $(docker ps -a -q)
$ docker rm $(docker ps -a -q)
# 列舉並刪除未被使用的捲
$ docker volume ls -f dangling=true
$ docker volume prune
# 根據指定的樣式刪除捲
$ docker volume prune --filter "label!=keep"
# 刪除未被關聯的網路
$ docker network prune
$ docker network prune --filter "until=24h"
複製程式碼我們也可以手動指定日誌檔案的尺寸或者清空日誌檔案:
# 設定日誌檔案最大尺寸
$ dockerd ... --log-opt max-size=10m --log-opt max-file=3
# 清空當前日誌檔案
truncate -s 0 /var/lib/docker/containers/*/*-json.log
# 指定 Docker Compose 檔案版本
version: '3'
services:
web:
# 指定從本地目錄進行編譯
build: .
# 指定匯出埠
ports:
- '5000:5000'
# 替換預設的 CMD 命令
command: python app.py
# 將本地目錄系結到容器內目錄
volumes:
- .:/code
redis:
# 映象的 ID
image: 'redis:alpine'
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
cache = redis.Redis(host='redis', port=6379)
# 互動式啟動
$ docker-compose up
# 守護行程式啟動
$ docker-compose up -d
# 檢視執行情況
$ docker-compose ps
# 關閉
$ docker-compose stop
# 移除內部捲
$ docker-compose down --volumes
version: "3.2"
services:
web:
image: nginx:alpine
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static
db:
image: postgres:latest
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data"
volumes:
mydata:
dbdata:
# 建立一個新的服務
$ docker service create \
--image nginx \
--replicas 2 \
nginx
# 更新服務
$ docker service update \
--image nginx:alpine \
nginx
# 刪除服務
$ docker service rm nginx
# 縮容,而不是直接刪除服務
$ docker service scale nginx=0
# 擴容
$ docker service scale nginx=5
# 列出所有的服務
$ docker service ls
# 列出一個服務的所有實體(包括服務的健康狀況)
$ docker service ps nginx
# 服務的詳細資訊
$ docker service inspect nginx
$ docker stack deploy application
version: '3'
services:
web:
image: registry.gitlab.com/example/example # you need to use external image
command: npm run prod
ports:
- 80:80
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
-
https://github.com/wxyyxc1992/Awesome-Links/blob/master/Infrastructure/Virtualization/Container/Docker/Docker-Links.md
-
https://github.com/wxyyxc1992/Awesome-CheatSheet/blob/master/Infrastructure/OS/Linux/Linux-Commands-CheatSheet.md
-
https://github.com/wxyyxc1992/Backend-Boilerplate/tree/master/infra/docker
-
https://mirrors.ustc.edu.cn/help/docker-ce.html
-
https://docs.docker.com/config/containers/multi-service_container/