Galaxy

姚皓的技术博客-一杯咖啡,一首音乐,一台电脑,编程

0%

容器-7-Kubernetes实战-私有仓库和打包镜像

我们先从比较简单的部分开始做。静态网站是一个比较合适的开端。独立,有界面方便验证,而且无状态。

1. 搭建Docker私有仓库

按照容器的思路,我们需要先做一个静态网站文件+Nginx的镜像,然后在服务器上把镜像拖下来后实例化为容器运行。

从安全和网络速度上考虑,我们做的这个镜像不太适合放到公网的Docker Hub上。所以要先搭个私有仓库。

我们先在一台虚机上按照kubeadm部署指南中的“2.1 安装Docker”和“2.2 启动Docker服务”两节安装docker。然后关闭防火墙。最后执行一句docker run就解决了:

1
docker run -d -p 5000:5000 --restart=always --name docker-registry registry

一开始没有关闭防火墙,在启动的时候报错了。再次启动的时候提示容器已存在。这时候只需要将docker run命令改为docker start命令就可以了。
PS. 如果是要在Windows上运行,要把端口从5000映射到5001,不然会因为和Docker Desktop端口冲突而容器启动失败。
我把Docker Registry私有仓库部署在10.16.34.197服务器上,于是现在访问http://10.16.34.197:5000/v2/_catalog,就可以看到当前还没有镜像:

1
{"repositories":[]}

2. 镜像打包服务器配置

在要打包和push镜像的服务器上(一般是Gitlab或Jenkins服务器吧),需要执行以下命令(要替换ip):

1
2
3
4
5
6
7
8
cat <<EOF > /etc/docker/daemon.json
{
"insecure-registries": [
"10.16.34.197:5000"
]
}
EOF
systemctl restart docker

要不然之后push的时候就会遇到报错信息:

1
2
3
[root@docker-4 vue-hello-world]# docker push 10.16.34.197:5000/staticsite
The push refers to repository [10.16.34.197:5000/staticsite]
Get https://10.16.34.197:5000/v2/: http: server gave HTTP response to HTTPS client

另外也需要在k8s的每个master和worker节点上都执行。不然在部署的时候也会遇到报错信息。

3. 打包网站镜像

略过不相关的web项目创建和提交代码过程,我们在Gitlab服务器上得到了需要部署的静态网站文件:

1
2
3
4
5
6
7
8
9
10
[root@docker-4 dist]# pwd
/git/vue-hello-world/dist
[root@docker-4 dist]# ll
total 12
drwxr-xr-x. 2 root root 30 Jun 13 01:42 css
-rw-r--r--. 1 root root 4286 Jun 13 01:42 favicon.ico
drwxr-xr-x. 2 root root 31 Jun 13 01:42 img
-rw-r--r--. 1 root root 730 Jun 13 01:42 index.html
drwxr-xr-x. 2 root root 126 Jun 13 01:42 js
[root@docker-4 dist]#

3.1 添加Nginx配置和Dockerfile

要将该网站host在Nginx上,只需要做两个步骤:

  • 将dist里的文件复制到Nginx的/usr/share/nginx/html目录下
  • 做一个conf配置,根目录/指向/usr/share/nginx/html,并设置默认首页网页文件名index.html

于是在网站下增加了一个default.conf文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 80;
server_name localhost;

charset utf-8;
#access_log /var/log/nginx/log/host.access.log main;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

另外增加了一个Dockerfile:

1
2
3
FROM nginx:alpine
COPY default.conf /etc/nginx/conf.d/default.conf
COPY ./dist /usr/share/nginx/html

nginx:alpine是Nginx官方的轻量级镜像。

3.2 执行打包命令

然后到Dockerfile所在目录构建镜像并推送到私有仓库:

1
2
docker build -t 10.16.34.197:5000/staticsite:1.0 .
docker push 10.16.34.197:5000/staticsite

现在访问私有仓库的catalog目录,就能看到repositories中已增加了一个静态网站的镜像:

1
{"repositories":["staticsite"]}

也可以不指定镜像版本,那么打出来的版本就是latest:

1
docker build -t 10.16.34.197:5000/staticsite .

可以通过如下的URL查看该镜像的所有可用版本:
http://10.16.34.197:5000/v2/staticsite/tags/list
(要访问其他镜像替换staticsite这个镜像名就可以了)

4. 接下来的步骤

如果只用docker,那么执行如下的命令就结束了:

1
docker run -itd --name staticsite --publish 8080:80 10.16.34.197:5000/staticsite:1.0

但到此为止的话,我们还是需要明确地指定在哪台机器上部署该容器。如果需要在多台机器上部署为高可用,就需要重复N遍同样的操作。为了保持高可用,还需要在部署容器的服务器前面额外部署负载均衡。
作为懒人,我很希望只要定义好需要的副本数量以及每个容器的硬件需求,就有人能替我把这些事情都包办了。万一哪个容器挂了还能迅速自动重启。
k8s就是这样的集群容器管家。我们下一章继续。

PS. Private Registry也可以部署在k8s上(所以上一章的架构图中它也在虚线框内),但为了简化POC的流程,我们先把这个放在后面做。

5. 使用Docker Hub作为Docker Registry

自己Demo的时候也可以省掉这个步骤,直接将镜像上传到Docker Hub,然后K8S从Docker Hub上拉取镜像。
在注册Docker Hub账号之后,如果是Windows机器,需要打开Docker Desktop,然后输入docker login就可以直接登录了,不需要再输入密码。如果是Linux上,则需要在docker login命令后输入用户名和密码。
构建镜像和推送命令需要改为:

1
2
docker build -t 账号/staticsite:1.0 .
docker push 账号/staticsite

在K8S集群里拉取镜像的步骤在下一章再介绍。

更详细步骤可以参考Pull an Image from a Private Registry - Kubernetes

6. 流程图

画了一下按角色划分的发布流程图。不管用的是k8s还是docker swarm,CI/CD的流程还是基本类似的。
容器CI/CD流程

7. 参考资料

这是本篇参考的一个最精简的静态网站的Docker配置
nishanttotla/DockerStaticSite: A simple static website using Docker and Nginx