|
| 1 | +--- |
| 2 | +title: Migrating Legacy Projects |
| 3 | +linkTitle: Migrating Projects to 1.0.0+ |
| 4 | +weight: 6 |
| 5 | +description: Instructions for migrating a Ansible-based project built prior to 1.0.0 to use the new Kubebuilder-style layout. |
| 6 | +--- |
| 7 | + |
| 8 | +## Overview |
| 9 | + |
| 10 | +The motivations for the new layout are related to bringing more flexibility to users and |
| 11 | +part of the process to [Integrating Kubebuilder and Operator SDK][integration-doc]. |
| 12 | + |
| 13 | +### What was changed |
| 14 | + |
| 15 | +- The `deploy` directory was replaced with the `config` directory including a new layout of Kubernetes manifests files: |
| 16 | + * CRD manifests in `deploy/crds/` are now in `config/crd/bases` |
| 17 | + * CR manifests in `deploy/crds/` are now in `config/samples` |
| 18 | + * Controller manifest `deploy/operator.yaml` is now in `config/manager/manager.yaml` |
| 19 | + * RBAC manifests in `deploy` are now in `config/rbac/` |
| 20 | + |
| 21 | +- `build/Dockerfile` is moved to `Dockerfile` in the project root directory |
| 22 | +- The `molecule/` directory is now more aligned to Ansible and the new Layout |
| 23 | + |
| 24 | +### What is new |
| 25 | + |
| 26 | +Scaffolded projects now use: |
| 27 | + |
| 28 | +- [kustomize][kustomize] to manage Kubernetes resources needed to deploy your operator |
| 29 | +- A `Makefile` with helpful targets for build, test, and deployment, and to give you flexibility to tailor things to your project's needs |
| 30 | +- Updated metrics configuration using [kube-auth-proxy][kube-auth-proxy], a `--metrics-addr` flag, and [kustomize][kustomize]-based deployment of a Kubernetes `Service` and prometheus operator `ServiceMonitor` |
| 31 | + |
| 32 | +## How to migrate |
| 33 | + |
| 34 | +The easy migration path is to a project from the scratch and let the tool scaffold the new layout. Then, add your customizations and implementations. See below for an example. |
| 35 | + |
| 36 | +### Creating a new project |
| 37 | + |
| 38 | +In Kubebuilder-style projects, CRD groups are defined using two different flags |
| 39 | +(`--group` and `--domain`). |
| 40 | + |
| 41 | +When we initialize a new project, we need to specify the domain that _all_ APIs in |
| 42 | +our project will share, so before creating the new project, we need to determine which |
| 43 | +domain we're using for the APIs in our existing project. |
| 44 | + |
| 45 | +To determine the domain, look at the `spec.group` field in your CRDs in the |
| 46 | +`deploy/crds` directory. |
| 47 | + |
| 48 | +The domain is everything after the first DNS segment. Using `cache.example.com` as an |
| 49 | +example, the `--domain` would be `example.com`. |
| 50 | + |
| 51 | +So let's create a new project with the same domain (`example.com`): |
| 52 | + |
| 53 | +```sh |
| 54 | +mkdir memcached-operator |
| 55 | +cd memcached-operator |
| 56 | +operator-sdk init --plugins=ansible --domain=example.com |
| 57 | +``` |
| 58 | + |
| 59 | +Now that we have our new project initialized, we need to recreate each of our APIs. |
| 60 | +Using our API example from earlier (`cache.example.com`), we'll use `cache` for the |
| 61 | +`--group` flag. |
| 62 | + |
| 63 | +For `--version` and `--kind`, we use `spec.versions[0].name` and `spec.names.kind`, respectively. |
| 64 | + |
| 65 | +For each API in the existing project, run: |
| 66 | + |
| 67 | +```sh |
| 68 | +operator-sdk create api \ |
| 69 | + --group=cache \ |
| 70 | + --version=v1 \ |
| 71 | + --kind=Memcached |
| 72 | +``` |
| 73 | + |
| 74 | +Running the above command creates an empty `roles/<kind>`. We can copy over the content of our old `roles/<kind>` to the new one. |
| 75 | + |
| 76 | +### Migrating your Custom Resource samples |
| 77 | + |
| 78 | +Update the CR manifests in `config/samples` with the values of the CRs in your existing project which are in `deploy/crds/<group>_<version>_<kind>_cr.yaml` In our example |
| 79 | +the `config/samples/cache_v1alpha1_memcached.yaml` will look like: |
| 80 | + |
| 81 | +```yaml |
| 82 | +apiVersion: cache.example.com/v1alpha1 |
| 83 | +kind: Memcached |
| 84 | +metadata: |
| 85 | + name: memcached-sample |
| 86 | +spec: |
| 87 | + # Add fields here |
| 88 | + size: 3 |
| 89 | +``` |
| 90 | +
|
| 91 | +### Migrating `watches.yaml |
| 92 | + |
| 93 | +Update the `watches.yaml` file with your `roles/playbooks` and check if you have custom options in the `watches.yaml` file of your existing project. If so, update the new `watches.yaml file to match. |
| 94 | + |
| 95 | +In our example, we will replace `# FIXME: Specify the role or playbook for this resource.` with our previous role and it will look like: |
| 96 | + |
| 97 | +```yaml |
| 98 | +--- |
| 99 | +# Use the 'create api' subcommand to add watches to this file. |
| 100 | +- version: v1alpha1 |
| 101 | + group: cache.example.com |
| 102 | + kind: Memcached |
| 103 | + role: memcached |
| 104 | +# +kubebuilder:scaffold:watch |
| 105 | +``` |
| 106 | + |
| 107 | +**NOTE**: Do not remove the `+kubebuilder:scaffold:watch` [marker][marker]. It allows the tool to update the watches file when new APIs are created. |
| 108 | + |
| 109 | +### Migrating your Molecule tests |
| 110 | + |
| 111 | +If you are using [Molecule][molecule] in your project will be required to port the tests for the new layout. |
| 112 | + |
| 113 | +See that default structure changed from: |
| 114 | + |
| 115 | +```sh |
| 116 | +├── cluster |
| 117 | +│ ├── converge.yml |
| 118 | +│ ├── create.yml |
| 119 | +│ ├── destroy.yml |
| 120 | +│ ├── molecule.yml |
| 121 | +│ ├── prepare.yml |
| 122 | +│ └── verify.yml |
| 123 | +├── default |
| 124 | +│ ├── converge.yml |
| 125 | +│ ├── molecule.yml |
| 126 | +│ ├── prepare.yml |
| 127 | +│ └── verify.yml |
| 128 | +├── templates |
| 129 | +│ └── operator.yaml.j2 |
| 130 | +└── test-local |
| 131 | + ├── converge.yml |
| 132 | + ├── molecule.yml |
| 133 | + ├── prepare.yml |
| 134 | + └── verify.yml |
| 135 | +
|
| 136 | +``` |
| 137 | + |
| 138 | +To: |
| 139 | + |
| 140 | +``` |
| 141 | +├── default |
| 142 | +│ ├── converge.yml |
| 143 | +│ ├── create.yml |
| 144 | +│ ├── destroy.yml |
| 145 | +│ ├── kustomize.yml |
| 146 | +│ ├── molecule.yml |
| 147 | +│ ├── prepare.yml |
| 148 | +│ ├── tasks |
| 149 | +│ │ └── foo_test.yml |
| 150 | +│ └── verify.yml |
| 151 | +└── kind |
| 152 | + ├── converge.yml |
| 153 | + ├── create.yml |
| 154 | + ├── destroy.yml |
| 155 | + └── molecule.yml |
| 156 | +``` |
| 157 | + |
| 158 | +Ensure that the `provisioner.host_vars.localhost` has the following `host_vars`: |
| 159 | + |
| 160 | +``` |
| 161 | +.... |
| 162 | + host_vars: |
| 163 | + localhost: |
| 164 | + ansible_python_interpreter: '{{ ansible_playbook_python }}' |
| 165 | + config_dir: ${MOLECULE_PROJECT_DIRECTORY}/config |
| 166 | + samples_dir: ${MOLECULE_PROJECT_DIRECTORY}/config/samples |
| 167 | + operator_image: ${OPERATOR_IMAGE:-""} |
| 168 | + operator_pull_policy: ${OPERATOR_PULL_POLICY:-"Always"} |
| 169 | + kustomize: ${KUSTOMIZE_PATH:-kustomize} |
| 170 | +... |
| 171 | +``` |
| 172 | + |
| 173 | +For more information read the [Testing with Molecule][testing-guide]. |
| 174 | + |
| 175 | +### Checking the Permissions (RBAC) |
| 176 | + |
| 177 | +In your new project, roles are automatically generated in `config/rbac/role.yaml`. |
| 178 | +If you modified these permissions manually in `deploy/role.yaml` in your existing |
| 179 | +project, you need to re-apply them in `config/rbac/role.yaml`. |
| 180 | + |
| 181 | +New projects are configured to watch all namespaces by default, so they need a `ClusterRole` to have the necessary permissions. Ensure that `config/rbac/role.yaml` remains a `ClusterRole` if you want to retain the default behavior of the new project conventions. For further information refer to the [operator scope][operator-scope] documentation. |
| 182 | + |
| 183 | +The following rules were used in earlier versions of anisible-operator to automatically create and manage services and `servicemonitors` for metrics collection. If your operator's don't require these rules, they can safely be left out of the new `config/rbac/role.yaml` file: |
| 184 | + |
| 185 | +```yaml |
| 186 | + - apiGroups: |
| 187 | + - monitoring.coreos.com |
| 188 | + resources: |
| 189 | + - servicemonitors |
| 190 | + verbs: |
| 191 | + - get |
| 192 | + - create |
| 193 | + - apiGroups: |
| 194 | + - apps |
| 195 | + resourceNames: |
| 196 | + - memcached-operator |
| 197 | + resources: |
| 198 | + - deployments/finalizers |
| 199 | + verbs: |
| 200 | + - update |
| 201 | +``` |
| 202 | + |
| 203 | +### Configuring your Operator |
| 204 | + |
| 205 | +If your existing project has customizations in `deploy/operator.yaml`, they need to be ported to |
| 206 | +`config/manager/manager.yaml`. If you are passing custom arguments in your deployment, make sure to also update `config/default/auth_proxy_patch.yaml`. |
| 207 | + |
| 208 | +Note that the following environment variables are no longer used. |
| 209 | + |
| 210 | +- `OPERATOR_NAME` is deprecated. It is used to define the name for a leader election config map. Operator authors should begin using `--leader-election-id` instead. |
| 211 | +- `POD_NAME` has been removed. It was used to enable a particular pod to hold the leader election lock when the Ansible operator used the leader for life mechanism. Ansible operator now uses controller-runtime's leader with lease mechanism. |
| 212 | + |
| 213 | +## Exporting metrics |
| 214 | + |
| 215 | +If you are using metrics and would like to keep them exported you will need to configure |
| 216 | +it in the `config/default/kustomization.yaml`. Please see the [metrics][metrics] doc to know how you can perform this setup. |
| 217 | + |
| 218 | +The default port used by the metric endpoint binds to was changed from `:8383` to `:8080`. To continue using port `8383`, specify `--metrics-addr=:8383` when you start the operator. |
| 219 | + |
| 220 | +## Checking the changes |
| 221 | + |
| 222 | +Finally, follow the steps in the section [Build and run the Operator][build-and-run-the-operator] to verify your project is running. |
| 223 | + |
| 224 | +Note that, you also can troubleshooting by checking the container logs. |
| 225 | +E.g `$ kubectl logs deployment.apps/memcached-operator-controller-manager -n memcached-operator-system -c manager` |
| 226 | + |
| 227 | +[quickstart-legacy]: https://v0-19-x.sdk.operatorframework.io/docs/ansible/quickstart/ |
| 228 | +[quickstart]: /docs/building-operators/ansible/quickstart |
| 229 | +[integration-doc]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/integrating-kubebuilder-and-osdk.md |
| 230 | +[build-and-run-the-operator]: /docs/building-operators/ansible/tutorial/#deploy-the-operator |
| 231 | +[kustomize]: https://github.com/kubernetes-sigs/kustomize |
| 232 | +[kube-auth-proxy]: https://github.com/brancz/kube-rbac-proxy |
| 233 | +[metrics]: https://book.kubebuilder.io/reference/metrics.html?highlight=metr#metrics |
| 234 | +[marker]: https://book.kubebuilder.io/reference/markers.html?highlight=markers#marker-syntax |
| 235 | +[operator-scope]: /docs/building-operators/golang/operator-scope |
| 236 | +[molecule]: https://molecule.readthedocs.io/en/latest/# |
| 237 | +[testing-guide]: /docs/building-operators/ansible/testing-guide |
0 commit comments