前提: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"]}

 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐