zoukankan      html  css  js  c++  java
  • Docker 008 自建Registry

    Docker 008 自建Registry

    registry 是什么?可以做什么?

    Registry 是一个无状态高扩展的服务程序,他可以存储并分发镜像。

    很多时候使用 docker hub 并不方便,尤其是公司内网无法访问公网或者有不想公开的信息的时候,这个时候我们可以自建 registry。

    使用 Registry,我们可以:

    • 严格控制镜像的存储位置
    • 镜像发布管道的全部所有权
    • 将镜像的存储和发布紧密的继承到你的内部开发工作流中

    如果要执行以下操作,则可使用registry:

    • 严格控制图像的存储位置
    • 完全拥有您的图像分发管道
    • 将图像存储和分发紧密集成到您的内部开发工作流程中

    registry 的分类

    Sponsor Registry第三方的registry,客户和Docker社区使用
    Mirror Registry 第三方的registry,只让客户使用
    Vendor Registry 由发布Docker镜像的供应商提供的registry
    Private Registry 通过设有防火墙和额外的安全层的私有实体提供的registry

    国内可用的 registry

    一般使用 docker hub 会比较慢,幸好的是,国内的一些厂商也提供了registry 服务:

    国内的镜像源有

    • docker官方中国区 https://registry.docker-cn.com
    • 网易 http://hub-mirror.c.163.com
    • ustc http://docker.mirrors.ustc.edu.cn
    • 阿里云 http://<你的ID>.mirror.aliyuncs.com

    如果想使用国内的源,可做如下配置():

    # 指定源后,需要重启 docker
    $ vim /etc/docker/daemon.json
     
    {
     "registry-mirrors": ["https://registry.docker-cn.com"] # 这里是一个列表,可添加多个
    }
    

    关于配置文件

    参考https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file

    Linux上可配置选项的完整示例

    {
    	"authorization-plugins": [],
    	"data-root": "",
    	"dns": [],
    	"dns-opts": [],
    	"dns-search": [],
    	"exec-opts": [],
    	"exec-root": "",
    	"experimental": false,
    	"features": {},
    	"storage-driver": "",
    	"storage-opts": [],
    	"labels": [],
    	"live-restore": true,
    	"log-driver": "json-file",
    	"log-opts": {
    		"max-size": "10m",
    		"max-file":"5",
    		"labels": "somelabel",
    		"env": "os,customer"
    	},
    	"mtu": 0,
    	"pidfile": "",
    	"cluster-store": "",
    	"cluster-store-opts": {},
    	"cluster-advertise": "",
    	"max-concurrent-downloads": 3,
    	"max-concurrent-uploads": 5,
    	"default-shm-size": "64M",
    	"shutdown-timeout": 15,
    	"debug": true,
    	"hosts": [],
    	"log-level": "",
    	"tls": true,
    	"tlsverify": true,
    	"tlscacert": "",
    	"tlscert": "",
    	"tlskey": "",
    	"swarm-default-advertise-addr": "",
    	"api-cors-header": "",
    	"selinux-enabled": false,
    	"userns-remap": "",
    	"group": "",
    	"cgroup-parent": "",
    	"default-ulimits": {
    		"nofile": {
    			"Name": "nofile",
    			"Hard": 64000,
    			"Soft": 64000
    		}
    	},
    	"init": false,
    	"init-path": "/usr/libexec/docker-init",
    	"ipv6": false,
    	"iptables": false,
    	"ip-forward": false,
    	"ip-masq": false,
    	"userland-proxy": false,
    	"userland-proxy-path": "/usr/libexec/docker-proxy",
    	"ip": "0.0.0.0",
    	"bridge": "",
    	"bip": "",
    	"fixed-cidr": "",
    	"fixed-cidr-v6": "",
    	"default-gateway": "",
    	"default-gateway-v6": "",
    	"icc": false,
    	"raw-logs": false,
    	"allow-nondistributable-artifacts": [],
    	"registry-mirrors": [],
    	"seccomp-profile": "",
    	"insecure-registries": [],
    	"no-new-privileges": false,
    	"default-runtime": "runc",
    	"oom-score-adjust": -500,
    	"node-generic-resources": ["NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2"],
    	"runtimes": {
    		"cc-runtime": {
    			"path": "/usr/bin/cc-runtime"
    		},
    		"custom": {
    			"path": "/usr/local/bin/my-runc-replacement",
    			"runtimeArgs": [
    				"--debug"
    			]
    		}
    	},
    	"default-address-pools":[
    		{"base":"172.80.0.0/16","size":24},
    		{"base":"172.90.0.0/16","size":24}
    	]
    }
    

    Win 下的可配置选项的完整示例:

    {
        "authorization-plugins": [],
        "data-root": "",
        "dns": [],
        "dns-opts": [],
        "dns-search": [],
        "exec-opts": [],
        "experimental": false,
        "features":{},
        "storage-driver": "",
        "storage-opts": [],
        "labels": [],
        "log-driver": "",
        "mtu": 0,
        "pidfile": "",
        "cluster-store": "",
        "cluster-advertise": "",
        "max-concurrent-downloads": 3,
        "max-concurrent-uploads": 5,
        "shutdown-timeout": 15,
        "debug": true,
        "hosts": [],
        "log-level": "",
        "tlsverify": true,
        "tlscacert": "",
        "tlscert": "",
        "tlskey": "",
        "swarm-default-advertise-addr": "",
        "group": "",
        "default-ulimits": {},
        "bridge": "",
        "fixed-cidr": "",
        "raw-logs": false,
        "allow-nondistributable-artifacts": [],
        "registry-mirrors": [],
        "insecure-registries": []
    }
    

    使用容器部署 registry

    从容器运行 registry

    从容器安装一个 registry 非常简单:

    # 启动一个 regidtry 容器
    $ docker run -d -p 5000:5000 --name registry registry:2
    # --restart参数可以让容器自动重启
    $ docker run -d -p 5000:5000 --restart=always --name registry registry:2
    # 自定义端口
    $ docker run -d -p 5001:5000 --name registry-test registry:2
    # 自定义存储后端
    $ docker run -d -p 5000:5000 --restart=always --name registry -v /mnt/registry:/var/lib/registry registry:2
    
    # 从 hub 上拉取一个镜像
    $ docker pull ubuntu
    
    # 修改镜像 tag,将 tag 指向自建 registry
    docker image tag ubuntu localhost:5000/myfirstimage
    
    # 把镜像推送到自建 registry
    docker push localhost:5000/myfirstimage
    
    # 从自建 registry 上拉取镜像
    docker pull localhost:5000/myfirstimage
    
    # 停止registry容器并删除所有数据
    docker container stop registry && docker container rm -v registry
    

    运行一个可外部访问的 registry

    上面部署的 registry 只有本地可访问,用途有限;为了使registry可供外部访问,我们首先应使用 TLS 保护它。

    获取证书

    这里的示例假定已满足如下条件:

    • 你的 registry 的 URL 是 https://myregistry.domain.com/
    • registry 所在主机的443端口允许被访问
    • 你已经从证书颁发机构获取到了证书
    1. 创建certs 目录,并将从 CA 获取到的 .crt和 .key文件复制到 certs 目录;下面的步骤中假定文件名是domain.crtdomain.key

      $ mkdir -p certs
      
    2. 关闭当前运行的 registry:

      $ docker container stop registry
      
    3. 指定 TLS 证书后,重启 registry;下面的命令将 certs 目录绑定到容器的 /certs 目录上,并设置了环境变量,环境变量告诉容器在哪里可以找到domain.crtdomain.key

      $ docker run -d 
        --restart=always 
        --name registry 
        -v "$(pwd)"/certs:/certs 
        -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
      
    4. Docker客户端现在可以用外部地址拉取或推送镜像到你的 registry:

      $ docker pull ubuntu:16.04
      $ docker tag ubuntu:16.04 myregistry.domain.com/my-ubuntu
      $ docker push myregistry.domain.com/my-ubuntu
      $ docker pull myregistry.domain.com/my-ubuntu
      

    使用中间证书

    证书颁发机构可能会向你提供中间证书,这时,就必须将证书与中间证书连接起来,可使用如下命令完成连接:

    $ cat domain.crt intermediate-certificates.pem > certs/domain.crt
    

    可以使用自签名证书,或者使用不安全的 registry (无 TLS),除非已为自签名证书设置了验证,否则不推荐用于非测试环境。

    使用 yum 部署 registry

    下面的例子中以centos 为例,centos 版本为7.4.1708:

    # 安装
    $ yum install docker-registry
    # 实际安装的软件包是: docker-distribution
    # 我这里安装的是 docker-distribution-2.6.2-2.git48294d9.el7.x86_64
    
    # 查看有哪些文件
    $ rpm -ql docker-distribution-2.6.2-2.git48294d9.el7.x86_64
    /etc/docker-distribution/registry/config.yml
    /usr/bin/registry
    /usr/lib/systemd/system/docker-distribution.service
    /usr/share/doc/docker-distribution-2.6.2
    /usr/share/doc/docker-distribution-2.6.2/AUTHORS
    /usr/share/doc/docker-distribution-2.6.2/CONTRIBUTING.md
    /usr/share/doc/docker-distribution-2.6.2/LICENSE
    /usr/share/doc/docker-distribution-2.6.2/MAINTAINERS
    /usr/share/doc/docker-distribution-2.6.2/README.md
    /var/lib/registry
    
    
    

    可以看到,配置文件为/etc/docker-distribution/registry/config.yml,config.yml的格式为 yaml,

    # 默认配置
    $ cat /etc/docker-distribution/registry/config.yml
    version: 0.1   
    log: 
      fields:
        service: registry
    storage:
        cache:
            layerinfo: inmemory
        filesystem:
            rootdirectory: /var/lib/registry
    http:
        addr: :5000
    
    • version: 必填项,用于指定配置的版本

    • log :用户配置日志记录系统的行为,日志记录系统会将所有的内容输出到标准输出,通过 log 可以调整输出的格式和颗粒度:

      log:
        accesslog:
          disabled: true
        level: debug
        formatter: text
        fields:
          service: registry
          environment: staging
      
      ParameterRequired描述
      level no 设置日志输出级别. 可用的值有 errorwarninfodebug,默认是 info.
      formatter no 设置日志输出的格式,格式主要影响日志行中键控属性的编码方式,值可以是 textjsonlogstash。默认是 text.
      fields no 字段名和值的映射,会被添加到每个日志行的上下文中,对其他系统中混合日志消息源的识别很有用
    • accesslog:

      accesslog:
        disabled: true
      

      在 log 中,accesslog 记录访问日志记录系统的行为,默认访问日志记录系统会用组合日志格式输出到标准输出,通过将 disable 设置为 true 来禁用访问日志记录

    更多内容: https://docs.docker.com/registry/configuration/

    配置文件的可配置项

    参考 https://docs.docker.com/registry/configuration/

    version: 0.1
    log:
      accesslog:
        disabled: true
      level: debug
      formatter: text
      fields:
        service: registry
        environment: staging
      hooks:
        - type: mail
          disabled: true
          levels:
            - panic
          options:
            smtp:
              addr: mail.example.com:25
              username: mailuser
              password: password
              insecure: true
            from: sender@example.com
            to:
              - errors@example.com
    loglevel: debug # deprecated: use "log"
    storage:
      filesystem:
        rootdirectory: /var/lib/registry
        maxthreads: 100
      azure:
        accountname: accountname
        accountkey: base64encodedaccountkey
        container: containername
      gcs:
        bucket: bucketname
        keyfile: /path/to/keyfile
        credentials:
          type: service_account
          project_id: project_id_string
          private_key_id: private_key_id_string
          private_key: private_key_string
          client_email: client@example.com
          client_id: client_id_string
          auth_uri: http://example.com/auth_uri
          token_uri: http://example.com/token_uri
          auth_provider_x509_cert_url: http://example.com/provider_cert_url
          client_x509_cert_url: http://example.com/client_cert_url
        rootdirectory: /gcs/object/name/prefix
        chunksize: 5242880
      s3:
        accesskey: awsaccesskey
        secretkey: awssecretkey
        region: us-west-1
        regionendpoint: http://myobjects.local
        bucket: bucketname
        encrypt: true
        keyid: mykeyid
        secure: true
        v4auth: true
        chunksize: 5242880
        multipartcopychunksize: 33554432
        multipartcopymaxconcurrency: 100
        multipartcopythresholdsize: 33554432
        rootdirectory: /s3/object/name/prefix
      swift:
        username: username
        password: password
        authurl: https://storage.myprovider.com/auth/v1.0 or https://storage.myprovider.com/v2.0 or https://storage.myprovider.com/v3/auth
        tenant: tenantname
        tenantid: tenantid
        domain: domain name for Openstack Identity v3 API
        domainid: domain id for Openstack Identity v3 API
        insecureskipverify: true
        region: fr
        container: containername
        rootdirectory: /swift/object/name/prefix
      oss:
        accesskeyid: accesskeyid
        accesskeysecret: accesskeysecret
        region: OSS region name
        endpoint: optional endpoints
        internal: optional internal endpoint
        bucket: OSS bucket
        encrypt: optional data encryption setting
        secure: optional ssl setting
        chunksize: optional size valye
        rootdirectory: optional root directory
      inmemory:  # This driver takes no parameters
      delete:
        enabled: false
      redirect:
        disable: false
      cache:
        blobdescriptor: redis
      maintenance:
        uploadpurging:
          enabled: true
          age: 168h
          interval: 24h
          dryrun: false
        readonly:
          enabled: false
    auth:
      silly:
        realm: silly-realm
        service: silly-service
      token:
        autoredirect: true
        realm: token-realm
        service: token-service
        issuer: registry-token-issuer
        rootcertbundle: /root/certs/bundle
      htpasswd:
        realm: basic-realm
        path: /path/to/htpasswd
    middleware:
      registry:
        - name: ARegistryMiddleware
          options:
            foo: bar
      repository:
        - name: ARepositoryMiddleware
          options:
            foo: bar
      storage:
        - name: cloudfront
          options:
            baseurl: https://my.cloudfronted.domain.com/
            privatekey: /path/to/pem
            keypairid: cloudfrontkeypairid
            duration: 3000s
            ipfilteredby: awsregion
            awsregion: us-east-1, use-east-2
            updatefrenquency: 12h
            iprangesurl: https://ip-ranges.amazonaws.com/ip-ranges.json
      storage:
        - name: redirect
          options:
            baseurl: https://example.com/
    reporting:
      bugsnag:
        apikey: bugsnagapikey
        releasestage: bugsnagreleasestage
        endpoint: bugsnagendpoint
      newrelic:
        licensekey: newreliclicensekey
        name: newrelicname
        verbose: true
    http:
      addr: localhost:5000
      prefix: /my/nested/registry/
      host: https://myregistryaddress.org:5000
      secret: asecretforlocaldevelopment
      relativeurls: false
      draintimeout: 60s
      tls:
        certificate: /path/to/x509/public
        key: /path/to/x509/private
        clientcas:
          - /path/to/ca.pem
          - /path/to/another/ca.pem
        letsencrypt:
          cachefile: /path/to/cache-file
          email: emailused@letsencrypt.com
          hosts: [myregistryaddress.org]
      debug:
        addr: localhost:5001
        prometheus:
          enabled: true
          path: /metrics
      headers:
        X-Content-Type-Options: [nosniff]
      http2:
        disabled: false
    notifications:
      events:
        includereferences: true
      endpoints:
        - name: alistener
          disabled: false
          url: https://my.listener.com/event
          headers: <http.Header>
          timeout: 1s
          threshold: 10
          backoff: 1s
          ignoredmediatypes:
            - application/octet-stream
          ignore:
            mediatypes:
               - application/octet-stream
            actions:
               - pull
    redis:
      addr: localhost:6379
      password: asecret
      db: 0
      dialtimeout: 10ms
      readtimeout: 10ms
      writetimeout: 10ms
      pool:
        maxidle: 16
        maxactive: 64
        idletimeout: 300s
    health:
      storagedriver:
        enabled: true
        interval: 10s
        threshold: 3
      file:
        - file: /path/to/checked/file
          interval: 10s
      http:
        - uri: http://server.to.check/must/return/200
          headers:
            Authorization: [Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==]
          statuscode: 200
          timeout: 3s
          interval: 10s
          threshold: 3
      tcp:
        - addr: redis-server.domain.com:6379
          timeout: 3s
          interval: 10s
          threshold: 3
    proxy:
      remoteurl: https://registry-1.docker.io
      username: [username]
      password: [password]
    compatibility:
      schema1:
        signingkeyfile: /etc/registry/key.json
        enabled: true
    validation:
      manifests:
        urls:
          allow:
            - ^https?://([^/]+.)*example.com/
          deny:
            - ^https?://www.example.com/
    
  • 相关阅读:
    创建Variant数组
    ASP与存储过程(Stored Procedures)
    FileSystemObject对象成员概要
    Kotlin 朱涛9 委托 代理 懒加载 Delegate
    Kotlin 朱涛 思维4 空安全思维 平台类型 非空断言
    Kotlin 朱涛7 高阶函数 函数类型 Lambda SAM
    Kotlin 朱涛16 协程 生命周期 Job 结构化并发
    Proxy 代理模式 动态代理 cglib MD
    RxJava 设计理念 观察者模式 Observable lambdas MD
    动态图片 Movie androidgifdrawable GifView
  • 原文地址:https://www.cnblogs.com/resn/p/12553094.html
Copyright © 2011-2022 走看看