github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/docs/site/src/zh/advanced/define-cloudimage.md (about)

     1  # 自定义Cloud image
     2  
     3  ## 自定义CloudRootfs
     4  
     5  运行kubernetes集群所需的所有文件。
     6  
     7  其中包含:
     8  
     9  * Bin 文件,如 docker、containerd、crictl、kubeadm、kubectl...
    10  * 配置文件,如 kubelet systemd config、docker systemd config、docker daemon.json...
    11  * 注册docker镜像。
    12  * 一些元数据,例如 Kubernetes 版本
    13  * 注册表文件,包含所有的docker镜像,比如kubernetes核心组件docker镜像...* Scripts, some shell script using to install docker and kubelet... sealer will call init.sh and clean.sh.
    14  * 其他静态文件
    15  
    16  rootfs 树状图
    17  
    18  ```
    19  .
    20  ├── bin
    21  │   ├── conntrack
    22  │   ├── containerd-rootless-setuptool.sh
    23  │   ├── containerd-rootless.sh
    24  │   ├── crictl
    25  │   ├── kubeadm
    26  │   ├── kubectl
    27  │   ├── kubelet
    28  │   ├── nerdctl
    29  │   └── seautil
    30  ├── cri
    31  │   └── docker.tar.gz # cri 二进制文件包括 docker、containerd、runc。
    32  ├── etc
    33  │   ├── 10-kubeadm.conf
    34  │   ├── Clusterfile  # 镜像默认集群文件
    35  │   ├── daemon.json # docker 守护进程配置文件。
    36  │   ├── docker.service
    37  │   ├── kubeadm.yml # kubeadm config 包括 Cluster Configuration、JoinConfiguration 等。
    38  │   ├── kubelet.service
    39  │   ├── registry_config.yml # docker 注册表配置,包括存储根目录和 http 相关配置。
    40  │   └── registry.yml # 如果用户想自定义用户名和密码,可以覆盖这个文件。
    41  ├── images
    42  │   └── registry.tar  # 注册docker镜像,将加载此镜像并在集群中运行本地注册表
    43  ├── Kubefile
    44  ├── Metadata
    45  ├── README.md
    46  ├── registry # 将此目录挂载到本地注册表
    47  │   └── docker
    48  │       └── registry
    49  ├── scripts
    50  │   ├── clean.sh
    51  │   ├── docker.sh
    52  │   ├── init-kube.sh
    53  │   ├── init-registry.sh
    54  │   ├── init.sh
    55  │   └── kubelet-pre-start.sh
    56  └── statics # yaml文件, sealer 将渲染这些文件中的值
    57      └── audit-policy.yml
    58  ```
    59  
    60  ### 如何获取 CloudRootfs
    61  
    62  1. 拉取基础镜像 `sealer pull kubernetes:v1.19.8-alpine`
    63  2. 查看镜像层信息 `sealer inspect kubernetes:v1.19.8-alpine`
    64  3. 进入BaseImage层 `ls /var/lib/sealer/data/overlay2/{layer-id}`
    65  
    66  您将找到 CloudRootfs 层。
    67  
    68  ### 构建自己的 CloudRootfs
    69  
    70  您可以在 CloudRootfs 中编辑您想要的任何文件,例如您想定义自己的 docker daemon.json,只需编辑它并构建一个新的 CloudImage。
    71  
    72  ```shell script
    73  FROM scratch
    74  COPY . .
    75  ```
    76  
    77  ```shell script
    78  sealer build -t user-defined-kubernetes:v1.19.8 .
    79  ```
    80  
    81  然后,您可以将此镜像用作 BaseImage。
    82  
    83  ### 覆盖 CloudRootfs 文件
    84  
    85  有时您不想关心 CloudRootfs 上下文,但需要自定义一些配置。
    86  
    87  您可以使用 `kubernetes:v1.19.8` 作为 BaseImage,并使用自己的配置文件覆盖 CloudRootfs 中的默认文件。
    88  
    89  例如:daemon.json 是您的 docker 引擎配置,使用它来覆盖默认配置:
    90  
    91  ```shell script
    92  FROM kubernetes:v1.19.8
    93  COPY daemon.json etc/
    94  ```
    95  
    96  ```shell script
    97  sealer build -t user-defined-kubernetes:v1.19.8 .
    98  ```
    99  
   100  ## 构建cloud image
   101  
   102  ### 使用特定目录构建
   103  
   104  #### image目录
   105  
   106  保存容器镜像的目录,该目录下的离线镜像会在sealer运行时加载到内置注册表中。
   107  
   108  示例:将离线 tar 文件复制到此目录。
   109  
   110  `COPY mysql.tar images`
   111  
   112  #### plugin目录
   113  
   114  插件文件保存目录,该目录下的插件文件会在sealer运行时加载到运行界面。
   115  
   116  示例:将插件配置文件复制到此目录。
   117  
   118  插件配置:shell.yaml:
   119  
   120  ```
   121  apiVersion: sealer.aliyun.com/v1alpha1
   122  kind: Plugin
   123  metadata:
   124    name: taint
   125  spec:
   126    type: SHELL
   127    action: PostInstall
   128    on: node-role.kubernetes.io/master=
   129    data: |
   130       kubectl taint nodes --all node-role.kubernetes.io/master-
   131  ```
   132  
   133  `COPY shell.yaml plugins`
   134  
   135  #### charts目录
   136  
   137  保存charts包的目录,sealer构建时会解析该目录下的charts文件,下载并保存对应的容器镜像。
   138  
   139  示例:将 nginx charts复制到此目录。
   140  
   141  `COPY nginx charts`
   142  
   143  #### manifests目录
   144  
   145  保存yaml文件或“imageList”文件的目录,sealer构建时会解析该目录下的yaml和“imageList”文件,下载并保存对应的容器镜像。
   146  
   147  示例:将“imageList”文件复制到此目录。
   148  
   149  ```shell
   150  [root@iZbp143f9driomgoqx2krlZ build]# cat imageList
   151  busybox
   152  ```
   153  
   154  `COPY imageList manifests`
   155  
   156  示例:将仪表板 yaml 文件复制到此目录。
   157  
   158  `COPY recommend.yaml manifests`
   159  
   160  ### 自定义私有registry
   161  
   162  Sealer对docker registry进行了优化和扩展,使其可以同时支持多个域名的代理缓存和多个私有registry。
   163  
   164  在构建过程中,会出现使用需要身份验证的私有registry的情况。在这种情况下,镜像缓存需要 docker 的身份验证。在执行构建操作之前,可以先通过以下命令进行登录操作:
   165  
   166  ```shell
   167  sealer login registry.com -u username -p password
   168  ```
   169  
   170  另一种依赖场景,kubernetes节点通过sealer内置registry代理私有registry,私有registry需要认证,可以通过自定义registryconfig配置。参考 [registry config](../../../../design/docker-image-cache.md)
   171  
   172  您可以通过定义 Kubefile 来自定义注册表配置:
   173  
   174  ```shell
   175  FROM kubernetes:v1.19.8
   176  COPY registry_config.yaml etc/
   177  ```
   178  
   179  ### 自定义 kubeadm 配置
   180  
   181  Sealer 会将默认配置替换为 $Rootfs/etc/kubeadm.yml 中的自定义配置文件。
   182  
   183  #### 示例:使用 Docker Unix socket的自定义配置。
   184  
   185  1. 自定义 kubeadm 初始化配置:
   186  
   187  ```yaml
   188  apiVersion: kubeadm.k8s.io/v1beta2
   189  kind: InitConfiguration
   190  localAPIEndpoint:
   191    bindPort: 6443
   192  nodeRegistration:
   193    criSocket: /var/run/dockershim.sock
   194  ```
   195  
   196  2. 自定义 kubeadm join 配置:
   197  
   198  ```yaml
   199  apiVersion: kubeadm.k8s.io/v1beta2
   200  kind: JoinConfiguration
   201  caCertPath: /etc/kubernetes/pki/ca.crt
   202  discovery:
   203    timeout: 5m0s
   204  nodeRegistration:
   205    criSocket: /var/run/dockershim.sock
   206  controlPlane:
   207    localAPIEndpoint:
   208      bindPort: 6443
   209  ```
   210  
   211  3. 构建您自己的云映像,使用自定义配置覆盖默认配置。请注意,文件名“kubeadm.yml”是固定的:
   212  
   213  ```yaml
   214  #Kubefile
   215  FROM kubernetes-clusterv2:v1.19.8
   216  COPY kubeadm.yml etc
   217  ```
   218  
   219  > sealer build -t user-define-kubeadm-kubernetes:v1.19.8 .
   220  
   221  #### 包含完整内容的默认 kubeadm 配置文件:
   222  
   223  选择 kubeadm.yml 的任何部分进行自定义:
   224  
   225  ```yaml
   226  apiVersion: kubeadm.k8s.io/v1beta2
   227  kind: InitConfiguration
   228  localAPIEndpoint:
   229    # advertiseAddress: 192.168.2.110
   230    bindPort: 6443
   231  nodeRegistration:
   232    criSocket: /var/run/dockershim.sock
   233  
   234  ---
   235  apiVersion: kubeadm.k8s.io/v1beta2
   236  kind: ClusterConfiguration
   237  kubernetesVersion: v1.19.8
   238  #controlPlaneEndpoint: "apiserver.cluster.local:6443"
   239  imageRepository: sea.hub:5000/library
   240  networking:
   241    # dnsDomain: cluster.local
   242    podSubnet: 100.64.0.0/10
   243    serviceSubnet: 10.96.0.0/22
   244  apiServer:
   245    #  certSANs:
   246    #    - 127.0.0.1
   247    #    - apiserver.cluster.local
   248    #    - aliyun-inc.com
   249    #    - 10.0.0.2
   250    #    - 10.103.97.2
   251    extraArgs:
   252      #    etcd-servers: https://192.168.2.110:2379
   253      feature-gates: TTLAfterFinished=true,EphemeralContainers=true
   254      audit-policy-file: "/etc/kubernetes/audit-policy.yml"
   255      audit-log-path: "/var/log/kubernetes/audit.log"
   256      audit-log-format: json
   257      audit-log-maxbackup: '10'
   258      audit-log-maxsize: '100'
   259      audit-log-maxage: '7'
   260      enable-aggregator-routing: 'true'
   261    extraVolumes:
   262      - name: "audit"
   263        hostPath: "/etc/kubernetes"
   264        mountPath: "/etc/kubernetes"
   265        pathType: DirectoryOrCreate
   266      - name: "audit-log"
   267        hostPath: "/var/log/kubernetes"
   268        mountPath: "/var/log/kubernetes"
   269        pathType: DirectoryOrCreate
   270      - name: localtime
   271        hostPath: /etc/localtime
   272        mountPath: /etc/localtime
   273        readOnly: true
   274        pathType: File
   275  controllerManager:
   276    extraArgs:
   277      feature-gates: TTLAfterFinished=true,EphemeralContainers=true
   278      experimental-cluster-signing-duration: 876000h
   279    extraVolumes:
   280      - hostPath: /etc/localtime
   281        mountPath: /etc/localtime
   282        name: localtime
   283        readOnly: true
   284        pathType: File
   285  scheduler:
   286    extraArgs:
   287      feature-gates: TTLAfterFinished=true,EphemeralContainers=true
   288    extraVolumes:
   289      - hostPath: /etc/localtime
   290        mountPath: /etc/localtime
   291        name: localtime
   292        readOnly: true
   293        pathType: File
   294  etcd:
   295    local:
   296      extraArgs:
   297        listen-metrics-urls: http://0.0.0.0:2381
   298  ---
   299  apiVersion: kubeproxy.config.k8s.io/v1alpha1
   300  kind: KubeProxyConfiguration
   301  mode: "ipvs"
   302  ipvs:
   303    excludeCIDRs:
   304      - "10.103.97.2/32"
   305  
   306  ---
   307  apiVersion: kubelet.config.k8s.io/v1beta1
   308  kind: KubeletConfiguration
   309  authentication:
   310    anonymous:
   311      enabled: false
   312    webhook:
   313      cacheTTL: 2m0s
   314      enabled: true
   315    x509:
   316      clientCAFile: /etc/kubernetes/pki/ca.crt
   317  authorization:
   318    mode: Webhook
   319    webhook:
   320      cacheAuthorizedTTL: 5m0s
   321      cacheUnauthorizedTTL: 30s
   322  cgroupDriver:
   323  cgroupsPerQOS: true
   324  clusterDomain: cluster.local
   325  configMapAndSecretChangeDetectionStrategy: Watch
   326  containerLogMaxFiles: 5
   327  containerLogMaxSize: 10Mi
   328  contentType: application/vnd.kubernetes.protobuf
   329  cpuCFSQuota: true
   330  cpuCFSQuotaPeriod: 100ms
   331  cpuManagerPolicy: none
   332  cpuManagerReconcilePeriod: 10s
   333  enableControllerAttachDetach: true
   334  enableDebuggingHandlers: true
   335  enforceNodeAllocatable:
   336    - pods
   337  eventBurst: 10
   338  eventRecordQPS: 5
   339  evictionHard:
   340    imagefs.available: 15%
   341    memory.available: 100Mi
   342    nodefs.available: 10%
   343    nodefs.inodesFree: 5%
   344  evictionPressureTransitionPeriod: 5m0s
   345  failSwapOn: true
   346  fileCheckFrequency: 20s
   347  hairpinMode: promiscuous-bridge
   348  healthzBindAddress: 127.0.0.1
   349  healthzPort: 10248
   350  httpCheckFrequency: 20s
   351  imageGCHighThresholdPercent: 85
   352  imageGCLowThresholdPercent: 80
   353  imageMinimumGCAge: 2m0s
   354  iptablesDropBit: 15
   355  iptablesMasqueradeBit: 14
   356  kubeAPIBurst: 10
   357  kubeAPIQPS: 5
   358  makeIPTablesUtilChains: true
   359  maxOpenFiles: 1000000
   360  maxPods: 110
   361  nodeLeaseDurationSeconds: 40
   362  nodeStatusReportFrequency: 10s
   363  nodeStatusUpdateFrequency: 10s
   364  oomScoreAdj: -999
   365  podPidsLimit: -1
   366  port: 10250
   367  registryBurst: 10
   368  registryPullQPS: 5
   369  rotateCertificates: true
   370  runtimeRequestTimeout: 2m0s
   371  serializeImagePulls: true
   372  staticPodPath: /etc/kubernetes/manifests
   373  streamingConnectionIdleTimeout: 4h0m0s
   374  syncFrequency: 1m0s
   375  volumeStatsAggPeriod: 1m0s
   376  ---
   377  apiVersion: kubeadm.k8s.io/v1beta2
   378  kind: JoinConfiguration
   379  caCertPath: /etc/kubernetes/pki/ca.crt
   380  discovery:
   381    timeout: 5m0s
   382  nodeRegistration:
   383    criSocket: /var/run/dockershim.sock
   384  controlPlane:
   385    localAPIEndpoint:
   386      bindPort: 6443
   387  ```