Skip to content

Commit afd8833

Browse files
committed
[container] refactor: rewrite container document.
1 parent dbaa22e commit afd8833

2 files changed

Lines changed: 52 additions & 22 deletions

File tree

README.md

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,7 @@ docker login
151151

152152
## Container
153153

154-
> Container (容器) 是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用“装”起来的技术。这样,应用与应用之间,就因为有了边界而不至于相互干扰;而被装进集装箱的应用,也可以被方便地搬来搬去。
155-
156-
我们来创建一个后续 k8s 教程需要的容器镜像,首先新建一个 `main.go` 的 golang 文件,里面写的是 `v1` 版本的代码,逻辑很简单,创建一个 `http server`,调用配置端口 `3000` 返回字符串 `[v1] Hello, Kubernetes!`
154+
我们的旅程从一段代码开始。新建一个 `main.go` 文件,复制下面的代码到文件中。
157155

158156
```go
159157
package main
@@ -173,9 +171,17 @@ func main() {
173171
}
174172
```
175173

176-
接下来我们编写 `Dockerfile` 文件,简单的方案当然是直接使用 golang 的 alpine 镜像来打包,但是因为我们后续练习需要频繁的 push image 到 dockerhub 和 pull image 到 kubernetes 中,为了优化网络速度,可以先在 `golang:1.16-buster` 中将上述代码编译成二进制文件,再将二进制文件复制到 `base-debian10` 镜像中运行。
174+
上面是一串用 [Go](https://go.dev/) 写的代码,代码逻辑非常的简单,首先启动 HTTP 服务器,监听 `3000` 端口,当访问路由 `/`的时候 返回字符串 `[v1] Hello, Kubernetes!`
175+
176+
在以前,如果你想将这段代码运行起来并测试一下。你首先需要懂得如何下载 golang 的安装包进行安装,接着需要懂得 `golang module` 的基本使用,最后还需要了解 golang 的编译和运行命令,才能将该代码运行起来。甚至在过程中,可能会因为环境变量问题、操作系统问题、处理器架构等问题导致编译或运行失败。
177+
178+
但是通过容器技术,只需要上面的代码,附带着对应的容器 `Dockerfile` 文件,那么你就不需要 golang 的任何知识,也能将代码顺利运行起来。
177179

178-
这样我们可以将 300MB~500MB 大小的镜像变成只有 20MB 的镜像,甚至压缩上传到 DockerHub 后大小只有 10MB。
180+
> Container (容器) 是一种沙盒技术。它是基于 Linux 中 Namespace / Cgroups / chroot 等技术结合而成,更多技术细节可以参看这个视频 [如何自己实现一个容器](https://www.youtube.com/watch?v=8fi7uSYlOdc)
181+
182+
下面就是 Go 代码对应的 `Dockerfile`,简单的方案是直接使用 golang 的 alpine 镜像来打包,但是因为我们后续练习需要频繁的推送镜像到 DockerHub 和拉取镜像到 k8s 集群中,为了优化网络速度,我们选择先在 `golang:1.16-buster` 中将上述 Go 代码编译成二进制文件,再将二进制文件复制到 `base-debian10` 镜像中运行 (Dockerfile 不理解没有关系,不影响后续教程学习)。
183+
184+
这样我们可以将 300MB 大小的镜像变成只有 20MB 的镜像,甚至压缩上传到 DockerHub 后大小只有 10MB!
179185

180186
```dockerfile
181187
# Dockerfile
@@ -196,29 +202,38 @@ EXPOSE 3000
196202
ENTRYPOINT ["/main"]
197203
```
198204

199-
执行 `docker build` 命令,第一次需要先 pull base images,需要耐心等待一会。
200-
201-
需要注意将 `guangzhengli` 替换成自己的 `DockerHub` 账号名称。 这样我们后续可以 push image 到我们自己的 `DockerHub` 仓库当中。
205+
需要注意 `main.go` 文件需要和 `Dockerfile` 文件在同一个目录下,执行下方 `docker build` 命令,第一次需要耐心等待拉取基础镜像。并且**需要注意将 `guangzhengli` 替换成自己的 `DockerHub` 账号名称**。 这样我们后续可以推送镜像到自己注册的 `DockerHub` 仓库当中。
202206

203207
```shell
204208
docker build . -t guangzhengli/hellok8s:v1
209+
# Step 1/11 : FROM golang:1.16-buster AS builder
210+
# ...
211+
# ...
212+
# Step 11/11 : ENTRYPOINT ["/main"]
213+
# Successfully tagged guangzhengli/hellok8s:v1
214+
215+
216+
docker images
217+
# guangzhengli/hellok8s v1 f956e8cf7d18 8 days ago 25.4MB
205218
```
206219

207-
`docker build` 完成后我们可以通过 `docker images` 查看镜像基础信息,执行 `docker run` 命令将容器启动, `-p` 指定 `3000` 作为端口,`-d` 指定刚打包成功的镜像名称。
220+
`docker build` 命令完成后我们可以通过 `docker images` 命令查看镜像是否 build 成功,最后我们执行 `docker run` 命令将容器启动, `-p` 指定 `3000` 作为端口,`-d` 指定刚打包成功的镜像名称。
208221

209222
```shell
210223
docker run -p 3000:3000 --name hellok8s -d guangzhengli/hellok8s:v1
211224
```
212225

213226
运行成功后,可以通过浏览器或者 `curl` 来访问 `http://127.0.0.1:3000` , 查看是否成功返回字符串 `[v1] Hello, Kubernetes!`
214227

215-
这里因为我的 docker runtime 是使用 `minikube`,所以我需要先调用 `minikube ip` 来或者 IP 地址,例如这里返回了 `192.168.59.100`,所以我需要访问 `http://192.168.59.100:3000` 来判断是否成功返回字符串 `[v1] Hello, Kubernetes!`
228+
这里因为我本地只用 Docker CLI,而 docker runtime 是使用 `minikube`,所以我需要先调用 `minikube ip` 来返回 minikube IP 地址,例如返回了 `192.168.59.100`,所以我需要访问 `http://192.168.59.100:3000` 来判断是否成功返回字符串 `[v1] Hello, Kubernetes!`
229+
230+
最后确认没有问题,使用 `docker push` 将镜像上传到远程的 `DockerHub` 仓库当中,这样可以供他人下载使用,也方便后续 `Minikube` 下载镜像使用。 **需要注意将 `guangzhengli` 替换成自己的 `DockerHub` 账号名称**
216231

217232
```shell
218233
docker push guangzhengli/hellok8s:v1
219234
```
220235

221-
最后确认没有问题,`docker push` 将镜像上传到远程的 `DockerHub` 仓库当中,这样可以供他人下载使用,也方便后续 `Minikube` 下载镜像使用。
236+
经过这一节的练习,有没有对容器的强大有一个初步的认识呢?可以想象当你想部署一个更复杂的服务时,例如 Nginx,MySQL,Redis。你只需要到 [DockerHub 搜索](https://hub.docker.com/search?q=) 中搜索对应的镜像,通过 `docker pull` 下载镜像,`docker run` 启动服务即可!而无需关系依赖和各种配置!
222237

223238
## Pod
224239

docs/container.md

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
## Container
22

3-
> Container (容器) 是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用“装”起来的技术。这样,应用与应用之间,就因为有了边界而不至于相互干扰;而被装进集装箱的应用,也可以被方便地搬来搬去。
4-
5-
我们来创建一个后续 k8s 教程需要的容器镜像,首先新建一个 `main.go` 的 golang 文件,里面写的是 `v1` 版本的代码,逻辑很简单,创建一个 `http server`,调用配置端口 `3000` 返回字符串 `[v1] Hello, Kubernetes!`
3+
我们的旅程从一段代码开始。新建一个 `main.go` 文件,复制下面的代码到文件中。
64

75
```go
86
package main
@@ -22,9 +20,17 @@ func main() {
2220
}
2321
```
2422

25-
接下来我们编写 `Dockerfile` 文件,简单的方案当然是直接使用 golang 的 alpine 镜像来打包,但是因为我们后续练习需要频繁的 push image 到 dockerhub 和 pull image 到 kubernetes 中,为了优化网络速度,可以先在 `golang:1.16-buster` 中将上述代码编译成二进制文件,再将二进制文件复制到 `base-debian10` 镜像中运行。
23+
上面是一串用 [Go](https://go.dev/) 写的代码,代码逻辑非常的简单,首先启动 HTTP 服务器,监听 `3000` 端口,当访问路由 `/`的时候 返回字符串 `[v1] Hello, Kubernetes!`
24+
25+
在以前,如果你想将这段代码运行起来并测试一下。你首先需要懂得如何下载 golang 的安装包进行安装,接着需要懂得 `golang module` 的基本使用,最后还需要了解 golang 的编译和运行命令,才能将该代码运行起来。甚至在过程中,可能会因为环境变量问题、操作系统问题、处理器架构等问题导致编译或运行失败。
26+
27+
但是通过容器技术,只需要上面的代码,附带着对应的容器 `Dockerfile` 文件,那么你就不需要 golang 的任何知识,也能将代码顺利运行起来。
28+
29+
> Container (容器) 是一种沙盒技术。它是基于 Linux 中 Namespace / Cgroups / chroot 等技术结合而成,更多技术细节可以参看这个视频 [如何自己实现一个容器](https://www.youtube.com/watch?v=8fi7uSYlOdc)
30+
31+
下面就是 Go 代码对应的 `Dockerfile`,简单的方案是直接使用 golang 的 alpine 镜像来打包,但是因为我们后续练习需要频繁的推送镜像到 DockerHub 和拉取镜像到 k8s 集群中,为了优化网络速度,我们选择先在 `golang:1.16-buster` 中将上述 Go 代码编译成二进制文件,再将二进制文件复制到 `base-debian10` 镜像中运行 (Dockerfile 不理解没有关系,不影响后续教程学习)。
2632

27-
这样我们可以将 300MB~500MB 大小的镜像变成只有 20MB 的镜像,甚至压缩上传到 DockerHub 后大小只有 10MB
33+
这样我们可以将 300MB 大小的镜像变成只有 20MB 的镜像,甚至压缩上传到 DockerHub 后大小只有 10MB
2834

2935
```dockerfile
3036
# Dockerfile
@@ -45,26 +51,35 @@ EXPOSE 3000
4551
ENTRYPOINT ["/main"]
4652
```
4753

48-
执行 `docker build` 命令,第一次需要先 pull base images,需要耐心等待一会。
49-
50-
需要注意将 `guangzhengli` 替换成自己的 `DockerHub` 账号名称。 这样我们后续可以 push image 到我们自己的 `DockerHub` 仓库当中。
54+
需要注意 `main.go` 文件需要和 `Dockerfile` 文件在同一个目录下,执行下方 `docker build` 命令,第一次需要耐心等待拉取基础镜像。并且**需要注意将 `guangzhengli` 替换成自己的 `DockerHub` 账号名称**。 这样我们后续可以推送镜像到自己注册的 `DockerHub` 仓库当中。
5155

5256
```shell
5357
docker build . -t guangzhengli/hellok8s:v1
58+
# Step 1/11 : FROM golang:1.16-buster AS builder
59+
# ...
60+
# ...
61+
# Step 11/11 : ENTRYPOINT ["/main"]
62+
# Successfully tagged guangzhengli/hellok8s:v1
63+
64+
65+
docker images
66+
# guangzhengli/hellok8s v1 f956e8cf7d18 8 days ago 25.4MB
5467
```
5568

56-
`docker build` 完成后我们可以通过 `docker images` 查看镜像基础信息,执行 `docker run` 命令将容器启动, `-p` 指定 `3000` 作为端口,`-d` 指定刚打包成功的镜像名称。
69+
`docker build` 命令完成后我们可以通过 `docker images` 命令查看镜像是否 build 成功,最后我们执行 `docker run` 命令将容器启动, `-p` 指定 `3000` 作为端口,`-d` 指定刚打包成功的镜像名称。
5770

5871
```shell
5972
docker run -p 3000:3000 --name hellok8s -d guangzhengli/hellok8s:v1
6073
```
6174

6275
运行成功后,可以通过浏览器或者 `curl` 来访问 `http://127.0.0.1:3000` , 查看是否成功返回字符串 `[v1] Hello, Kubernetes!`
6376

64-
这里因为我的 docker runtime 是使用 `minikube`,所以我需要先调用 `minikube ip` 来或者 IP 地址,例如这里返回了 `192.168.59.100`,所以我需要访问 `http://192.168.59.100:3000` 来判断是否成功返回字符串 `[v1] Hello, Kubernetes!`
77+
这里因为我本地只用 Docker CLI,而 docker runtime 是使用 `minikube`,所以我需要先调用 `minikube ip` 来返回 minikube IP 地址,例如返回了 `192.168.59.100`,所以我需要访问 `http://192.168.59.100:3000` 来判断是否成功返回字符串 `[v1] Hello, Kubernetes!`
78+
79+
最后确认没有问题,使用 `docker push` 将镜像上传到远程的 `DockerHub` 仓库当中,这样可以供他人下载使用,也方便后续 `Minikube` 下载镜像使用。 **需要注意将 `guangzhengli` 替换成自己的 `DockerHub` 账号名称**
6580

6681
```shell
6782
docker push guangzhengli/hellok8s:v1
6883
```
6984

70-
最后确认没有问题,`docker push` 将镜像上传到远程的 `DockerHub` 仓库当中,这样可以供他人下载使用,也方便后续 `Minikube` 下载镜像使用。
85+
经过这一节的练习,有没有对容器的强大有一个初步的认识呢?可以想象当你想部署一个更复杂的服务时,例如 Nginx,MySQL,Redis。你只需要到 [DockerHub 搜索](https://hub.docker.com/search?q=) 中搜索对应的镜像,通过 `docker pull` 下载镜像,`docker run` 启动服务即可!而无需关系依赖和各种配置!

0 commit comments

Comments
 (0)