Docker 介紹
參考:爲什麼需要Docker?
Docker 是一個開源的應用容器引擎,基於 Go 語言並遵從 Apache2.0 協議開源。
主要應用場景如下:
-
環境隔離
容器間環境相互獨立,互不影響。類似於虛擬機,但相比於更輕量。Docker 各個容器共享一個操作系統內核,而每一個虛擬機都有一套完整的操作系統。
-
整體部署
可以將一整套環境構建爲鏡像,進行整體部署,避免線上線下開發環境帶來的各種問題,同時也極大地提高了部署效率,不再需要重複配置開發環境。
Docker 架構
Docker 的三個重要概念:
-
鏡像(Image)
相當於一個操作系統模板,比如官方鏡像 mysql 就包含了一套完整的操作系統。
-
容器(Container)
容器是鏡像運行的實體,好比於 Java 中對象是類的實例。容器可以被創建、啓動、暫停和停止等。
-
倉庫(Repository)
保存鏡像的倉庫,好比於 Maven 倉庫用來保存依賴的 Jar 包。
Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程 API 來管理和創建 Docker 容器。
-
Docker_Client
通過命令行與 Docker daemon(守護進程)通信。
-
Docker_Host
用於執行 Docker daemon 的主機。
-
Registry
Docker 倉庫,一個 Registry 可以包含多個 Repository 倉庫。
Docker 安裝
CentOS
卸載舊版本(如果存在)
yum remove docker docker-common docker-selinux docker-engine
安裝依賴軟件包
yum install -y yum-utils device-mapper-persistent-data lvm2
設置 yum 源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安裝 Docker
yum install -y docker-ce docker-ce-cli containerd.io
可能由於版本原因提示 requires containerd.io >= 1.2.2-3,先手動安裝新版 containerd.io:
wget https://download.docker.com/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm
yum -y install containerd.io-1.2.6-3.3.el7.x86_64.rpm
然後重新執行 Docker 安裝命令即可。
啓動並加入開機啓動
systemctl start docker && systemctl enable docker
驗證
docker version
鏡像加速
運行 bash 命令;
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
然後重啓 docker 服務;
systemctl daemon-reload && systemctl restart docker
遠程訪問
修改 docker 服務腳本:
vi /lib/systemd/system/docker.service
在 ExecStart=/usr/bin/dockerd
這一行的後面添加:
-H tcp://0.0.0.0:2375
然後重啓 docker 服務:
systemctl daemon-reload && systemctl restart docker
驗證操作結果:
curl http://localhost:2375/version
遠程訪問(TLS)
上述開放遠程訪問存在極大的安全隱患,沒有認證授權,可採用 TLS 認證完善;
#創建 Docker TLS 證書
#!/bin/bash
#相關配置信息
SERVER="106.13.180.17"
PASSWORD="123456"
COUNTRY="CN"
STATE="湖北省"
CITY="武漢市"
ORGANIZATION="公司名稱"
ORGANIZATIONAL_UNIT="Dev"
EMAIL="[email protected]"
###開始生成文件###
echo "開始生成文件"
#切換到生產密鑰的目錄
cd /etc/docker
#生成ca私鑰(使用aes256加密)
openssl genrsa -aes256 -passout pass:$PASSWORD -out ca-key.pem 2048
#生成ca證書,填寫配置信息
openssl req -new -x509 -passin "pass:$PASSWORD" -days 3650 -key ca-key.pem -sha256 -out ca.pem -subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORGANIZATION/OU=$ORGANIZATIONAL_UNIT/CN=$SERVER/emailAddress=$EMAIL"
echo "subjectAltName = IP:$SERVER" >> extfile.cnf
echo "extendedKeyUsage = serverAuth" >> extfile.cnf
#生成server證書私鑰文件
openssl genrsa -out server-key.pem 2048
#生成server證書請求文件
openssl req -subj "/CN=$SERVER" -new -key server-key.pem -out server.csr
#使用CA證書及CA密鑰以及上面的server證書請求文件進行簽發,生成server自簽證書
openssl x509 -req -days 3650 -in server.csr -CA ca.pem -CAkey ca-key.pem -passin "pass:$PASSWORD" -CAcreateserial -out server-cert.pem -extfile extfile.cnf
#生成client證書RSA私鑰文件
openssl genrsa -out key.pem 2048
#生成client證書請求文件
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
echo "extendedKeyUsage=clientAuth" > extfile.cnf
#生成client自簽證書(根據上面的client私鑰文件、client證書請求文件生成)
openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca-key.pem -passin "pass:$PASSWORD" -CAcreateserial -out cert.pem -extfile extfile.cnf
#更改密鑰權限
chmod 0400 ca-key.pem key.pem server-key.pem
#更改密鑰權限
chmod 0444 ca.pem server-cert.pem cert.pem
#刪除無用文件
rm client.csr server.csr
echo "生成文件完成"
###生成結束###
同時修改 docker 服務腳本:
vi /lib/systemd/system/docker.service
修改ExecStart=/usr/bin/dockerd
這一行爲:
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock \
--tlsverify \
--tlscacert=/etc/docker/ca.pem \
--tlscert=/etc/docker/server-cert.pem \
--tlskey=/etc/docker/server-key.pem \
-H tcp://0.0.0.0:2376
重啓 docker;
systemctl daemon-reload && systemctl restart docker
連接驗證;
docker --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/cert.pem --tlskey=/etc/docker/key.pem -H tcp://106.13.180.17:2376 version
注意服務 IP 填寫自己對應的主機 IP。
Hello World
docker run hello-world
運行 hello-world 鏡像,先在本地主機查找,不存在則從鏡像倉庫中拉取。
[root@localhost ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
常用命令
參考:Docker 命令大全
docker run ubuntu:15.10 /bin/echo "Hello world"
運行一個 ubuntu 容器,版本號爲 15.10,並執行 /bin/echo “hello world”。
docker exec -it centos /bin/bash
進入一個 name 爲 centos 的容器,並且跳轉到該容器 bash 終端。
可選項
-
-i
交互式操作,通常和 -t 組合使用;
-
-t
在新容器內指定一個僞終端;
-
-d
後臺運行;
-
-e
設置環境變量;
-
-p
端口映射,
主機端口:容器端口
;
容器
-
ps
獲取容器列表;
-
run
指定鏡像運行一個容器;
-
start/stop/restart
啓動、停止或重啓一個容器;
-
rm
刪除容器;
-
exec
在容器內執行命令;
-
logs
獲取容器內的日誌;
鏡像
-
images
獲取本地鏡像列表;
-
rmi
刪除本地鏡像;
部分 <none>:<none> 的鏡像沒有任何引用,可以通過 docker rmi $(docker images -f “dangling=true” -q) 清除。
實踐
時間同步
通常宿主機和 docker 容器機器時間不一致,可採取外部掛載解決;
-v /etc/localtime:/etc/localtime:ro
MySQL 安裝
安裝
創建一個 mysql 容器,映射本機端口 3306 至容器,並初始化密碼爲 123456;
docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
數據持久化
每次重新創建 mysql 容器相關數據會被初始化,可以通過 -v 指定掛載路徑;
docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /docker/mysql/data:/var/lib/mysql mysql
添加遠程用戶
進入 mysql 容器 bash 終端交互;
docker exec -it mysql /bin/bash
連接 mysql 服務;
mysql -uroot -p123456
執行下面 SQL;
create user 'caojiantao'@'%' identified with mysql_native_password by '123456';
grant all privileges on *.* to 'caojiantao'@'%' with grant option;
flush privileges;
SpringBoot 部署(Idea)
Docker 連接
如果 docker 遠程連接採用 TLS 連接,那麼首先將服務器的ca.pem
、cert.pem
和key.pem
三個文件下載到本地D:\docker
目錄,然後如圖設置 docker 連接;
Dockerfile
新建 Dockerfile 文件,用來構建鏡像,放在項目的根目錄;
FROM java:8
ADD "/target/docker-0.0.1-SNAPSHOT.jar" "app.jar"
EXPOSE 8080
ENTRYPOINT [ "java", "-jar", "app.jar" ]
鏡像部署
增加鏡像部署配置,注意最底部 Maven 命令,clean package -DskipTests,用來生成構建鏡像需要的 jar 包;
外部掛載
通常需要掛載“項目配置”、“靜態資源”和“服務日誌”幾個目錄,通過 idea 也能很方便的操作,通過上圖中的Bind mounts
設置;