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 ```