diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index c78a323b24..2fc61e6fd5 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -6,5 +6,6 @@ - [AWS](./capi/providers/aws.md) - [Azure](./capi/providers/azure.md) - [DigitalOcean](./capi/providers/digitalocean.md) + - [OpenStack](./capi/providers/openstack.md) - [vSphere](./capi/providers/vsphere.md) - [Glossary](./glossary.md) diff --git a/docs/book/src/capi/capi.md b/docs/book/src/capi/capi.md index cdbfbb8085..46a5d7e960 100644 --- a/docs/book/src/capi/capi.md +++ b/docs/book/src/capi/capi.md @@ -13,6 +13,7 @@ The Image Builder can be used to build images intended for use with Kubernetes [ * [Azure](./providers/azure.md) * [DigitalOcean](./providers/digitalocean.md) * Google *TODO* +* [OpenStack](./providers/openstack.md) * [vSphere](./providers/vsphere.md) ## Make targets diff --git a/docs/book/src/capi/providers/openstack.md b/docs/book/src/capi/providers/openstack.md new file mode 100644 index 0000000000..fc5bd5a14b --- /dev/null +++ b/docs/book/src/capi/providers/openstack.md @@ -0,0 +1,20 @@ +# Building Images for OpenStack + +## Prerequisites + +The `make deps-qemu` target will test that Ansible and Packer are installed and available. If they are not, they will be installed to `images/capi/.bin`. This directory will need to be added to your `$PATH`. + +### Hypervisor + +The image is built using KVM hypervisor. + +### Prerequisites for all images + +- [Packer](https://www.packer.io/intro/getting-started/install.html) +- [Ansible](http://docs.ansible.com/ansible/latest/intro_installation.html) version >= 2.8.0 + +## Building Images + +### Building QCOW2 Image + +From the `images/capi` directory, run `make build-qemu-ubuntu-1804`. The image is built and located in `images/capi/output/BUILD_NAME+kube-KUBERNETES_VERSION`. diff --git a/images/capi/Makefile b/images/capi/Makefile index d038c714d6..c37c76ca31 100644 --- a/images/capi/Makefile +++ b/images/capi/Makefile @@ -72,6 +72,12 @@ deps-ova: hack/ensure-ansible.sh hack/ensure-packer.sh +.PHONY: deps-qemu +deps-qemu: ## Installs/checks dependencies for QEMU builds +deps-qemu: + hack/ensure-ansible.sh + hack/ensure-packer.sh + ## -------------------------------------- ## Packer flags ## -------------------------------------- @@ -127,6 +133,8 @@ AZURE_BUILD_NAMES ?= azure-sig-ubuntu-1804 azure-vhd-ubuntu-1804 DO_BUILD_NAMES ?= do-default +QEMU_BUILD_NAMES ?= qemu-ubuntu-1804 + ## -------------------------------------- ## Dynamic build targets ## -------------------------------------- @@ -136,6 +144,7 @@ AMI_BUILD_TARGETS := $(addprefix build-,$(AMI_BUILD_NAMES)) GCE_BUILD_TARGETS := $(addprefix build-,$(GCE_BUILD_NAMES)) AZURE_BUILD_TARGETS := $(addprefix build-,$(AZURE_BUILD_NAMES)) DO_BUILD_TARGETS := $(addprefix build-,$(DO_BUILD_NAMES)) +QEMU_BUILD_TARGETS := $(addprefix build-,$(QEMU_BUILD_NAMES)) .PHONY: $(OVA_BUILD_TARGETS) $(OVA_BUILD_TARGETS): @@ -161,6 +170,11 @@ $(DO_BUILD_TARGETS): packer build $(PACKER_FLAGS) -var-file="$(abspath packer/digitalocean/$(subst build-,,$@).json)" $(PACKER_VAR_FILES) packer/digitalocean/packer.json .PHONY: $(DO_BUILD_TARGETS) +$(QEMU_BUILD_TARGETS): + packer build $(PACKER_FLAGS) -var-file="$(abspath packer/qemu/$(subst build-,,$@).json)" $(PACKER_VAR_FILES) packer/qemu/packer.json +.PHONY: $(QEMU_BUILD_TARGETS) + + ## -------------------------------------- ## Dynamic clean targets ## -------------------------------------- @@ -169,6 +183,11 @@ OVA_CLEAN_TARGETS := $(subst build-,clean-,$(OVA_BUILD_TARGETS)) $(OVA_CLEAN_TARGETS): rm -fr output/$(subst clean-ova-,,$@)* +QEMU_CLEAN_TARGETS := $(subst build-,clean-,$(QEMU_BUILD_TARGETS)) +.PHONY: $(QEMU_CLEAN_TARGETS) +$(QEMU_CLEAN_TARGETS): + rm -fr output/$(subst clean-qemu-,,$@)* + ## -------------------------------------- ## Document dynamic build targets ## -------------------------------------- @@ -192,18 +211,24 @@ build-esx-photon-3: ## Builds Photon 3 OVA w remote hypervisor build-esx-ubuntu-1804: ## Builds Ubuntu 18.04 OVA w remote hypervisor build-esx-ubuntu-2004: ## Builds Ubuntu 20.04 OVA w remote hypervisor +build-qemu-ubuntu-1804: ## Builds Ubuntu 18.04 QEMU image + ## -------------------------------------- ## Clean targets ## -------------------------------------- ##@ Cleaning -.PHONY: clean-ova +.PHONY: clean clean: ## Cleans all local image caches -clean: $(OVA_CLEAN_TARGETS) clean-packer-cache +clean: $(OVA_CLEAN_TARGETS) $(QEMU_CLEAN_TARGETS) clean-packer-cache .PHONY: clean-ova clean-ova: ## Removes all ova image output directories (see NOTE at top of help) clean-ova: $(OVA_CLEAN_TARGETS) +.PHONY: clean-qemu +clean-qemu: ## Removes all qemu image output directories (see NOTE at top of help) +clean-qemu: $(QEMU_CLEAN_TARGETS) + .PHONY: clean-packer-cache clean-packer-cache: ## Removes the packer cache clean-packer-cache: diff --git a/images/capi/ansible/roles/providers/tasks/main.yml b/images/capi/ansible/roles/providers/tasks/main.yml index fffa5c97b7..6025fce68d 100644 --- a/images/capi/ansible/roles/providers/tasks/main.yml +++ b/images/capi/ansible/roles/providers/tasks/main.yml @@ -23,3 +23,6 @@ - include_tasks: googlecompute.yml when: packer_builder_type.startswith('googlecompute') + +- include_tasks: qemu.yml + when: packer_builder_type is search('qemu') diff --git a/images/capi/ansible/roles/providers/tasks/qemu.yml b/images/capi/ansible/roles/providers/tasks/qemu.yml new file mode 100644 index 0000000000..a40683fba0 --- /dev/null +++ b/images/capi/ansible/roles/providers/tasks/qemu.yml @@ -0,0 +1,57 @@ +# Copyright 2020 The Kubernetes Authors. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +- name: Install cloud-init packages + apt: + name: "{{ packages }}" + state: present + force_apt_get: yes + vars: + packages: + - cloud-init + - cloud-guest-utils + - cloud-initramfs-copymods + - cloud-initramfs-dyn-netconf + - cloud-initramfs-growroot + when: ansible_os_family == "Debian" + +- name: Install cloud-init packages + yum: + name: "{{ packages }}" + state: present + vars: + packages: + - cloud-init + - cloud-utils-growpart + when: ansible_os_family == "RedHat" + +#- name: Unlock password +# replace: +# path: /etc/cloud/cloud.cfg +# regexp: '(?i)lock_passwd: True' +# replace: 'lock_passwd: False' + +- name: Symlink /usr/libexec/cloud-init to /usr/lib/cloud-init + file: + src: /usr/libexec/cloud-init + dest: /usr/lib/cloud-init + state: link + when: ansible_os_family == "RedHat" + +- name: Disable Hyper-V KVP protocol daemon on Ubuntu + systemd: + name: hv-kvp-daemon + state: stopped + enabled: false + when: ansible_os_family == "Debian" diff --git a/images/capi/packer/qemu/linux b/images/capi/packer/qemu/linux new file mode 120000 index 0000000000..2df94647a5 --- /dev/null +++ b/images/capi/packer/qemu/linux @@ -0,0 +1 @@ +../ova/linux \ No newline at end of file diff --git a/images/capi/packer/qemu/packer.json b/images/capi/packer/qemu/packer.json new file mode 100644 index 0000000000..7670fbb4a4 --- /dev/null +++ b/images/capi/packer/qemu/packer.json @@ -0,0 +1,90 @@ +{ + "variables": { + "ansible_common_vars": "", + "ansible_extra_vars": "", + "boot_wait": "10s", + "build_timestamp": "{{timestamp}}", + "containerd_version": null, + "containerd_sha256": null, + "containerd_url": "https://storage.googleapis.com/cri-containerd-release/cri-containerd-{{user `containerd_version`}}.linux-amd64.tar.gz", + "existing_ansible_ssh_args": "{{env `ANSIBLE_SSH_ARGS`}}", + "extra_debs": "", + "extra_repos": "", + "extra_rpms": "", + "accelerator": "kvm", + "cpus": "1", + "disk_size": "20480", + "memory": "2048", + "format": "qcow2", + "headless": "true", + "kubernetes_cni_deb_version": null, + "kubernetes_cni_semver": null, + "kubernetes_cni_source_type": null, + "kubernetes_cni_http_source": null, + "kubernetes_series": null, + "kubernetes_semver": null, + "kubernetes_source_type": null, + "kubernetes_http_source": null, + "kubernetes_rpm_version": null, + "kubernetes_deb_version": null, + "kubernetes_rpm_repo": null, + "kubernetes_rpm_gpg_key": null, + "kubernetes_deb_repo": null, + "kubernetes_deb_gpg_key": null, + "kubernetes_rpm_gpg_check": null, + "kubernetes_container_registry": null, + "output_directory": "./output/{{user `build_name`}}-kube-{{user `kubernetes_semver`}}", + "reenable_public_repos": "true", + "remove_extra_repos": "false", + "qemu_binary": "qemu-system-x86_64", + "ssh_password": "builder", + "ssh_username": "builder" + }, + "builders": [ + { + "name": "{{ user `build_name`}}", + "vm_name": "{{user `build_name`}}-kube-{{user `kubernetes_semver`}}", + "output_directory": "{{user `output_directory`}}", + "type": "qemu", + "accelerator": "{{user `accelerator`}}", + "cpus": "{{user `cpus`}}", + "disk_size": "{{user `disk_size`}}", + "memory": "{{user `memory`}}", + "boot_wait": "{{user `boot_wait`}}", + "disk_interface": "virtio-scsi", + "format": "{{user `format`}}", + "headless": "{{user `headless`}}", + "http_directory": "./packer/qemu/linux/{{user `distro_name`}}/http/", + "iso_checksum": "{{user `iso_checksum`}}", + "iso_checksum_type": "{{user `iso_checksum_type`}}", + "iso_url": "{{user `iso_url`}}", + "boot_command": [ + "{{user `boot_command_prefix`}}", + "http://{{ .HTTPIP }}:{{ .HTTPPort }}", + "{{user `boot_command_suffix`}}" + ], + "net_device": "virtio-net", + "qemu_binary": "{{user `qemu_binary`}}", + "shutdown_command": "echo '{{user `ssh_password`}}' | sudo -S -E sh -c 'usermod -L {{user `ssh_username`}} && {{user `shutdown_command`}}'", + "ssh_password": "{{user `ssh_password`}}", + "ssh_username": "{{user `ssh_username`}}", + "ssh_timeout": "2h" + } + ], + "provisioners": [ + { + "type": "ansible", + "playbook_file": "./ansible/playbook.yml", + "ansible_env_vars": [ + "ANSIBLE_SSH_ARGS='{{user `existing_ansible_ssh_args`}} -o IdentitiesOnly=yes'", + "ANSIBLE_REMOTE_TEMP='/tmp/.ansible/'" + ], + "extra_arguments": [ + "--extra-vars", + "{{user `ansible_common_vars`}}", + "--extra-vars", + "{{user `ansible_extra_vars`}}" + ] + } + ] +} diff --git a/images/capi/packer/qemu/qemu-ubuntu-1804.json b/images/capi/packer/qemu/qemu-ubuntu-1804.json new file mode 100644 index 0000000000..ea90299510 --- /dev/null +++ b/images/capi/packer/qemu/qemu-ubuntu-1804.json @@ -0,0 +1,12 @@ +{ + "build_name": "ubuntu-1804", + "distro_name": "ubuntu", + "os_display_name": "Ubuntu 18.04", + "guest_os_type": "ubuntu-64", + "iso_url": "http://old-releases.ubuntu.com/releases/18.04.2/ubuntu-18.04.2-server-amd64.iso", + "iso_checksum": "a2cb36dc010d98ad9253ea5ad5a07fd6b409e3412c48f1860536970b073c98f5", + "iso_checksum_type": "sha256", + "boot_command_prefix": "/install/vmlinuz auto console-setup/ask_detect=false console-setup/layoutcode=us console-setup/modelcode=pc105 debconf/frontend=noninteractive debian-installer=en_US fb=false initrd=/install/initrd.gz kbd-chooser/method=us keyboard-configuration/layout=USA keyboard-configuration/variant=USA locale=en_US netcfg/get_domain=local netcfg/get_hostname=localhost grub-installer/bootdev=/dev/sda preseed/url=", + "boot_command_suffix": "/18.04/preseed.cfg -- ", + "shutdown_command": "shutdown -P now" +}