From 7aa584b59baba5a7018d38aadd19aa7646702391 Mon Sep 17 00:00:00 2001 From: Dan Osborne Date: Fri, 10 Mar 2017 16:07:45 -0800 Subject: Add calico. --- roles/calico/README.md | 28 ++++++ roles/calico/defaults/main.yaml | 10 ++ roles/calico/handlers/main.yml | 8 ++ roles/calico/meta/main.yml | 16 ++++ roles/calico/tasks/main.yml | 74 +++++++++++++++ roles/calico/templates/calico.cfg.j2 | 9 ++ roles/calico/templates/calico.conf.j2 | 18 ++++ roles/calico/templates/calico.service.j2 | 29 ++++++ roles/calico_master/README.md | 28 ++++++ roles/calico_master/defaults/main.yaml | 2 + roles/calico_master/meta/main.yml | 17 ++++ roles/calico_master/tasks/main.yml | 41 ++++++++ .../templates/calico-policy-controller.yml.j2 | 105 +++++++++++++++++++++ roles/openshift_common/tasks/main.yml | 9 ++ roles/openshift_facts/library/openshift_facts.py | 19 ++++ 15 files changed, 413 insertions(+) create mode 100644 roles/calico/README.md create mode 100644 roles/calico/defaults/main.yaml create mode 100644 roles/calico/handlers/main.yml create mode 100644 roles/calico/meta/main.yml create mode 100644 roles/calico/tasks/main.yml create mode 100644 roles/calico/templates/calico.cfg.j2 create mode 100644 roles/calico/templates/calico.conf.j2 create mode 100644 roles/calico/templates/calico.service.j2 create mode 100644 roles/calico_master/README.md create mode 100644 roles/calico_master/defaults/main.yaml create mode 100644 roles/calico_master/meta/main.yml create mode 100644 roles/calico_master/tasks/main.yml create mode 100644 roles/calico_master/templates/calico-policy-controller.yml.j2 (limited to 'roles') diff --git a/roles/calico/README.md b/roles/calico/README.md new file mode 100644 index 000000000..99e870521 --- /dev/null +++ b/roles/calico/README.md @@ -0,0 +1,28 @@ +# Calico + +Configure Calico components for the Master host. + +## Requirements + +* Ansible 2.2 + +## Warning: This Calico Integration is in Alpha + +Calico shares the etcd instance used by OpenShift, and distributes client etcd certificates to each node. +For this reason, **we do not (yet) recommend running Calico on any production-like +cluster, or using it for any purpose besides early access testing.** + +## Installation + +To install, set the following inventory configuration parameters: + +* `openshift_use_calico=True` +* `openshift_use_openshift_sdn=False` +* `os_sdn_network_plugin_name='cni'` + + +### Contact Information + +Author: Dan Osborne + +For support, join the `#openshift` channel on the [calico users slack](calicousers.slack.com). diff --git a/roles/calico/defaults/main.yaml b/roles/calico/defaults/main.yaml new file mode 100644 index 000000000..a81fc3af7 --- /dev/null +++ b/roles/calico/defaults/main.yaml @@ -0,0 +1,10 @@ +--- +kubeconfig: "{{openshift.common.config_base}}/node/{{ 'system:node:' + openshift.common.hostname }}.kubeconfig" +etcd_endpoints: "{{ hostvars[groups.oo_first_master.0].openshift.master.etcd_urls | join(',') }}" + +cni_conf_dir: "/etc/cni/net.d/" +cni_bin_dir: "/opt/cni/bin/" + +calico_etcd_ca_cert_file: "/etc/origin/calico/calico.etcd-ca.crt" +calico_etcd_cert_file: "/etc/origin/calico/calico.etcd-client.crt" +calico_etcd_key_file: "/etc/origin/calico/calico.etcd-client.key" diff --git a/roles/calico/handlers/main.yml b/roles/calico/handlers/main.yml new file mode 100644 index 000000000..65d75cf00 --- /dev/null +++ b/roles/calico/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: restart calico + become: yes + systemd: name=calico state=restarted + +- name: restart docker + become: yes + systemd: name=docker state=restarted diff --git a/roles/calico/meta/main.yml b/roles/calico/meta/main.yml new file mode 100644 index 000000000..102b82bde --- /dev/null +++ b/roles/calico/meta/main.yml @@ -0,0 +1,16 @@ +--- +galaxy_info: + author: Dan Osborne + description: Calico networking + company: Tigera, Inc. + license: Apache License, Version 2.0 + min_ansible_version: 2.2 + platforms: + - name: EL + versions: + - 7 + categories: + - cloud + - system +dependencies: +- role: openshift_facts diff --git a/roles/calico/tasks/main.yml b/roles/calico/tasks/main.yml new file mode 100644 index 000000000..287fed321 --- /dev/null +++ b/roles/calico/tasks/main.yml @@ -0,0 +1,74 @@ +--- +- include: ../../../roles/etcd_client_certificates/tasks/main.yml + vars: + etcd_cert_prefix: calico.etcd- + etcd_cert_config_dir: "{{ openshift.common.config_base }}/calico" + embedded_etcd: "{{ hostvars[groups.oo_first_master.0].openshift.master.embedded_etcd }}" + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" + etcd_cert_subdir: "openshift-calico-{{ openshift.common.hostname }}" + +- name: Assure the calico certs have been generated + stat: + path: "{{ item }}" + with_items: + - "{{ calico_etcd_ca_cert_file }}" + - "{{ calico_etcd_cert_file}}" + - "{{ calico_etcd_key_file }}" + +- name: Configure Calico service unit file + template: + dest: "/lib/systemd/system/calico.service" + src: calico.service.j2 + +- name: Enable calico + become: yes + systemd: + name: calico + daemon_reload: yes + state: started + enabled: yes + register: start_result + +- name: Assure CNI conf dir exists + become: yes + file: path="{{ cni_conf_dir }}" state=directory + +- name: Generate Calico CNI config + become: yes + template: + src: "calico.conf.j2" + dest: "{{ cni_conf_dir }}/10-calico.conf" + +- name: Assures Kuberentes CNI bin dir exists + become: yes + file: path="{{ cni_bin_dir }}" state=directory + +- name: Download Calico CNI Plugin + become: yes + get_url: + url: https://github.com/projectcalico/cni-plugin/releases/download/v1.5.5/calico + dest: "{{ cni_bin_dir }}" + mode: a+x + +- name: Download Calico IPAM Plugin + become: yes + get_url: + url: https://github.com/projectcalico/cni-plugin/releases/download/v1.5.5/calico-ipam + dest: "{{ cni_bin_dir }}" + mode: a+x + +- name: Download and unzip standard CNI plugins + become: yes + unarchive: + remote_src: True + src: https://github.com/containernetworking/cni/releases/download/v0.4.0/cni-amd64-v0.4.0.tgz + dest: "{{ cni_bin_dir }}" + +- name: Assure Calico conf dir exists + become: yes + file: path=/etc/calico/ state=directory + +- name: Set calicoctl.cfg + template: + src: calico.cfg.j2 + dest: "/etc/calico/calicoctl.cfg" diff --git a/roles/calico/templates/calico.cfg.j2 b/roles/calico/templates/calico.cfg.j2 new file mode 100644 index 000000000..722385ed8 --- /dev/null +++ b/roles/calico/templates/calico.cfg.j2 @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: calicoApiConfig +metadata: +spec: + datastoreType: "etcdv2" + etcdEndpoints: "{{ etcd_endpoints }}" + etcdKeyFile: "{{ calico_etcd_key_file }}" + etcdCertFile: "{{ calico_etcd_cert_file }}" + etcdCaCertFile: "{{ calico_etcd_ca_cert_file }}" diff --git a/roles/calico/templates/calico.conf.j2 b/roles/calico/templates/calico.conf.j2 new file mode 100644 index 000000000..3c8c6b046 --- /dev/null +++ b/roles/calico/templates/calico.conf.j2 @@ -0,0 +1,18 @@ +{ + "name": "calico", + "type": "calico", + "ipam": { + "type": "calico-ipam" + }, + "etcd_endpoints": "{{ etcd_endpoints }}", + "etcd_key_file": "{{ calico_etcd_key_file }}", + "etcd_cert_file": "{{ calico_etcd_cert_file }}", + "etcd_ca_cert_file": "{{ calico_etcd_ca_cert_file }}", + "kubernetes": { + "kubeconfig": "{{ kubeconfig }}" + }, + "hostname": "{{ openshift.common.hostname }}", + "policy": { + "type": "k8s" + } +} diff --git a/roles/calico/templates/calico.service.j2 b/roles/calico/templates/calico.service.j2 new file mode 100644 index 000000000..b882a5597 --- /dev/null +++ b/roles/calico/templates/calico.service.j2 @@ -0,0 +1,29 @@ +[Unit] +Description=calico +After=docker.service +Requires=docker.service + +[Service] +Restart=always +ExecStartPre=-/usr/bin/docker rm -f calico-node +ExecStart=/usr/bin/docker run --net=host --privileged \ + --name=calico-node \ + -e WAIT_FOR_DATASTORE=true \ + -e FELIX_DEFAULTENDPOINTTOHOSTACTION=ACCEPT \ + -e CALICO_IPV4POOL_IPIP=always \ + -e FELIX_IPV6SUPPORT=false \ + -e ETCD_ENDPOINTS={{ etcd_endpoints }} \ + -v /etc/origin/calico:/etc/origin/calico \ + -e ETCD_CA_CERT_FILE={{ calico_etcd_ca_cert_file }} \ + -e ETCD_CERT_FILE={{ calico_etcd_cert_file }} \ + -e ETCD_KEY_FILE={{ calico_etcd_key_file }} \ + -e NODENAME={{ openshift.common.hostname }} \ + -v /var/log/calico:/var/log/calico \ + -v /lib/modules:/lib/modules \ + -v /var/run/calico:/var/run/calico \ + calico/node:v1.1.0 + +ExecStop=-/usr/bin/docker stop calico-node + +[Install] +WantedBy=multi-user.target diff --git a/roles/calico_master/README.md b/roles/calico_master/README.md new file mode 100644 index 000000000..2d34a967c --- /dev/null +++ b/roles/calico_master/README.md @@ -0,0 +1,28 @@ +# Calico (Master) + +Configure Calico components for the Master host. + +## Requirements + +* Ansible 2.2 + +## Warning: This Calico Integration is in Alpha + +Calico shares the etcd instance used by OpenShift, and distributes client etcd certificates to each node. +For this reason, **we do not (yet) recommend running Calico on any production-like +cluster, or using it for any purpose besides early access testing.** + +## Installation + +To install, set the following inventory configuration parameters: + +* `openshift_use_calico=True` +* `openshift_use_openshift_sdn=False` +* `os_sdn_network_plugin_name='cni'` + + +### Contact Information + +Author: Dan Osborne + +For support, join the `#openshift` channel on the [calico users slack](calicousers.slack.com). diff --git a/roles/calico_master/defaults/main.yaml b/roles/calico_master/defaults/main.yaml new file mode 100644 index 000000000..db0d17884 --- /dev/null +++ b/roles/calico_master/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +kubeconfig: "{{ openshift.common.config_base }}/master/openshift-master.kubeconfig" diff --git a/roles/calico_master/meta/main.yml b/roles/calico_master/meta/main.yml new file mode 100644 index 000000000..4d70c79cf --- /dev/null +++ b/roles/calico_master/meta/main.yml @@ -0,0 +1,17 @@ +--- +galaxy_info: + author: Dan Osborne + description: Calico networking + company: Tigera, Inc. + license: Apache License, Version 2.0 + min_ansible_version: 2.2 + platforms: + - name: EL + versions: + - 7 + categories: + - cloud + - system +dependencies: +- role: calico +- role: openshift_facts diff --git a/roles/calico_master/tasks/main.yml b/roles/calico_master/tasks/main.yml new file mode 100644 index 000000000..3358abe23 --- /dev/null +++ b/roles/calico_master/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: Assure the calico certs have been generated + stat: + path: "{{ item }}" + with_items: + - "{{ calico_etcd_ca_cert_file }}" + - "{{ calico_etcd_cert_file}}" + - "{{ calico_etcd_key_file }}" + +- name: Create temp directory for policy controller definition + command: mktemp -d /tmp/openshift-ansible-XXXXXXX + register: mktemp + changed_when: False + +- name: Write Calico Policy Controller definition + template: + dest: "{{ mktemp.stdout }}/calico-policy-controller.yml" + src: calico-policy-controller.yml.j2 + +- name: Launch Calico Policy Controller + command: > + {{ openshift.common.client_binary }} create + -f {{ mktemp.stdout }}/calico-policy-controller.yml + --config={{ openshift.common.config_base }}/master/admin.kubeconfig + register: calico_create_output + failed_when: ('already exists' not in calico_create_output.stderr) and ('created' not in calico_create_output.stdout) + changed_when: ('created' in calico_create_output.stdout) + +- name: Delete temp directory + file: + name: "{{ mktemp.stdout }}" + state: absent + changed_when: False + + +- name: oc adm policy add-scc-to-user privileged system:serviceaccount:kube-system:calico + oc_adm_policy_user: + user: system:serviceaccount:kube-system:calico + resource_kind: scc + resource_name: privileged + state: present diff --git a/roles/calico_master/templates/calico-policy-controller.yml.j2 b/roles/calico_master/templates/calico-policy-controller.yml.j2 new file mode 100644 index 000000000..66c334ceb --- /dev/null +++ b/roles/calico_master/templates/calico-policy-controller.yml.j2 @@ -0,0 +1,105 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: calico + namespace: kube-system +--- +kind: ClusterRole +apiVersion: v1 +metadata: + name: calico + namespace: kube-system +rules: + - apiGroups: [""] + resources: + - pods + - namespaces + verbs: + - list + - get + - watch + - apiGroups: ["extensions"] + resources: + - networkpolicies + verbs: + - list + - get + - watch +--- +apiVersion: v1 +kind: ClusterRoleBinding +metadata: + name: calico +roleRef: + name: calico +subjects: +- kind: SystemUser + name: kube-system:calico +- kind: ServiceAccount + name: calico + namespace: kube-system +userNames: + - system:serviceaccount:kube-system:calico +--- +# This manifest deploys the Calico policy controller on Kubernetes. +# See https://github.com/projectcalico/k8s-policy +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: calico-policy-controller + namespace: kube-system + labels: + k8s-app: calico-policy + annotations: + scheduler.alpha.kubernetes.io/critical-pod: '' + scheduler.alpha.kubernetes.io/tolerations: | + [{"key": "dedicated", "value": "master", "effect": "NoSchedule" }, + {"key":"CriticalAddonsOnly", "operator":"Exists"}] +spec: + # The policy controller can only have a single active instance. + replicas: 1 + strategy: + type: Recreate + template: + metadata: + name: calico-policy-controller + namespace: kube-system + labels: + k8s-app: calico-policy + spec: + # The policy controller must run in the host network namespace so that + # it isn't governed by policy that would prevent it from working. + hostNetwork: true + serviceAccountName: calico + containers: + - name: calico-policy-controller + image: quay.io/calico/kube-policy-controller:v0.5.3 + env: + # The location of the Calico etcd cluster. + - name: ETCD_ENDPOINTS + value: {{ etcd_endpoints }} + # Location of the CA certificate for etcd. + - name: ETCD_CA_CERT_FILE + value: {{ calico_etcd_ca_cert_file }} + # Location of the client key for etcd. + - name: ETCD_KEY_FILE + value: {{ calico_etcd_key_file }} + # Location of the client certificate for etcd. + - name: ETCD_CERT_FILE + value: {{ calico_etcd_cert_file }} + # Since we're running in the host namespace and might not have KubeDNS + # access, configure the container's /etc/hosts to resolve + # kubernetes.default to the correct service clusterIP. + - name: CONFIGURE_ETC_HOSTS + value: "true" + volumeMounts: + # Mount in the etcd TLS secrets. + - name: certs + mountPath: /etc/origin/calico + + volumes: + # Mount in the etcd TLS secrets. + - name: certs + hostPath: + path: /etc/origin/calico diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml index e55c288a8..d9ccf87bc 100644 --- a/roles/openshift_common/tasks/main.yml +++ b/roles/openshift_common/tasks/main.yml @@ -23,6 +23,14 @@ msg: Contiv can not be used with nuage when: openshift_use_nuage | default(false) | bool and openshift_use_contiv | default(false) | bool +- fail: + msg: Calico can not be used with openshift sdn, set openshift_use_openshift_sdn=false if you want to use Calico + when: openshift_use_openshift_sdn | default(true) | bool and openshift_use_calico | default(false) | bool + +- fail: + msg: Calico cannot currently be used with Flannel in Openshift. Set either openshift_use_calico or openshift_use_flannel, but not both + when: openshift_use_calico | default(false) | bool and openshift_use_flannel | default(false) | bool + - fail: msg: openshift_hostname must be 64 characters or less when: openshift_hostname is defined and openshift_hostname | length > 64 @@ -35,6 +43,7 @@ use_openshift_sdn: "{{ openshift_use_openshift_sdn | default(None) }}" sdn_network_plugin_name: "{{ os_sdn_network_plugin_name | default(None) }}" use_flannel: "{{ openshift_use_flannel | default(None) }}" + use_calico: "{{openshift_use_calico | default(None) }}" use_nuage: "{{ openshift_use_nuage | default(None) }}" use_contiv: "{{ openshift_use_contiv | default(None) }}" use_manageiq: "{{ openshift_use_manageiq | default(None) }}" diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py index eeab8a99c..e1f4c4e6d 100755 --- a/roles/openshift_facts/library/openshift_facts.py +++ b/roles/openshift_facts/library/openshift_facts.py @@ -467,6 +467,24 @@ def set_flannel_facts_if_unset(facts): return facts +def set_calico_facts_if_unset(facts): + """ Set calico facts if not already present in facts dict + dict: the facts dict updated with the calico facts if + missing + Args: + facts (dict): existing facts + Returns: + dict: the facts dict updated with the calico + facts if they were not already present + + """ + if 'common' in facts: + if 'use_calico' not in facts['common']: + use_calico = False + facts['common']['use_calico'] = use_calico + return facts + + def set_nuage_facts_if_unset(facts): """ Set nuage facts if not already present in facts dict dict: the facts dict updated with the nuage facts if @@ -1953,6 +1971,7 @@ class OpenShiftFacts(object): facts = set_url_facts_if_unset(facts) facts = set_project_cfg_facts_if_unset(facts) facts = set_flannel_facts_if_unset(facts) + facts = set_calico_facts_if_unset(facts) facts = set_nuage_facts_if_unset(facts) facts = set_contiv_facts_if_unset(facts) facts = set_node_schedulability(facts) -- cgit v1.2.1