本文以nova-api容器爲例,說明kolla如何將nova-api配置文件傳入容器,容器如何啓動nova-api服務並讀取配置文件node
注:第一部分比較無趣,二三部分 會有意思一些python
nova-api: container_name: "nova_api" group: "nova-api" image: "{{ nova_api_image_full }}" enabled: True privileged: True volumes: # 將用戶nova-api服務配置目錄/etc/kolla/nova-api傳入容器,映射爲/var/lib/kolla/config_files/,並設置爲只讀 - "{{ node_config_directory }}/nova-api/:{{ container_config_directory }}/:ro" # 容器時鐘和虛擬機時鐘同步 - "/etc/localtime:/etc/localtime:ro" # 宿主機內核,mount給容器以後,容器能夠啓用宿主機未啓用的內核模塊 - "/lib/modules:/lib/modules:ro" # openstack日誌目錄 - "kolla_logs:/var/log/kolla/"
- name: Restart nova-api container vars: service_name: "nova-api" service: "{{ nova_services[service_name] }}" config_json: 略 nova_conf: 略 policy_json: 略 nova_api_container: 略 kolla_docker: action: "recreate_or_restart_container" common_options: "{{ docker_common_options }}" name: "{{ service.container_name }}" image: "{{ service.image }}" privileged: "{{ service.privileged | default(False) }}" volumes: "{{ service.volumes|reject('equalto', '')|list }}" when: 略
def create_container(self): self.changed = True # 獲取建立容器的volume配置等容器建立參數 options = self.build_container_options() # 調用docker driver建立容器 self.dc.create_container(**options) def build_container_options(self): #生成volume參數 volumes, binds = self.generate_volumes() return { 'detach': self.params.get('detach'), 'environment': self._format_env_vars(), 'host_config': self.build_host_config(binds), 'labels': self.params.get('labels'), 'image': self.params.get('image'), 'name': self.params.get('name'), 'volumes': volumes, 'tty': True } def generate_volumes(self): # self.params在初始化時使用1中的kolla_docker參數定義 volumes = self.params.get('volumes') # 解析字符串,略 for vol in volumes: #解析字符串,略 return vol_list, vol_dict
# 定義父鏡像爲nova-base鏡像 FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} # 做者信息,略 # 安裝nova-api服務的步驟,略 COPY extend_start.sh /usr/local/bin/kolla_nova_extend_start RUN chmod 755 /usr/local/bin/kolla_nova_extend_start USER nova
這個dockerfile定義了一個基於nova-base的nova-api鏡像,在nova-base鏡像的基礎上,主要作了兩件事:安裝nova-api服務,複製extend_start.sh文件爲kolla_nova_extend_start文件。git
"/usr/local/bin/" 是環境變量PATH的默認值之一,將extend_start.sht文件拷貝到這個目錄後,kolla_nova_extend_start成爲容器裏能夠直接執行的一個命令。docker
Dockerfile中,對容器啓動時執行的命令是這個定義的CMD ["可執行命令"], 在這個dockerfile中沒有定義容器啓動命令CMD。shell
FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" build-date="{{ build_date }}" # 安裝全部nova服務通用的rpm包,如:python-keystoneclient,nova-common,etc,代碼略 # 建立/etc/nova目錄並設置權限 COPY nova_sudoers /etc/sudoers.d/kolla_nova_sudoers RUN chmod 750 /etc/sudoers.d \ && chmod 440 /etc/sudoers.d/kolla_nova_sudoers COPY extend_start.sh /usr/local/bin/kolla_extend_start RUN touch /usr/local/bin/kolla_nova_extend_start \ && chmod 755 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_nova_extend_start
在這個文件裏面,kolla複製extend_start.sh生成kolla_extend_start文件。這裏依然沒有定義CMD。json
FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} # 安裝openstack通用rpm包,如git,gcc,eventle,代碼略 ENV PATH /var/lib/kolla/venv/bin:$PATH RUN {{ macros.install_pip(openstack_base_pip_packages | customizable("pip_packages")) }}
在這裏kolla設置了環境變量PATH=/var/lib/kolla/venv/bin,這個目錄下存放了nova-api文件,這樣nova-api成爲可在容器裏直接執行的命令api
FROM {{ base_image }}:{{ base_distro_tag }} # 建立用戶組 # 配置yum或者apt的源,pip源 COPY set_configs.py /usr/local/bin/kolla_set_configs COPY start.sh /usr/local/bin/kolla_start COPY sudoers /etc/sudoers COPY curlrc /root/.curlrc # 安裝並設置dumb-init # 建立 /var/log/kolla 並設置權限 # 建立/usr/local/bin/kolla_extend_start 文件並設置權限 CMD ["kolla_start"]
能夠看到這裏生成了kolla_start文件,而且將容器啓動命令設置爲kolla_start,因爲base鏡像是全部kolla鏡像的公共鏡像,因此,幾乎全部kolla容器啓動時,執行的命令,都是kolla_start命令,之因此說幾乎,是由於有個別鏡像重寫了CMDbash
kolla_start是一個shell腳本,內容以下:curl
#!/bin/bash set -o errexit # 解析 /var/lib/kolla/config_files/目錄下的config.json,將config.json中的command寫入/command文件,將config.json中的config_files拷貝到指定目錄。 /var/lib/kolla/config_files是由咱們在1.1中定義的/etc/kolla/nova-api目錄映射而來。 sudo -E kolla_set_configs # 獲取config.json中的command內容,對於nova-api,它的值是"nova-api" CMD=$(cat /run_command) ARGS="" #執行kolla_extend_start命令,設置nova日誌目錄的權限,並調用kolla_nova_extend_start命令,進行判斷:若是是初始化nova-api服務,執行dbsync,若是不是,什麼都不作 . kolla_extend_start #執行nova-api命令,啓動該服務 echo "Running command: '${CMD}${ARGS:+ $ARGS}'" exec ${CMD} ${ARGS}
能夠看出,全部的openstack服務都按照上面的流程啓動,不一樣的服務:函數