環(huán)境
Ubuntu16.04
安裝Docker CE
若之前安裝過老版本的docker
澈蚌,先卸載
sudo apt-get remove docker docker-engine docker.io containerd runc
1.更新apt
包索引
sudo apt-get update
2.安裝軟件包支持apt
使用基于Https的倉庫
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
3.添加Docker官方的GPG key
# 官方
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 中科大鏡像
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
驗證key
sudo apt-key fingerprint 0EBFCD88
4.添加Docker倉庫
# 官方
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 中科大 速度快一點
sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) \
stable"
5.更新apt
包索引
sudo apt-get update
6.安裝最新的Docker CE
sudo apt-get install docker-ce docker-ce-cli containerd.io
查看版本信息
查看Docker版本
docker --version
Docker version 18.09.3, build 774a1f4
查看更多Docker信息,docker version 或者 docker info廓脆,這里使用sudo
进萄,否則會出現(xiàn)權(quán)限錯誤
$ sudo docker info
一般使用docker命令得加上sudo
捻脖,為了避免出現(xiàn)權(quán)限錯誤 ,設(shè)置把用戶加入到docker組中 Read more.
創(chuàng)建docker用戶組中鼠,可能會提示已經(jīng)存在
sudo groupadd docker
把用戶添加到docker用戶組
sudo usermod -aG docker $USER
登出賬號
logout
然后重新登錄可婶,現(xiàn)在不加sudo
也可以使用
docker info
測試
通過運行一個簡單的image
來測試Docker
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/library/hello-world/manifests/latest: Get https://auth.docker.io/token?scope=repository%3Alibrary%2Fhello-world%3Apull&service=registry.docker.io: net/http: request canceled (Client.Timeout exceeded while awaiting headers).
See 'docker run --help'.
錯誤解決:
打開/etc/docker/daemon.json
,如果不存在創(chuàng)建文件援雇,添加內(nèi)容
{
"registry-mirrors": [
"http://141e5461.m.daocloud.io"
]
}
重啟Docker服務(wù)
sudo service docker restart
再次運行
$ docker run hello-world
查看下載的image
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 2 months ago 1.84kB
列出所有的容器矛渴,不加--all
默認列出仍在運行的容器,hello-world
輸出語句后就結(jié)束了熊杨,因此不加--all
就看不到hello-world
容器
docker container ls --all
Containers
簡單來說曙旭,Container
就是包含運行環(huán)境,代碼晶府,以及構(gòu)建運行命令的容器桂躏,他和傳統(tǒng)運行程序的區(qū)別就是環(huán)境不隨宿主機的環(huán)境變化,自己擁有自己的一套運行環(huán)境川陆,環(huán)境變量剂习,可以通過端口與宿主機交流信息。下面示例構(gòu)建了一個容器:
在新建文件夾下较沪,添加三個文件
Dockerfile
# 程序運行需要的環(huán)境鳞绕,也是一個鏡像
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# 需要運行的命令,這里使用pip安裝需要的模塊
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 暴露80端口
# Make port 80 available to the world outside this container
EXPOSE 80
# 定義環(huán)境變量
# Define environment variable
ENV NAME World
# 當(dāng)容器運行的時候執(zhí)行的命令
# Run app.py when the container launches
CMD ["python", "app.py"]
requirements.txt
Flask
Redis
app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
構(gòu)建應(yīng)用
當(dāng)前的目錄結(jié)構(gòu)
$ ls
Dockerfile app.py requirements.txt
--tag
設(shè)置鏡像的名字尸曼,可以使用-t
代替
docker build --tag=friendlyhello
查看鏡像们何,這里顯示了所有本地鏡像,包括剛構(gòu)建的以及從遠程倉庫下載的
$ docker image ls
運行應(yīng)用
$ docker run -p 4000:80 friendlyhello
-p 4000:80
將宿主機的4000端口映射到容器的80端口
訪問http://宿主機IP:4000
[圖片上傳失敗...(image-41cadb-1582005529611)]
在終端按CTRL+C
停止容器
在后臺運行app
$ docker run -d -p 4000:80 friendlyhello
d5d06d6b7efc6c9e8e2e730ee0139c78200951743df80afd0ce2bc604da917a1
d5d06d6b7efc6c9e8e2e730ee0139c78200951743df80afd0ce2bc604da917a1
是容器ID控轿,每個運行的容器實例都有一個ID
查看運行的容器
$ youthful_mirzakhani
停止運行app
docker container stop d5d06d6b7efc
或者
docker container stop youthful_mirzakhani
youthful_mirzakhani
是實例的NAMES
屬性
分享鏡像
使用官方Registry非常慢冤竹,這里只是學(xué)習(xí)一下拂封,建議使用其他Registry 阿里云容器鏡像服務(wù)的基本使用
Docker支持將鏡像上傳到一個類似Github
和Maven
的公共倉庫,需要在 hub.docker.com 注冊賬號
登錄Docker賬號
$ docker login
為鏡像打標(biāo)簽
格式
$ docker tag image username/repository:tag
例如
$ docker tag friendlyhello vczyh/get-started:part2
$ docker image ls
發(fā)布鏡像
$ docker push username/repository:tag
拉取鏡像并運行
$ docker run -p 4000:80 username/repository:tag
Services
在分布式應(yīng)用中鹦蠕,不同的部分被稱為服務(wù)冒签。比如,你想做一個視頻分享網(wǎng)站钟病,網(wǎng)站可能包括存儲服務(wù)萧恕,用戶上傳視頻后的轉(zhuǎn)碼服務(wù),前臺服務(wù)等肠阱。
服務(wù)實際上只是生產(chǎn)中的容器票唆,一個服務(wù)僅運行一個鏡像,但它通過編碼決定了鏡像的運行方式——使用的端口辖所,運行副本的數(shù)量惰说,便于容器擁有它所需要的容量等。拓展服務(wù)改變了運行軟件的容器實例數(shù)量缘回,從而為進程中的服務(wù)分配更多的資源吆视。
幸運的是,使用Docker平臺定義酥宴、運行和擴展服務(wù)非常容易——只需編寫一個docker-compose.yml
文件啦吧。
docker-compose.yml
文件是一個YAML文件,它定義Docker容器在生產(chǎn)環(huán)境中的行為拙寡。
docker-compose.yml
version: "3"
services:
# 定義一個叫web的服務(wù)
web:
# 鏡像授滓,本地或者遠程
# replace username/repo:tag with your name and image details
# image: username/repo:tag
image: registry.cn-hangzhou.aliyuncs.com/zhangyuheng/hello
deploy:
# 包含5個副本
replicas: 5
resources:
limits:
# 每個副本最多使用10%的CPU
cpus: "0.1"
# 每個副本最多使用50M內(nèi)存空間
memory: 50M
restart_policy:
# 如果有任何一個失敗,則立即重啟
condition: on-failure
ports:
# 將主機4000端口映射到web服務(wù)的80端口
- "4000:80"
networks:
# 指示web容器通過稱為webnet的負載均衡網(wǎng)絡(luò)共享80端口(在內(nèi)部肆糕,容器本身在一個臨時端口上發(fā)布到web的80端口般堆。)
- webnet
networks:
# 使用默認設(shè)置定義webnet網(wǎng)絡(luò)(一個負載均衡的覆蓋網(wǎng)絡(luò))。
webnet:
運行你的負載均衡應(yīng)用
首先先運行:
$ docker swarm init
getstartedlab
是app的名字:
$ docker stack deploy -c docker-compose.yml getstartedlab
Creating network getstartedlab_webnet
Creating service getstartedlab_web
現(xiàn)在單個服務(wù)堆棧在一臺主機上運行了5個已部署鏡像的實例
查看服務(wù):
$ docker service ls
也可以這樣查看服務(wù):
$ docker stack services getstartedlab
服務(wù)中運行的單個容器稱為任務(wù)诚啃。任務(wù)被賦予惟一的id淮摔,這些id在數(shù)字上遞增,直到您在docker-comp.yml
中定義的副本的數(shù)量始赎。
列出你的服務(wù)任務(wù):
$ docker service ps getstartedlab_web
也可以通過查看容器來查看任務(wù):-q
僅僅列出容器ID
$ docker container ls
瀏覽器多次訪問:http://localhost:4000
或者多次輸入:
$ curl -4 http://localhost:4000
可以看到顯示的Hostname(容器ID)每次都不一樣和橙,也驗證了輪詢方式的負載均衡
顯示一個stack的所有任務(wù):
$ docker stack ps getstartedlab
拓展應(yīng)用
可以通過改變replicas
的值來拓展應(yīng)用:
docker-compose.yml
deploy:
# 包含5個副本
replicas: 7
$ docker stack deploy -c docker-compose.yml getstartedlab
Docker更新服務(wù)不需要關(guān)掉服務(wù)或者關(guān)掉任何容器
查看目前的容器和任務(wù):
$ docker stack ps getstartedlab
移除應(yīng)用
$ docker stack rm getstartedlab
移除集群
$ docker swarm leave --force
常用命令
docker stack ls # List stacks or apps
docker stack deploy -c <composefile> <appname> # Run the specified Compose file
docker service ls # List running services associated with an app
docker service ps <service> # List tasks associated with an app
docker inspect <task or container> # Inspect task or container
docker container ls -q # List container IDs
docker stack rm <appname> # Tear down an application
docker swarm leave --force # Take down a single node swarm from the manager
Swarms
安裝docker-machine
$ base=https://github.com/docker/machine/releases/download/v0.16.0 &&
curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
sudo install /tmp/docker-machine /usr/local/bin/docker-machine
這個豈止是慢,根本就沒速度造垛,所以采用手動安裝魔招,先去https://github.com/docker/machine/releases/
下載,這里下載也得翻墻==
下載好安裝:
$ sudo install docker-machine-Linux-x86_64 /usr/local/bin/docker-machine
驗證:
$ docker-machine version
docker-machine version 0.16.0, build 702c267f
創(chuàng)建虛擬機集群
安裝virtualbox驅(qū)動:
$ sudo apt install virtualbox
創(chuàng)建名為myvm1
的虛擬機:
$ docker-machine create --driver virtualbox myvm1
Running pre-create checks...
Error with pre-create check: "This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory"
出現(xiàn)錯誤五辽,這里使用的是VMware办斑,解決:
$ docker-machine create --driver virtualbox myvm1
從github下載iso
文件非常慢,采用手動下載杆逗,參考:
把iso
文件放到默認位置:
$ cp boot2docker.iso ~/.docker/machine/cache/
$ docker-machine create --driver virtualbox myvm1
Running pre-create checks...
Creating machine...
(myvm1) Copying /home/vczyh/.docker/machine/cache/boot2docker.iso to /home/vczyh/.docker/machine/machines/myvm1/boot2docker.iso...
(myvm1) Creating VirtualBox VM...
(myvm1) Creating SSH key...
(myvm1) Starting the VM...
(myvm1) Check network to re-create if needed...
(myvm1) Found a new host-only adapter: "vboxnet0"
(myvm1) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env myvm1
同樣乡翅,再創(chuàng)建一個名為myvm2
的虛擬機:
$ docker-machine create --driver virtualbox myvm2
查看虛擬機:
$ docker-machine ls
連接虛擬機
$ docker-machine --native-ssh ssh myvm1
docker@myvm1:~$
初始化swarm以及添加節(jié)點
連接myvm1
后:指定myvm1
為swarm manager
吁讨,192.168.99.100
是myvm1
的IP
docker@myvm1:~$ docker swarm init --advertise-addr 192.168.99.100
CTRL+D
退出連接,連接myvm2
后:設(shè)置myvm2
為swarm worker
docker@myvm2:~$ docker swarm join --token SWMTKN-1
現(xiàn)在一個swarm已經(jīng)創(chuàng)建完成
在swarm manager(myvm1)
中查看所有節(jié)點:
docker@myvm1:~$ docker node ls
另外一種與虛擬機對話方式
$ docker-machine env myvm1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/sam/.docker/machine/machines/myvm1"
export DOCKER_MACHINE_NAME="myvm1"
# Run this command to configure your shell:
# eval $(docker-machine env myvm1)
運行:
eval $(docker-machine env myvm1)
現(xiàn)在實現(xiàn)了和ssh連接myvm1
相同的結(jié)果:
docker node ls
好處之一就是虛擬機可以直接使用宿主機的文件
斷開對話:
eval $(docker-machine env -u)
部署應(yīng)用到swarm
使用eval $(docker-machine env myvm1)
打開與myvm1
的對話
$ docker stack deploy -c docker-compose.yml getstartedlab
如果docker-compose.yml
里使用的鏡像不是Docker Hub
的:
docker login registry.example.com
docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
$ docker stack ps getstartedlab
現(xiàn)在5個實例(容器)已經(jīng)分布在倆個虛擬機中
查看myvm1
的容器:其他的3個實例在myvm2
中
$ docker container ls
測試
宿主機運行:192.168.99.101
是任意一個虛擬機的IP
curl 192.168.99.101:4000
每次訪問的Hostname
不同峦朗,證實了集群的負載均衡
拓展應(yīng)用
第一種:修改docker-compose.yml
第二種:使用docker swarm join
為集群添加機器
這倆種操作之后,重新執(zhí)行docker stack deploy -c docker-compose.yml getstartedlab
關(guān)閉應(yīng)用
關(guān)閉stack
docker stack rm getstartedlab
關(guān)閉swarm
:
docker swarm leave // worker
docker swarm leave --force // manager
常用命令
docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10
docker-machine env myvm1 # View basic information about your node
docker-machine ssh myvm1 "docker node ls" # List the nodes in your swarm
docker-machine ssh myvm1 "docker node inspect <node ID>" # Inspect a node
docker-machine ssh myvm1 "docker swarm join-token -q worker" # View join token
docker-machine ssh myvm1 # Open an SSH session with the VM; type "exit" to end
docker node ls # View nodes in swarm (while logged on to manager)
docker-machine ssh myvm2 "docker swarm leave" # Make the worker leave the swarm
docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm
docker-machine ls # list VMs, asterisk shows which VM this shell is talking to
docker-machine start myvm1 # Start a VM that is currently not running
docker-machine env myvm1 # show environment variables and command for myvm1
eval $(docker-machine env myvm1) # Mac command to connect shell to myvm1
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression # Windows command to connect shell to myvm1
docker stack deploy -c <file> <app> # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file
docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>" # Deploy an app using ssh (you must have first copied the Compose file to myvm1)
eval $(docker-machine env -u) # Disconnect shell from VMs, use native docker
docker-machine stop $(docker-machine ls -q) # Stop all running VMs
docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images
Docker其他配置
鏡像配置
/etc/docker/daemon.json
{
"registry-mirrors": [
"http://141e5461.m.daocloud.io"
]
}
sudo service docker restart
DNS配置
Docker實例里的DNS可能出問題排龄,所以配置Docker使用的DNS
/etc/docker/daemon.json
{
"dns": ["your_dns_address", "8.8.8.8"]
}
sudo service docker restart