Docker端口映射及創建鏡像演示(二)


Docker暴露容器方法

 

第一種:將容器中的一個端口映射成宿主機中的一個隨機端口

第二種:將容器中的一個端口映射成宿主機中的一個端口

第三種:將容器中的一個端口映射成宿主機中的一個特定網卡上的隨機端口

第四種:將容器中的一個端口映射成宿主機中的一個特定網卡上的一個端口

【使用多次-p選項可以實現暴露多個端口】

 

Docker端口映射的四種方法使用演示

 

第一種:將容器中的一個端口映射成宿主機中的一個隨機端口

下面的操作確保虛擬機是在橋接模式

第一步:下載httpd鏡像

[root@ken ~]# docker pull httpd
[root@ken ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd               latest              2a51bb06dc8b        12 days ago         132MB
redis               latest              55cb7014c24f        5 months ago        83.4MB

 

第二步:啟動httpd容器

–name: 指定容器名

-d: 后台運行

-P: 大寫的P,映射隨機端口(暴露容器內所有端口,映射到宿主機的隨機端口)

–rm: 表示退出容器時刪除容器

[root@ken ~]# docker container run --name httpd1 -d -P --rm  httpd

 

第三步:查看端口

可以發現容器內的80端口被指向了宿主機的32768端口

[root@ken ~]# docker container ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
b02a0dd47b7b        httpd               "httpd-foreground"   25 seconds ago      Up 20 seconds       0.0.0.0:32768->80/tcp   httpd1

查看宿主機是否有32768端口

[root@ken ~]# ss -tnl | grep 32768
LISTEN     0      1024        :::32768                   :::*

 

第四步:訪問

輸入宿主機的IP地址加映射的端口號

通過以上的方法就可以實現外部主機訪問一個容器了。

 

 第二種:將容器中的一個端口映射成宿主機中的一個端口

第一步:啟動httpd容器

–name:指定容器名稱

-d:后台運行

-p:小寫的p指定端口,123為宿主機端口,80為容器的端口

–rm:退出容器及刪除容器

[root@ken ~]# docker container run --name httpd2 -d -p 1234:80 --rm httpd

 

第二步:查看端口

 
[root@ken ~]# docker container ps 
CONTAINER ID        IMAGE               COMMAND              CREATED              STATUS              PORTS                 NAMES
e083fd2915a7        httpd               "httpd-foreground"   About a minute ago   Up About a minute   0.0.0.0:1234->80/tcp   httpd2
[root@ken ~]# ss -tnl | grep 1234
LISTEN     0      1024        :::1234                    :::*
 

 

第三步:訪問

輸入宿主機IP地址和設置的端口即可訪問

 

第三種:將容器中的一個端口映射成宿主機中的一個特定網卡上的隨機端口

第一步:啟動httpd容器

指定特定的網卡需要使用小p 后面加上 網卡ip::容器端口

[root@ken ~]# docker container run --name httpd3 -d -p 10.220.5.13::80 --rm httpd

 

第二步:查看端口

可以看到下面生成了一個隨機端口32768

 
[root@ken ~]# docker container ps 
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                       NAMES
63060c0e83f0        httpd               "httpd-foreground"   7 seconds ago       Up 5 seconds        10.220.5.13:32768->80/tcp   httpd3
[root@ken ~]# ss -tnl | grep 32768
LISTEN     0      1024   10.220.5.13:32768                    *:*
 

 

第三步:訪問

使用生成的隨機端口加上IP 地址即可進行容器的訪問

 

第四種:將容器中的一個端口映射成宿主機中的一個特定網卡上的一個端口

第一步:啟動容器

指定特定的網卡需要使用小p 后面加上 網卡ip:宿主機端口:容器端口

這里我指定了使用宿主機的8080端口進行容器端口的映射

[root@ken ~]# docker container run --name httpd3 -d -p 10.220.5.13:8080:80 --rm httpd

 

第二步:查看端口

 
[root@ken ~]# docker container ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                      NAMES
2a30717c6df7        httpd               "httpd-foreground"   57 seconds ago      Up 56 seconds       10.220.5.13:8080->80/tcp   httpd3
[root@ken ~]# ss -tnl | grep 8080
LISTEN     0      1024   10.220.5.13:8080                     *:*
 

 

第三步:瀏覽器訪問

只要輸入ip:端口即可進行訪問

 

如果想要暴露一個容器內的多個端口可以使用多個-p

 

創建自己的鏡像倉庫

 

需要在阿里雲創建鏡像倉庫

 

控制台–》鏡像倉庫

 

第一步:創建鏡像倉庫

點擊創建鏡像倉庫

 

第二步:填寫你的注冊信息

 

第三步:點擊本地倉庫

 

第四步:如下就創建好了一個自己的鏡像倉庫

 

往阿里雲倉庫推送和拉取鏡像:

1. 登錄阿里雲Docker Registry

$ sudo docker login --username=kenkendyg registry.cn-hangzhou.aliyuncs.com

用於登錄的用戶名為阿里雲賬號全名,密碼為開通服務時設置的密碼。

您可以在產品控制台首頁修改登錄密碼。

2. 從Registry中拉取鏡像

$ sudo docker pull registry.cn-hangzhou.aliyuncs.com/kenken/myself:[鏡像版本號]

3. 將鏡像推送到Registry

$ sudo docker login --username=kenkendyg registry.cn-hangzhou.aliyuncs.com$ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/kenken/myself:[鏡像版本號]$ sudo docker push registry.cn-hangzhou.aliyuncs.com/kenken/myself:[鏡像版本號]

請根據實際鏡像信息替換示例中的[ImageId]和[鏡像版本號]參數。

 

基於容器創建鏡像

 

獲取使用幫助

commit用來基於一個現有容器來創建鏡像

[root@ken ~]# docker commit --help

Usage:    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes

 

參數詳解

  -a,           作者信息 (e.g., "John Hannibal Smith <hannibal@a-team.com>")
  -c,           將Dockerfile指令應用於創建的映像 (default [])-m, --message string   
  -m            提交信息
  -p,           提交時暫停容器 (default true)

 

第一步:啟動容器

[root@ken ~]# docker container run -it --name busybox1 busybox

 

第二步:創建則是頁面

[root@ken ~]# docker container exec -it busybox1 /bin/sh
/ # mkdir /data
/ # echo "test for my image">/data/index.html
/ # httpd -h /data
/ #

 

第三步:基於容器創建鏡像

[root@ken ~]# docker commit -a "ken" -p -c "CMD ["/bin/httpd","-f","-h","/data"]" busybox1 kenken/httpd1
sha256:29846cdbd83478bc9469b6ad25e76851655072bca6c984eeffedb52a8c8b91c0

 

第四步:查看鏡像

可以看到第一個就是剛才創建的鏡像

 
[root@ken ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
kenken/httpd1       latest              29846cdbd834        23 seconds ago      1.15 MB
docker.io/nginx     latest              568c4670fa80        16 hours ago        109 MB
docker.io/redis     latest              c188f257942c        12 days ago         94.9 MB
docker.io/httpd     latest              2a51bb06dc8b        12 days ago         132 MB
docker.io/busybox   latest              59788edf1f3e        8 weeks ago         1.15 MB
 

 

第五步:往阿里雲推送

首先需要登錄阿里雲

輸入的密碼是注冊的阿里雲賬號的密碼

[root@ken ~]# docker login --username=kenkendyg registry.cn-beijing.aliyuncs.com
Password: 
Login Succeeded

 

第六步:給制作好的鏡像打一個標簽

29846cdbd834是你的鏡像的ID
[root@ken ~]# docker tag 29846cdbd834 registry.cn-beijing.aliyuncs.com/kenken/httpd:v1

 

第七步:推送鏡像

[root@ken ~]# docker push registry.cn-beijing.aliyuncs.com/kenken/httpd:v1
The push refers to a repository [registry.cn-beijing.aliyuncs.com/kenken/httpd]
b4a60ebae046: Pushed 
8a788232037e: Pushed 
v1: digest: sha256:88008e08275bc85dbbef8f770d66cdec5cf96e86e4ad5e2a38c5b5a8c1b2e57f size: 734

 

第八步:在阿里雲查看

首先點擊管理

點擊鏡像 版本即可查看

第九步:拉取阿里雲鏡像到本地

拉取鏡像需要在另一台主機上面登錄阿里雲

 
[root@ken ~]#  docker login --username=kenkendyg registry.cn-beijing.aliyuncs.com
Password: 
Login Succeeded
[root@ken ~]# docker pull registry.cn-beijing.aliyuncs.com/kenken/httpd:v1
v1: Pulling from kenken/httpd
90e01955edcd: Already exists 
3d5cd4fa148f: Pull complete 
Digest: sha256:88008e08275bc85dbbef8f770d66cdec5cf96e86e4ad5e2a38c5b5a8c1b2e57f
Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/kenken/httpd:v1
[root@ken ~]# docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
registry.cn-beijing.aliyuncs.com/kenken/httpd   v1                  29846cdbd834        17 minutes ago      1.15MB
nginx                                           latest              568c4670fa80        17 hours ago        109MB
httpd                                           latest              2a51bb06dc8b        12 days ago         132MB
busybox                                         latest              59788edf1f3e        8 weeks ago         1.15MB
redis                                           latest              55cb7014c24f        5 months ago        83.4MB
 

實現容器的底層技術

 

為了更好地理解容器的特性,我們將討論容器的底層實現技術。
cgroup 和 namespace 是最重要的兩種技術。cgroup 實現資源限額, namespace 實現資源隔離。

 

cgroup

cgroup 全稱 Control Group。Linux 操作系統通過 cgroup 可以設置進程使用 CPU、內存 和 IO 資源的限額。

cgroup 到底長什么樣子呢?我們可以在 /sys/fs/cgroup 中找到它。還是用例子來說明,啟動一個容器,設置內存為512M

在 /sys/fs/cgroup/memory/docker 目錄中,Linux 會為每個容器創建一個 cgroup 目錄,以容器長ID 命名:

 

對內存使用限制

Docker 可以通過 -c 或 –cpu-shares 設置容器使用 CPU 的權重。如果不指定,默認值為 1024。

與內存限額不同,通過 -c 設置的 cpu share 並不是 CPU 資源的絕對數量,而是一個相對的權重值。某個容器最終能分配到的 CPU 資源取決於它的 cpu share 占所有容器 cpu share 總和的比例

換句話說:通過 cpu share 可以設置容器使用 CPU 的優先級。

比如在 host 中啟動了兩個容器:

docker run –name “containerA” -c 1024 httpd

docker run –name “containerB” -c 512 httpd

containerA 的 cpu share 1024,是 containerB 的兩倍。當兩個容器都需要 CPU 資源時,containerA 可以得到的 CPU 是 containerB 的兩倍。

需要特別注意的是,這種按權重分配 CPU 只會發生在 CPU 資源緊張的情況下。如果 containerA 處於空閑狀態,這時,為了充分利用 CPU 資源,container_B 也可以分配到全部可用的 CPU。

 

可以在這里找到設置的cpu

[root@ken1 ~]# cat /sys/fs/cgroup/cpu/docker/a1f00b2682796ec9d0c64c8356645ecaeba95c622b4d306124c01d17fd9e5829/cpu.shares 512 

 

 

namespace

在每個容器中,我們都可以看到文件系統,網卡等資源,這些資源看上去是容器自己的。拿網卡來說,每個容器都會認為自己有一塊獨立的網卡,即使 host 上只有一塊物理網卡。這種方式非常好,它使得容器更像一個獨立的計算機。

Linux 實現這種方式的技術是 namespace。namespace 管理着 host 中全局唯一的資源,並可以讓每個容器都覺得只有自己在使用它。換句話說,namespace 實現了容器間資源的隔離

Linux 使用了六種 namespace,分別對應六種資源:Mount、UTS、IPC、PID、Network 和 User,下面我們分別討論。

 

Mount namespace

Mount namespace 讓容器看上去擁有整個文件系統。

容器有自己的 / 目錄,可以執行 mount 和 umount 命令。當然我們知道這些操作只在當前容器中生效,不會影響到 host 和其他容器。

 

UTS namespace

簡單的說,UTS namespace 讓容器有自己的 hostname。 默認情況下,容器的 hostname 是它的短ID,可以通過 -h 或 --hostname 參數設置。

 

 

IPC namespace

IPC namespace 讓容器擁有自己的共享內存和信號量(semaphore)來實現進程間通信,而不會與 host 和其他容器的 IPC 混在一起。

 

PID namespace

容器在 host 中以進程的形式運行。容器內進程的 PID 不同於 host 中對應進程的 PID,容器中 PID=1 的進程當然也不是 host 的systemd進程。也就是說:容器擁有自己獨立的一套 PID,這就是 PID namespace 提供的功能。

 

Network namespace

Network namespace 讓容器擁有自己獨立的網卡、IP、路由等資源。

 

User namespace

User namespace 讓容器能夠管理自己的用戶,host 不能看到容器中創建的用戶。

 
 

Continue Reading

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM