Docker學習與實踐 Ⅱ

四、倉庫管理

1.創建本地倉庫

①獲取官方registry鏡像

[root@dockertest ~]# docker run -d -p 5000:5000 --restart=always --name registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
81033e7c1d6a: Pull complete 
b235084c2315: Pull complete 
c692f3a6894b: Pull complete 
ba2177f3a70e: Pull complete 
a8d793620947: Pull complete 
Digest: sha256:672d519d7fd7bbc7a448d17956ebeefe225d5eb27509d8dc5ce67ecb4a0bce54
Status: Downloaded newer image for registry:2
f59d18d8302b6589d5e94f901c1161a48854593cc32ee3259c806bc648c437df

#默認情況下,倉庫會被創建在容器的/var/lib/registry目錄下,可以通過-v將鏡像文件存放在宿主機的指定目錄下。

docker run -d -p 5000:5000 --restart=always \
–v /opt/docker/registry/data:/var/lib/registry --name registry registry:2

② 推送一個鏡像到鏡像倉庫

[root@dockertest ~]# docker tag nginx:latest 192.168.10.131:5000/nginx:latest
[root@dockertest ~]# docker push 192.168.10.131:5000/nginx:latest
The push refers to repository [192.168.10.131:5000/nginx]
Get https://192.168.10.131:5000/v2/: http: server gave HTTP response to HTTPS client

#對於Centos7來說需要配置docker允許https的方式來訪問倉庫,並重啓docker

[root@dockertest ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com"
    ],
"insecure-registries": [
"192.168.10.131:5000"
    ]
}
[root@dockertest ~]# systemctl restart docker.service
[root@dockertest ~]# docker push 192.168.10.131:5000/nginx:latest
The push refers to repository [192.168.10.131:5000/nginx]
e89b70d28795: Pushed 
832a3ae4ac84: Pushed 
014cf8bfcb2d: Pushed 
latest: digest: sha256:600bff7fb36d7992512f8c07abd50aac08db8f17c94e3c83e47d53435a1a6f7c size: 948
[root@dockertest ~]# curl 192.168.10.131:5000/v2/_catalog
{"repositories":["nginx"]}

③刪除本地鏡像,從倉庫重新下載該鏡像

[root@dockertest ~]# docker image rm 192.168.10.131:5000/nginx:latest
[root@dockertest ~]# docker pull 192.168.10.131:5000/nginx:latest
latest: Pulling from nginx
8176e34d5d92: Pull complete 
5b19c1bdd74b: Pull complete 
4e9f6296fa34: Pull complete 
Digest: sha256:600bff7fb36d7992512f8c07abd50aac08db8f17c94e3c83e47d53435a1a6f7c
Status: Downloaded newer image for 192.168.10.131:5000/nginx:latest

2.配置需要證書認證的私有倉庫

①修改/etc/pki/tls/openssl.cnf文件使證書支持IP訪問

[ v3_ca ]
subjectAltName = IP:192.168.10.131

②使用openssl生成證書和密鑰

[root@dockertest registry]# mkdir -p certs 
[root@dockertest registry]# openssl req \
> -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
> -x509 -days 365 -out certs/domain.crt
Generating a 4096 bit RSA private key
...........++
..............................................................................................++
writing new private key to 'certs/domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:192.168.10.131:5000
Email Address []:

③將剛生成的domain.crt複製到/etc/docker/certs.d/192.168.100.9:5000/ca.crt,並重啓docker

[root@dockertest registry]# mkdir -p /etc/docker/certs.d/192.168.100.9:5000
[root@dockertest registry]# cp certs/domain.crt /etc/docker/certs.d/192.168.100.9:5000/ca.crt
[root@dockertest registry]# systemctl restart docker

④運行registry

[root@dockertest registry]# docker run -d -u root -p 5000:5000 \
> --name private_registry  --restart=always \
> -v /opt/docker/registry/data:/var/lib/registry \
> -v /opt/docker/registry/certs:/certs \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
> registry:2
9d145ea538fda7687734a2a170ff21524bc8fc65fee81b2a12c43ef3a43a576a

⑤push一個到registry上

[root@dockertest ~]# docker push 192.168.10.131:5000/nginx
The push refers to repository [192.168.10.131:5000/nginx]
e89b70d28795: Pushed 
832a3ae4ac84: Pushed 
014cf8bfcb2d: Pushed 
latest: digest: sha256:600bff7fb36d7992512f8c07abd50aac08db8f17c94e3c83e47d53435a1a6f7c size: 948

⑥換臺機器下載剛上傳的鏡像

[root@localhost ~]# docker pull 192.168.10.131:5000/nginx
Using default tag: latest
Error response from daemon: Get https://192.168.10.131:5000/v2/: x509: certificate signed by unknown authority

#發現報錯,原因是沒有證書,將192.168.10.131上的證書拷貝到這臺機器爲/etc/docker/certs.d/192.168.10.131:5000/ca.crt,並重啓docker

[root@localhost 192.168.10.131:5000]# docker pull 192.168.10.131:5000/nginx
Using default tag: latest
latest: Pulling from nginx
8176e34d5d92: Pull complete 
5b19c1bdd74b: Pull complete 
4e9f6296fa34: Pull complete 
Digest: sha256:600bff7fb36d7992512f8c07abd50aac08db8f17c94e3c83e47d53435a1a6f7c
Status: Downloaded newer image for 192.168.10.131:5000/nginx:latest

五、數據管理

1.數據卷

①創建一個數據卷

[root@dockertest ~]# docker volume create v1
v1
[root@dockertest ~]# docker volume ls
DRIVER              VOLUME NAME
local               v1

②查看數據卷信息

[root@dockertest ~]# docker volume ls
DRIVER              VOLUME NAME
local               v1
[root@dockertest ~]# docker volume inspect v1
[
    {
        "CreatedAt": "2018-06-04T01:47:39-04:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/v1/_data",
        "Name": "v1",
        "Options": {},
        "Scope": "local"
    }
]

③掛載容器

[root@dockertest ~]# docker run -d -p 80:80 --name web --mount source=v1,target=/webapp nginx
3f315ab9ed576d5f0b72dc9e8c067331e0ef785a9577c2c3c6d2e74ec77e51fd
[root@dockertest ~]# docker exec -it web /bin/bash
root@3f315ab9ed57:/# cd /webapp/
root@3f315ab9ed57:/webapp# touch ss.txt
root@3f315ab9ed57:/webapp# exit
exit
[root@dockertest ~]# ls /var/lib/docker/volumes/v1/_data/
ss.txt

④查看容器信息

[root@dockertest ~]# docker inspect -f "{{.Mounts}}" web 
[{volume v1 /var/lib/docker/volumes/v1/_data /webapp local z true }]

⑤刪除數據卷

[root@dockertest ~]# docker volume rm v1

⑥掛載主機目錄

[root@dockertest ~]# docker run -d -p 80:80 --name web --mount type=bind,source=/dockerdata,target=/webapp  nginx
67f90a8a2c6171bfbfce4c84606f0742adb7e283cdb45b488d47035b7f02871b
#掛載的主機目錄默認權限是讀寫,也可以通過增加readonly來指定爲只讀
[root@dockertest ~]# docker run -d -p 81:80 --name web2 --mount type=bind,source=/dockerdata,target=/webapp,readonly nginx
ced71fc7a97d251bfea388768e3e45cafe3a12680282d820e032d9845c74a1bf
#加上readonly後在容器內/webapp目錄新建文件就會報錯
[root@dockertest ~]# docker exec -it web2 /bin/bash
root@ced71fc7a97d:/# cd webapp/
root@ced71fc7a97d:/webapp# touch ss
touch: cannot touch 'ss': Read-only file system
root@ced71fc7a97d:/webapp# exit
exit

2.數據卷容器

如果用戶需要在容器之間共享一些持續更新的數據,可以採用數據卷容器,數據卷容器其實是一個普通的容器,專門用來提供數據卷供其它容器掛載。
①創建一個數據卷並掛載數據捲到web1

[root@dockertest ~]# docker volume create v1
v1
[root@dockertest ~]# docker run -dit --mount source=v1,target=/tmp/test --name web1 centos
237879201e1c8fedae870af923083625ab8d0fb2b375f66784e1da4179e068c7
[root@dockertest ~]# docker exec -it web1 ls -d /tmp/test
/tmp/test

②創建兩個容器並從web1掛載數據卷

[root@dockertest ~]# docker run -dit --volumes-from web1 --name db1 centos
0b656f36fe24ce835b94d2c891645962e6545e3e18c70bbc6a3e24edbd45f153
[root@dockertest ~]# docker run -dit --volumes-from web1 --name db2 centos   
4468244e0b8b7d6caa57801a2c98d1272c6fdb7d59e89ce704533b53fe969b70
[root@dockertest ~]# docker inspect -f "{{".Mounts"}}" db2
[{volume v1 /var/lib/docker/volumes/v1/_data /tmp/test local  true }]

③分別在web1和db1中新建兩個測試文件

[root@dockertest ~]# docker exec -it web1 touch /tmp/test/web1.txt
[root@dockertest ~]# docker exec -it db1 touch /tmp/test/db1.txt
#在db2和本地主機中查看
[root@dockertest ~]# docker exec -it db2 ls /tmp/test
db1.txt  web1.txt
[root@dockertest ~]# ls /var/lib/docker/volumes/v1/_data/
db1.txt  web1.txt

④使用db2作爲db3的容器數據卷

[root@dockertest ~]# docker run -dit --volumes-from db2 --name db3 centos
7ccd5f862ce125121b2e216c3f312c1921a41df0214a327e957a15bd2041cf07
[root@dockertest ~]# docker exec -it db3 ls /tmp/test
db1.txt  web1.txt

⑤停止web1並查看關聯容器的掛載文件

[root@dockertest ~]# docker stop web1 
web1
[root@dockertest ~]# docker exec -it db3 ls /tmp/test
db1.txt  web1.txt

3.使用數據卷容器遷移數據

①創建數據卷並掛載

[root@dockertest ~]# docker volume create v2
v2
[root@dockertest ~]# docker run -it --mount source=v2,target=/backup --name datamove centos
[root@19de5488667a /]# cd /backup/
[root@19de5488667a backup]# touch {a,b,c,d,ss}
[root@19de5488667a backup]# ls
a  b  c  d  ss

②數據卷的備份

[root@dockertest ~]# docker run --volumes-from datamove -v /dockerdata/:/back --name backup centos tar cvf /back/backup.tar /backup
tar: Removing leading `/' from member names
/backup/
/backup/a
/backup/b
/backup/c
/backup/d
/backup/ss
[root@dockertest ~]# ls /dockerdata/
backup.tar

③創建一個容器savedata還原數據卷

[root@dockertest ~]# docker run --volumes-from datamove -v /dockerdata/:/back --name savedata centos tar xvf /back/backup.tar
backup/
backup/a
backup/b
backup/c
backup/d
backup/ss

④創建一個容器掛載savedata

[root@dockertest ~]# docker run -dit --volumes-from savedata --name savetest centos
faa008b4f18360b0bed3619f740ccc6a326d7e718020347bdb3027750d48ef60
[root@dockertest ~]# docker exec -it savetest ls /backup
a  b  c  d  ss

六、網絡配置

1.端口映射

①一對一映射

[root@dockertest ~]# docker run -dit -p 80:80 --name port1 centos

②多對多映射

[root@dockertest ~]# docker run -dit -p 8088:8088 -p 8080:8080 --name port2 centos

③隨機映射一個端口

[root@dockertest ~]# docker run -dit -p :80 --name port3 centos

④映射UDP端口

[root@dockertest ~]# docker run -dit -p :80/udp --name port4 centos

⑤查看端口映射

[root@dockertest ~]# docker container ls 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                            NAMES
dbdbe92054f2        centos              "/bin/bash"         7 minutes ago       Up 7 minutes        0.0.0.0:32769->80/udp                            port4
3880ae523333        centos              "/bin/bash"         7 minutes ago       Up 7 minutes        0.0.0.0:32769->80/tcp                            port3
8293f668125f        centos              "/bin/bash"         7 minutes ago       Up 7 minutes        0.0.0.0:8080->8080/tcp, 0.0.0.0:8088->8088/tcp   port2
e01160b11472        centos              "/bin/bash"         8 minutes ago       Up 7 minutes        0.0.0.0:80->80/tcp                               port1

2.容器互聯

①新建一個網絡

[root@dockertest ~]# docker network create -d bridge my-net
cf09779c2aac2043c84b98a9728ed597c2dac7e8f67c8946b57dc4b9aa3f7cd2
[root@dockertest ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
da971fe6813b        bridge              bridge              local
eec69c6ab2da        host                host                local
cf09779c2aac        my-net              bridge              local
d2be30ca65ba        none                null                local

②運行一個容器並連接到新建my-net的網絡

[root@dockertest ~]# docker run -it --rm --name web1 --network my-net centos
[root@ac92ecff44e1 /]# 

③打開新的終端,再運行一個容器並加入到my-net網絡

[root@dockertest ~]# docker run -it --rm --name web2 --network my-net centos
[root@a6e5609d4e6f /]# 

④測試連接

[root@a6e5609d4e6f /]# ping web1
PING web1 (172.18.0.2) 56(84) bytes of data.
64 bytes from web1.my-net (172.18.0.2): icmp_seq=1 ttl=64 time=0.102 ms
64 bytes from web1.my-net (172.18.0.2): icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from web1.my-net (172.18.0.2): icmp_seq=3 ttl=64 time=0.053 ms
^C
--- web1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.045/0.066/0.102/0.026 ms
[root@a6e5609d4e6f /]# 

3.配置DNS

①在容器中查看掛載信息

[root@ac92ecff44e1 /]# mount | grep etc
/dev/mapper/centos-root on /etc/resolv.conf type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/centos-root on /etc/hostname type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/centos-root on /etc/hosts type xfs (rw,relatime,attr2,inode64,noquota)
[root@ac92ecff44e1 /]# 

這種機制可以讓宿主主機 DNS 信息發生更新後,所有 Docker容器的DNS配置通過/etc/resolv.conf 文件會得到更新。

②配置全部容器的DNS可以在/etc/docker/daemon.json中增加DNS相關項來設置

{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
#這樣每次啓動容器時容器的DNS會自動配置爲添加的地址
[root@dockertest ~]# docker run -it --rm centos cat etc/resolv.conf
search localdomain
nameserver 114.114.114.114
nameserver 8.8.8.8

③如果想要手動指定容器的配置,可以在使用 docker run 命令啓動容器時加入如下參數:
-h 設定容器的主機名,它會被寫到容器內的/etc/hostname 和 /etc/hosts中,但它在容器外部看不到,既不會在docker ps 中顯示,也不會在其他的容器的 /etc/hosts 看到。
--dns=IP_ADDRESS 添加 DNS 服務器到容器的 /etc/resolv.conf 中,讓容器用這個服務器來解析所有不在/etc/hosts 中的主機名。
--dns-search=DOMAIN 設定容器的搜索域,當設定搜索域爲 .example.com 時,在搜索一個名爲 host 的主機時,DNS 不僅搜索 host,還會搜索 host.example.com 。

#學習文檔地址:https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章