Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Ansible practice: running ansible based on docker

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/02 Report--

Prepare the host with Ansible installed as the experimental environment.

There is a newly installed Centos7 system that uses ansible to do the following on the host:

Host initialization settings, mainly yum installation python3 installation docker, and make an ansible image SSH and user account security settings preparation work

Prepare a host with the Centos7 system installed, and then go to the host of ansible to operate on the target host.

My ansible here is also newly installed, so if you encounter some tools that you don't have, you will add them step by step when you encounter them. The following is the summary.

For a newly installed ansible, there are still many dependencies, some of which are closely related to specific modules and can be installed when using specific modules.

There are others with a wide range of use, so it is recommended to install them first:

Yum installs sshpass. # yum install sshpass if python3 is installed on the target host, you need to update pip to the latest and install selinux. # pip install selinux

Modify ansible.cfg configuration file

For the convenience of testing, only the following three items have been set up in my experimental environment:

[defaults] # host_key_checking = Falseinventory = ~ / hostsvault_password_file = ~ / vault_password_file

The [defaults] in the first line of the configuration file cannot be saved.

Add Host

Edit / etc/ansible/hosts to add host information:

Host1 ansible_host=192.168.24.172

My experimental environment is put directly into the home catalog.

Test connectivity with the ping module first:

[root@Ansible ~] # ansible host1-m ping-kSSH password: host1 | SUCCESS = > {"ansible_facts": {"discovered_interpreter_python": "/ usr/bin/python"}, "changed": false, "ping": "pong"} [root@Ansible ~] #

The-k parameter is used here to enter the password manually.

To test connectivity, you can add the-c parameter to specify local. But we need to verify the ssh connection here.

Install sshpass

If you are using it for the first time, you may be prompted to install sshpass. This is simple, just install yum:

$yum install sshpass

Add password information

The best thing to do is to use SSHKey to log in without a password. Here we talk about the use of passwords.

For convenience, you can also add the password to the configuration so that you do not have to enter the password every time:

Host2 ansible_host=192.168.24.172 ansible_ssh_pass=123456

In doing so, the password is stored in plain code, which is very insecure. There are safer ways to do this.

Encrypt and save the password

Use ansible-vault to encrypt sensitive information

Modify the configuration file

This step is not required, you can add the parameter-vault_password_file to specify your password file when running the command. However, you can save this parameter by setting it:

$vi / etc/ansible/ansible.cfg# If set, configures the path to the Vault password file as an alternative to# specifying-- vault-password-file on the command line.vault_password_file = ~ / vault_password_file

Use openssl to generate random passwords

Use openssl to generate random base64-encoded content:

$openssl rand-base64 128-out vault_password_file$ chmod Amurw vault_password_file$ chattr + I vault_password_file

After the file is generated, some protection is made to the file to prevent it from being modified. The ugo permission to modify a file is only valid for ordinary users, and root can still modify the file. The latter command locks the file, even if root cannot be modified, to prevent accidental manipulation of the file.

If you need to modify or delete a file, you can unlock the file first, just change the + I of the command to-I:

$chattr-I vault_password_file

Generate encrypted string

The following is the use of ansible-vault to generate encrypted strings:

[root@Ansible] # ansible-vault encrypt_string "123456"-- name ansible_ssh_passansible_ssh_pass:! vault | $ANSIBLE_VAULT;1.1;AES256 33336539343737316132653732383631636335323965383334326562303134626565613537 3134313631393931376361363761313165393966613831360a343338353765326331663433613533 316362381333636396130613438636363363166323033633623338323730383563 6562626265393535310a623732633863633765363066636265303265316661373464323961666131 6561Encryption successful [root@Ansible ~] #

Next, you need to copy the information obtained here into the configuration file.

Modify the host configuration file

Here, the configuration file has been greatly modified. It was originally in INI format, but now it has been changed to YAML format:

-all: hosts: host1: ansible_host: 192.168.24.172 ansible_ssh_pass:! vault | $ANSIBLE_VAULT;1.1;AES256 333365393737316132653732383634316363353239623338333265623031346513513537 3134313631393931376361363761313165393966613831360a343338353765326331663433613533 316362381333636396130613438636363931663230336336306233383237383563 6562626265393535310a623732633863633765363066636265303265316661373464323961666131 6561.

YAML is used because the INI format does not support embedded vault. The official explanation is as follows:

This is an example using an extract from a YAML inventory, as the INI format does not support inline vaults:

INI format of the host configuration file, feel more readable. If you still want to use the configuration in INI format, you can create a separate vars file and write the additional parameters in another file in YAML format.

Verification

This time the command module is used for verification:

$ansible host1-a hostnamehost1 | CHANGED | rc=0 > > Host1 $

At this point, all the preparatory work has been done and can be successfully connected to the host.

Problems with the python3 version

It is common for multiple versions of python to coexist. After the Centos7 system is installed, there is a python2 by default. Generally speaking, if you want to use python3, you will install another one, which will bring some problems.

The problem encountered before is that ansible uses the python3 of the target host to perform tasks, while some modules have problems using python3.

The host with the previous problem pointed the system's python command to python3. And modify the first #! / usr/bin/python2 in the yum-related commands to ensure that yum can run properly.

By default, ansible will go to the target host to look for / usr/bin/python to execute, which results in the default use of python3 for execution.

Here we force the value of ansible_python_interpreter to point to the python3 of the target host to reproduce the problem.

Yum module

Yum is written in python2, so python3 is not supported. The following is the error report:

[root@Ansible ~] # ansible host1-m yum-a "name=wget state=present"-e "ansible_python_interpreter=/usr/bin/python3" host1 | FAILED! = > {"ansible_facts": {"pkg_mgr": "yum"}, "changed": false, "msg": "The Python 2 bindings for rpm are needed for this module. If you require Python 3 support use the `dnf` Ansible module instead.. The Python 2 yum module is needed for this module. If you require Python 3 support use the `dnf` Ansible module instead. "} [root@Ansible ~] #

According to msg's hint. Dnf is recommended, but the attempt still fails.

The simple way is to specify the ansible_python_interpreter parameter and use Python2.

Python2 must be specified to use the yum module, there is no other way for the time being.

Selinux

When using the get_utl module, you will encounter the problem of selinux. This kind of problem should be solved simply by turning off selinux (I haven't tried it), but let's see what happens.

[root@Ansible ~] # ansible host1-m get_url-a 'url= "http://mirrors.aliyun.com/repo/epel-7.repo" dest=" / etc/yum.repos.d/epel-7.repo "'-e" ansible_python_interpreter=/usr/bin/python3 "host1 | FAILED! = > {" changed ": false," msg ":" Aborting, target uses selinux but python bindings (libselinux-python) aren't installed! "} [root@Ansible ~] #

One way is to use python2, because the system has installed the python2 version of selnux by default, which should be the following:

[root@PlayHost ~] # yum info libselinux-python loaded plug-in: fastestmirrorLoading mirror speeds from cached hostfile * base: ftp.sjtu.edu.cn * extras: ftp.sjtu.edu.cn * updates: ftp.sjtu.edu.cn installed package name: libselinux-python Architecture: x86 / 64 version: 2.5 release: 14.1.el7 size: 589k Source: installed from Source: anaconda introduction: SELinux python bindings For libselinux: https://github.com/SELinuxProject/selinux/wiki Protocol: Public Domain description: The libselinux-python package contains the python bindings for developing: SELinux applications. [root@PlayHost ~] #

If you use python2, you won't have this problem.

It's OK to use python3, as long as you put this on the package. No corresponding python3 version was found in yum, but there are:

[root@PlayHost ~] # pip install selinuxCollecting selinux Downloading https://files.pythonhosted.org/packages/59/38/780baac7aafcf44cca8e77318ec935660f93fc30e3de92f8de7a7dbc0513/selinux-0.1.6-py2.py3-none-any.whlInstalling collected packages: selinuxSuccessfully installed selinux-0.1.6 [root@PlayHost ~] #

The operation here is done on the target host, or it can be done remotely with ansible. But the main purpose here is to clarify the problem.

It is recommended that you install selinux after installing python3 on the target host. In this way, it will not be a problem for some python2 and python3 compatible modules to use any version.

Pip

There is no pip on the initial system, and then I will only install pip for python3. And all python modules that need to be installed by pip are installed for python3.

So when installing pip, you need to specify the ansible_python_interpreter parameter and use Python3. This is the opposite of the yum module.

When using the pip module, you can add the parameter extra_args:-I https://mirrors.aliyun.com/pypi/simple/ to specify the pypi source.

However, for convenience, you can also write directly to the configuration file to specify the default pypi source. Configuration files can also be added with commands without editing the file. The commands used are as follows:

$pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/

The running command can be implemented with the command module.

Install pip and updates

I install python36-pip using the yum module (there is a problem with the easy_install module installation, which I can't solve). After the installation is complete, update pip with the pip module.

After updating pip, and then installing selinux by the way, that's the problem in the previous section.

Actual combat playbook

Here you need to configure a host with the ansible of your test environment. After completing the initial configuration, install python3 and docker, and then create a mirror of ansible. Finally, there are SSH and account security settings.

Yum installation tool

The main thing is to set the domestic mirror source, and then use yum to install the tool:

-hosts: host1 vars: ansible_python_interpreter: / usr/bin/python2 # specifies the use of python2 Tasks:-name: delete the default repo file file: path: "/ etc/yum.repos.d/ {{item}}" state: absent with_items:-CentOS-Base.repo-CentOS-Debuginfo.repo-CentOS-Media.repo-CentOS-Vault.repo-CentOS-CR.repo-CentOS-fasttrack .repo-CentOS-Sources.repo-name: download Ali source Centos-7.repo epel-7.repo get_url: url: "http://mirrors.aliyun.com/repo/{{ item.url}}" dest: "/ etc/yum.repos.d/ {{item.dest}}" with_items:-{url: "Centos-7.repo" Dest: "CentOS-7.repo"}-{url: "epel-7.repo", dest: "epel-7.repo"}-name: yum installation wget net-tools bind-utils net-snmp-utils traceroute lrzsz yum: name:-wget-net-tools-bind-utils-net-snmp-utils-traceroute-lrzsz state: present... Install python3

Use yum to install python3 and pip, then update pip to the latest version, and set the domestic pip mirror source:

-hosts: host1 tasks:-name: yum installation python3 yum: name: [python36, python36-setuptools, python36-pip] state: present-name: update pip # error will be reported if you install easy_install Here update pip: name: pip state: latest extra_args:-I https://mirrors.aliyun.com/pypi/simple/ # with pip to specify python3 with the pip of python3 Otherwise, it is possible to call python2's pip vars: {ansible_python_interpreter: / usr/bin/python3}-name: check whether the pip configuration file exists file: path: ~ / .config/pip/pip.conf state: file ignore_errors: True register: result-name: if the pip configuration file does not exist: set to use Ali source command: pip config set global .index-url https://mirrors.aliyun.com/pypi/simple/ when: result is failed-name: install selinux pip: {name: selinux State: present} vars: {ansible_python_interpreter: / usr/bin/python3}...

Install selinux as mentioned before, by the way.

Install docker

There is no big problem with installing docker. You need to install docker-py first. Install with pip, so the docker module can only run on the python3 environment,

Selinux has been installed before. In this way, everything except yum can run on the python3 environment.

-hosts: host1 vars: ansible_tag: v1 # specify the tag (version number) of the ansible image tasks:-name: download Ali's installation source get_url: url: http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo dest: / etc/yum.repos.d/-name: yum install docker-ce specified version yum: Name: docker-ce-18.06.0.ce-3.el7 state: present-name: start docker Boot service: name=docker.service state=started enabled=yes-name: check whether the docker configuration file exists file: path: / etc/docker/daemon.json state: file ignore_errors: True register: result-name: if the docker configuration file does not exist, create an initial file to set the image accelerator when: result is failed block:-name: file write content Set Settings Image Accelerator lineinfile: path: / etc/docker/daemon.json create: yes line: | {"registry-mirrors": ["http://hub-mirror.c.163.com"," https://docker.mirrors.ustc.edu.cn"]}-name: restart docker Enable Image Accelerator service: name=docker.service state=restarted-name: install the module that manages the docker Check whether the image exists vars: {ansible_python_interpreter: / usr/bin/python3} block:-name: pip installation docker-py selinux pip: name: [docker-py Selinux] state: present-name: check whether the Ansible image exists vars: {ansible_python_interpreter: / usr/bin/python3} docker_image: name: ansible tag: "{{ansible_tag}}" source: local ignore_errors: True register: result-name: make Ansible image vars: { Ansible_python_interpreter: / usr/bin/python3} when: result is failed block:-name: Dockerfile copy to the target host # copy requires selinux So the above installs the version of python3 copy: src: ansible/Dockerfile dest: / tmp/docker_file/ansible/-name: docker build docker_image: name: ansible tag: "{{ansible_tag}}" build: path: / tmp/docker_file/ansible/ pull: yes with pip Source: build-name: delete Dockerfile file: path: / tmp/docker_file/ state: absent...

The configuration file for docker is in json format, and json has no comments, so you cannot use the blockinfile module. You can use either the lineinfile module or the copy module. However, there is a small problem with the copy module, which cannot create a directory recursively. The lineinfile module has a create parameter and also supports multiple lines.

Make a mirror image through Dockerfile

This is the Dockerfile of Architectural ansible:

FROM centos:centos7RUN curl-o / etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo & &\ yum-y install python36 python36-setuptools python36-pip & &\ yum clean all & &\ pip3 install pip-- upgrade-I https://mirrors.aliyun.com/pypi/simple/ & &\ / usr/local/bin/pip3 install ansible-I https://mirrors.aliyun.com/pypi / simple/ & &\ mkdir / opt/ansible_project/etc/ansible-p & &\ ln-s / opt/ansible_project/etc/ansible/ / etc/ansibleVOLUME / opt/ansible_projectCMD ["ansible" "--version"]

The folder where the Dockerfile that created the mirror lookup is located is on the target host. So you need to copy the folder first with the copy module.

When the copy module uses a relative directory, the starting directory of the source file is the directory where the playbook is located, and the starting directory of the destination is determined by the target host (Centos's system, which is in the user's home directory after logging in by default).

Chinese garbled code

After testing, it is found that this basic image does not support Chinese characters. You need to add the following to the Dockerfile:

RUN yum install kde-l10n-Chinese-yRUN yum install glibc-common-yRUN localedef-c-f UTF-8-I zh_CN zh_CN.utf8RUN export LANG=zh_CN.UTF-8RUN echo "export LANG=zh_CN.UTF-8" > > / etc/locale.confENV LANG zh_CN.UTF-8ENV LC_ALL zh_CN.UTF-8

The problem of Chinese characters is solved only on the finished mirror image. The above content is not tested, so it is listed separately and not merged into the entire Dockerfile.

Account and SSH security optimization

Mainly did two things:

Open an administrator account to modify the port number used by the default ssh

Playbook is as follows:

-hosts: host1 vars: ansible_python_interpreter: / usr/bin/python2 # specifies whether to use python2 to prevent init_ssh_user: admin # from creating users, and disables root password login init_ssh_port: 2849 # whether to modify the default ssh port tasks: # create administrator user Disable root login-block:-name: create user {{init_ssh_user}} user: name: "{{init_ssh_user}}" # this is a symmetric encryption with salt, so it can be reversed. The official website has a way to generate passwords: # https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#how-do-i-generate-encrypted-passwords-for-the-user-module password: "$6 ${{my_secret_salt}} $CSQSsXSoAkwtWDzjlReQ3u0jy1YyxBLouwe403dCVe.ystdi9JQvjSxhoTpYwNoT5nprsJV/UpYb9Ktj.7jLX/" groups: wheel state: present-name: modify / etc/ssh/sshd_config prohibited Root login lineinfile: dest: / etc/ssh/sshd_config state: present regexp: "^ #? PermitRootLogin" line: "PermitRootLogin no" notify: systemctl restart sshd.service when: init_ssh_user is defined # modify ssh port-block:-name: firewall open port {{init_ssh_port}} Firewalld: port: "{{init_ssh_port}} / tcp" state: enabled permanent: yes immediate: yes-name: yum installation policycoreutils-python yum: {name: policycoreutils-python State: present}-name: set selinux: `allowage port-a-t ssh_port_t-p tcp {{init_ssh_port}} `seport: ports: "{{init_ssh_port}}" proto: tcp setype: ssh_port_t state: present-name: modify the port setting lineinfile of / etc/ssh/sshd_config: Dest: / etc/ssh/sshd_config state: present regexp: "^ #? Port" line: "Port {{init_ssh_port}}" notify: systemctl restart sshd.service when: init_ssh_port is defined handlers:-name: systemctl restart sshd.service service: name=sshd.service state=restarted... Verification

Go to the target host to verify:

# docker run-- rm ansible:v1ansible 2.8.4 config file = None configured module search path = ['/ root/.ansible/plugins/modules','/ usr/share/ansible/plugins/modules'] ansible python module location = / usr/local/lib/python3.6/site-packages/ansible executable location = / usr/local/bin/ansible python version = 3.6.8 (default, Apr 25 2019, 21:02:35) [GCc 4.8.5 20150623 (Red Hat 4.8.5-36)] #

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report