By Sai Sarath Chandra, Alibaba Cloud Community Blog author.
IronFunctions is an open-source serverless computing platform that is written in the Go programming Language. IronFunctions was designed for developers to Function as a Service (FaaS), having an infrastructure that allows for easy integration and advance job processing that can significantly reduce task time.
IronFunctions is one of the framework currently used in support of many on-premises deployments in the industry, especially those using AWS Lambda. IronFunctions has the major advantage of allowing people not to be locked in with a certain cloud provider since IronFunctions is open source and can work with any cloud provider. In other words, you can deploy existing AWS format function to other cloud providers, including Alibaba Cloud, if you're using IronFunctions.
In this tutorial, we will discuss how we can install IronFunctions on an Alibaba Cloud Elastic Compute Service (ECS) instance with Ubuntu 18.04. You'll need to create an Alibaba Cloud ECS Instance. Next, you'll also need Docker installed, and you'll have to also install IronFunctions.
When it comes to creating the ECS instance, there are several basic steps which you should pay attention to:
1.Billing method
Make sure you choose Pay-As-You-Go as the billing method if you are prototyping the application
2.Image
You need to select the Ubuntu 18.04 (64-bit)
1.Make sure you select the proper security group here. Of course, though, we can open the ports while we are working on this.
1.For this tutorial, I chose password-based authentication.
1.The complete information for the selected configuration that you choose. Note that you can also save it as a template so that in the future when creating an ECS instance you can do so in a single click.
2.If you wish to release the instance at the later point in time, select the Auto-Release schedule option.
Also, make sure that your instance is up and running like the one below:
Now, let's get your ECS instance ready for the later steps of this tutorial. Open your command line interface and let's do some coding. First, let's connect to the instance using SHH, as shown below:
ssh root@<IP ADDRESS>
The authenticity of host 'AAA.CCC.BBB.DDD' can't be established.
ECDSA key fingerprint is SHA256:/il4fRYvgAake/ENoBgJSZvdO8DxY7H99oeIuye8AEo.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ' AAA.CCC.BBB.DDD ' (ECDSA) to the list of known hosts.
root@<IP ADDRESS>'s password:
Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-23-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Welcome to Alibaba Cloud Elastic Compute Service !
You can update the package entries by running the following command:
sudo apt-get update
Once that's done, we will upgrade any obsolete packages. Next, we will know what packages are to be updated and removed by running the below command:
sudo apt-get upgrade
You will see a similar message as the one below, where it asks for your consent to upgrade:
The following packages were automatically installed and are no longer required:
libopts25 sntp
Use 'sudo apt autoremove' to remove them.
The following packages have been kept back:
linux-generic linux-headers-generic linux-image-generic
The following packages will be upgraded:
amd64-microcode apparmor apt apt-utils base-files bind9-host binutils binutils-common binutils-x86-64-linux-gnu
bsdutils chrony console-setup console-setup-linux cpp cpp-7 cups-bsd cups-client cups-common curl
distro-info-data dnsutils dpkg dpkg-dev fdisk friendly-recovery g++ g++-7 gcc gcc-7 gcc-7-base gcc-8-base
grub-common grub-pc grub-pc-bin grub2-common guile-2.0-libs initramfs-tools initramfs-tools-bin
initramfs-tools-core intel-microcode iperf keyboard-configuration kmod language-pack-en language-pack-en-base
language-pack-gnome-en language-pack-gnome-en-base libapparmor1 libapt-inst2.0 libapt-pkg5.0
libarchive-zip-perl libarchive13 libasan4 libatomic1 libavahi-client3 libavahi-common-data libavahi-common3
libbind9-160 libbinutils libblkid1 libcc1-0 libcilkrts5 libcryptsetup12 libcups2 libcupsimage2 libcurl4
libdns-export1100 libdns1100 libdpkg-perl libfdisk1 libgcc-7-dev libgcc1 libglib2.0-0 libglib2.0-data libgomp1
libirs160 libisc-export169 libisc169 libisccc160 libisccfg160 libitm1 libjpeg-turbo8 libkmod2 liblsan0
liblwres160 libmount1 libmpx2 libmysqlclient20 libnss-systemd libpam-systemd libparted2 libperl5.26
libplymouth4 libpng16-16 libpolkit-gobject-1-0 libpython3-stdlib libpython3.6 libpython3.6-minimal
libpython3.6-stdlib libquadmath0 librados2 librbd1 libsmartcols1 libstdc++-7-dev libstdc++6 libsystemd0
libtsan0 libubsan0 libudev1 libuuid1 libx11-6 libx11-data libxml2 linux-libc-dev lshw man-db mount netplan.io
networkd-dispatcher nplan openssh-client openssh-server openssh-sftp-server parted perl perl-base
perl-modules-5.26 plymouth plymouth-theme-ubuntu-text python-apt-common python3 python3-apt python3-distupgrade
python3-minimal python3-requests python3-update-manager python3.6 python3.6-minimal sntp ssh systemd
systemd-sysv tzdata ubuntu-release-upgrader-core udev update-manager-core util-linux uuid-runtime
148 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
Need to get 79.6 MB of archives.
After this operation, 312 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Input Y
and also if you wish to remove the unused packages, removal can be done by running the following command
sudo apt autoremove
This command will also give the similar prompt asking for the same thing as above. The upgrade will take some time. There might be some warning while it is installing like the one I gave below.
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_CTYPE = "UTF-8",
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
One fix to the warning give above is to do the following. You can run the locale
command. You will see the following output:
locale
LANGUAGE=
LC_CTYPE=C.UTF-8
LC_NUMERIC="C.UTF-8"
LC_TIME="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES="C.UTF-8"
LC_PAPER="C.UTF-8"
LC_NAME="C.UTF-8"
LC_ADDRESS="C.UTF-8"
LC_TELEPHONE="C.UTF-8"
LC_MEASUREMENT="C.UTF-8"
LC_IDENTIFICATION="C.UTF-8"
LC_ALL=
From this you can figure out that you need to set the LC_ALL
and Language
settings by running the following commands:
export LANGUAGE="en_US.UTF-8"
export LC_ALL="en_US.UTF-8"
Before we proceed anything else, we need to point the pip registry to the global site, this can be done by running the following command:
~root@iZa2d4spx9n9e90jofcyxoZ:~# sudo nano /root/.pip/pip.conf
Next, you'll want to replace the output with the below text:
## Note, this file is written by cloud-init on first boot of an instance
## modifications made here will not survive a re-bundle.
###[m
[global]
## index-url=http://ap-south-1.mirrors.cloud.aliyuncs.com/pypi/simple/
index-url=https://pypi.python.org/simple/
[install]
## trusted-host=ap-south-1.mirrors.cloud.aliyuncs.com
trusted-host=pypi.python.org
We need to install all the required tools and other packages using the following command:
sudo apt-get install git python-pip python-setuptools build-essential libssl-dev libffi-dev python-dev software-properties-common
Before you install Docker, you will need to first install Ansible. You can do so with the following command:
sudo pip install ansible==2.1.2.0
If the installation is complete, you will get the following message:
Successfully installed ansible-2.1.2.0 bcrypt-3.1.4 cffi-1.11.5 paramiko-2.4.2 pyasn1-0.4.4 pycparser-2.19 pynacl-1.3.0
You are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Now we will install Docker. To do so, first the key and the repository:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
Next, enter the following:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
Then, update the repository with this command:
~root@iZa2d4spx9n9e90jofcyxoZ:~# sudo apt update
We will set and make sure that the version from the Docker repository is stable. We can also verify that using the Docker command.
~root@iZa2d4spx9n9e90jofcyxoZ:~# apt-cache policy docker-ce
The output will be the following:
docker-ce:
Installed: (none)
Candidate: 5:18.09.0~3-0~ubuntu-bionic
Version table:
5:18.09.0~3-0~ubuntu-bionic 500
500 https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
18.06.1~ce~3-0~ubuntu 500
500 https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
18.06.0~ce~3-0~ubuntu 500
500 https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
18.03.1~ce~3-0~ubuntu 500
500 https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
We will install Docker by running the install command:
sudo apt install docker-ce
You can verify the installation by running the following command:
sudo systemctl status docker
The output will show that it is in the running status:
docker.service - Docker Application Container Engine[m
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Sat CST; 4s ago
Docs: https://docs.docker.com[m
Main PID: 25119 (dockerd)
Tasks: 9
CGroup: /system.slice/docker.service
└─25119 /usr/bin/dockerd -H unix://
Now, we need to make some changes to the configuration file, edit the config file using the command below:
sudo vi /lib/systemd/system/docker.service
Then, update the "ExecStart" with the line below:
/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
We will reload the docker daemon and restart the docker service:
sudo systemctl daemon-reload
sudo systemctl restart docker.service
After we see the status as running, we can check the other environment details by running the following command:
curl http://localhost:2375/version
{"Platform":{"Name":"Docker Engine - Community"},"Components":[{"Name":"Engine","Version":"18.09.0","Details":{"ApiVersion":"1.39","Arch":"amd64","BuildTime":"ABCD","Experimental":"false","GitCommit":"4d60db4","GoVersion":"go1.10.4","KernelVersion":"4.15.0-23-generic","MinAPIVersion":"1.12","Os":"linux"}}],"Version":"18.09.0","ApiVersion":"1.39","MinAPIVersion":"1.12","GitCommit":"4d60db4","GoVersion":"go1.10.4","Os":"linux","Arch":"amd64","KernelVersion":"4.15.0-23-generic","BuildTime":"ABCD"}
Now it's about time that you install and configure IronFunctions. Before we install IronFunctions we need to install screen, which will help us to run multiple processes in linux. To install screen run the following command:
apt install screen
Also, login to docker hub by running the following command:
docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: <your username>
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Then, start a new process "screen":
docker run --rm -it --name functions -v ${PWD}/data:/app/data -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 iron/functions
Unable to find image 'iron/functions:latest' locally
latest: Pulling from iron/functions
+ eval dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=overlay2
+ dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=overlay2
can't create unix socket /var/run/docker.sock: device or resource busy
+ echo Docker crashed with exit code 1. Respawning..
Docker crashed with exit code 1. Respawning..
+ pidfile=/var/run/docker/libcontainerd/docker-containerd.pid
+ cat /var/run/docker/libcontainerd/docker-containerd.pid
cat: can't open '/var/run/docker/libcontainerd/docker-containerd.pid': No such file or directory
+ kill -9
sh: you need to specify whom to kill
+ exec ./functions
INFO Serving Functions API on address `:8080`
INFO Halting...
If successful, you will see the cli version as below:
curl -LSs git.io/ironfn | sh
fn version 0.2.72
Now, that that's finished we can go ahead to install IronFunctions. To do so, create a directory and a function:
sudo nano func.go
Then, copy the function definition to the file:
package main
import (
"encoding/json"
"fmt"
"os"
)
type Person struct {
Name string
}
func main() {
p := &Person{Name: "World"}
json.NewDecoder(os.Stdin).Decode(p)
fmt.Printf("Hello %v!", p.Name)
}
Run the following commands in the same folder
# create func.yaml file, replace $USERNAME with your Docker Hub username.
fn init <docker username>/hello
# build the function
fn build
# test it - you can pass data into it too by piping it in, eg: `cat hello.payload.json | fn run`
fn run
Hello World!
# Once it's ready, build and push it to Docker Hub
fn build && fn push
Running prebuild command: docker run --rm -v /root/test:/go/src/github.com/x/y -w /go/src/github.com/x/y iron/go:dev go build -o func
Building image saichandu415/hello:0.0.1
Sending build context to Docker daemon 557.1kB
Sending build context to Docker daemon 2.333MB
Step 1/4 : FROM iron/go
---> ed7df0451f6c
Step 2/4 : WORKDIR /function
---> Using cache
---> 9de3968aa402
Step 3/4 : ADD . /function/
---> Using cache
---> 3136a9e9ae54
Step 4/4 : ENTRYPOINT ["./func"]
---> Using cache
---> 6235a1829834
Successfully built 6235a1829834
Successfully tagged saichandu415/hello:0.0.1
Function saichandu415/hello:0.0.1 built successfully.
# create an app - you only do this once per app
fn apps create myapp
myapp created
# create a route that maps /hello to your new function
fn routes create myapp /hello
/hello created with saichandu415/hello:0.0.1
You can test the functions here by running the following command:
curl http://localhost:8080/r/myapp/hello
Hello World!
We can also achieve the same result by using the functions UI, which can be installed by running the following command:
docker run --rm -it --link functions:api -p 4000:4000 -e "API_URL=http://api:8080" iron/functions-ui:0.0.2
Unable to find image 'iron/functions-ui:0.0.2' locally
0.0.2: Pulling from iron/functions-ui
> FunctionsUI@0.0.2 start /app
> node server
Using API url: api:8080
Server running on port 4000
We have the function running at port 4000 on the public IP of ECS instance:
You can create an app by clicking the Create App button and enter a name and config information if you have it:
Once you create the application, we can create a function by choosing Add Route and fill in all the corresponding information.
You can test the function directly from the IronFunctions UI.
2,599 posts | 764 followers
FollowAlibaba Clouder - August 1, 2019
Alibaba Clouder - June 3, 2020
Alibaba Cloud Serverless - August 4, 2021
Alibaba Container Service - July 29, 2019
Alibaba Clouder - August 1, 2019
Xi Ning Wang(王夕宁) - August 7, 2023
2,599 posts | 764 followers
FollowElastic and secure virtual cloud servers to cater all your cloud hosting needs.
Learn MoreAlibaba Cloud Function Compute is a fully-managed event-driven compute service. It allows you to focus on writing and uploading code without the need to manage infrastructure such as servers.
Learn MoreLearn More
More Posts by Alibaba Clouder