前言

在企业落地 K8S 的过程中,私有镜像库 (专用镜像库) 必不可少,特别是在 Docker Hub 开始对免费用户限流之后, 越发的体现了搭建私有镜像库的重要性。

私有镜像库不但可以加速镜像的拉取还可以避免因特有的"网络问题"导致镜像拉取失败尴尬。

当然部署了私有镜像库之后也需要对镜像库设置一些安全策略,大部分私有镜像库采用 IP访问策略+认证 (非公开项目) 的方式对镜像库进行安全保护。

那么对于含有认证限制的镜像库,在 K8S 中该如何优雅的集成呢?

下文就总结了在 K8S 中使用私有镜像库的几种情况和方式。

在 K8S 中使用私有镜像库

首先要确定私有镜像库的授权使用方式,在针对不同的使用方式选择对应的认证配置。

  1. 针对节点 (Node)

    这个应该是企业使用 K8S 时最常用的方式,一般也只要使用这个就够了,并且该方案几乎是使用了私有镜像库之后必不可少的配置,它可以做到:

    在节点环境中进行一定的配置,不需要在 K8S 中进行其它的配置即可享有具体私有库的权限。

    该方案对该节点上的所有 Pods 生效,同时还对非 Pods 镜像生效,例如: kubelet 的 pause 镜像,这个非常关键

  2. 针对服务账号 (ServiceAccount)、针对命名空间 (Namespace)

    配置了该 ServiceAccount 的 Pod 都享有这个 ServiceAccount 所配置的镜像库认证设置。

    还可以利用 K8S 中 default ServiceAccount 机制,达到对一个具体命名空间中没有特殊设置的所有 Pod 生效。

  3. 针对 Pod

    针对具体的 Pod 进行认证配置,该 Pod 就会具有私有库的权限。

    Deployment、DaemonSet、StatefulSet、CronJob、Job 等资源都使用了PodTemplate 最终都会以具体的 Pod 资源体验,所以在 PodTemplate 中配置也算对 Pod 配置。

配置步骤

前提条件

  1. 一个可用私有镜像库 (可用采用 Harbor 搭建)
  2. 私有镜像库的账号和密码 (推荐只给只读权限)
  3. CRI 基于 Docker (其它的 CRI 暂没有验证)

针对节点 (Node) 配置

  1. 编写 Docker 配置文件
  2. 将 Docker 配置文件放在指定位置
  3. 重启 kubelet

编写 Docker 配置文件

首先编写 Docker 的认证配置文件, 格式如下:

{
"auths": {
"<HOST>": {
"auth": "<BASIC_AUTHORIZATION>"
}
}
}

<HOST> 为私有镜像库的地址, 例如: hub.docker.com

<BASIC_AUTHORIZATION>BASE64(<USERNAME>:<PASSWORD>)

例如: cmVhZGVyOjEyMzQ1Ng==, 其中账号是: reader, 密码是: 123456

使用 : 拼接后进行 base64

完整的配置文件, 例

{
"auths": {
"hub.docker.com": {
"auth": "cmVhZGVyOjEyMzQ1Ng=="
},
"harbor.domain.cn": {
"auth": "cmVhZGVyOiFAIzQ1Ng=="
}
}
}

如有多个镜像库在 auths 节中进行添加即可。

将 Docker 配置文件放在指定位置

推荐放在 kubelet 根目录中, 配置文件需以 config.json 命名。

默认的 kubelet 根目录一般为 /var/lib/kubelet (如有修改进行替换即可)

也就是需要放置在 /var/lib/kubelet/config.json

还可以放在以下位置:

{--root-dir:-/var/lib/kubelet}/config.json
{cwd of kubelet}/config.json
${HOME}/.docker/config.json
/.docker/config.json
{--root-dir:-/var/lib/kubelet}/.dockercfg
{cwd of kubelet}/.dockercfg
${HOME}/.dockercfg
/.dockercfg

参考文档:

https://kubernetes.io/docs/concepts/containers/images/#configuring-nodes-to-authenticate-to-a-private-registry

放在 ${HOME} 开头的位置

需要在 kubelet service 环境中配置 HOME 的路径, 不然不会生效, 例如: HOME=/root

下面是使用 kubeadm 安装的环境中可用的脚本, 如果不是请自行配置

echo "HOME=${HOME}" >> /var/lib/kubelet/kubeadm-flags.env

重启 kubelet

如果 init 不是 systemd,请自行替换服务重启的命令

systemctl daemon-reload; systemctl restart kubelet

针对服务账号 (ServiceAccount)、针对命名空间 (Namespace)

  1. 创建一个 Docker 注册表机密资源
  2. 设置 ServiceAccount 的 imagePullSecrets
  3. 将 Pod 的 serviceAccountName 设置为该 ServiceAccount 的名称

创建一个 Docker 注册表机密资源

使用 kubectl cli 创建注册表机密资源

kubectl create secret docker-registry <SECRET_NAME> --docker-server=<DOCKER_REGISTRY_SERVER> --docker-username=<DOCKER_USER> --docker-password=<DOCKER_PASSWORD> -n <NAMESPACE>

其中

<SECRET_NAME> 是机密资源的名称, 在编辑 sa 资源的时需要引用

<DOCKER_REGISTRY_SERVER> 是私有镜像库的服务器地址

<DOCKER_USER> 是私有镜像库认证的账号

<DOCKER_PASSWORD> 是私有镜像库认证的密码

<NAMESPACE> 是命名空间名称

示例命令如下:

kubectl create secret docker-registry docker-reader-secret --docker-server=harbor.domain.cn --docker-username=reader --docker-password=123456 -n basic

使用 yaml 创建注册表机密资源

apiVersion: v1
data:
.dockerconfigjson: eyJhdXRocyI6eyJET0NLRVJfUkVHSVNUUllfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImF1dGgiOiJSRTlEUzBWU1gxVlRSVkk2UkU5RFMwVlNYMUJCVTFOWFQxSkUifX19
kind: Secret
metadata:
name: docker-reader-secret
namespace: default
type: kubernetes.io/dockerconfigjson

.dockerconfigjson 是base64之后的字符串, 具体内容参考 "编写 Docker 配置文件" 节中的内容

kubectl apply -f docker-reader-secret.yaml

设置 ServiceAccount 的 imagePullSecrets

apiVersion: v1
kind: ServiceAccount
metadata:
name: service1
namespace: basic
secrets:
- name: service1-token-mp4qs
imagePullSecrets:
- name: docker-reader-secret

将资源的 serviceAccountName 设置为该 ServiceAccount 的名称

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
serviceAccountName: service1

如何针对命名空间内的所有Pod?

K8S 中有个默认的机制,会在命名空间中创建一个名称为 default 的 ServiceAccount (sa) 资源。

并且在资源没有单独指定 serviceAccountName 时, 默认使用 default 作为serviceAccountName。

所以我们只需设置 default ServiceAccount 的 imagePullSecrets 即可对该命名空间中没有特殊指定 serviceAccountName 字段的 Pod 生效了。

针对 Pod

  1. 创建一个 Docker 注册表机密资源
  2. 设置 Pod 的 imagePullSecrets

创建一个 Docker 注册表机密资源

参考 "创建一个 Docker 注册表机密资源" 节中的内容

一个具体的 Pod

apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: docker-reader-secret

针对具有 PodTemplate 内容的资源

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
imagePullSecrets:
- name: docker-reader-secret

最后

如果大家的私有镜像库还没有采用认证,就赶紧行动起来吧!

血的教训,安全问题刻不容缓。

如何在K8S中优雅的使用私有镜像库 (Docker版)的更多相关文章

  1. Docker 安装私有镜像库的简单使用

    公司的网络实在是太差了, 想着自己搭建一个私有的镜像库进行使用测试使用.... docker pull registry.docker-cn.com/library/registry docker t ...

  2. 160803、如何在ES6中管理类的私有数据

    如何在ES6中管理类的私有数据?本文为你介绍四种方法: 在类的构造函数作用域中处理私有数据成员 遵照命名约定(例如前置下划线)标记私有属性 将私有数据保存在WeakMap中 使用Symbol作为私有属 ...

  3. 如何在MyBatis中优雅的使用枚举

    问题 在编码过程中,经常会遇到用某个数值来表示某种状态.类型或者阶段的情况,比如有这样一个枚举:   public enum ComputerState { OPEN(10), //开启 CLOSE( ...

  4. 如何在 Swoole 中优雅的实现 MySQL 连接池

    如何在 Swoole 中优雅的实现 MySQL 连接池 一.为什么需要连接池 ? 数据库连接池指的是程序和数据库之间保持一定数量的连接不断开, 并且各个请求的连接可以相互复用, 减少重复连接数据库带来 ...

  5. docker搭建harbor私有镜像库

    创建harbor私有镜像库 一.部署准备: harbor软件包   在部署节点上: 1)解压harbor的软件包将harbor目录下所有文件发送到/opt/目录下   tar zxvf harbor- ...

  6. 第4篇创建harbor私有镜像库

        一.部署准备: 1.准备harbor软件包       在部署节点上:       2.挂载一个磁盘,专门存储harbor镜像和文件     3.进入到/etc/docker/harbor/目 ...

  7. 【下一代核心技术DevOps】:(四)私有镜像库阿里云Docker服务使用

    1.使用阿里云镜像库有很多优点 稳定可靠,阿里技术,放心使用. 国内cdn多节点加速,下载速度非常快 可以和阿里云Git代码集成,不需要第三方CI工具,当然带的自动构建服务也可以和其他的Git库集成, ...

  8. docker从私有镜像库pull/push镜像问题:Error response from daemon: Get https://xxxx.com/: x509: certificate signed by unknown authority

    docker从私有镜像库pull/push镜像问题:Error response from daemon: Get https://harbor.op.xxxx.com/v2/: x509: cert ...

  9. 如何在Vue中优雅的使用防抖节流

    1. 什么是防抖节流 防抖:防止重复点击触发事件 首先啥是抖? 抖就是一哆嗦!原本点一下,现在点了3下!不知道老铁脑子是不是很有画面感!哈哈哈哈哈哈 典型应用就是防止用户多次重复点击请求数据. 代码实 ...

随机推荐

  1. C#(二)基础篇—操作符

    2020-12-02 本随笔为个人复习巩固知识用,多从书上总结与理解得来,如有错误麻烦指正 1.数学操作符 int a=2,b=3,c=0; float d=0; c=a+b; //c=5 c++; ...

  2. crash安装使用

     cash作为Linux内核调试的工具是必不可少少的一部分,但是他的下载并不是 yum install一下这么简单的,本文就来讲一下如何安装crash进行调试.  首先就是了解Linux的内核版本.这 ...

  3. PyQt学习随笔:QTextEdit和QTextBrowser删除光标所在行内容的方法

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 在使用QTextBrowser用于记录输出日志,并 ...

  4. PyQt(Python+Qt)学习随笔:QTableWidgetItem项操作相关的flags、isSelected、checkState方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget中项操作相关的属性包括是否可用.是否可选中.是否可编辑.是否可复选.是否选中 ...

  5. PyQt学习随笔:使用PyCharm+PyQt开发遇到的坑

    最近三天,老猿都在使用PyCharm+QtDesigner工具,通过xlwings读取Excel的数据到TableView中显示的练习,本以为很容易的一件事,断断续续持续了三天时间才终于成功.在这个过 ...

  6. PyQt(Python+Qt)学习随笔:QAbstractScrollArea的viewPort(视口)理解

    老猿Python博文目录 老猿Python博客地址 在学习Designer中ItemViews类部件时,这些部件都有个父类QAbstractScrollArea,该父类是Qt滚动区域的低级抽象.该区域 ...

  7. RedHat操作指令第3篇

    系统信息 arch 显示机器的处理器架构 uname -m 显示机器的处理器架构 uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS / DMI) ...

  8. crawlergo动态爬虫去除Spidername使用

    本来是想用AWVS的爬虫来联动Xray的,但是需要主机安装AWVS,再进行规则联动,只是使用其中的目标爬虫功能感觉就太重了,在github上面找到了由360 0Kee-Team团队从360天相中分离出 ...

  9. 重磅!Panda Global获悉立陶宛下周将发行区块链数字货币!

    近日,Panda Global从路透社获悉,立陶宛将在下周开始预售2.4万枚由央行发行的数字货币.该名为LBCoin的数字货币基于区块链技术生产,也是该国试点具有国家支持背景的数字货币和区块链技术的项 ...

  10. 基于Fisco-Bcos的区块链智能合约-简单案例实践

    一.智能合约介绍 智能合约是指把合同/协议条款以代码的形式电子化地放到区块链网络上.FISCO BCOS平台支持两种智能合约类型:Solidity智能合约与预编译智能合约 Solidity与Java类 ...