虛擬化容器技術:Docker
一、簡介
二、安裝Docker
在ubuntu下安裝docker非常簡單,只需要一條命令即可
sudo apt update
sudo apt install -y docker.io
apt安裝的已經自動設置爲開機自啓
在centos7中使用可以使用以下命令
sudo yum update
sudo yum install –y docker
sudo systemctl enable docker
sudo systemctl start docker
由於在linux下我們一般不是使用root賬號登錄,運行docker會有權限問題,需要對當前用戶賦予docker的權限
sudo groupadd docker #創建docker用戶組
sudo gpasswd -a $USER docker #將當前用戶加入docker用戶組
newgrp docker #更新用戶組權限
sudo service docker restart #重啓docker服務 使用 sudo systemctl restart docker 亦可
docker ps #測試用戶是否可以使用
國內使用docker鏡像下載資源會非常慢,需要使用阿里雲的鏡像源。首先打開阿里雲鏡像加速器 https://cr.console.aliyun.com/cn-qingdao/instances/mirrors ,獲取自己的加速器地址,然後按照上面提示修改 /etc/docker/daemon.json文件。
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
#這裏替換成自己的加速器地址,因爲這也是一個私服地址,每個人都是不同的
}
配置完成後記得重啓一下docker
sudo systemctl daemon-reload
sudo systemctl restart docker
三、Docker的基本使用
在docker中,有三個核心的概念:鏡像(Image)、容器(Container)和倉庫(Repository)。這三個部分組成了docker的整個生命週期。如下圖顯示,容器由鏡像實例化而來(docker run),鏡像可以提交到倉庫保存(docker push),倉庫提供鏡像給docker拉取(docker pull),運行的容器可以提交爲鏡像。
3.1 鏡像
Docker鏡像(Image)是一個文件系統,包含了我們運行程序所需的代碼、依賴、環境配置、系統內核等。
玩過VMware的應該都知道,我們在安裝虛擬機之前需要準備一個系統鏡像iso文件,docker中的鏡像也類似於虛擬機中的鏡像文件,是容器實例的“模版”。
3.1.1 搜索倉庫中的鏡像
例如要搜索Tomcat,輸入以下命令,就可以得到相關結果
docker search tomcat
不過在命令行中搜索鏡像使用起來不是很方便,我建議還是使用docker官方倉庫網站https://hub.docker.com/來搜索。
3.1.2 查看本地所有鏡像
docker images
3.2 容器
Docker容器(Container)是由鏡像實例化出來的一個“子系統”,包括了root用戶權限、進程空間、用戶空間和網絡空間,它類似於一個沙盤,容器之間互相隔離,互不影響。
容器的生命週期包括創建、啓動、暫停、停止、重啓、刪除。需要注意的是,容器一旦被刪除,裏面的數據也會隨之消失。如果要保存其中數據,可以通過容器數據卷或者提交容器成爲鏡像來實現。生命週期如下圖所示:
3.2.1 創建容器
創建一個狀態爲“創建”的容器,但並沒有被啓動。
docker create --name my-redis -p 6379:6379 redis:3.2
語法格式爲 docker create [可選參數] 鏡像名稱:鏡像tag 其中鏡像tag可以省略,如果省略,則使用默認的latest
–name 指定這個容器的名稱
-p 指定端口映射,用於在外部訪問容器 格式爲: 主機端口:容器內端口
3.2.2 查看容器
可以看到一個status爲Created名字爲my-redis的容器,這裏就不展示了,自己去實踐一下。
docker ps -a
輸入docker ps --help
查看docker ps
命令的可用參數
-a 顯示所有容器(包括剛創建、已經停止的等),不帶此參數只顯示運行中的
-q 只返回容器id,可用於對容器操作場景
3.2.3 啓動容器
剛剛創建一個“創建”狀態的容器,並沒有啓動,現在我們來啓動它,然後再docker ps
查看my-redis的status已經變成up。
docker start my-redis #通過容器名稱或者容器ID啓動容器
3.2.4 創建並啓動容器
最開始學docker時候就接觸的這條命令,也是最常用的命令之一
docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
-d 後臺運行
-e 指定容器的環境變量,這裏的mysql鏡像通過這個環境變量設置root的密碼,具體看鏡像介紹-v 掛載容器數據卷,將容器內數據保存到宿主機,例:-v /data:/data 宿主機路徑:容器內路徑
–add-host 給容器添加host
-it 交互方式進入
3.2.5 停止容器
docker stop my-redis #對容器的操作都可以通過名字或者ID
3.2.6 重啓容器
docker restart my-redis
3.2.7 刪除容器
docker rm my-redis
3.2.8 顯示容器內正在運行的進程
docker top mysql
3.3 倉庫
Docker倉庫(Repository)是集中存放鏡像文件的地方,倉庫中可以保存不同的鏡像,不同版本的同種鏡像。目前,最大的公開倉庫就是docker官方倉庫https://hub.docker.com/,可以在上面註冊賬號並推送自己的鏡像上去。如果用戶不希望自己的鏡像公開分享,可以在本地創建私有註冊服務器來創建一個本地倉庫。此外,阿里雲也提供了個人的私服,就是上面提到的那個阿里雲加速器,具體參照阿里雲加速器文檔。
3.3.1 創建本地私服
docker run -d -v /data/docker-registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:2
-d表示後臺運行
-v掛載容器數據卷,作數據持久化
-p開放端口映射,可以在宿主機訪問
–restart=always設置docker啓動時候就啓動這個容器,即開機自啓
在多機公用一個私服的時候,建議添加一個host來配置私服
修改/etc/hosts
文件 添加一行
192.168.149.133 docker-registry #此處ip修改爲自己的局域網ip
在所有使用這個私服的機子中,修改/etc/docker/daemon.json
文件,添加私服地址
"insecure-registries":["docker-registry:5000"]
3.3.2 推送到倉庫
創建一個鏡像並推送到私服中,這裏使用busybox做演示,並未真正“創建”一個新的鏡像,只是修改Tag
docker pull busybox
docker tag busybox:latest docker-registry:5000/zhanjixun/my-busybox:1.0
docker push docker-registry:5000/zhanjixun/my-busybox:1.0
語法格式:docker push 鏡像ID/鏡像名稱 私服名稱:私服端口/用戶名/推入鏡像名稱:鏡像版本標籤
如果是推送到docker hub官方倉庫,則可以省略 私服名稱:私服端口
四、進一步使用
容器通常都是運行一些中間件或者我們的代碼項目的,前面介紹瞭如何運行啓動容器。那麼,一旦容器運行起來,我們如何控制和管理容器呢?比如如何查看容器運行日誌,如何在容器內執行命令。下面介紹
4.1 查看容器日誌
這裏查看的只是容器內控制檯的輸出內容,如果一些日誌是打印在文件裏面的,還需要去文件內查看。
docker logs -ft --tail=1000 容器名稱/容器ID
-f 表示跟蹤日誌輸出
-t 顯示時間戳
–tail 末尾n行
4.2 在容器內執行命令
容器相當於一個“子系統”,那麼如果想要在其中運行命令行該如何操作呢,請看以下代碼
docker exec my-redis date
docker exec mysql ls /
docker exec -it my-redis /bin/bash
exec指令是在容器內執行命令的用法 格式 docker exec 容器名稱/容器ID 執行的命令
-it 表示以交互方式進入容器 /bin/bash是shell解析器 有些容器的解析器是/bin/sh
進入容器後終端的命令行就變成了容器的終端了,輸入命令即可操作容器,輸入exit退出交互
4.3 安裝可視化界面Portainer
容器在docker中運行,經常需要對其管理,總是面對命令行終端顯得有點枯燥。爲了更好更方便的管理和使用docker,使用可視化的管理工具似乎更符合人的習慣。下面演示如何在docker中安裝portainer。
docker run -d --name portainer -p 9000:9000 --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /data/portainer:/data portainer/portainer:latest
/var/run/docker.sock掛載這個數據卷是因爲要在容器內部訪問docker
portainer的數據都存放在/data目錄下,容器數據卷我選擇掛載到/data/portainer下,做數據持久化
安裝完後,瀏覽器打開地址 http://localhost:9000 按照提示設置密碼,docker選擇Local的就行了。
在左邊菜單欄,看到Stacks、Containers、Images、Networks和Volumes,每個功能可以自己點一下,玩幾下就熟悉了。
五、使用Dockerfile自定義鏡像
六、Docker三劍客之一:Docker Compose
在前面的介紹中,對容器的操作都是單個的,但是在現實的項目中,尤其是分佈式或微服務的項目,我們通常都是要啓動很多個容器的,如果每一個容器都要手動啓動停止,那管理效率之低,維護成本之高可想而知了。
在這種情況下,使用Docker Compose可以輕鬆、高效的管理容器,它是基於docker api開發的用來定義一組容器(服務)的應用工具。
Docker Compose並不是docker官方提供的工具,但是也是一個優秀的工具,它使用python開發,要享受Docker Compose帶來的便利,需要額外安裝它。
6.1 安裝Docker Compose
sudo apt install docker-compose
6.2 Docker Compose語法
在Docker Compose中,使用docker-compose.yml
文件定義一組服務。先看一個例子
version: "3"
services:
db-mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=123456
6.3 使用Docker Compose部署Dubbo分佈式項目
七、Docker三劍客之一:Docker Swarm
Docker Swarm是一個Docker的編排工具,前面介紹的Docker Compose是用來編排容器的,這裏Docker Swarm用來管理Docker集羣,其主要的作用就是把若干臺Docker主機抽象成一個整體,通過統一的管理調配Docker主機上的Docker資源。參考官網:https://docs.docker.com/engine/swarm/
7.1 Docker Swarm集羣搭建
Docker Swarm通過Docker API把各個Docker主機連接起來,被連接的某個主機成爲節點。按節點角色分,可分爲管理節點(manger)和工作節點(worker)。下面通過2臺ubuntu Docker環境演示如何搭建集羣,基本信息如下:
ubuntu-manger 192.168.197.128
ubuntu-worker 192.168.197.131
首先需要設置各個節點的主機名稱,並確定ip地址
hostnamectl set-hostname ubuntu-manger #在管理節點運行
hostnamectl set-hostname ubuntu-worker #在工作節點運行
hostnamectl #查看主機名稱
7.1.1 初始化管理節點
docker swarm init
Swarm initialized: current node (s750sab8tte49cksp16pk5ptr) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-41x7s99e8ojwizkqrqpjq1l314aba59zk3ye1lliquyfurizc9-9ipi8elm1nklpi6j70ut0o51m 192.168.197.128:2377
To add a manager to this swarm, run ‘docker swarm join-token manager’ and follow the instructions.
按照上面提示,將中間的命令複製到工作節點執行則可加入集羣。如果不小心忘記了加入集羣的命令可以通過以下命令查看。
docker swarm join-token worker #查看以工作節點角色加入的命令
docker swarm join-token manager #查看以管理節點角色加入的命令
7.1.2 查看集羣所有節點
docker node ls
ID | HOSTNAME | STATUS | AVAILABILITY | MANAGER STATUS | ENGINE VERSION |
---|---|---|---|---|---|
s750sab8tte49cksp16pk5ptr * | ubuntu-manger | Ready | Active | Leader | 18.09.7 |
9vlcp6tk40kjwdn2zw9xsmj4h | ubuntu-worker | Ready | Active | 18.09.7 |
7.1.3 在集羣中運行服務
7.1.4 集羣下安裝可視化界面Portainer
docker service create \
--replicas 1 \
--name portainer \
--publish 9000:9000 \
--constraint 'node.role == manager' \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
--mount type=bind,src=/data/portainer,dst=/data \
portainer/portainer:latest
–replicas 表示運行的服務個數,可以動態修改進行縮擴容
–publish 9000:9000 端口映射,在swarm中部署的服務,在所有的節點機器上的端口都可以映射上,如訪問的節點不是具體運行的節點,會轉發到具體運行的節點
–mount 綁定數據卷