原文作者:木环
原文链接
更多云原生技术资讯可关注阿里巴巴云原生技术圈
什么是容器?
因为虚拟机(vm)存在一定不足,容器技术的诞生后才如此受欢迎。以传统的Java应用架构而言,将一个应用程序生成一个war包,放到一个tomcat容器当中并在一台虚拟机(VM)中启动运行,然后配置nginx的负载均衡策略,将来自用户的请求转发到某个tomcat应用上,这种基于主机或虚拟机部署的应用会存在以下问题:可移植性差、可维护性差、可扩展性差、无法资源隔离。[扩展阅读]()
而容器是什么呢?它就是一个视图隔离、资源可限制、独立文件系统的进程集合。所谓“视图隔离”就是能够看到部分进程以及具有独立的主机名等;控制资源使用率则是可以对于内存大小以及 CPU 使用个数等进行限制。容器就是一个进程集合,它将系统的其他资源隔离开来,具有自己独立的资源视图。
容器具有一个独立的文件系统,因为使用的是系统的资源,所以在独立的文件系统内不需要具备内核相关的代码或者工具,我们只需要提供容器所需的二进制文件、配置文件以及依赖即可。只要容器运行时所需的文件集合都能够具备,那么这个容器就能够运行起来。扩展阅读《详解 K8s 容器基本概念》
什么是容器镜像?
从一个比较具体的角度去看,镜像就是一个多层存储的文件,相较于普通的ISO系统镜像来说,分层存储会带来两个优点:
- 一个是分层存储的镜像比较容易扩展,比如我们可以基于一个Ubuntu镜像去构建我们的Nginx镜像,这样我们只需要在Ubuntu镜像的基础上面做一些Nginx的安装配置工作。一个Nginx镜像工作就算制作完成了,我们不需要从头开始去制作各种镜像。
- 另一点是可以优化镜像存储空间,假如我们有两个镜像,Tag1.0镜像和 Tag2.0镜像,我们如果以传统方式去传这两个镜像,每个镜像大概130多兆,但如果我们以分层的方式去存储两个镜像,我们通过下面两个紫色的才能共享,可以节约大量的空间,两个镜像加起来只需要140多兆的空间就可以存下来。这样一是节省了存储空间,二是可以减少网络上的开销,比如我们已经把下面镜像下载了,我们要去下载上面镜像的时候,我们只需要去下10M的部分。
如果从抽象的角度去看,Docker镜像其实是Docker提供的一种标准化的交付手段,传统应用在交付的时候其实是交付一个可执行文j件。问题在于传统方式的这个可执行文件不包括它的运行环境,我们可能会因为32位系统或64位系统,或者开发测试使用1.0软件,结果交付时候发现用户的环境是2.0等各种各样的问题,导致我们要去花时间去排查;但是,如果我们以Docker镜像的标准化形式去交付,我们就会避免掉这些问题。
扩展阅读《Docker 镜像优化与最佳实践》
好了,闲话少叙。下面开始实验时间。
1. 实验概述
本实验会使用 Dockerfile 将下面 golang 代码构建成镜像,并通过阿里云镜像服务将镜像分发到阿里云虚拟机,运行该镜像。
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello! World\n")
})
fmt.Println("start to serve...")
http.ListenAndServe(":80", nil)
}
2. 实验目标
完成此实验后,可以掌握的能力有:
- Dockerfile 编写和使用
- 使用阿里云镜像服务来分发镜像。
NOTE: 学前建议: 了解 docker 的基本操作命令 以及 如何使用 ECS 实例。
3. 实验详情
3.1 准备应用代码和 Dockerfile
首先在本地生成一个文件夹 demo
,并将 golang 代码拷贝到 demo
文件夹下的 main.go
.
$ pwd
/tmp/demo
$ ls
main.go
$ cat main.go
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello! World\n")
})
fmt.Println("start to serve...")
http.ListenAndServe(":80", nil)
}
在当前 demo
目录下编写 Dockerfile ,如下所示
$ cat Dockerfile
FROM golang:1.12-alpine
# change current working dir
WORKDIR /go/src/app
# copy main.go into /go/src/app
COPY . .
# go build and install the app
RUN go install -v ./...
# run the app by default
CMD ["app"]
3.2 构建镜像
通常情况下,使用以下命令即可构建镜像
$ pwd
/tmp/demo
# demo:v1 表示镜像名字demo和标签v1
$ docker build . -t demo:v1
Sending build context to Docker daemon 3.072kB
Step 1/5 : FROM golang:1.12-alpine
---> 8ff3fd35cf82
Step 2/5 : WORKDIR /go/src/app
Removing intermediate container ffd88a948413
---> 1056ea513b89
Step 3/5 : COPY . .
---> 9fc4655c973a
Step 4/5 : RUN go install -v ./...
---> Running in 928fc776a6e1
app
Removing intermediate container 928fc776a6e1
---> a93f17a3a726
Step 5/5 : CMD ["app"]
---> Running in 9e3463aa81f6
Removing intermediate container 9e3463aa81f6
---> 8697c7279c74
Successfully built 8697c7279c74
Successfully tagged demo:v1
NOTE:
在国内访问 Docker Hub 速度比较慢,可以在Docker引擎中设置镜像加速器加速对Docker Hub的访问。
更新/etc/docker/daemon.json
,添加如下参数,并重启Docker引擎。
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
构建完毕之后,可以在本地运行验证下是否符合预期
映射容器内 80 端到宿主机上的 8000 端口
$ docker run -d -p 8000:80 demo:v1
<a name="o6x1Z"></a>
curl 一下查看结果
$ curl localhost:8000<br />Hello! World
如果看到 Hello! World
字样,我们就可以进入下一个环节了。
3.3 推送镜像至阿里云容器镜像服务
在推送之前,需要注册阿里云账号和开通阿里云容器镜像服务
阿里云注册链接: 注册阿里云
阿里云登录链接: 登录阿里云
阿里云容器镜像服务页面: 访问阿里云容器镜像服务
容器镜像服务(Container Registry)提供安全的应用镜像托管能力,精确的镜像安全扫描功能,稳定的国内外镜像构建服务,便捷的镜像授权功能,方便用户进行镜像全生命周期管理。
当我们拥有阿里云容器镜像服务账号之后呢,可以使用 docker 客户端来登陆服务。
$ docker login -username=_*_* registry.cn-hangzhou.aliyuncs.com<br />Password:<br />Login Succeeded
在推送到镜像之前,需要将本地镜像修改为对应的镜像仓库地址:
mydemo 可以替换成自己的命名空间
$ docker tag demo:v1 registry.cn-hangzhou.aliyuncs.com/mydemo/demo:v1<br />$ docker push registry.cn-hangzhou.aliyuncs.com/mydemo/demo:v1
3.4 登陆阿里云 ECS 机器来下载 demo:v1 镜像
登陆 ECS 实例,通过 docker pull 来下载镜像
<a name="fwe7n"></a>
# mydemo 请替换成 3.3 步骤中指定的命令空间
$ docker pull registry.cn-hangzhou.aliyuncs.com/mydemo/demo:v1
下载完毕之后,我们就可以直接运行该镜像
$ docker run -d -p 8000:80 registry.cn-hangzhou.aliyuncs.com/mydemo/demo:v1
并查看 ECS 机器的 8000
端口
$ curl localhost:8000
“ 阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”