简单!自己打包的 docker镜像,如何部署到本地 k8s 上?
前提:k8s 内部使用的 docker 和本地安装的 docker daemon 是两回事,这就导致一个问题,我在本地打包的 docker image,如何在 k8s 里部署呢?答案是:使用 docker 本地仓库,将 docker image push 到本地仓库,然后修改 k8s 为从本地仓库拉取 image。在实际使用docker的过程中,因为产品主要使用了微服务的架构,会有很多不同的服务镜
前提:k8s 内部使用的 docker 和本地安装的 docker daemon 是两回事,这就导致一个问题,我在本地打包的 docker image,如何在 k8s 里部署呢?
答案是:使用 docker 本地仓库,将 docker image push 到本地仓库,然后修改 k8s 为从本地仓库拉取 image。
在实际使用docker的过程中,因为产品主要使用了微服务的架构,会有很多不同的服务镜像,将生成的镜像放到docker-hub上是不合适的。而且为了便于后续的自动化运维和部署方便,都需要在产品运行的内网部署一个私有化的docker仓库。将部署的过程简单记录如下:
安装docker-ce
docker官网有比较详细的文档进行指导,参考如下链接:
https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/
使用registry
docker local仓库也是通过docker镜像提供的,官方提供了一个registry的镜像,关于registry的相关介绍在docker官网上有比较详细的说明,本文只是说明了搭建本地镜像的一个简化过程。如果想了解更多的详细,可以参考如下链接:
https://docs.docker.com/registry/deploying/
使用的时候,直接启动registry镜像就可以了。启动命令如下:
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /mnt/docker_imgs:/var/lib/registry \
registry:2
目前一般都是使用v2版本的, -v指定了宿主机上的目录用来作为docker仓库的存储位置,如果不指定的话,registry镜像重启之后会丢失已经存储在本地仓库的镜像文件。其他命令都是docker常见命令,可以参考官网的docker命令文档。
启动registry镜像之后,可以通过docker ps看到如下信息:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cd88743185ff registry:2 "/entrypoint.sh /e..." 4 seconds ago Up 4 seconds 0.0.0.0:5000->5000/tcp registry
按照上面的命令启动之后,就可以直接在本地使用local仓库了。用ubuntu镜像实验之后,是下面的效果:
root@worker:/home/zhbo# docker tag ubuntu:16.04 localhost:5000/fcss/base
root@worker:/home/zhbo# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2 177391bcf802 2 days ago 33.3MB
ubuntu 16.04 20c44cd7596f 2 weeks ago 123MB
localhost:5000/fcss/base latest 20c44cd7596f 2 weeks ago 123MB
root@worker:/home/zhbo# docker push localhost:5000/fcss/base
The push refers to a repository [localhost:5000/fcss/base]
2f5b0990636a: Pushed
c9748fbf541d: Pushed
b3968bc26fbd: Pushed
aa4e47c45116: Pushed
788ce2310e2f: Pushed
latest: digest: sha256:d4558f7616365813792918b6d73dc474bcacf99b13d1ed947731a653fb6e260c size: 1357
root@worker:/home/zhbo# ls
docker_imgs sources.list
root@worker:/home/zhbo# ls docker_imgs
docker
root@worker:/home/zhbo# ls docker_imgs/docker
registry
root@worker:/home/zhbo# ls docker_imgs/docker/registry/
v2
root@worker:/home/zhbo# ls docker_imgs/docker/registry/v2
blobs repositories
root@worker:/home/zhbo# ls docker_imgs/docker/registry/v2/repositories/
fcss
root@worker:/home/zhbo# ls docker_imgs/docker/registry/v2/repositories/fcss
base
root@worker:/home/zhbo# ls docker_imgs/docker/registry/v2/repositories/fcss/base
_layers _manifests _uploads
但是这个时候,如果在其他pc上通过docker pull获取新加的这个镜像,是会出错的,如下:
root@zhbo-OptiPlex-9020:/home/zhbo# docker pull 172.22.15.165:5000/fcss/base
Using default tag: latest
Error response from daemon: Get https://172.22.15.165:5000/v1/_ping: http: server gave HTTP response to HTTPS client
这是因为:registry官方镜像为了保证安全,缺省使用https进行通信,毕竟在生产环境中如果使用了http,是很容易被中间人攻击的。 测试环境中我们可以将通信方式修改为http,生产环境强烈不建议这样做。
修改通信方式为http
-
修改docker client pc里面的/etc/docker/daemon.json文件,如果没有该文件,可以手工创建。在这个文件中添加如下内容:
{ "insecure-registries" : ["myregistrydomain.com:5000"] }
-
重启client端的docker服务
使用自签名证书
更安全的方式是使用自签名证书,在docker官网上有介绍:
https://docs.docker.com/registry/insecure/#use-self-signed-certificates
这种方式可以在测试环境中使用,因为可信的证书颁发机构都需要有一个可用的域名,我们在内网部署的时候不一定是有域名的。可能就是一个内网IP地址。
这个时候可以用下面的方法使用自签名证书:
生成自签名证书
在docker registry的server上,执行:
$ mkdir -p certs
$ openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt
注意:common name要填写实际的域名,不能使用ip地址,否则在使用的时候可能会提示如下错误:
Using default tag: latest
Error response from daemon: Get https://172.22.15.165:443/v1/_ping: x509: cannot validate certificate for 172.22.15.165 because it doesn't contain any IP SANs
重启registry镜像
docker run -d \
--restart=always \
--name registry \
-v `pwd`/certs:/certs \
-v /mnt/docker_imgs:/var/lib/registry \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-p 443:443 \
registry:2
添加信任关系
在所有需要用到docker daemon的pc上执行如下命令。这里以ubuntu作为示例:
$ cp certs/domain.crt /usr/local/share/ca-certificates/myregistrydomain.com.crt
update-ca-certificates
在实验环境中,可能并没有域名。这个时候可以通过修改/etc/hosts加上静态域名解析。添加CA证书之后需要重新启动docker daemon.
实际使用的效果如下:
root@zhbo-OptiPlex-9020:/home/zhbo# docker pull dockers.fcss:443/fcss/base
Using default tag: latest
latest: Pulling from fcss/base
660c48dd555d: Pull complete
4c7380416e78: Pull complete
421e436b5f80: Pull complete
e4ce6c3651b3: Pull complete
be588e74bd34: Pull complete
Digest: sha256:d4558f7616365813792918b6d73dc474bcacf99b13d1ed947731a653fb6e260c
Status: Downloaded newer image for dockers.fcss.fortinet:443/fcss/base:latest
使用受信任的证书
在生产环境中可以使用上面的自签名证书,这样在部署的时候就需要将domain.crt复制到所有的docker daemon的宿主机上。如果有自己的域名,可以通过let's encrypt申请免费的ssl证书,这样就不用像现在这样麻烦了。
私有仓库的一些操作:
私有仓库可以通过registry提供的api来操作,可以参考官网的api文档,链接如下:
https://docs.docker.com/registry/spec/api/#detail
查看所有镜像
docker search命令不能搜索本地仓库的镜像文件,实际测试会报错。可以用下面的方式获取本地仓库中的所有镜像:
# curl https://<registry domain>/v2/_catalog
{"repositories":["fcss/base"]}
更多推荐
所有评论(0)